Author: bugman Date: Wed Jul 27 17:54:24 2011 New Revision: 13932 URL: http://svn.gna.org/viewcvs/relax?rev=13932&view=rev Log: Redesign of the structure.load_spins user function back end. This redesign is required due to problems encountered by Han in the xyz branch. See the thread starting at https://mail.gna.org/public/relax-devel/2011-07/msg00021.html. This commit consists of a number of changes: - The combine_models argument has been removed as it is a relic, and isn't used at all. - The spins are now created in the standard way via the generic_fns.mol_res_spin.create_spin() function, eliminating all of the issues and complications of the old code. - The atomic positions are now converted to numpy arrays. - Only the created spins are included in the print out, and not replicated for each model. Modified: 1.3/generic_fns/structure/main.py 1.3/prompt/structure.py 1.3/sample_scripts/n_state_model/conformation_analysis_rdc+pcs.py 1.3/test_suite/shared_data/align_data/population_model/generate.py 1.3/test_suite/system_tests/scripts/n_state_model/lactose_n_state.py 1.3/test_suite/system_tests/scripts/n_state_model/missing_data_test.py 1.3/test_suite/system_tests/scripts/n_state_model/populations.py 1.3/test_suite/system_tests/scripts/n_state_model/vector_loading.py Modified: 1.3/generic_fns/structure/main.py URL: http://svn.gna.org/viewcvs/relax/1.3/generic_fns/structure/main.py?rev=13932&r1=13931&r2=13932&view=diff ============================================================================== --- 1.3/generic_fns/structure/main.py (original) +++ 1.3/generic_fns/structure/main.py Wed Jul 27 17:54:24 2011 @@ -1,6 +1,6 @@ ############################################################################### # # -# Copyright (C) 2003-2010 Edward d'Auvergne # +# Copyright (C) 2003-2011 Edward d'Auvergne # # # # This file is part of the program relax. # # # @@ -22,7 +22,7 @@ # Python module imports. from math import sqrt -from numpy import dot, float64, ndarray, zeros +from numpy import array, dot, float64, ndarray, zeros from numpy.linalg import norm from os import F_OK, access from re import search @@ -32,7 +32,7 @@ # relax module imports. from generic_fns import molmol, relax_re -from generic_fns.mol_res_spin import exists_mol_res_spin_data, generate_spin_id, linear_ave, return_molecule, return_residue, return_spin, spin_loop +from generic_fns.mol_res_spin import create_spin, exists_mol_res_spin_data, generate_spin_id, linear_ave, return_molecule, return_residue, return_spin, spin_loop from generic_fns import pipes from generic_fns.structure.internal import Internal from generic_fns.structure.scientific import Scientific_data @@ -159,19 +159,14 @@ spin.pos = ave[0] -def load_spins(spin_id=None, str_id=None, combine_models=True, ave_pos=False): +def load_spins(spin_id=None, str_id=None, ave_pos=False): """Load the spins from the structural object into the relax data store. @keyword spin_id: The molecule, residue, and spin identifier string. @type spin_id: str - @keyword str_id: The structure identifier. This can be the file name, model number, - or structure number. + @keyword str_id: The structure identifier. This can be the file name, model number, or structure number. @type str_id: int or str - @keyword combine_models: A flag specifying if spins from only one structure of the ensemble - or from all should be loaded. - @type combine_models: bool - @keyword ave_pos: A flag specifying if the average atom position or the atom position - from all loaded structures is loaded into the SpinContainer. + @keyword ave_pos: A flag specifying if the average atom position or the atom position from all loaded structures is loaded into the SpinContainer. @type ave_pos: bool """ @@ -192,9 +187,11 @@ spin_nums = [] spin_names = [] + # Initialise data for the atom loop. + model_index = -1 + last_model = 1000000 + # Loop over all atoms of the spin_id selection. - model_index = -1 - last_model = None for model_num, mol_name, res_num, res_name, atom_num, atom_name, element, pos in cdp.structure.atom_loop(atom_id=spin_id, str_id=str_id, model_num_flag=True, mol_name_flag=True, res_num_flag=True, res_name_flag=True, atom_num_flag=True, atom_name_flag=True, element_flag=True, pos_flag=True, ave=ave_pos): # Update the model info. if last_model != model_num: @@ -209,84 +206,48 @@ if atom_name and search('\+', atom_name): atom_name = replace(atom_name, '+', '') - # Initialise the identification string. - id = '' - - # Get the molecule container corresponding to the molecule name. - mol_cont = None - if mol_name: - # Update the ID string. - id = id + '#' + mol_name - - # The container. - mol_cont = return_molecule(id) - - # Add the molecule if it doesn't exist. - if mol_cont == None: - # Get the unnamed molecule, assuming there is only one. - mol_cont = return_molecule() - - # Got something! - if mol_cont != None: - # Rename the molecule container if the mol name is given and the sole container is unnamed. - if mol_cont.name == None and mol_name: - # Print out. - print(("Renaming the unnamed sole molecule container to '%s'." % mol_name)) - - # Set the name. - mol_cont.name = mol_name - - # Nothing exists yet. - else: - # Add the molecule. - cdp.mol.add_item(mol_name=mol_name) - - # Get the container. - mol_cont = cdp.mol[-1] - - # Add the residue number to the ID string (residue name is ignored because only the number is unique). - id = id + ':' + repr(res_num) - - # Get the corresponding residue container. - res_cont = return_residue(id) - - # Add the residue if it doesn't exist. - if res_cont == None: - # Add the residue. - mol_cont.res.add_item(res_name=res_name, res_num=res_num) - - # Get the container. - res_cont = mol_cont.res[-1] - - # Add the atom number to the ID string (atom name is ignored because only the number is unique). - id = id + '@' + repr(atom_num) - - # Get the corresponding spin container. - spin_cont = return_spin(id) - - # Add the spin if it doesn't exist. - if spin_cont == None: - # Add the spin. - res_cont.spin.add_item(spin_name=atom_name, spin_num=atom_num) - - # Get the container. - spin_cont = res_cont.spin[-1] - - # Append all the spin ID info. + # Generate a spin ID for the current atom. + id = generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=atom_num, spin_name=atom_name) + + # Create the spin. + try: + spin_cont = create_spin(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=atom_num, spin_name=atom_name) + except RelaxError: + # Throw a warning if still on the first model. + if not model_index: + warn(RelaxWarning("The spin '%s' already exists." % id)) + continue + + # Otherwise, get the spin container. + spin_cont = return_spin(id) + + # Append all the spin ID info for the first model for printing later. + if model_index == 0: mol_names.append(mol_name) res_nums.append(res_num) res_names.append(res_name) spin_nums.append(atom_num) spin_names.append(atom_name) - # Add the position vector and element type to the spin container. + # Convert the position vector to a numpy array. + pos = array(pos, float64) + + # Average position vector (already averaged across models in the atom_loop). if ave_pos: spin_cont.pos = pos + + # All positions. else: + # Initialise. if not hasattr(spin_cont, 'pos'): spin_cont.pos = [] + + # Add the current model's position. spin_cont.pos.append(pos) - spin_cont.element = element + + # Add the element. + if not model_index: + spin_cont.element = element # Catch no data. if len(mol_names) == 0: Modified: 1.3/prompt/structure.py URL: http://svn.gna.org/viewcvs/relax/1.3/prompt/structure.py?rev=13932&r1=13931&r2=13932&view=diff ============================================================================== --- 1.3/prompt/structure.py (original) +++ 1.3/prompt/structure.py Wed Jul 27 17:54:24 2011 @@ -277,15 +277,13 @@ generic_fns.structure.main.delete() - def load_spins(self, spin_id=None, combine_models=True, ave_pos=True): + def load_spins(self, spin_id=None, ave_pos=True): """Load spins from the structure into the relax data store. Keyword Arguments ~~~~~~~~~~~~~~~~~ spin_id: The spin identification string. - - combine_models: A flag which specifies if spins from separate models should be combined. ave_pos: A flag specifying if the position of the atom is to be averaged across models. @@ -298,9 +296,6 @@ is used to select which molecules, which residues, and which atoms will be recognised as spin systems within relax. If spin_id is left as None, then all molecules, residues, and atoms will be placed within the data store. - - If the combine_models flag is True, then the spins from only a single structure from the - ensemble of models will be taken. If False, then spins will be loaded for each model. If the ave_pos flag is True, the average position of all models will be loaded into the spin container. If False, then the positions from all models will be loaded. @@ -340,17 +335,15 @@ if self._exec_info.intro: text = self._exec_info.ps3 + "structure.load_spins(" text = text + "spin_id=" + repr(spin_id) - text = text + ", combine_models=" + repr(combine_models) text = text + ", ave_pos=" + repr(ave_pos) + ")" print(text) # The argument checks. arg_check.is_str(spin_id, 'spin identification string', can_be_none=True) - arg_check.is_bool(combine_models, 'model combining flag') arg_check.is_bool(ave_pos, 'average position flag') # Execute the functional code. - generic_fns.structure.main.load_spins(spin_id=spin_id, combine_models=combine_models, ave_pos=ave_pos) + generic_fns.structure.main.load_spins(spin_id=spin_id, ave_pos=ave_pos) def read_pdb(self, file=None, dir=None, read_mol=None, set_mol_name=None, read_model=None, set_model_num=None, parser='internal'): Modified: 1.3/sample_scripts/n_state_model/conformation_analysis_rdc+pcs.py URL: http://svn.gna.org/viewcvs/relax/1.3/sample_scripts/n_state_model/conformation_analysis_rdc%2Bpcs.py?rev=13932&r1=13931&r2=13932&view=diff ============================================================================== --- 1.3/sample_scripts/n_state_model/conformation_analysis_rdc+pcs.py (original) +++ 1.3/sample_scripts/n_state_model/conformation_analysis_rdc+pcs.py Wed Jul 27 17:54:24 2011 @@ -106,7 +106,7 @@ structure.read_pdb(file='LactoseMCMM4_'+`i+1`, dir='../../../structures/tag_1000/080704_MCMM4_aligned-forEd1000', parser='internal', set_model_num=i+1, set_mol_name='tag') # Load the lanthanide atoms. -structure.load_spins(spin_id=':4@C1', combine_models=False, ave_pos=False) +structure.load_spins(spin_id=':4@C1', ave_pos=False) # Switch back to the main analysis data pipe. pipe.switch('lactose') Modified: 1.3/test_suite/shared_data/align_data/population_model/generate.py URL: http://svn.gna.org/viewcvs/relax/1.3/test_suite/shared_data/align_data/population_model/generate.py?rev=13932&r1=13931&r2=13932&view=diff ============================================================================== --- 1.3/test_suite/shared_data/align_data/population_model/generate.py (original) +++ 1.3/test_suite/shared_data/align_data/population_model/generate.py Wed Jul 27 17:54:24 2011 @@ -24,8 +24,8 @@ structure.read_pdb(file='lactose_MCMM4_S1_%i.pdb' % i, dir=str_path, set_model_num=i, set_mol_name='LE') # Load the sequence information. -structure.load_spins(spin_id=':UNK@C*', combine_models=False, ave_pos=False) -structure.load_spins(spin_id=':UNK@H*', combine_models=False, ave_pos=False) +structure.load_spins(spin_id=':UNK@C*', ave_pos=False) +structure.load_spins(spin_id=':UNK@H*', ave_pos=False) # Deselect the CH2 protons (the rotation of these doesn't work in the model, but the carbon doesn't move). deselect.spin(spin_id=':UNK@H6') Modified: 1.3/test_suite/system_tests/scripts/n_state_model/lactose_n_state.py URL: http://svn.gna.org/viewcvs/relax/1.3/test_suite/system_tests/scripts/n_state_model/lactose_n_state.py?rev=13932&r1=13931&r2=13932&view=diff ============================================================================== --- 1.3/test_suite/system_tests/scripts/n_state_model/lactose_n_state.py (original) +++ 1.3/test_suite/system_tests/scripts/n_state_model/lactose_n_state.py Wed Jul 27 17:54:24 2011 @@ -27,8 +27,8 @@ structure.read_pdb(file='lactose_MCMM4_S1_'+repr(i+1), dir=str_path, parser='internal', set_model_num=i+1, set_mol_name='lactose_MCMM4_S1') # Load the sequence information. -structure.load_spins(spin_id=':UNK@C*', combine_models=False, ave_pos=False) -structure.load_spins(spin_id=':UNK@H*', combine_models=False, ave_pos=False) +structure.load_spins(spin_id=':UNK@C*', ave_pos=False) +structure.load_spins(spin_id=':UNK@H*', ave_pos=False) # Deselect the CH2 protons (the rotation of these doesn't work in the model, but the carbon doesn't move). deselect.spin(spin_id=':UNK@H6') @@ -74,7 +74,7 @@ structure.read_pdb(file='tag_MCMM4_'+repr(i+1), dir=str_path, parser='internal', set_model_num=i+1, set_mol_name='tag') # Load the lanthanide atoms. -structure.load_spins(spin_id='@C1', combine_models=False, ave_pos=False) +structure.load_spins(spin_id='@C1', ave_pos=False) # Switch back to the main analysis data pipe. pipe.switch('lactose') Modified: 1.3/test_suite/system_tests/scripts/n_state_model/missing_data_test.py URL: http://svn.gna.org/viewcvs/relax/1.3/test_suite/system_tests/scripts/n_state_model/missing_data_test.py?rev=13932&r1=13931&r2=13932&view=diff ============================================================================== --- 1.3/test_suite/system_tests/scripts/n_state_model/missing_data_test.py (original) +++ 1.3/test_suite/system_tests/scripts/n_state_model/missing_data_test.py Wed Jul 27 17:54:24 2011 @@ -18,8 +18,8 @@ structure.read_pdb(file='LE_trunc.pdb', dir=str_path, set_mol_name='LE') # Load the sequence information. -structure.load_spins(spin_id='@C*', combine_models=False, ave_pos=False) -structure.load_spins(spin_id='@H*', combine_models=False, ave_pos=False) +structure.load_spins(spin_id='@C*', ave_pos=False) +structure.load_spins(spin_id='@H*', ave_pos=False) # Load the CH vectors for the C atoms. structure.vectors(spin_id='@C*', attached='H*', ave=False) Modified: 1.3/test_suite/system_tests/scripts/n_state_model/populations.py URL: http://svn.gna.org/viewcvs/relax/1.3/test_suite/system_tests/scripts/n_state_model/populations.py?rev=13932&r1=13931&r2=13932&view=diff ============================================================================== --- 1.3/test_suite/system_tests/scripts/n_state_model/populations.py (original) +++ 1.3/test_suite/system_tests/scripts/n_state_model/populations.py Wed Jul 27 17:54:24 2011 @@ -23,8 +23,8 @@ i += 1 # Load the sequence information. -structure.load_spins(spin_id=':UNK@C*', combine_models=False, ave_pos=False) -structure.load_spins(spin_id=':UNK@H*', combine_models=False, ave_pos=False) +structure.load_spins(spin_id=':UNK@C*', ave_pos=False) +structure.load_spins(spin_id=':UNK@H*', ave_pos=False) # Deselect the CH2 protons (the rotation of these doesn't work in the model, but the carbon doesn't move). deselect.spin(spin_id=':UNK@H6') Modified: 1.3/test_suite/system_tests/scripts/n_state_model/vector_loading.py URL: http://svn.gna.org/viewcvs/relax/1.3/test_suite/system_tests/scripts/n_state_model/vector_loading.py?rev=13932&r1=13931&r2=13932&view=diff ============================================================================== --- 1.3/test_suite/system_tests/scripts/n_state_model/vector_loading.py (original) +++ 1.3/test_suite/system_tests/scripts/n_state_model/vector_loading.py Wed Jul 27 17:54:24 2011 @@ -20,7 +20,7 @@ structure.read_pdb(file='lactose_MCMM4_S1_%i.pdb' % (ds.order_struct[i]+1), dir=str_path, set_model_num=ds.order_model[i]+1, set_mol_name='LE') # Load the sequence information. -structure.load_spins(spin_id=':UNK@C1', combine_models=False, ave_pos=False) +structure.load_spins(spin_id=':UNK@C1', ave_pos=False) # Load the CH vectors for the C atoms. structure.vectors(spin_id='@C*', attached='H*', ave=False)