代码:
class EquipartitionTest(Test):
@classmethod
def parser(cls):
parser = argparse.ArgumentParser(
description='Tests the equipartition of the kinetic energy.',
formatter_class=argparse.RawTextHelpFormatter,
prog=cls.__name__
)
parser.add_argument('--distribution', default=False, action='store_true',
help=('If set, the groups of degrees of freedom will\n'
'be separately tested as Maxwell-Boltzmann\n'
'distributions. Otherwise, only the difference in\n'
'average kinetic energy is checked.'))
parser.add_argument('-t', '--tolerance', type=float, default=0.1,
help=('If --distribution is set:\n'
' The alpha value (confidence interval) used in the\n'
' statistical test. Default: 0.1.\n'
'Else:\n'
' The maximum deviation allowed between groups.\n'
' Default: 0.1 (10%%)'))
parser.add_argument('--random_groups', type=int, default=0,
help='Number of random division tests attempted.\n'
'Default: 0 (random division tests off).')
parser.add_argument('--random_divisions', type=int, default=2,
help='Number of groups the system is randomly divided in.\n'
'Default: 2.')
parser.add_argument('--molec_group', type=int, nargs='*', default=None, action='append',
help=('List of molecule indeces defining a group. Useful to\n'
'pre-define groups of molecules\n'
'(e.g. solute / solvent, liquid mixture species, ...).\n'
'If not set, no pre-defined molecule groups will be\ntested.\n'
'Note: If the last --molec-group flag is given empty,\n'
'the remaining molecules are collected in this group.\n'
'This allows, for example, to only specify the solute,\n'
'and indicate the solvent by giving an empty flag.'))
return parser
这段代码是一个Python类,名为EquipartitionTest,它继承了另一个名为Test的类。这个类提供了一个名为parser的类方法,该方法返回一个argparse.ArgumentParser对象,用于解析命令行参数。这些参数控制了一个测试程序,用于检测气体分子是否遵循平均动能定理,即在温度相同的情况下,每个自由度(每个方向的速度)的平均动能应该相等。具体来说,这个测试程序可以通过检查不同自由度的平均动能之间的差异来检测这一点,也可以将自由度分成不同的组,检查每组之间的平均动能之间的差异是否遵循Maxwell-Boltzmann分布。这个类方法接受几个参数,包括 --distribution(控制是否进行分布检验)、--tolerance(控制允许的误差范围)、--random_groups(控制随机分组测试的数量)、--random_divisions(控制随机分组的组数)和 --molec_group(用于定义分组的分子序号列表)。
接着写这个类:
@classmethod
def prepare(cls, input_dir, target_dir, system_name, nobackup):
# no additional sims needed, base is enough
# could check position, velocity & energy writing settings
return []
@classmethod
def prepare_parser(cls, input_dir, target_dir, system_name, nobackup, args):
return cls.prepare(input_dir, target_dir, system_name, nobackup)
@classmethod
def analyze_parser(cls, gmx_parser, system_dir, system_name, base_data, verbosity, args):
args = cls.parser().parse_args(args)
return cls.analyze(gmx_parser, system_dir, system_name, base_data, verbosity,
tolerance=args.tolerance, distribution=args.distribution,
random_groups=args.random_groups, random_divisions=args.random_divisions,
molec_group=args.molec_group)
这段代码使用了类方法(classmethod)和类变量(cls),其中包含了三个类方法:prepare、prepare_parser 和 analyze_parser。这些方法用于对数据进行准备、解析和分析。其中,prepare 方法接受输入目录、目标目录、系统名称和备份选项作为参数,返回一个空列表;prepare_parser 方法也接受相同的参数,并调用 prepare 方法返回结果;analyze_parser 方法接受更多的参数,包括 Gromacs 解析器(gmx_parser)、系统目录、系统名称、基础数据、详细程度、以及其他的一些参数。它也会调用类方法 parser() 来解析参数,最终返回一个分析结果。
接着写这个类:
@classmethod
def analyze(cls, gmx_parser, system_dir, system_name, base_data, verbosity,
tolerance=None, distribution=None,
random_groups=None, random_divisions=None,
molec_group=None):
# Standard values
if tolerance is None:
tolerance = cls.parser().get_default('tolerance')
if distribution is None:
distribution = cls.parser().get_default('distribution')
if random_groups is None:
random_groups = cls.parser().get_default('random_groups')
if random_divisions is None:
random_divisions = cls.parser().get_default('random_divisions')
if molec_group is None:
molec_group = cls.parser().get_default('molec_group')
# base data
if base_data['full'] is None:
current_dir = os.path.join(system_dir, 'base')
base_data['full'] = gmx_parser.get_simulation_data(
mdp=os.path.join(current_dir, 'mdout.mdp'),
top=os.path.join(current_dir, 'system.top'),
edr=os.path.join(current_dir, 'system.edr'),
gro=os.path.join(current_dir, 'system.trr')
)
base_result = base_data['full'] # 基本数据
# 调用平衡函数计算结果
result = kinetic_energy.equipartition(base_result,
dtemp=tolerance, alpha=tolerance,
distribution=distribution, molec_groups=molec_group,
random_divisions=random_divisions, random_groups=random_groups,
verbosity=0)
这个Python代码段定义了一个名为“analyze”的类方法(classmethod)。该方法接受gmx_parser,system_dir,system_name,base_data,verbosity,tolerance,distribution,random_groups,random_divisions和molec_group等参数。接下来,该方法使用默认值或给定值设置了tolerance,distribution,random_groups,random_divisions和molec_group等变量。如果base_data['full']为空,该方法将获取模拟数据并将其存储在base_result变量中。最后,该方法使用equipartition函数对base_result进行操作,该函数接受dtemp,alpha,distribution,molec_groups,random_divisions,random_groups和verbosity等参数。
接着写这个类:
if distribution:
res = min(result)
test = res >= tolerance
if test:
message = 'EquipartitionTest PASSED (min p = {:g}, alpha = {:f})'.format(res, tolerance)
else:
message = 'EquipartitionTest FAILED (min p = {:g}, alpha = {:f})'.format(res, tolerance)
else:
dev_min = min(result)
dev_max = max(result)
if (1-dev_min) > (dev_max-1):
res = dev_min
else:
res = dev_max
test = res <= tolerance
if test:
message = 'EquipartitionTest PASSED (max dev = {:g}, tolerance = {:f})'.format(res, tolerance)
else:
message = 'EquipartitionTest FAILED (max dev = {:g}, tolerance = {:f})'.format(res, tolerance)
return {'test': test,
'result': res,
'tolerance': tolerance,
'message': message}
该代码是一个函数,它根据输入的参数计算结果,然后返回一个字典,其中包含以下四个键值对:
- 'test': 布尔值,表示测试是否通过。
- 'result': 浮点数,表示测试的结果。
- 'tolerance': 浮点数,表示测试的容差。
- 'message': 字符串,表示测试的结果和容差。
函数的第一个参数是'distribution',它是一个布尔值。如果该值为True,函数将使用分布数据来执行测试。否则,函数将使用非分布数据来执行测试。
如果输入参数'distribution'为True,那么函数将执行一个EquipartitionTest,这是一个用于检测数据集中的值是否接近于均匀分布的统计测试。该测试的结果是一个浮点数'res',代表检测结果中最小的概率。如果'res'的值大于等于给定的容差值'tolerance',那么测试将被视为通过,否则测试失败。函数将根据测试结果和容差值生成一条测试结果信息'message',并返回包含测试结果的字典。
如果输入参数'distribution'为False,则函数将执行另一种测试,并返回包含测试结果的字典。在这种情况下,函数将找到结果中的最小值'dev_min'和最大值'dev_max'。如果 1 - dev_min 的值大于 dev_max - 1的值,那么 'res' 将等于 'dev_min',否则 'res' 将等于 'dev_max'。与分布测试类似,如果 'res' 小于等于给定的容差值 'tolerance',那么测试将被视为通过,否则测试失败。函数将根据测试结果和容差值生成一条测试结果信息 'message',并返回包含测试结果的字典。