Package auto_analyses :: Module relax_fit
[hide private]
[frames] | no frames]

Source Code for Module auto_analyses.relax_fit

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2004,2006-2008,2010-2012,2014-2015,2017 Edward d'Auvergne     # 
  4  # Copyright (C) 2010 Michael Bieri                                            # 
  5  # Copyright (C) 2014 Troels E. Linnet                                         # 
  6  #                                                                             # 
  7  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  8  #                                                                             # 
  9  # This program is free software: you can redistribute it and/or modify        # 
 10  # it under the terms of the GNU General Public License as published by        # 
 11  # the Free Software Foundation, either version 3 of the License, or           # 
 12  # (at your option) any later version.                                         # 
 13  #                                                                             # 
 14  # This program is distributed in the hope that it will be useful,             # 
 15  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 16  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 17  # GNU General Public License for more details.                                # 
 18  #                                                                             # 
 19  # You should have received a copy of the GNU General Public License           # 
 20  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 21  #                                                                             # 
 22  ############################################################################### 
 23   
 24  # Module docstring. 
 25  """The automatic relaxation curve fitting protocol.""" 
 26   
 27  # Python module imports. 
 28  from os import sep 
 29  from time import time 
 30  import sys 
 31   
 32  # relax module imports. 
 33  from lib.errors import RelaxNoPipeError 
 34  from lib.plotting.grace import create_grace2images 
 35  from lib.text.sectioning import section, title 
 36  from lib.timing import print_elapsed_time 
 37  from pipe_control.mol_res_spin import spin_loop 
 38  from pipe_control.pipes import cdp_name, has_pipe, switch 
 39  from prompt.interpreter import Interpreter 
 40  from status import Status; status = Status() 
 41   
 42   
