-
Notifications
You must be signed in to change notification settings - Fork 0
Developer Documentation
Please read this documentation before modifying the MDMC code base. Any pull requests that are not consistent with this documentation will not be merged.
Follow standards described in PEP 8, except where it differs from standards already adopted in surrounding code. For example, snake_case is used for all variables names, except when the variable contains an abbreviation. So a variable related to a molecular dynamics (MD) engine is MD_engine, rather than md_engine. The same applies for physical symbols, e.g. Q for momentum transfer and E for energy should both be upper case.
All physical quantities within MDMC should possess units.
Everything related to units in MDMC is defined in MDMC.common.units. This includes:
- the system of units (in the SYSTEM dictionary)
- A Unit class, which derives from str to add additional mul, div, and pow methods so that strings representing units (e.g.
'Ang','s') can be combined by these operations:Unit('Ang') * Unit('s') == Unit('Ang s') - UnitFloat and UnitArray classes, which derive from float and numpy.ndArray to add additional a Unit object to the representation, by means of a unit attribute.
So all physical quantities must be a UnitFloat or a UnitArray, and have the correct Unit object as an attribute. This can be achieved by having the unit as a property, rather than an attribute, and using one of the following decorators (in MDMC.common.decorators):
- unit_decorator. This should typically be the decorator that is used as it sets the property to be either a UnitFloat or UnitArray. It should be added to the property setter:
@property
def velocity(self):
return self._velocity
@velocity.setter
@unit_decorator(unit=units.LENGTH / units.TIME)
def velocity(self, velocity):
self._velocity = velocity
- unit_decorator_getter. This only be used either where the property has no setter method or where the getter method performs a calculation before setting the value (which may result in the UnitFloat/UnitArray being cast to a float/ndArray). It should only be used in these cases as it is more expensive than unit_decorator, as it initialises a UnitFloat/UnitArray object every time the getter is called. It should be added to the property getter:
@property
@unit_decorator_getter(unit=units.LENGTH)
def dims(self):
return self._dims
In both of the above examples the unit passed to the decorator is a constant from the SYSTEM of units defined in the units module; however it would be equally valid to define a unit in this argument:
from MDMC.common.units import Unit
@property
@unit_decorator_getter(unit=Unit('nm'))
def dims(self):
return self._dims
MDMC follows the NumPy documentation style, which is consistent with PEP 257.
Use a code checker or linter such as pylint or flake8, to ensure PEP 8 coding standards are adopted.