class PipeContainer(Prototype): """Class containing all the program data.""" def __init__(self): """Set up all the PipeContainer data structures.""" # The molecule-residue-spin object. self.mol = MoleculeList() # The interatomic data object. self.interatomic = InteratomList() # The data pipe type. self.pipe_type = None # Hybrid models. self.hybrid_pipes = [] def __repr__(self): """The string representation of the object. Rather than using the standard Python conventions (either the string representation of the value or the "<...desc...>" notation), a rich-formatted description of the object is given. """ # Intro text. text = "The data pipe storage object.\n" # Special objects/methods (to avoid the getattr() function call on). spec_obj = ['exp_info', 'mol', 'interatomic', 'diff_tensor', 'structure'] # Objects. text = text + "\n" text = text + "Objects:\n" for name in dir(self): # Molecular list. if name == 'mol': text = text + " mol: The molecule list (for the storage of the spin system specific data)\n" # Interatomic data list. if name == 'interatomic': text = text + " interatomic: The interatomic data list (for the storage of the inter-spin system data)\n" # Diffusion tensor. if name == 'diff_tensor': text = text + " diff_tensor: The Brownian rotational diffusion tensor data object\n" # Molecular structure. if name == 'structure': text = text + " structure: The 3D molecular data object\n" # The experimental info data container. if name == 'exp_info': text = text + " exp_info: The data container for experimental information\n" # Skip the PipeContainer methods. if name in list(self.__class__.__dict__.keys()): continue # Skip certain objects. if match("^_", name) or name in spec_obj: continue # Add the object's attribute to the text string. text = text + " " + name + ": " + repr(getattr(self, name)) + "\n" # Return the text representation. return text def _back_compat_hook(self, file_version=None): """Method for converting old data structures to the new ones. @keyword file_version: The relax XML version of the XML file. @type file_version: int """ # Relaxation data. self._back_compat_hook_ri_data() def _back_compat_hook_ri_data(self): """Converting the old relaxation data structures to the new ones.""" # Nothing to do. if not (hasattr(cdp, 'frq_labels') and hasattr(cdp, 'noe_r1_table') and hasattr(cdp, 'remap_table')): return # Initialise the new structures. cdp.ri_ids = [] cdp.ri_type = {} frq = {} # This will be placed into cdp later as cdp.spectrometer_frq still exists. # Generate the new structures. for i in range(cdp.num_ri): # The ID. ri_id = "%s_%s" % (cdp.ri_labels[i], cdp.frq_labels[cdp.remap_table[i]]) # Not unique. if ri_id in cdp.ri_ids: # Loop until a unique ID is found. for j in range(100): # New id. new_id = "%s_%s" % (ri_id, j) # Unique. if not new_id in cdp.ri_ids: ri_id = new_id break # Add the ID. cdp.ri_ids.append(ri_id) # The relaxation data type. cdp.ri_type[ri_id] = cdp.ri_labels[i] # The frequency data. frq[ri_id] = cdp.frq[cdp.remap_table[i]] # Delete the old structures. del cdp.frq del cdp.frq_labels del cdp.noe_r1_table del cdp.num_frq del cdp.num_ri del cdp.remap_table del cdp.ri_labels # Set the frequencies. cdp.frq = frq def from_xml(self, pipe_node, file_version=None, dir=None): """Read a pipe container XML element and place the contents into this pipe. @param pipe_node: The data pipe XML node. @type pipe_node: xml.dom.minidom.Element instance @keyword file_version: The relax XML version of the XML file. @type file_version: int @keyword dir: The name of the directory containing the results file (needed for loading external files). @type dir: str """ # Test if empty. if not self.is_empty(): raise RelaxFromXMLNotEmptyError(self.__class__.__name__) # Get the global data node, and fill the contents of the pipe. global_node = pipe_node.getElementsByTagName('global')[0] xml_to_object(global_node, self, file_version=file_version) # Backwards compatibility transformations. self._back_compat_hook(file_version) # Get the hybrid node (and its sub-node), and recreate the hybrid object. hybrid_node = pipe_node.getElementsByTagName('hybrid')[0] pipes_node = hybrid_node.getElementsByTagName('pipes')[0] setattr(self, 'hybrid_pipes', node_value_to_python(pipes_node.childNodes[0])) # Get the experimental information data nodes and, if they exist, fill the contents. exp_info_nodes = pipe_node.getElementsByTagName('exp_info') if exp_info_nodes: # Create the data container. self.exp_info = ExpInfo() # Fill its contents. self.exp_info.from_xml(exp_info_nodes[0], file_version=file_version) # Get the diffusion tensor data nodes and, if they exist, fill the contents. diff_tensor_nodes = pipe_node.getElementsByTagName('diff_tensor') if diff_tensor_nodes: # Create the diffusion tensor object. self.diff_tensor = DiffTensorData() # Fill its contents. self.diff_tensor.from_xml(diff_tensor_nodes[0], file_version=file_version) # Get the alignment tensor data nodes and, if they exist, fill the contents. align_tensor_nodes = pipe_node.getElementsByTagName('align_tensors') if align_tensor_nodes: # Create the alignment tensor object. self.align_tensors = AlignTensorList() # Fill its contents. self.align_tensors.from_xml(align_tensor_nodes[0], file_version=file_version) # Recreate the interatomic data structure (this needs to be before the 'mol' structure as the backward compatibility hooks can create interatomic data containers!). interatom_nodes = pipe_node.getElementsByTagName('interatomic') self.interatomic.from_xml(interatom_nodes, file_version=file_version) # Recreate the molecule, residue, and spin data structure. mol_nodes = pipe_node.getElementsByTagName('mol') self.mol.from_xml(mol_nodes, file_version=file_version) # Get the structural object nodes and, if they exist, fill the contents. str_nodes = pipe_node.getElementsByTagName('structure') if str_nodes: # Create the structural object. fail = False self.structure = Internal() # Fill its contents. if not fail: self.structure.from_xml(str_nodes[0], dir=dir, file_version=file_version) def is_empty(self): """Method for testing if the data pipe is empty. @return: True if the data pipe is empty, False otherwise. @rtype: bool """ # Is the molecule structure data object empty? if hasattr(self, 'structure'): return False # Is the molecule/residue/spin data object empty? if not self.mol.is_empty(): return False # Is the interatomic data object empty? if not self.interatomic.is_empty(): return False # Tests for the initialised data (the pipe type can be set in an empty data pipe, so this isn't checked). if self.hybrid_pipes: return False # An object has been added to the container. for name in dir(self): # Skip the objects initialised in __init__(). if name in ['mol', 'interatomic', 'pipe_type', 'hybrid_pipes']: continue # Skip the PipeContainer methods. if name in list(self.__class__.__dict__.keys()): continue # Skip special objects. if match("^_", name): continue # An object has been added. return False # The data pipe is empty. return True def to_xml(self, doc, element): """Create a XML element for the current data pipe. @param doc: The XML document object. @type doc: xml.dom.minidom.Document instance @param element: The XML element to add the pipe XML element to. @type element: XML element object """ # Add all simple python objects within the PipeContainer to the global element. global_element = doc.createElement('global') element.appendChild(global_element) global_element.setAttribute('desc', 'Global data located in the top level of the data pipe') fill_object_contents(doc, global_element, object=self, blacklist=['align_tensors', 'diff_tensor', 'exp_info', 'interatomic', 'hybrid_pipes', 'mol', 'pipe_type', 'structure'] + list(self.__class__.__dict__.keys())) # Hybrid info. self.xml_create_hybrid_element(doc, element) # Add the experimental information. if hasattr(self, 'exp_info'): self.exp_info.to_xml(doc, element) # Add the diffusion tensor data. if hasattr(self, 'diff_tensor'): self.diff_tensor.to_xml(doc, element) # Add the alignment tensor data. if hasattr(self, 'align_tensors'): self.align_tensors.to_xml(doc, element) # Add the molecule-residue-spin data. self.mol.to_xml(doc, element) # Add the interatomic data. self.interatomic.to_xml(doc, element) # Add the structural data, if it exists. if hasattr(self, 'structure'): self.structure.to_xml(doc, element) def xml_create_hybrid_element(self, doc, element): """Create an XML element for the data pipe hybridisation information. @param doc: The XML document object. @type doc: xml.dom.minidom.Document instance @param element: The element to add the hybridisation info to. @type element: XML element object """ # Create the hybrid element and add it to the higher level element. hybrid_element = doc.createElement('hybrid') element.appendChild(hybrid_element) # Set the hybridisation attributes. hybrid_element.setAttribute('desc', 'Data pipe hybridisation information') # Create an element to store the pipes list. list_element = doc.createElement('pipes') hybrid_element.appendChild(list_element) # Add the pipes list. text_val = doc.createTextNode(str(self.hybrid_pipes)) list_element.appendChild(text_val)
class PipeContainer(Prototype): """Class containing all the program data.""" def __init__(self): """Set up all the PipeContainer data structures.""" # The molecule-residue-spin object. self.mol = MoleculeList() # The interatomic data object. self.interatomic = InteratomList() # The data pipe type. self.pipe_type = None # Hybrid models. self.hybrid_pipes = [] def __repr__(self): """The string representation of the object. Rather than using the standard Python conventions (either the string representation of the value or the "<...desc...>" notation), a rich-formatted description of the object is given. """ # Intro text. text = "The data pipe storage object.\n" # Special objects/methods (to avoid the getattr() function call on). spec_obj = [ 'exp_info', 'mol', 'interatomic', 'diff_tensor', 'structure' ] # Objects. text = text + "\n" text = text + "Objects:\n" for name in dir(self): # Molecular list. if name == 'mol': text = text + " mol: The molecule list (for the storage of the spin system specific data)\n" # Interatomic data list. if name == 'interatomic': text = text + " interatomic: The interatomic data list (for the storage of the inter-spin system data)\n" # Diffusion tensor. if name == 'diff_tensor': text = text + " diff_tensor: The Brownian rotational diffusion tensor data object\n" # Molecular structure. if name == 'structure': text = text + " structure: The 3D molecular data object\n" # The experimental info data container. if name == 'exp_info': text = text + " exp_info: The data container for experimental information\n" # Skip the PipeContainer methods. if name in self.__class__.__dict__: continue # Skip certain objects. if match("^_", name) or name in spec_obj: continue # Add the object's attribute to the text string. text = text + " " + name + ": " + repr(getattr(self, name)) + "\n" # Return the text representation. return text def _back_compat_hook(self, file_version=None): """Method for converting old data structures to the new ones. @keyword file_version: The relax XML version of the XML file. @type file_version: int """ # Relaxation data. self._back_compat_hook_ri_data() def _back_compat_hook_ri_data(self): """Converting the old relaxation data structures to the new ones.""" # Nothing to do. if not (hasattr(cdp, 'frq_labels') and hasattr(cdp, 'noe_r1_table') and hasattr(cdp, 'remap_table')): return # Initialise the new structures. cdp.ri_ids = [] cdp.ri_type = {} frq = { } # This will be placed into cdp later as cdp.spectrometer_frq still exists. # Generate the new structures. for i in range(cdp.num_ri): # The ID. ri_id = "%s_%s" % (cdp.ri_labels[i], cdp.frq_labels[cdp.remap_table[i]]) # Not unique. if ri_id in cdp.ri_ids: # Loop until a unique ID is found. for j in range(100): # New id. new_id = "%s_%s" % (ri_id, j) # Unique. if not new_id in cdp.ri_ids: ri_id = new_id break # Add the ID. cdp.ri_ids.append(ri_id) # The relaxation data type. cdp.ri_type[ri_id] = cdp.ri_labels[i] # The frequency data. frq[ri_id] = cdp.frq[cdp.remap_table[i]] # Delete the old structures. del cdp.frq del cdp.frq_labels del cdp.noe_r1_table del cdp.num_frq del cdp.num_ri del cdp.remap_table del cdp.ri_labels # Set the frequencies. cdp.frq = frq def from_xml(self, pipe_node, file_version=None, dir=None): """Read a pipe container XML element and place the contents into this pipe. @param pipe_node: The data pipe XML node. @type pipe_node: xml.dom.minidom.Element instance @keyword file_version: The relax XML version of the XML file. @type file_version: int @keyword dir: The name of the directory containing the results file (needed for loading external files). @type dir: str """ # Test if empty. if not self.is_empty(): raise RelaxFromXMLNotEmptyError(self.__class__.__name__) # Get the global data node, and fill the contents of the pipe. global_node = pipe_node.getElementsByTagName('global')[0] xml_to_object(global_node, self, file_version=file_version) # Backwards compatibility transformations. self._back_compat_hook(file_version) # Get the hybrid node (and its sub-node), and recreate the hybrid object. hybrid_node = pipe_node.getElementsByTagName('hybrid')[0] pipes_node = hybrid_node.getElementsByTagName('pipes')[0] setattr(self, 'hybrid_pipes', node_value_to_python(pipes_node.childNodes[0])) # Get the experimental information data nodes and, if they exist, fill the contents. exp_info_nodes = pipe_node.getElementsByTagName('exp_info') if exp_info_nodes: # Create the data container. self.exp_info = ExpInfo() # Fill its contents. self.exp_info.from_xml(exp_info_nodes[0], file_version=file_version) # Get the diffusion tensor data nodes and, if they exist, fill the contents. diff_tensor_nodes = pipe_node.getElementsByTagName('diff_tensor') if diff_tensor_nodes: # Create the diffusion tensor object. self.diff_tensor = DiffTensorData() # Fill its contents. self.diff_tensor.from_xml(diff_tensor_nodes[0], file_version=file_version) # Get the alignment tensor data nodes and, if they exist, fill the contents. align_tensor_nodes = pipe_node.getElementsByTagName('align_tensors') if align_tensor_nodes: # Create the alignment tensor object. self.align_tensors = AlignTensorList() # Fill its contents. self.align_tensors.from_xml(align_tensor_nodes[0], file_version=file_version) # Recreate the interatomic data structure (this needs to be before the 'mol' structure as the backward compatibility hooks can create interatomic data containers!). interatom_nodes = pipe_node.getElementsByTagName('interatomic') self.interatomic.from_xml(interatom_nodes, file_version=file_version) # Recreate the molecule, residue, and spin data structure. mol_nodes = pipe_node.getElementsByTagName('mol') self.mol.from_xml(mol_nodes, file_version=file_version) # Get the structural object nodes and, if they exist, fill the contents. str_nodes = pipe_node.getElementsByTagName('structure') if str_nodes: # Create the structural object. fail = False self.structure = Internal() # Fill its contents. if not fail: self.structure.from_xml(str_nodes[0], dir=dir, file_version=file_version) def is_empty(self): """Method for testing if the data pipe is empty. @return: True if the data pipe is empty, False otherwise. @rtype: bool """ # Is the molecule structure data object empty? if hasattr(self, 'structure'): return False # Is the molecule/residue/spin data object empty? if not self.mol.is_empty(): return False # Is the interatomic data object empty? if not self.interatomic.is_empty(): return False # Tests for the initialised data (the pipe type can be set in an empty data pipe, so this isn't checked). if self.hybrid_pipes: return False # An object has been added to the container. for name in dir(self): # Skip the objects initialised in __init__(). if name in ['mol', 'interatomic', 'pipe_type', 'hybrid_pipes']: continue # Skip the PipeContainer methods. if name in self.__class__.__dict__: continue # Skip special objects. if match("^_", name): continue # An object has been added. return False # The data pipe is empty. return True def to_xml(self, doc, element, pipe_type=None): """Create a XML element for the current data pipe. @param doc: The XML document object. @type doc: xml.dom.minidom.Document instance @param element: The XML element to add the pipe XML element to. @type element: XML element object @keyword pipe_type: The type of the pipe being converted to XML. @type pipe_type: str """ # Add all simple python objects within the PipeContainer to the global element. global_element = doc.createElement('global') element.appendChild(global_element) global_element.setAttribute( 'desc', 'Global data located in the top level of the data pipe') fill_object_contents( doc, global_element, object=self, blacklist=[ 'align_tensors', 'diff_tensor', 'exp_info', 'interatomic', 'hybrid_pipes', 'mol', 'pipe_type', 'structure' ] + list(self.__class__.__dict__.keys())) # Hybrid info. self.xml_create_hybrid_element(doc, element) # Add the experimental information. if hasattr(self, 'exp_info'): self.exp_info.to_xml(doc, element) # Add the diffusion tensor data. if hasattr(self, 'diff_tensor'): self.diff_tensor.to_xml(doc, element) # Add the alignment tensor data. if hasattr(self, 'align_tensors'): self.align_tensors.to_xml(doc, element) # Add the molecule-residue-spin data. self.mol.to_xml(doc, element, pipe_type=pipe_type) # Add the interatomic data. self.interatomic.to_xml(doc, element, pipe_type=pipe_type) # Add the structural data, if it exists. if hasattr(self, 'structure'): self.structure.to_xml(doc, element) def xml_create_hybrid_element(self, doc, element): """Create an XML element for the data pipe hybridisation information. @param doc: The XML document object. @type doc: xml.dom.minidom.Document instance @param element: The element to add the hybridisation info to. @type element: XML element object """ # Create the hybrid element and add it to the higher level element. hybrid_element = doc.createElement('hybrid') element.appendChild(hybrid_element) # Set the hybridisation attributes. hybrid_element.setAttribute('desc', 'Data pipe hybridisation information') # Create an element to store the pipes list. list_element = doc.createElement('pipes') hybrid_element.appendChild(list_element) # Add the pipes list. text_val = doc.createTextNode(str(self.hybrid_pipes)) list_element.appendChild(text_val)
def from_xml(self, pipe_node, file_version=None, dir=None): """Read a pipe container XML element and place the contents into this pipe. @param pipe_node: The data pipe XML node. @type pipe_node: xml.dom.minidom.Element instance @keyword file_version: The relax XML version of the XML file. @type file_version: int @keyword dir: The name of the directory containing the results file (needed for loading external files). @type dir: str """ # Test if empty. if not self.is_empty(): raise RelaxFromXMLNotEmptyError(self.__class__.__name__) # Get the global data node, and fill the contents of the pipe. global_node = pipe_node.getElementsByTagName('global')[0] xml_to_object(global_node, self, file_version=file_version) # Backwards compatibility transformations. self._back_compat_hook(file_version) # Get the hybrid node (and its sub-node), and recreate the hybrid object. hybrid_node = pipe_node.getElementsByTagName('hybrid')[0] pipes_node = hybrid_node.getElementsByTagName('pipes')[0] setattr(self, 'hybrid_pipes', node_value_to_python(pipes_node.childNodes[0])) # Get the experimental information data nodes and, if they exist, fill the contents. exp_info_nodes = pipe_node.getElementsByTagName('exp_info') if exp_info_nodes: # Create the data container. self.exp_info = ExpInfo() # Fill its contents. self.exp_info.from_xml(exp_info_nodes[0], file_version=file_version) # Get the diffusion tensor data nodes and, if they exist, fill the contents. diff_tensor_nodes = pipe_node.getElementsByTagName('diff_tensor') if diff_tensor_nodes: # Create the diffusion tensor object. self.diff_tensor = DiffTensorData() # Fill its contents. self.diff_tensor.from_xml(diff_tensor_nodes[0], file_version=file_version) # Get the alignment tensor data nodes and, if they exist, fill the contents. align_tensor_nodes = pipe_node.getElementsByTagName('align_tensors') if align_tensor_nodes: # Create the alignment tensor object. self.align_tensors = AlignTensorList() # Fill its contents. self.align_tensors.from_xml(align_tensor_nodes[0], file_version=file_version) # Recreate the interatomic data structure (this needs to be before the 'mol' structure as the backward compatibility hooks can create interatomic data containers!). interatom_nodes = pipe_node.getElementsByTagName('interatomic') self.interatomic.from_xml(interatom_nodes, file_version=file_version) # Recreate the molecule, residue, and spin data structure. mol_nodes = pipe_node.getElementsByTagName('mol') self.mol.from_xml(mol_nodes, file_version=file_version) # Get the structural object nodes and, if they exist, fill the contents. str_nodes = pipe_node.getElementsByTagName('structure') if str_nodes: # Create the structural object. fail = False self.structure = Internal() # Fill its contents. if not fail: self.structure.from_xml(str_nodes[0], dir=dir, file_version=file_version)
def setUp(self): """Set 'self.diff_data' to an empty instance of the DiffTensorData class.""" self.diff_data = DiffTensorData()
class Test_diff_tensor(TestCase): """Unit tests for the data.diff_tensor relax module.""" def calc_spheroid_objects(self, tm, Da, theta, phi): """Function for calculating the spheroidal diffusion tensor objects.""" # The parameter values. Diso = 1/(6*tm) Dpar = Diso + 2.0/3.0 * Da Dper = Diso - 1.0/3.0 * Da Dratio = Dpar / Dper # Vectors. Dpar_unit = array([sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)]) # Matrices. if Dpar > Dper: axis = array([0, 0, 1], float64) tensor_diag = array([[ Dper, 0.0, 0.0], [ 0.0, Dper, 0.0], [ 0.0, 0.0, Dpar]]) else: axis = array([1, 0, 0], float64) tensor_diag = array([[ Dpar, 0.0, 0.0], [ 0.0, Dper, 0.0], [ 0.0, 0.0, Dper]]) # The rotation. rotation = zeros((3, 3), float64) two_vect_to_R(Dpar_unit, axis, rotation) # The diffusion tensor. tensor = dot(rotation, dot(tensor_diag, transpose(rotation))) # Return the objects. return Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor def setUp(self): """Set 'self.diff_data' to an empty instance of the DiffTensorData class.""" self.diff_data = DiffTensorData() def test_append_spheroid_sim(self): """Test the appending of Monte Carlo simulation spheroidal diffusion tensor parameters. The following parameters will be appended to empty lists: - tm: 8 ns - Da: -1e7 - theta: 150 degrees - phi: 30 degrees """ # The MC sim parameter values. tm = 8e-9 Da = -1e7 theta = (150 / 360.0) * 2.0 * pi phi = (30 / 360.0) * 2.0 * pi # Set the diffusion type. self.diff_data.set(param='type', value='spheroid') self.diff_data.set(param='spheroid_type', value='oblate') # Set the number of MC sims. self.diff_data.set_sim_num(1) # Set the initial values. self.diff_data.set(param='tm', value=tm, category='sim', sim_index=0) self.diff_data.set(param='Da', value=Da, category='sim', sim_index=0) self.diff_data.set(param='theta', value=theta, category='sim', sim_index=0) self.diff_data.set(param='phi', value=phi, category='sim', sim_index=0) # Test the set values. self.assertEqual(self.diff_data.type, 'spheroid') self.assertEqual(self.diff_data.tm_sim[0], tm) self.assertEqual(self.diff_data.Da_sim[0], Da) self.assertEqual(self.diff_data.theta_sim[0], theta) self.assertEqual(self.diff_data.phi_sim[0], phi) # Calculate the diffusion tensor objects. Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor = self.calc_spheroid_objects(tm, Da, theta, phi) # Test the automatically created values. self.assertEqual(self.diff_data.Diso_sim[0], Diso) self.assertEqual(self.diff_data.Dpar_sim[0], Dpar) self.assertEqual(self.diff_data.Dper_sim[0], Dper) self.assertEqual(self.diff_data.Dratio_sim[0], Dratio) # Test the vectors. self.assertEqual(self.diff_data.Dpar_unit_sim[0].tostring(), Dpar_unit.tostring()) # Test the matrices. self.assertEqual(self.diff_data.tensor_diag_sim[0].tostring(), tensor_diag.tostring()) self.assertEqual(self.diff_data.rotation_sim[0].tostring(), rotation.tostring()) self.assertEqual(self.diff_data.tensor_sim[0].tostring(), tensor.tostring()) def test_display(self): """Test that the contents of the diffusion tensor object can be displayed.""" print(self.diff_data) def test_set_Diso(self): """Test that the Diso parameter cannot be set.""" # Assert that a RelaxError occurs when Diso is set (to the tm value of 10 ns). self.assertRaises(RelaxError, setattr, self.diff_data, 'Diso', 1/(6*1e-8)) # Make sure that the Diso parameter has not been set. self.assert_(not hasattr(self.diff_data, 'Diso')) def test_set_spheroid_errors(self): """Test the setting of spheroidal diffusion tensor parameter errors. The following parameter errors will be set: - tm: 1 ns - Da: 1e3 - theta: 3 degrees - phi: 5 degrees """ # The parameter errors. tm = 1e-8 Da = 1e3 theta = (3 / 360.0) * 2.0 * pi phi = (5 / 360.0) * 2.0 * pi # Set the diffusion type. self.diff_data.set(param='type', value='spheroid') self.diff_data.set(param='spheroid_type', value='prolate') # Set the diffusion parameter errors. self.diff_data.set(param='tm', value=tm, category='err') self.diff_data.set(param='Da', value=Da, category='err') self.diff_data.set(param='theta', value=theta, category='err') self.diff_data.set(param='phi', value=phi, category='err') # Test the set values. self.assertEqual(self.diff_data.type, 'spheroid') self.assertEqual(self.diff_data.tm_err, tm) self.assertEqual(self.diff_data.Da_err, Da) self.assertEqual(self.diff_data.theta_err, theta) self.assertEqual(self.diff_data.phi_err, phi) # Calculate the diffusion tensor objects. Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor = self.calc_spheroid_objects(tm, Da, theta, phi) # Test the automatically created values. self.assertEqual(self.diff_data.Diso_err, Diso) self.assertEqual(self.diff_data.Dpar_err, Dpar) self.assertEqual(self.diff_data.Dper_err, Dper) self.assertEqual(self.diff_data.Dratio_err, Dratio) # Test the vectors. self.assertEqual(self.diff_data.Dpar_unit_err.tostring(), Dpar_unit.tostring()) def test_set_spheroid_params(self): """Test the setting of spheroidal diffusion tensor parameters. The following parameters will be set: - tm: 20 ns - Da: 2e6 - theta: 60 degrees - phi: 290 degrees """ # The parameter values. tm = 2e-8 Da = 2e6 theta = (60 / 360.0) * 2.0 * pi phi = (290 / 360.0) * 2.0 * pi # Set the diffusion type. self.diff_data.set(param='type', value='spheroid') self.diff_data.set(param='spheroid_type', value='prolate') # Set the diffusion parameters. self.diff_data.set(param='tm', value=tm) self.diff_data.set(param='Da', value=Da) self.diff_data.set(param='theta', value=theta) self.diff_data.set(param='phi', value=phi) # Test the set values. self.assertEqual(self.diff_data.type, 'spheroid') self.assertEqual(self.diff_data.tm, tm) self.assertEqual(self.diff_data.Da, Da) self.assertEqual(self.diff_data.theta, theta) self.assertEqual(self.diff_data.phi, phi) # Calculate the diffusion tensor objects. Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor = self.calc_spheroid_objects(tm, Da, theta, phi) # Test the automatically created values. self.assertEqual(self.diff_data.Diso, Diso) self.assertEqual(self.diff_data.Dpar, Dpar) self.assertEqual(self.diff_data.Dper, Dper) self.assertEqual(self.diff_data.Dratio, Dratio) # Test the vectors. self.assertEqual(self.diff_data.Dpar_unit.tostring(), Dpar_unit.tostring()) # Test the matrices. self.assertEqual(self.diff_data.tensor_diag.tostring(), tensor_diag.tostring()) self.assertEqual(self.diff_data.rotation.tostring(), rotation.tostring()) self.assertEqual(self.diff_data.tensor.tostring(), tensor.tostring()) def test_set_spheroid_sim(self): """Test the setting of Monte Carlo simulation spheroidal diffusion tensor parameters. Firstly the following parameters will be appended to empty lists: - tm: 2 ns - Da: 1e5 - theta: 0 degrees - phi: 360 degrees These MC sim values will then be explicity overwritten by setting the first elements of the lists to: - tm: 0.5 ns - Da: 3e5 - theta: 2 degrees - phi: 0 degrees """ # Set the diffusion type. self.diff_data.set(param='type', value='spheroid') self.diff_data.set(param='spheroid_type', value='prolate') # Set the number of MC sims. self.diff_data.set_sim_num(1) # Set the initial values. self.diff_data.set(param='tm', value=2e-9, category='sim', sim_index=0) self.diff_data.set(param='Da', value=1e5, category='sim', sim_index=0) self.diff_data.set(param='theta', value=0.0, category='sim', sim_index=0) self.diff_data.set(param='phi', value=2.0 * pi, category='sim', sim_index=0) # The new MC sim parameter values. tm = 0.5e-9 Da = 3e5 theta = (2 / 360.0) * 2.0 * pi phi = 0.0 # Set the MC sim parameter values (overwriting the initial values). self.diff_data.set(param='tm', value=tm, category='sim', sim_index=0) self.diff_data.set(param='Da', value=Da, category='sim', sim_index=0) self.diff_data.set(param='theta', value=theta, category='sim', sim_index=0) self.diff_data.set(param='phi', value=phi, category='sim', sim_index=0) # Test the set values. self.assertEqual(self.diff_data.type, 'spheroid') self.assertEqual(self.diff_data.tm_sim[0], tm) self.assertEqual(self.diff_data.Da_sim[0], Da) self.assertEqual(self.diff_data.theta_sim[0], theta) self.assertEqual(self.diff_data.phi_sim[0], phi) # Calculate the diffusion tensor objects. Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor = self.calc_spheroid_objects(tm, Da, theta, phi) # Test the automatically created values. self.assertEqual(self.diff_data.Diso_sim[0], Diso) self.assertEqual(self.diff_data.Dpar_sim[0], Dpar) self.assertEqual(self.diff_data.Dper_sim[0], Dper) self.assertEqual(self.diff_data.Dratio_sim[0], Dratio) # Test the vectors. self.assertEqual(self.diff_data.Dpar_unit_sim[0].tostring(), Dpar_unit.tostring()) # Test the matrices. self.assertEqual(self.diff_data.tensor_diag_sim[0].tostring(), tensor_diag.tostring()) self.assertEqual(self.diff_data.rotation_sim[0].tostring(), rotation.tostring()) self.assertEqual(self.diff_data.tensor_sim[0].tostring(), tensor.tostring()) def test_set_tm(self): """Test the setting of the tm parameter. The tm parameter will be set to 10 ns. The setting of tm should automatically create the Diso parameter. """ # Set the diffusion type. self.diff_data.set(param='type', value='sphere') # Set the tm value to 10 ns. self.diff_data.set(param='tm', value=1e-8) # Test that the tm parameter has been set correctly. self.assert_(hasattr(self.diff_data, 'tm')) self.assertEqual(self.diff_data.tm, 1e-8) # Test that the Diso parameter has been set correctly. self.assert_(hasattr(self.diff_data, 'Diso')) self.assertEqual(self.diff_data.Diso, 1/(6*1e-8))
class Test_diff_tensor(TestCase): """Unit tests for the data.diff_tensor relax module.""" def calc_spheroid_objects(self, tm, Da, theta, phi): """Function for calculating the spheroidal diffusion tensor objects.""" # The parameter values. Diso = 1 / (6 * tm) Dpar = Diso + 2.0 / 3.0 * Da Dper = Diso - 1.0 / 3.0 * Da Dratio = Dpar / Dper # Vectors. Dpar_unit = array( [sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)]) # Matrices. if Dpar > Dper: axis = array([0, 0, 1], float64) tensor_diag = array([[Dper, 0.0, 0.0], [0.0, Dper, 0.0], [0.0, 0.0, Dpar]]) else: axis = array([1, 0, 0], float64) tensor_diag = array([[Dpar, 0.0, 0.0], [0.0, Dper, 0.0], [0.0, 0.0, Dper]]) # The rotation. rotation = zeros((3, 3), float64) two_vect_to_R(Dpar_unit, axis, rotation) # The diffusion tensor. tensor = dot(rotation, dot(tensor_diag, transpose(rotation))) # Return the objects. return Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor def setUp(self): """Set 'self.diff_data' to an empty instance of the DiffTensorData class.""" self.diff_data = DiffTensorData() def test_append_spheroid_sim(self): """Test the appending of Monte Carlo simulation spheroidal diffusion tensor parameters. The following parameters will be appended to empty lists: - tm: 8 ns - Da: -1e7 - theta: 150 degrees - phi: 30 degrees """ # The MC sim parameter values. tm = 8e-9 Da = -1e7 theta = (150 / 360.0) * 2.0 * pi phi = (30 / 360.0) * 2.0 * pi # Set the diffusion type. self.diff_data.set(param='type', value='spheroid') self.diff_data.set(param='spheroid_type', value='oblate') # Set the number of MC sims. self.diff_data.set_sim_num(1) # Set the initial values. self.diff_data.set(param='tm', value=tm, category='sim', sim_index=0) self.diff_data.set(param='Da', value=Da, category='sim', sim_index=0) self.diff_data.set(param='theta', value=theta, category='sim', sim_index=0) self.diff_data.set(param='phi', value=phi, category='sim', sim_index=0) # Test the set values. self.assertEqual(self.diff_data.type, 'spheroid') self.assertEqual(self.diff_data.tm_sim[0], tm) self.assertEqual(self.diff_data.Da_sim[0], Da) self.assertEqual(self.diff_data.theta_sim[0], theta) self.assertEqual(self.diff_data.phi_sim[0], phi) # Calculate the diffusion tensor objects. Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor = self.calc_spheroid_objects( tm, Da, theta, phi) # Test the automatically created values. self.assertEqual(self.diff_data.Diso_sim[0], Diso) self.assertEqual(self.diff_data.Dpar_sim[0], Dpar) self.assertEqual(self.diff_data.Dper_sim[0], Dper) self.assertEqual(self.diff_data.Dratio_sim[0], Dratio) # Test the vectors. self.assertEqual(self.diff_data.Dpar_unit_sim[0].tostring(), Dpar_unit.tostring()) # Test the matrices. self.assertEqual(self.diff_data.tensor_diag_sim[0].tostring(), tensor_diag.tostring()) self.assertEqual(self.diff_data.rotation_sim[0].tostring(), rotation.tostring()) self.assertEqual(self.diff_data.tensor_sim[0].tostring(), tensor.tostring()) def test_display(self): """Test that the contents of the diffusion tensor object can be displayed.""" print(self.diff_data) def test_set_Diso(self): """Test that the Diso parameter cannot be set.""" # Assert that a RelaxError occurs when Diso is set (to the tm value of 10 ns). self.assertRaises(RelaxError, setattr, self.diff_data, 'Diso', 1 / (6 * 1e-8)) # Make sure that the Diso parameter has not been set. self.assert_(not hasattr(self.diff_data, 'Diso')) def test_set_spheroid_errors(self): """Test the setting of spheroidal diffusion tensor parameter errors. The following parameter errors will be set: - tm: 1 ns - Da: 1e3 - theta: 3 degrees - phi: 5 degrees """ # The parameter errors. tm = 1e-8 Da = 1e3 theta = (3 / 360.0) * 2.0 * pi phi = (5 / 360.0) * 2.0 * pi # Set the diffusion type. self.diff_data.set(param='type', value='spheroid') self.diff_data.set(param='spheroid_type', value='prolate') # Set the diffusion parameter errors. self.diff_data.set(param='tm', value=tm, category='err') self.diff_data.set(param='Da', value=Da, category='err') self.diff_data.set(param='theta', value=theta, category='err') self.diff_data.set(param='phi', value=phi, category='err') # Test the set values. self.assertEqual(self.diff_data.type, 'spheroid') self.assertEqual(self.diff_data.tm_err, tm) self.assertEqual(self.diff_data.Da_err, Da) self.assertEqual(self.diff_data.theta_err, theta) self.assertEqual(self.diff_data.phi_err, phi) # Calculate the diffusion tensor objects. Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor = self.calc_spheroid_objects( tm, Da, theta, phi) # Test the automatically created values. self.assertEqual(self.diff_data.Diso_err, Diso) self.assertEqual(self.diff_data.Dpar_err, Dpar) self.assertEqual(self.diff_data.Dper_err, Dper) self.assertEqual(self.diff_data.Dratio_err, Dratio) # Test the vectors. self.assertEqual(self.diff_data.Dpar_unit_err.tostring(), Dpar_unit.tostring()) def test_set_spheroid_params(self): """Test the setting of spheroidal diffusion tensor parameters. The following parameters will be set: - tm: 20 ns - Da: 2e6 - theta: 60 degrees - phi: 290 degrees """ # The parameter values. tm = 2e-8 Da = 2e6 theta = (60 / 360.0) * 2.0 * pi phi = (290 / 360.0) * 2.0 * pi # Set the diffusion type. self.diff_data.set(param='type', value='spheroid') self.diff_data.set(param='spheroid_type', value='prolate') # Set the diffusion parameters. self.diff_data.set(param='tm', value=tm) self.diff_data.set(param='Da', value=Da) self.diff_data.set(param='theta', value=theta) self.diff_data.set(param='phi', value=phi) # Test the set values. self.assertEqual(self.diff_data.type, 'spheroid') self.assertEqual(self.diff_data.tm, tm) self.assertEqual(self.diff_data.Da, Da) self.assertEqual(self.diff_data.theta, theta) self.assertEqual(self.diff_data.phi, phi) # Calculate the diffusion tensor objects. Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor = self.calc_spheroid_objects( tm, Da, theta, phi) # Test the automatically created values. self.assertEqual(self.diff_data.Diso, Diso) self.assertEqual(self.diff_data.Dpar, Dpar) self.assertEqual(self.diff_data.Dper, Dper) self.assertEqual(self.diff_data.Dratio, Dratio) # Test the vectors. self.assertEqual(self.diff_data.Dpar_unit.tostring(), Dpar_unit.tostring()) # Test the matrices. self.assertEqual(self.diff_data.tensor_diag.tostring(), tensor_diag.tostring()) self.assertEqual(self.diff_data.rotation.tostring(), rotation.tostring()) self.assertEqual(self.diff_data.tensor.tostring(), tensor.tostring()) def test_set_spheroid_sim(self): """Test the setting of Monte Carlo simulation spheroidal diffusion tensor parameters. Firstly the following parameters will be appended to empty lists: - tm: 2 ns - Da: 1e5 - theta: 0 degrees - phi: 360 degrees These MC sim values will then be explicity overwritten by setting the first elements of the lists to: - tm: 0.5 ns - Da: 3e5 - theta: 2 degrees - phi: 0 degrees """ # Set the diffusion type. self.diff_data.set(param='type', value='spheroid') self.diff_data.set(param='spheroid_type', value='prolate') # Set the number of MC sims. self.diff_data.set_sim_num(1) # Set the initial values. self.diff_data.set(param='tm', value=2e-9, category='sim', sim_index=0) self.diff_data.set(param='Da', value=1e5, category='sim', sim_index=0) self.diff_data.set(param='theta', value=0.0, category='sim', sim_index=0) self.diff_data.set(param='phi', value=2.0 * pi, category='sim', sim_index=0) # The new MC sim parameter values. tm = 0.5e-9 Da = 3e5 theta = (2 / 360.0) * 2.0 * pi phi = 0.0 # Set the MC sim parameter values (overwriting the initial values). self.diff_data.set(param='tm', value=tm, category='sim', sim_index=0) self.diff_data.set(param='Da', value=Da, category='sim', sim_index=0) self.diff_data.set(param='theta', value=theta, category='sim', sim_index=0) self.diff_data.set(param='phi', value=phi, category='sim', sim_index=0) # Test the set values. self.assertEqual(self.diff_data.type, 'spheroid') self.assertEqual(self.diff_data.tm_sim[0], tm) self.assertEqual(self.diff_data.Da_sim[0], Da) self.assertEqual(self.diff_data.theta_sim[0], theta) self.assertEqual(self.diff_data.phi_sim[0], phi) # Calculate the diffusion tensor objects. Diso, Dpar, Dper, Dratio, Dpar_unit, tensor_diag, rotation, tensor = self.calc_spheroid_objects( tm, Da, theta, phi) # Test the automatically created values. self.assertEqual(self.diff_data.Diso_sim[0], Diso) self.assertEqual(self.diff_data.Dpar_sim[0], Dpar) self.assertEqual(self.diff_data.Dper_sim[0], Dper) self.assertEqual(self.diff_data.Dratio_sim[0], Dratio) # Test the vectors. self.assertEqual(self.diff_data.Dpar_unit_sim[0].tostring(), Dpar_unit.tostring()) # Test the matrices. self.assertEqual(self.diff_data.tensor_diag_sim[0].tostring(), tensor_diag.tostring()) self.assertEqual(self.diff_data.rotation_sim[0].tostring(), rotation.tostring()) self.assertEqual(self.diff_data.tensor_sim[0].tostring(), tensor.tostring()) def test_set_tm(self): """Test the setting of the tm parameter. The tm parameter will be set to 10 ns. The setting of tm should automatically create the Diso parameter. """ # Set the diffusion type. self.diff_data.set(param='type', value='sphere') # Set the tm value to 10 ns. self.diff_data.set(param='tm', value=1e-8) # Test that the tm parameter has been set correctly. self.assert_(hasattr(self.diff_data, 'tm')) self.assertEqual(self.diff_data.tm, 1e-8) # Test that the Diso parameter has been set correctly. self.assert_(hasattr(self.diff_data, 'Diso')) self.assertEqual(self.diff_data.Diso, 1 / (6 * 1e-8))