43 -class Relax_fit:
44 - def __init__(self, pipe_name=None, pipe_bundle=None, file_root='rx', results_dir=None, grid_inc=11, mc_sim_num=500, view_plots=True):
45 """Perform relaxation curve fitting. 46 47 To use this auto-analysis, a data pipe with all the required data needs to be set up. This data pipe should contain the following: 48 49 - All the spins loaded. 50 - Unresolved spins deselected. 51 - All the peak intensities loaded and relaxation delay times set. 52 - Either the baseplane noise RMSD values should be set or replicated spectra loaded. 53 54 @keyword pipe_name: The name of the data pipe containing all of the data for the analysis. 55 @type pipe_name: str 56 @keyword pipe_bundle: The data pipe bundle to associate all spawned data pipes with. 57 @type pipe_bundle: str 58 @keyword file_root: File root of the output filea. 59 @type file_root: str 60 @keyword results_dir: The directory where results files are saved. 61 @type results_dir: str 62 @keyword grid_inc: Number of grid search increments. 63 @type grid_inc: int 64 @keyword mc_sim_num: The number of Monte Carlo simulations to be used for error analysis at the end of the analysis. 65 @type mc_sim_num: int 66 @keyword view_plots: Flag to automatically view grace plots after calculation. 67 @type view_plots: bool 68 """ 69 70 # Initial printout. 71 title(file=sys.stdout, text="Relaxation curve-fitting auto-analysis") 72 73 # Safely execute the full protocol. 74 try: 75 # Execution lock. 76 status.exec_lock.acquire(pipe_bundle, mode='auto-analysis') 77 78 # Set up the analysis status object. 79 status.init_auto_analysis(pipe_bundle, type='relax_fit') 80 status.current_analysis = pipe_bundle 81 82 # Store the args. 83 self.pipe_name = pipe_name 84 self.pipe_bundle = pipe_bundle 85 self.file_root = file_root 86 self.results_dir = results_dir 87 if self.results_dir: 88 self.grace_dir = results_dir + sep + 'grace' 89 else: 90 self.grace_dir = 'grace' 91 self.mc_sim_num = mc_sim_num 92 self.grid_inc = grid_inc 93 self.view_plots = view_plots 94 95 # Data checks. 96 self.check_vars() 97 98 # Set the data pipe to the current data pipe. 99 if self.pipe_name != cdp_name(): 100 switch(self.pipe_name) 101 102 # Load the interpreter. 103 self.interpreter = Interpreter(show_script=False, raise_relax_error=True) 104 self.interpreter.populate_self() 105 self.interpreter.on(verbose=False) 106 107 # Execute. 108 self.run() 109 110 # Clean up. 111 finally: 112 # Final printout. 113 title(file=sys.stdout, text="Completion of the relaxation curve-fitting auto-analysis") 114 print_elapsed_time(time() - status.start_time) 115 116 # Finish and unlock execution. 117 status.auto_analysis[self.pipe_bundle].fin = True 118 status.current_analysis = None 119 status.exec_lock.release()
120 121
122 - def run(self):
123 """Set up and run the curve-fitting.""" 124 125 # Peak intensity error analysis. 126 self.error_analysis() 127 128 # Grid search. 129 self.interpreter.minimise.grid_search(inc=self.grid_inc) 130 131 # Minimise. 132 self.interpreter.minimise.execute('newton', scaling=False, constraints=False) 133 134 # Monte Carlo simulations. 135 self.interpreter.monte_carlo.setup(number=self.mc_sim_num) 136 self.interpreter.monte_carlo.create_data() 137 self.interpreter.monte_carlo.initial_values() 138 self.interpreter.minimise.execute('newton', scaling=False, constraints=False) 139 self.interpreter.monte_carlo.error_analysis() 140 141 # Determine the normalisation type and if the Iinf parameter exists. 142 norm_type = 'last' 143 iinf = True 144 for spin in spin_loop(skip_desel=True): 145 if spin.model not in ['sat', 'inv']: 146 norm_type = 'first' 147 iinf = False 148 break 149 150 # Save the relaxation rates and other parameter values. 151 self.interpreter.value.write(param='i0', file='i0.out', dir=self.results_dir, force=True) 152 if iinf: 153 self.interpreter.value.write(param='iinf', file='iinf.out', dir=self.results_dir, force=True) 154 self.interpreter.value.write(param='rx', file=self.file_root+'.out', dir=self.results_dir, force=True) 155 156 # Save the results. 157 self.interpreter.results.write(file='results', dir=self.results_dir, force=True) 158 159 # Create Grace plots of the data. 160 self.interpreter.grace.write(y_data_type='chi2', file='chi2.agr', dir=self.grace_dir, force=True) # Minimised chi-squared value. 161 self.interpreter.grace.write(y_data_type='i0', file='i0.agr', dir=self.grace_dir, force=True) # Initial peak intensity. 162 if iinf: 163 self.interpreter.grace.write(y_data_type='iinf', file='iinf.agr', dir=self.grace_dir, force=True) # Infinite peak intensity. 164 self.interpreter.grace.write(y_data_type='rx', file=self.file_root+'.agr', dir=self.grace_dir, force=True) # Relaxation rate. 165 self.interpreter.grace.write(x_data_type='relax_times', y_data_type='peak_intensity', file='intensities.agr', dir=self.grace_dir, force=True) # Average peak intensities. 166 self.interpreter.grace.write(x_data_type='relax_times', y_data_type='peak_intensity', norm_type=norm_type, norm=True, file='intensities_norm.agr', dir=self.grace_dir, force=True) # Average peak intensities (normalised). 167 168 # Create the Python "grace to PNG/EPS/SVG..." conversion script. 169 create_grace2images(dir=self.grace_dir) 170 171 # Display the Grace plots if selected. 172 if self.view_plots: 173 self.interpreter.grace.view(file='chi2.agr', dir=self.grace_dir) 174 self.interpreter.grace.view(file='i0.agr', dir=self.grace_dir) 175 self.interpreter.grace.view(file=self.file_root+'.agr', dir=self.grace_dir) 176 self.interpreter.grace.view(file='intensities.agr', dir=self.grace_dir) 177 self.interpreter.grace.view(file='intensities_norm.agr', dir=self.grace_dir) 178 179 # Save the program state. 180 self.interpreter.state.save(state='state', dir=self.results_dir, force=True)
181 182
183 - def error_analysis(self):
184 """Perform an error analysis of the peak intensities.""" 185 186 # Printout. 187 section(file=sys.stdout, text="Error analysis", prespace=2) 188 189 # Check if intensity errors have already been calculated by the user. 190 precalc = True 191 for spin in spin_loop(skip_desel=True): 192 # No structure. 193 if not hasattr(spin, 'peak_intensity_err'): 194 precalc = False 195 break 196 197 # Determine if a spectrum ID is missing from the list. 198 for id in cdp.spectrum_ids: 199 if id not in spin.peak_intensity_err: 200 precalc = False 201 break 202 203 # Skip. 204 if precalc: 205 print("Skipping the error analysis as it has already been performed.") 206 return 207 208 # Check if there is replicates, and the user has not specified them. 209 210 # Set flag for dublicates. 211 has_dub = False 212 213 if not hasattr(cdp, 'replicates'): 214 # Collect all times, and matching spectrum ID. 215 all_times = [] 216 all_id = [] 217 for spectrum_id in cdp.relax_times: 218 all_times.append(cdp.relax_times[spectrum_id]) 219 all_id.append(spectrum_id) 220 221 # Get the dublicates. 222 dublicates = [(val, [i for i in range(len(all_times)) if all_times[i] == val]) for val in all_times] 223 224 # Loop over the list of the mapping of times and duplications. 225 list_dub_mapping = [] 226 for i, dub in enumerate(dublicates): 227 # Get current spectum id. 228 cur_spectrum_id = all_id[i] 229 230 # Get the tuple of time and indexes of duplications. 231 time, list_index_occur = dub 232 233 # Collect mapping of index to id. 234 id_list = [] 235 if len(list_index_occur) > 1: 236 # There exist dublications. 237 has_dub = True 238 239 for list_index in list_index_occur: 240 id_list.append(all_id[list_index]) 241 242 # Store to list 243 list_dub_mapping.append((cur_spectrum_id, id_list)) 244 245 # If there is dublication, then assign them. 246 if has_dub: 247 # Assign dublicates. 248 for spectrum_id, dub_pair in list_dub_mapping: 249 if len(dub_pair) > 0: 250 self.interpreter.spectrum.replicated(spectrum_ids=dub_pair) 251 252 # Run the error analysis. 253 self.interpreter.spectrum.error_analysis()
254 255
256 - def check_vars(self):
257 """Check that the user has set the variables correctly.""" 258 259 # The pipe name. 260 if not has_pipe(self.pipe_name): 261 raise RelaxNoPipeError(self.pipe_name)
262