New Composite ObjectsΒΆ
Extending hoobas for new molecules is easy in most cases. There are three general scenarios depending on your needs :
- Use an existing class such as
hoobas.LinearChain.RandomPolymer - Inherit an existing class and overload the
hoobas.Composite.CompositeObject.build()method - Create an entire new class based on
hoobas.Composite.CompositeObject
The first case is covered in various examples and tutorials. If the molecule or object needs to be packaged for
dissemination, for instance as part of a publication, then the object simply has to be inherited and the constructor
overloaded. The hoobas.LinearChain.PolyStyreneSulfonateChain class is an example of this kind of packaging.
Overloading build()
The build function has no arguments and is invoked once per object added to the simulation. It needs to rely on arguments passed in the constructor (__init__) method. Developpers should assume that users are passing objects with arbitrary types and generally functions in. Such functions may depend on named arguments that should be queried from the CompositeObject. Let us consider a prototype class
class NewMolecule(hoobas.LinearChain.LinearChain):
def __init__(self, an_argument):
self.arg = an_argument
super(NewMolecule, self).__init__()
def build(self):
if hasattr(self.arg, '__call__'):
self.arg = self.arg(**self.resolve_args(self.arg))
# actually do some cool stuff with self.arg
super(NewMolecule, self).build()
The constructor defines a prototype for the molecule and since it is copied for every individual molecule in the simulation and thus changing the value of self.arg in build() will only affect the current molecule. Constructor arguments which cannot be called should be clearly indicated in the docstring and should be exceptions rather than norm.
Incorporating bonded force-fields
Complicated molecules, such as DNA, often come with force-field parametrizations. We generally recommend including bonded force-fields into the constructor itself. The constructor should also impose the units of the object by making sure the parameter units is correctly passed back to CompositeObject
class NewMolecule(hoobas.LinearChain.LinearChain):
def __init__(self, argument):
units = Units.SimulationUnits(mass='amu', energy='kJ/mol', length='nm')
super(NewMolecule, self).__init__(units)
self.arg = argument
self.b_types += Composite.BondType('ParametrizeBond', topodict={'P1': 1.0, 'P2':2.0}, unitdict={'P1':'L', 'P2':'E'})
self.a_types += Composite.AngleType('ParametrizedAngle', topodict={'P1':1.0, 'P2':3.1416}, unitdict={'P1':'E', 'P2':''})
Whenever the NewMolecule is added to another object (grafted or simply inserted into a box), the bonded force-field units will automatically be converted.