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.

Methods of DIP class

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

definitions.dip
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

modifications.dip
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.

definitions.dip
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.

modifications.dip
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')
}