Source code for ionize.IonComplex.IonComplex
from ..Ion import BaseIon, fixed_state
import contextlib
@fixed_state
class IonComplex(BaseIon):
"""IonComplex is a collection of ions that moves together.
:param name: The name for the complex.
:param members: An iterable of ion objects that make up the complex.
"""
_state = {'name': 'Name of the ion.',
'members': 'Components of the ion complex.'}
_members = tuple()
def __init__(self, name, members):
assert all(isinstance(member, BaseIon) for member in members), \
'All inputs to a complex must be Ions.'
self._name = name
self._members = tuple([member for member in members])
def context(self, context=False):
"""Control the context of the ion.
Complex contexts works by setting the context of the members of the
complex. The Complex has on context of its own.
See the context method for the members for additional information.
"""
old_context = [member.context() for member in self.members]
if context is False:
return tuple(old_context)
# Update to new context, save old_context
[member.context(context) for member in self.members]
# Return a context manager to revert to old_context
@contextlib.contextmanager
def manager():
yield
[member.context(context)
for member, old in zip(self.members, old_context)]
return manager()
def charge(self, pH=None, ionic_strength=None, temperature=None,
moment=1):
"""Return the net charge for the complex."""
return sum([member.charge(pH, ionic_strength, temperature) for
member in self.members])**moment
def mobility(self, pH=None, ionic_strength=None, temperature=None):
"""Return the mobility of the complex, in m^2/V/s."""
# NOTE: relies on the molecular-weight averaged mobility
return sum([member.mobility(pH, ionic_strength, temperature) *
member.molecular_weight / self.molecular_weight
for member in self])
@property
def molecular_weight(self):
try:
return sum([member.molecular_weight for member in self.members])
except TypeError:
raise TypeError('Each member must have a numeric molecular '
'weight to compute the complex weight.')
def __getitem__(self, idx):
return self.members[idx]
def __iter__(self):
return (member for member in self.members)