-
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.
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.
With regards mathematical operands, favour a space separating both sides of an operand:
E = h_bar * 1e18 * np.pi * np.arange(n) / (n * dt)
instead of:
E = h_bar*1e18*np.pi*np.arange(n)/(n*dt)
If an expression runs over two lines, prefer brackets to backslash, and align expressions in the same manner as for mathematical formula (i.e. new line should start with operand):
E = (h_bar * 1e18 * np.pi
* np.arange(n) / (n * dt))
instead of:
E = h_bar * 1e18 * np.pi\
* np.arange(n) / (n * dt)
or:
E = (h_bar * 1e18 * np.pi *
np.arange(n) / (n * dt))
Imports should be grouped in the following order:
- stdlib
- third party libraries
- local modules
Each group should be sorted alphabetically and should be separated by a newline.
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
It is then obviously important that all functions and methods that use these properties have the correct factors to ensure the unit conversions are correct.
MDMC follows the NumPy documentation style, which is consistent with PEP 257. The exceptions to this are:
- The Attributes section should be the last section in a class docstring. This is because Sphinx formats Attributes in the same manner to methods (without a heading), so it leads on to this.
Use a code checker or linter such as pylint or flake8, to ensure PEP 8 coding standards are adopted.