Hi, I've had a look at your code and there are a few things which will need more work. I'll go though your changes below. On Jan 9, 2008 9:38 PM, <sebastien.morin.1@xxxxxxxxx> wrote:
Author: semor Date: Wed Jan 9 21:38:52 2008 New Revision: 4583 URL: http://svn.gna.org/viewcvs/relax?rev=4583&view=rev Log: Started the shifting of the consistency tests code to the new relax design. Followed the tips by Edward d'Auvergne in the post at: https://mail.gna.org/public/relax-devel/2008-01/msg00012.html (Message-id: <1199821867.8905.7.camel@localhost>) Modified: branches/consistency_tests_1.3/specific_fns/consistency_tests.py Modified: branches/consistency_tests_1.3/specific_fns/consistency_tests.py URL: http://svn.gna.org/viewcvs/relax/branches/consistency_tests_1.3/specific_fns/consistency_tests.py?rev=4583&r1=4582&r2=4583&view=diff ============================================================================== --- branches/consistency_tests_1.3/specific_fns/consistency_tests.py (original) +++ branches/consistency_tests_1.3/specific_fns/consistency_tests.py Wed Jan 9 21:38:52 2008 @@ -38,18 +38,18 @@ """Class containing functions specific to consistency testing.""" - def calculate(self, run=None, verbosity=1, sim_index=None): + def calculate(self, verbosity=1, sim_spin=None): """Calculation of the consistency functions."""
Deleting the run argument is correct, but the sim_index should stay an index. The residue index arguments (int) should be replaced by the spin argument (SpinContainer instance). This is because now the relax data store structure looks like this: relax_data_store[relax_data_store.current_pipe].mol[mol_index].res[res_index].spin[spin_index].s2 With the spin loop, the mol, res, and spin are all looped over automatically so to access the model-free order parameter you get the spin container from the loop and type: spin.s2 But the sim_index (int) is different. This is because in the 'spin' spin container, the model-free order parameter for a simulation is located at: relax_data_store[relax_data_store.current_pipe].mol[mol_index].res[res_index].spin[spin_index].s2_sim[sim_index] or using the spin loop: spin.s2_sim[sim_index] I hope this makes sense.
- # Run argument. - self.run = run + # Alias the current data pipe. + cdp = relax_data_store[relax_data_store.current_pipe]
This aliasing simplifies the rest of the code.
# Test if the frequency has been set. - if not hasattr(relax_data_store, 'ct_frq') or not relax_data_store.ct_frq.has_key(self.run) or type(relax_data_store.ct_frq[self.run]) != float: + if not hasattr(cdp, 'ct_frq') or not relax_data_store.ct_frq.has_key(self.run) or type(relax_data_store.ct_frq[self.run]) != float: raise RelaxError, "The frequency for the run " + `self.run` + " has not been set up."
This is partly correct. However the test: if not relax_data_store.ct_frq.has_key(self.run) will be a problem. ct_frq (and its ancestor variable) used to be Python dictionaries with keys corresponding to the run. These dictionaries are no more. The redesign means that you have a PipeContainer in relax_data_store['my pipe']. Everything in the PipeContainer is associated with that pipe, and hence the self.run key has become the 'my pipe' key. The PipeContainer you have here now is called 'cdp'. So that test must be deleted. The third test: if type(relax_data_store.ct_frq[self.run]) != float should be changed to: if type(cdp.ct_frq) != float Also the RelaxError text should be changed to something like: "The frequency has not been set up."
# Test if the nucleus type has been set. - if not hasattr(relax_data_store, 'gx'): + if not hasattr(cdp, 'gx'): raise RelaxNucleusError # Test if the sequence data is loaded.
This is correct for now. Note that I am in the process of changing this though. The nucleus() user function has been deleted so now the value.set() user function will be used instead. In 1.2 all spins of the whole molecule used in the analysis was assumed to be of the same nucleus type. So you have 'cdp.gx' which is a float. In 1.3 each spin has its own nucleus type now stored in 'spin.nucleus'. This variable will be a str like 'N'. So for here, this entire test can be deleted.
@@ -57,9 +57,9 @@ raise RelaxNoSequenceError, self.run # Test if the CSA, bond length, angle Theta and correlation time values have been set. - for i in xrange(len(relax_data_store.res[self.run])): - # Skip unselected residues. - if not relax_data_store.res[self.run][i].select: + for spin in spin_loop(spin_id): + # Skip unselected spins. + if not spin.select: continue # CSA value.
This is good.
@@ -67,15 +67,15 @@ raise RelaxNoValueError, "CSA" # Bond length value. - if not hasattr(relax_data_store.res[self.run][i], 'r') or relax_data_store.res[self.run][i].r == None: + if not hasattr(cdp, 'r') or relax_data_store.res[self.run][i].r == None: raise RelaxNoValueError, "bond length"
This line should be: if not hasattr(spin, 'r') or spin.r == None: The bond length, CSA value, orientation, tc, etc are specific to each spin. They may all be the same, but each spin has its own value.
# Angle Theta - if not hasattr(self.relax.data.res[self.run][i], 'orientation') or self.relax.data.res[self.run][i].orientation == None: + if not hasattr(cdp, 'orientation') or relax_data_store.res[self.run][i].orientation == None: raise RelaxNoValueError, "angle Theta" # Correlation time - if not hasattr(self.relax.data.res[self.run][i], 'tc') or self.relax.data.res[self.run][i].tc == None: + if not hasattr(cdp, 'tc') or relax_data_store.res[self.run][i].tc == None: raise RelaxNoValueError, "correlation time" # Frequency index.
Same as above.
@@ -83,12 +83,12 @@ raise RelaxError, "No relaxation data corresponding to the frequency " + `relax_data_store.ct_frq[self.run]` + " has been loaded." # Consistency testing. - for i in xrange(len(relax_data_store.res[self.run])): + for i in xrange(len(cdp)): # Reassign data structure. - data = relax_data_store.res[self.run][i] - - # Skip unselected residues. - if not data.select: + data = cdp +
This should be another spin_loop.
+ # Skip unselected spins. + if not spin.select: continue # Residue specific frequency index. @@ -266,7 +266,7 @@ return 13 * 1e-9 - def num_instances(self, run=None): + def num_instances(self): """Function for returning the number of instances.""" # Arguments.
This is correct.
@@ -280,12 +280,12 @@ return len(relax_data_store.res[self.run]) - def overfit_deselect(self, run): + def overfit_deselect(self): """Function for deselecting residues without sufficient data to support calculation""" - # Test the sequence data exists: - if not relax_data_store.res.has_key(run): - raise RelaxNoSequenceError, run + # Test if the sequence data is loaded. + if not exists_mol_res_spin_data(): + raise RelaxNoSequenceError # Loop over residue data: for residue in relax_data_store.res[run]:
This is all correct.
@@ -444,7 +444,8 @@ """ __docformat__ = "plaintext" - def set_frq(self, run=None, frq=None): + + def set_frq(self, frq=None): """Function for selecting which relaxation data to use in the consistency tests.""" # Run argument.
Again all correct.
@@ -471,7 +472,7 @@ relax_data_store.ct_frq[self.run] = frq - def set_error(self, run, instance, index, error): + def set_error(self, instance, spin, error): """Function for setting parameter errors.""" # Arguments. @@ -490,7 +491,7 @@ relax_data_store.res[self.run][instance].f_r2_err = error
Where ever you encounter something like 'relax_data_store.res[self.run]', this is an indication that you need the SpinContainer instead. Usually you will get this through the spin_loop(), but there are other functions in the 'generic_fns.selection' module which can be used to get this object if you really need.
- def sim_return_param(self, run, instance, index): + def sim_return_param(self, instance, spin): """Function for returning the array of simulation parameter values.""" # Arguments. @@ -513,7 +514,7 @@ return relax_data_store.res[self.run][instance].f_r2_sim - def sim_return_selected(self, run, instance): + def sim_return_selected(self, instance): """Function for returning the array of selected simulation flags.""" # Arguments.
All ok.
@@ -523,7 +524,7 @@ return relax_data_store.res[self.run][instance].select_sim - def set_selected_sim(self, run, instance, select_sim): + def set_selected_sim(self, instance, select_sim): """Function for returning the array of selected simulation flags."""
This instance argument should be a spin container. This is because of "relax_data_store.res[self.run][instance]".
# Arguments. @@ -533,7 +534,7 @@ relax_data_store.res[self.run][instance].select_sim = select_sim - def sim_pack_data(self, run, i, sim_data): + def sim_pack_data(self, spin, sim_data): """Function for packing Monte Carlo simulation data.""" # Test if the simulation data already exists.
All ok.
@@ -595,7 +596,7 @@ file.write("\n") - def write_columnar_results(self, file, run): + def write_columnar_results(self, file): """Function for printing the results into a file.""" # Arguments.
ok.
@@ -689,8 +690,8 @@ index = j # Data exists for this data type. - ri.append(`data.relax_data[index]`) - ri_error.append(`data.relax_error[index]`) + ri.append(spin) + ri_error.append(spin)
Here these are global structures (i.e. located in the 'cdp' PipeContainer and not in the many SpinContainers) . In the whole section starting with the "# Relaxation data and errors." comment, the current data pipe should be accessed. So 'relax_data_store' should be replaced by 'cdp', and all "[self.run]" deleted.
# No data exists for this data type. except: @@ -809,7 +810,7 @@ # Relaxation data and errors. ri = [] ri_error = [] - if hasattr(self.relax.data, 'num_ri'): + if hasattr(relax_data_store, 'num_ri'): for k in xrange(relax_data_store.num_ri[self.run]): try: # Find the residue specific data corresponding to k.
Again this should be the current data pipe.
@@ -819,8 +820,8 @@ index = l # Data exists for this data type. - ri.append(`data.relax_sim_data[i][index]`) - ri_error.append(`data.relax_error[index]`) + ri.append(spin) + ri_error.append(spin)
This is the same problem as above.
# No data exists for this data type. except: _______________________________________________ relax (http://nmr-relax.com) This is the relax-commits mailing list relax-commits@xxxxxxx To unsubscribe from this list, get a password reminder, or change your subscription options, visit the list information page at https://mail.gna.org/listinfo/relax-commits
To test the changes and find bugs, the best way would be to add a system test or two. If you have a relax script implementing the consistency testing (importantly using a small data subset) then the script and the data can be added directly to relax. Adding this will let you know when everything is functional again. Unit tests might also help to make sure that your modified functions actually work as you expect. If you have any other questions about the new design, please don't hesitate to ask. Regards, Edward