Author: bugman Date: Tue Jun 19 14:12:23 2012 New Revision: 16955 URL: http://svn.gna.org/viewcvs/relax?rev=16955&view=rev Log: Expanded the functionality of the generic_fns.interatomic module. The copy() and exists_data() functions have been added to copy all interatomic data from one data pipe to another and to check if interatomic data exists within a data pipe respectively. The create_interatom() function now also accepts a 'pipe' argument so that non-current pipes can be used. Modified: branches/interatomic/generic_fns/interatomic.py Modified: branches/interatomic/generic_fns/interatomic.py URL: http://svn.gna.org/viewcvs/relax/branches/interatomic/generic_fns/interatomic.py?rev=16955&r1=16954&r2=16955&view=diff ============================================================================== --- branches/interatomic/generic_fns/interatomic.py (original) +++ branches/interatomic/generic_fns/interatomic.py Tue Jun 19 14:12:23 2012 @@ -23,34 +23,138 @@ # Module docstring. """Module for the manipulation of the interatomic data structures in the relax data store.""" +# Python module imports. +from copy import deepcopy +from re import search + # relax module imports. from generic_fns import pipes from generic_fns.mol_res_spin import return_spin -from relax_errors import RelaxError +from relax_errors import RelaxError, RelaxInteratomError, RelaxNoInteratomError +from relax_io import write_data from relax_warnings import RelaxNoSpinWarning -def create_interatom(spin_id1=None, spin_id2=None): +def copy(pipe_from=None, pipe_to=None, verbose=True): + """Copy the interatomic data from one data pipe to another. + + @keyword pipe_from: The data pipe to copy the interatomic data from. This defaults to the current data pipe. + @type pipe_from: str + @keyword pipe_to: The data pipe to copy the interatomic data to. This defaults to the current data pipe. + @type pipe_to: str + @keyword verbose: A flag which if True will cause info about each spin pair to be printed out. + @type verbose: bool + """ + + # Defaults. + if pipe_from == None and pipe_to == None: + raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.") + elif pipe_from == None: + pipe_from = pipes.cdp_name() + elif pipe_to == None: + pipe_to = pipes.cdp_name() + + # Test if the pipe_from and pipe_to data pipes exist. + pipes.test(pipe_from) + pipes.test(pipe_to) + + # Test if pipe_from contains interatomic data. + if not exists_data(pipe_from): + raise RelaxNoInteratomError + + # Test if pipe_to contains interatomic data. + if exists_data(pipe_to): + raise RelaxInteratomError + + # Loop over the interatomic data of the pipe_from data pipe. + ids = [] + for interatom in interatomic_loop(pipe=pipe_from): + # Create a new container. + new_interatom = create_interatom(spin_id1=interatom.spin_id1, spin_id2=interatom.spin_id2, pipe=pipe_to) + + # Duplicate all the objects of the container. + for name in dir(interatom): + # Skip special objects. + if search('^_', name): + continue + + # Skip the spin IDs. + if name in ['spin_id1', 'spin_id2']: + continue + + # Skip class methods. + if name in list(interatom.__class__.__dict__.keys()): + continue + + # Duplicate all other objects. + obj = deepcopy(getattr(interatom, name)) + setattr(new_interatom, name, obj) + + # Store the IDs for the print out. + ids.append([repr(interatom.spin_id1), repr(interatom.spin_id2)]) + + # Print out. + if verbose: + write_data(out=sys.stdout, headings=["Spin_ID_1", "Spin_ID_2"], data=ids) + + +def create_interatom(spin_id1=None, spin_id2=None, pipe=None): """Create and return the interatomic data container for the two spins. @keyword spin_id1: The spin ID string of the first atom. @type spin_id1: str @keyword spin_id2: The spin ID string of the first atom. @type spin_id2: str + @keyword pipe: The data pipe to create the interatomic data container for. This defaults to the current data pipe if not supplied. + @type pipe: str or None @return: The newly created interatomic data container. @rtype: data.interatomic.InteratomContainer instance """ + # The data pipe. + if pipe == None: + pipe = pipes.cdp_name() + + # Get the data pipe. + dp = pipes.get_pipe(pipe) + # Check that the spin IDs exist. - spin = return_spin(spin_id1) + spin = return_spin(spin_id1, pipe) if spin == None: raise RelaxNoSpinWarning(spin_id1) - spin = return_spin(spin_id2) + spin = return_spin(spin_id2, pipe) if spin == None: raise RelaxNoSpinWarning(spin_id2) # Add and return the data. - return cdp.interatomic.add_item(spin_id1=spin_id1, spin_id2=spin_id2) + return dp.interatomic.add_item(spin_id1=spin_id1, spin_id2=spin_id2) + + +def exists_data(pipe=None): + """Determine if any interatomic data exists. + + @keyword pipe: The data pipe in which the interatomic data will be checked for. + @type pipe: str + @return: The answer to the question about the existence of data. + @rtype: bool + """ + + # The current data pipe. + if pipe == None: + pipe = pipes.cdp_name() + + # Test the data pipe. + pipes.test(pipe) + + # Get the data pipe. + dp = pipes.get_pipe(pipe) + + # The interatomic data structure is empty. + if dp.interatomic.is_empty(): + return False + + # Otherwise. + return True def interatomic_loop(pipe=None): @@ -108,7 +212,7 @@ # Single spin. else: for i in range(len(dp.interatomic)): - if dp.interatomic[i].spin_id1 == spin_id1 or dp.interatomic[i].spin_id2 == spin_id1: + if dp.interatomic[i].spin_id1 == spin_id1 or dp.interatomic[i].spin_id2 == spin_id1: interatoms.append(dp.interatomic[i]) # Return the list of containers.