Parameter parsing
DIP code is used both: for definition of parameters by a code developer and for their modification by a code user. The definitions and modifications can be composed together and parsed as a parameter list that is later used by the code.
The DIP
class has following methods that can be used to combine various parts of DIP code together and parse resulting parameters.
Method |
Description |
---|---|
add_string(code:str) |
adds DIP code from a string |
add_file(filepath:str, source_name:str, absolute:bool) |
adds DIP code from a file |
add_source(name:str, path:str) |
adds a custom source |
add_unit(name:str, value:float, unit:str) |
adds a custom unit |
add_function(name:str, fn:Callable) |
adds a custom function |
parse() |
parse parameter environment |
parse_docs() |
parse documentation environment |
Direct modifications
Consider the following parameter definition file of a generic astrophysical numerical code
module
hydrodynamics bool = true
radiation bool = false
gravitation bool = false
simulation_box
grid str = "cartesian"
= "cartesian"
= "cylindrical"
= "spherical"
size float = 2 Mpc
and a modification file created by its user
module.radiation = true
module.gravitation = true
simulation_box.size = 5 Mpc
The final set of parameters can be obtained by parsing these two files together:
>>> from scinumtools.dip import DIP
>>>
>>> with DIP() as dip:
>>> dip.add_file('definitions.dip')
>>> dip.add_file('modifications.dip')
>>> env = dip.parse()
Parsed parameters can be then obtained in a form of a Python dictionary, while several output formats are available:
>>> from scinumtools.dip.settings import Format
>>>
>>> # Values are returned as Python datatypes
>>> env.data()
{
'module.hydrodynamics': True,
'module.radiation': True,
'module.gravitation': True,
'simulation_box.grid': 'cartesian',
'simulation_box.size': 5.0
}
>>> # Numbers with units are returned as tuples
>>> env.data(Format.TUPLE)
{
'module.hydrodynamics': True,
'module.radiation': True,
'module.gravitation': True,
'simulation_box.grid': 'cartesian',
'simulation_box.size': (5.0, 'Mpc')
}
>>> # Numbers are returned as Quantity objects
>>> env.data(Format.QUANTITY)
{
'module.hydrodynamics': True,
'module.radiation': True,
'module.gravitation': True,
'simulation_box.grid': 'cartesian',
'simulation_box.size': Quantity(5.000e+00 Mpc)
}
>>> # Values are returned as DIP datatypes
>>> env.data(Format.TYPE)
{
'module.hydrodynamics': BooleanType(True),
'module.radiation': BooleanType(True),
'module.gravitation': BooleanType(True),
'simulation_box.grid': StringType(cartesian),
'simulation_box.size': FloatType(5.0 Mpc)
}
Modifications using references
References and branching in DIP files bring an additional level of complication to the parameter parsing. In the case below, some of the nodes (e.g. box dimensions) depend on user settings.
module
hydrodynamics bool = true
radiation bool = false
gravitation bool = false
{mods?module.*}
simulation_box
grid str = {mods?simulation_box.grid}
= "cartesian"
= "cylindrical"
= "spherical"
size float = {mods?simulation_box.size} Mpc
@case ("{?simulation_box.grid}=='cartesian'")
size.x float = {?simulation_box.size} Mpc
size.y float = {?simulation_box.size} Mpc
size.z float = {?simulation_box.size} Mpc
@case ("{?simulation_box.grid}=='cylindrical'")
size.r float = {?simulation_box.size} Mpc
size.h float = {?simulation_box.size} Mpc
@else
size.r float = {?simulation_box.size} Mpc
The definition file cannot be simply modified, as in the previous section. One has to define a modification source first.
module.radiation = true
simulation_box.grid = "cylindrical"
simulation_box.size = 5 Mpc
Parsing of parameters in this case can be done in the following way:
>>> from scinumtools.dip import DIP
>>> from scinumtools.dip.settings import Format
>>>
>>> with DIP() as dip:
>>> dip.add_source('mods','modifications.dip')
>>> dip.add_file('definitions.dip')
>>> env = dip.parse()
>>> env.data(Format.TUPLE)
{
'module.hydrodynamics': True,
'module.radiation': True,
'module.gravitation': False,
'simulation_box.grid': 'cylindrical',
'simulation_box.size': (5.0, 'Mpc'),
'simulation_box.size.r': (5.0, 'Mpc'),
'simulation_box.size.h': (5.0, 'Mpc')
}