管理模拟运行的建议?

计算科学 蒙特卡洛 数据管理
2021-12-19 08:13:05

这个问题在 comp-sci 中可能有点离题。如果需要,请建议它适合的位置。

问题是关于如何有效地管理所有模拟运行。

比方说,例如,模拟需要修复 2 个必须在某个建议值范围内定义的参数。

为了找到由两个参数中的一对产生的更好结果(例如,通过将模拟结果与实验数据进行比较),可以通过为每个参数定义三个值来进行敏感性分析,然后制定 9 次运行。

以前我使用sed更改每次运行的输入,并通过在存储此运行的输入和结果的文件夹上写入值和参数名称来标记每次运行。但是我发现一旦参数数量增加(例如访问脚本中的文件夹名称以进行绘图),这将非常低效。

然后我决定使用简单的数字作为文件夹名称,并通过其他一些电子表格存储详细信息。到目前为止,这种方式还可以,但需要一些费力的工作。同样随着跑步次数的增加,犯错误也变得很常见,例如进行几天前已经完成的另一次跑步。

您对管理这些运行有什么好主意吗?我认为这对于进行蒙特卡洛分析的人来说非常重要?

提前致谢!

2个回答

TLDR
使用 Python 管理/修改您的输入和珊瑚您的输出,并使用 HDF5 来组织/存储您的数据。尽管起初看起来很复杂,但它仍然比 SQL-anything 更简单。

更长的答案 + 示例
我个人使用 Python 脚本和 HDF5 文件格式的组合来处理这些情况。Python 脚本可以处理更改运行文件所需的文本替换(并且可以检查重复运行),并且通过更多脚本,您可以从程序中获取输出数据并将其放入 HDF5 文件中。

最容易将 HDF5 视为或多或少完全类似于普通文件系统(即计算机上的目录和子目录集),但可以轻松扩展到大型数据集。每个目录/子目录都可以用元数据标记(在您的情况下,只是您正在改变的参数,或者整个参数集)。当需要分析数据时,您可以根据元数据进行搜索。

下面是一个简短的例子,它基于我的一些模拟数据(已经是 HDF5 格式)如何工作,如下所示:

mydata.hdf5
|___Run01(metadata: {size:13, maxSteps:1e7, maxTime:inf})
|___Run02(metadata: {size:10, maxSteps:1e6, maxTime:inf})
|___Run03(metadata: {size:13, maxSteps:1e7, maxTime:inf})
|___Run04(metadata: {size:9, maxSteps:1e7, maxTime:inf})

mydata.hdf5是 HDF5 文件,每个 Runxx 都是一个子目录,用于保存来自给定模拟的输出数据,并用相关元数据进行标记。搜索运行并返回具有所需元数据的列表的 python 脚本如下所示:

import sys
import h5py    #the python module that interfaces with HDF5

def GetRuns(hdfRoot, attributeValuePairs):
    return [subdir for subdir in hdfRoot.values() if not(attributeValuePairs.viewitems() - dict(subdir.attrs).viewitems())]

if __name__=="__main__":
    attributeValuePairs = dict(zip(sys.argv[2::2], sys.argv[3::2]))
    with h5py.File(sys.argv[1]) as hdfRoot:
        runs = GetRuns(hdfRoot, attributeValuePairs)

        #do something here with runs...

        print runs

因此,如果我在包含目录的命令行中,mydata.hdf5我可以像这样运行上面的脚本:

python myscript.py mydata.hdf5 maxSteps 1e7 size 13

这将告诉脚本查找任何元数据部分或全部匹配的运行{'maxSteps':'1e7', 'size':'13'}然后,该脚本可以按照您喜欢的方式操作该数据(在“在这里做一些事情”部分),然后它会打印一个看起来像这样的列表:

["Run01", "Run03"]

不过需要注意的是,只有当可以将您的数据表示为一组 n 维数组时,HDF5 才会为您的数据呈现完全自然的映射。模拟的输出在某种数组中是很常见的,所以这可能不是问题。

良好的起点
Python:http
://www.openbookproject.net/thinkcs/python/english2e/ HDF5:http ://www.h5py.org/docs/

我认为我们需要更多地了解您的工作流程才能提出任何严肃的建议。

我建议将您的运行视为键值存储。为每次运行的所有元数据创建一个简单的数据库,然后将运行中的任何相关信息散列到分配给每个输出的键中。

在最简单的情况下,您将使用文本文件存储元数据,并安全地将有关每次运行的元数据行附加到您的文本文件中。然后,您可以随心所欲地存储输出运行(单个目录、带有内容列表的备份等...)

你可以用任何你喜欢的语言来实现这个策略,但这在 Python 中是微不足道的。您还可以利用一些不错的功能,例如 Python 读取和写入 JSON 数据或与 SQL 数据库交互的能力。

这种方法实现了一个非常简单的轻量级数据库。有更重的策略可以提供更多的安全保证,您可能感兴趣的一个新策略是SciDB数据库为您的数据提供更强大的保证,并帮助您针对更大的数据集扩展您的方法。