格式化模拟输出的良好实践

时间:2011-06-17 20:36:21

标签: simulation

这几乎是一个编程问题,但面向物理学家。

假设我正在编写一个软件,它将一些系统参数作为输入,然后从中计算一些东西,在我的例子中是一个频谱函数$ A(k,\ omega)$。

当我想取输出并将其输入到gnuplot时,我应该让程序输出一个简单的表,其中一列为$ k $ -values,一列为$ \ omega $,另一列为$ A(k) ,\欧米加)$。

但是我无法存储所有附加信息,例如使用了哪些参数。也许我想在输出中存储一些额外的调试信息,例如中间数量。在我的例子中,光谱函数是从自身能量获得的,所以在某些情况下我可能想直接看自身能量。

我不想根据我想要的输出不断破解源代码。如果 all “运行”的相关数据将出现在单个文件/实体中会更好,但是仍然可以很容易地提取我可以提供给gnuplot的表。

不想重新发明轮子并开发完整的文件格式,在创建,处理和存储计算或模拟数据时最好使用一些“标准”吗?甚至可能是SQL数据库格式?

2 个答案:

答案 0 :(得分:1)

有几十种方法,没有太好的方法;我会分享两个我的:

  1. 如果该程序是值得的,我添加一个小的配置文件解析器。然后我就制作一个cofig,比方说SimA.in,模拟器会生成一堆包含相应数据SimA.pathsSimA.statsSimA.log等的文件。除非这些名称是独特的,我添加了代码版本进行记录,这使得结果完全可重复,模拟本身便于移植,易于管理。
  2. 如果没有,我只需稍微包装一下代码并使用R作为主机。然后我只返回所有数组和标量(R数据结构非常灵活,很容易构建原生R或C结构)并使用R来管理,保存/加载,当然还可以显示和分析数据。此外,通过Sweave和CacheSweave,整个执行,分析和报告可以优雅地捆绑在一起,完全可以通过一个命令重现。
  3. 如果您需要“企业”解决方案,请尝试NetCDFHDF5。但我觉得这可能有点过头了。

    当然,必须对模拟器代码进行版本控制。但那很明显=)

答案 1 :(得分:0)

对于我目前正在使用Python和C ++(通过SWIG)的项目,我打算使用一个简短的python脚本作为输入文件。因此,在某种程度上,我将“破解源代码”以更改参数,但是使用解释语言,而不是编译语言。

目前,我计划有一个像parameters.py这样的输入文件,并像from parameters import params一样使用它。但这可能过于依赖正确的语法。

params = {
"foods" : ["spam", "beans", "eggs"],
"costs" : [199, 4, 1],
"customerAge" : 23,
}

另一种选择可能是在parameters2.py中仅在脚本级别定义变量。这会丢失漂亮的字典包装,但却让用户更加难以理解它。而编写一个将这些脚本级变量放入一个漂亮的字典中的“解析器”可能并不困难。方法的一个优点是用户可以参数化最初未考虑的事物 - from parameters2 import *将覆盖这些参数的先前定义。当然,如果用户覆盖重要的内容,这可能会很糟糕。

foods = ["spam", "beans", "eggs"]
costs = [199, 4, 1]
customerAge = 23

parameters3.py会使用一个类,但Python对缩进的持续性是禁忌的。 from parameters3 import params

class params:
    foods = ["spam", "beans", "eggs"]
    costs = [199, 4, 1]
    customerAge = 23

为了完整起见,我还应该提一下,我们的C ++代码也定义了一个参数类。也就是说,在我们的实际项目中,parameters.py是相应C ++类的SWIG包装器。你会像from parameters4 import params一样使用。但是,这只允许已经在C ++类中声明的参数。

import parameters
params = parameters.Parameters()
params.foods = ["spam", "beans", "eggs"]
params.costs = [199, 4, 1]
params.customerAge = 23