1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 from os import F_OK, access, getcwd, listdir, sep
25 from re import search
26 from string import lower
27 from time import sleep
28
29
30 from doc_builder import LIST, PARAGRAPH, SECTION, SUBSECTION, TITLE, to_docstring
31 from float import floatAsByteArray
32 from info import Info_box; info = Info_box()
33 from generic_fns.mol_res_spin import exists_mol_res_spin_data, generate_spin_id, spin_index_loop, spin_loop
34 from generic_fns.pipes import cdp_name, get_pipe, has_pipe, pipe_names, switch
35 from generic_fns import selection
36 from prompt.interpreter import Interpreter
37 from relax_errors import RelaxError, RelaxNoSequenceError, RelaxNoValueError
38 from relax_io import DummyFileObject
39 from status import Status; status = Status()
40
41
42 doc = [
43 [TITLE, "Automatic analysis for black-box model-free results."],
44 [PARAGRAPH, "The dauvergne_protocol auto-analysis is designed for those who appreciate black-boxes or those who appreciate complex code. Importantly, data at multiple magnetic field strengths is essential for this analysis. If you would like to change how model-free analysis is performed, the code in the file auto_analyses/dauvergne_protocol.py in the base relax directory can be copied and modified as needed and used with the relax script interface. This file is simply a complex relax script. For a description of object-oriented coding in python using classes, functions/methods, self, etc., please see the python tutorial."],
45
46 [SECTION, "References"],
47
48 [SUBSECTION, "Auto-analysis primary reference"],
49 [PARAGRAPH, "The model-free optimisation methodology herein is that of:"],
50 [LIST, info.bib['dAuvergneGooley08b'].cite_short()],
51
52 [SUBSECTION, "Techniques used in the auto-analysis"],
53 [PARAGRAPH, "Other references for features of this dauvergne_protocol auto-analysis include model-free model selection using Akaike's Information Criterion:"],
54 [LIST, info.bib['dAuvergneGooley03'].cite_short()],
55 [PARAGRAPH, "The elimination of failed model-free models and Monte Carlo simulations:"],
56 [LIST, info.bib['dAuvergneGooley06'].cite_short()],
57 [PARAGRAPH, "Significant model-free optimisation improvements:"],
58 [LIST, info.bib['dAuvergneGooley08a'].cite_short()],
59 [PARAGRAPH, "Rather than searching for the lowest chi-squared value, this auto-analysis searches for the model with the lowest AIC criterion. This complex multi-universe, multi-dimensional problem is formulated, using set theory, as the universal solution:"],
60 [LIST, info.bib['dAuvergneGooley07'].cite_short()],
61 [PARAGRAPH, "The basic three references for the original and extended model-free theories are:"],
62 [LIST, info.bib['LipariSzabo82a'].cite_short()],
63 [LIST, info.bib['LipariSzabo82b'].cite_short()],
64 [LIST, info.bib['Clore90'].cite_short()],
65
66 [SECTION, "How to use this auto-analysis"],
67 [PARAGRAPH, "The five diffusion models used in this auto-analysis are:"],
68 [LIST, "Model I (MI) - Local tm."],
69 [LIST, "Model II (MII) - Sphere."],
70 [LIST, "Model III (MIII) - Prolate spheroid."],
71 [LIST, "Model IV (MIV) - Oblate spheroid."],
72 [LIST, "Model V (MV) - Ellipsoid."],
73 [PARAGRAPH, "If using the script-based user interface (UI), changing the value of the variable diff_model will determine the behaviour of this auto-analysis. Model I must be optimised prior to any of the other diffusion models, while the Models II to V can be optimised in any order. To select the various models, set the variable diff_model to the following strings:"],
74 [LIST, "MI - 'local_tm'"],
75 [LIST, "MII - 'sphere'"],
76 [LIST, "MIII - 'prolate'"],
77 [LIST, "MIV - 'oblate'"],
78 [LIST, "MV - 'ellipsoid'"],
79 [PARAGRAPH, "This approach has the advantage of eliminating the need for an initial estimate of a global diffusion tensor and removing all the problems associated with the initial estimate."],
80 [PARAGRAPH, "It is important that the number of parameters in a model does not exceed the number of relaxation data sets for that spin. If this is the case, the list of models in the mf_models and local_tm_models variables will need to be trimmed."],
81
82 [SUBSECTION, "Model I - Local tm"],
83 [PARAGRAPH, "This will optimise the diffusion model whereby all spin of the molecule have a local tm value, i.e. there is no global diffusion tensor. This model needs to be optimised prior to optimising any of the other diffusion models. Each spin is fitted to the multiple model-free models separately, where the parameter tm is included in each model."],
84 [PARAGRAPH, "AIC model selection is used to select the models for each spin."],
85
86 [SUBSECTION, "Model II - Sphere"],
87 [PARAGRAPH, "This will optimise the isotropic diffusion model. Multiple steps are required, an initial optimisation of the diffusion tensor, followed by a repetitive optimisation until convergence of the diffusion tensor. In the relax script UI each of these steps requires this script to be rerun, unless the conv_loop flag is True. In the GUI (graphical user interface), the procedure is repeated automatically until convergence. For the initial optimisation, which will be placed in the directory './sphere/init/', the following steps are used:"],
88 [PARAGRAPH, "The model-free models and parameter values for each spin are set to those of diffusion model MI."],
89 [PARAGRAPH, "The local tm parameter is removed from the models."],
90 [PARAGRAPH, "The model-free parameters are fixed and a global spherical diffusion tensor is minimised."],
91 [PARAGRAPH, "For the repetitive optimisation, each minimisation is named from 'round_1' onwards. The initial 'round_1' optimisation will extract the diffusion tensor from the results file in './sphere/init/', and the results will be placed in the directory './sphere/round_1/'. Each successive round will take the diffusion tensor from the previous round. The following steps are used:"],
92 [PARAGRAPH, "The global diffusion tensor is fixed and the multiple model-free models are fitted to each spin."],
93 [PARAGRAPH, "AIC model selection is used to select the models for each spin."],
94 [PARAGRAPH, "All model-free and diffusion parameters are allowed to vary and a global optimisation of all parameters is carried out."],
95
96 [SUBSECTION, "Model III - Prolate spheroid"],
97 [PARAGRAPH, "The methods used are identical to those of diffusion model MII, except that an axially symmetric diffusion tensor with Da >= 0 is used. The base directory containing all the results is './prolate/'."],
98
99 [SUBSECTION, "Model IV - Oblate spheroid"],
100 [PARAGRAPH, "The methods used are identical to those of diffusion model MII, except that an axially symmetric diffusion tensor with Da <= 0 is used. The base directory containing all the results is './oblate/'."],
101
102 [SUBSECTION, "Model V - Ellipsoid"],
103 [PARAGRAPH, "The methods used are identical to those of diffusion model MII, except that a fully anisotropic diffusion tensor is used (also known as rhombic or asymmetric diffusion). The base directory is './ellipsoid/'."],
104
105 [SUBSECTION, "Final run"],
106 [PARAGRAPH, "Once all the diffusion models have converged, the final run can be executed. This is done by setting the variable diff_model to 'final'. This consists of two steps, diffusion tensor model selection, and Monte Carlo simulations. Firstly AIC model selection is used to select between the diffusion tensor models. Monte Carlo simulations are then run solely on this selected diffusion model. Minimisation of the model is bypassed as it is assumed that the model is already fully optimised (if this is not the case the final run is not yet appropriate)."],
107 [PARAGRAPH, "The final black-box model-free results will be placed in the file 'final/results'."]
108 ]
109
110
111
112 __doc__ = to_docstring(doc)
113
114
115
117 """The model-free auto-analysis."""
118
119
120 opt_func_tol = 1e-25
121 opt_max_iterations = int(1e7)
122
123 - def __init__(self, pipe_name=None, results_dir=None, diff_model=None, mf_models=['m0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9'], local_tm_models=['tm0', 'tm1', 'tm2', 'tm3', 'tm4', 'tm5', 'tm6', 'tm7', 'tm8', 'tm9'], grid_inc=11, diff_tensor_grid_inc={'sphere': 11, 'prolate': 11, 'oblate': 11, 'ellipsoid': 6}, min_algor='newton', mc_sim_num=500, max_iter=None, user_fns=None, conv_loop=True):
124 """Perform the full model-free analysis protocol of d'Auvergne and Gooley, 2008b.
125
126 @keyword pipe_name: The name of the data pipe containing the sequence info. This data pipe should have all values set including the CSA value, the bond length, the heteronucleus name and proton name. It should also have all relaxation data loaded.
127 @keyword results_dir: The directory, where files are saved in.
128 @type results_dir: str
129 @keyword diff_model: The global diffusion model to optimise. This can be one of 'local_tm', 'sphere', 'oblate', 'prolate', 'ellipsoid', or 'final'. If all or a subset of these are supplied as a list, then these will be automatically looped over and calculated.
130 @type diff_model: str or list of str
131 @keyword mf_models: The model-free models.
132 @type mf_models: list of str
133 @keyword local_tm_models: The model-free models.
134 @type local_tm_models: list of str
135 @keyword grid_inc: The grid search size (the number of increments per dimension).
136 @type grid_inc: int
137 @keyword diff_tensor_grid_inc: A list of grid search sizes for the optimisation of the sphere, prolate spheroid, oblate spheroid, and ellipsoid.
138 @type diff_tensor_grid_inc: list of int
139 @keyword min_algor: The minimisation algorithm (in most cases this should not be changed).
140 @type min_algor: str
141 @keyword mc_sim_num: The number of Monte Carlo simulations to be used for error analysis at the end of the analysis.
142 @type mc_sim_num: int
143 @keyword max_iter: The maximum number of iterations for the global iteration. Set to None, then the algorithm iterates until convergence.
144 @type max_iter: int or None.
145 @keyword user_fns: A dictionary of replacement user functions. These will overwrite the standard user functions. The key should be the name of the user function or user function class and the value should be the function or class instance.
146 @type user_fns: dict
147 @keyword conv_loop: Automatic looping over all rounds until convergence.
148 @type conv_loop: bool
149 """
150
151
152 status.exec_lock.acquire(pipe_name, mode='auto-analysis')
153
154
155 self.pipe_name = pipe_name
156 self.mf_models = mf_models
157 self.local_tm_models = local_tm_models
158 self.grid_inc = grid_inc
159 self.diff_tensor_grid_inc = diff_tensor_grid_inc
160 self.min_algor = min_algor
161 self.mc_sim_num = mc_sim_num
162 self.max_iter = max_iter
163 self.conv_loop = conv_loop
164
165
166 if isinstance(diff_model, list):
167 self.diff_model_list = diff_model
168 else:
169 self.diff_model_list = [diff_model]
170
171
172 if results_dir:
173 self.results_dir = results_dir + sep
174 else:
175 self.results_dir = getcwd() + sep
176
177
178 self.check_vars()
179
180
181 if self.pipe_name != cdp_name():
182 switch(self.pipe_name)
183
184
185 self.status_setup()
186
187
188 self.interpreter = Interpreter(show_script=False, quit=False, raise_relax_error=True)
189 self.interpreter.populate_self()
190 self.interpreter.on(verbose=False)
191
192
193 if user_fns:
194 for name in user_fns:
195 setattr(self.interpreter, name, user_fns[name])
196
197
198 try:
199
200 for self.diff_model in self.diff_model_list:
201
202 sleep(1)
203
204
205 status.auto_analysis[self.pipe_name].diff_model = self.diff_model
206
207
208 self.conv_data = Container()
209 self.conv_data.chi2 = []
210 self.conv_data.models = []
211 self.conv_data.diff_vals = []
212 if self.diff_model == 'sphere':
213 self.conv_data.diff_params = ['tm']
214 elif self.diff_model == 'oblate' or self.diff_model == 'prolate':
215 self.conv_data.diff_params = ['tm', 'Da', 'theta', 'phi']
216 elif self.diff_model == 'ellipsoid':
217 self.conv_data.diff_params = ['tm', 'Da', 'Dr', 'alpha', 'beta', 'gamma']
218 self.conv_data.spin_ids = []
219 self.conv_data.mf_params = []
220 self.conv_data.mf_vals = []
221
222
223 self.execute()
224
225
226 finally:
227
228 status.auto_analysis[self.pipe_name].fin = True
229 status.current_analysis = None
230 status.exec_lock.release()
231
232
234 """Check that the user has set the variables correctly."""
235
236
237 valid_models = ['local_tm', 'sphere', 'oblate', 'prolate', 'ellipsoid', 'final']
238 for i in range(len(self.diff_model_list)):
239 if self.diff_model_list[i] not in valid_models:
240 raise RelaxError("The diff_model value '%s' is incorrectly set. It must be one of %s." % (self.diff_model_list[i], valid_models))
241
242
243 mf_models = ['m0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8', 'm9']
244 local_tm_models = ['tm0', 'tm1', 'tm2', 'tm3', 'tm4', 'tm5', 'tm6', 'tm7', 'tm8', 'tm9']
245 if not isinstance(self.mf_models, list):
246 raise RelaxError("The self.mf_models user variable must be a list.")
247 if not isinstance(self.local_tm_models, list):
248 raise RelaxError("The self.local_tm_models user variable must be a list.")
249 for i in range(len(self.mf_models)):
250 if self.mf_models[i] not in mf_models:
251 raise RelaxError("The self.mf_models user variable '%s' is incorrectly set. It must be one of %s." % (self.mf_models, mf_models))
252 for i in range(len(self.local_tm_models)):
253 if self.local_tm_models[i] not in local_tm_models:
254 raise RelaxError("The self.local_tm_models user variable '%s' is incorrectly set. It must be one of %s." % (self.local_tm_models, local_tm_models))
255
256
257 if not exists_mol_res_spin_data():
258 raise RelaxNoSequenceError(self.pipe_name)
259
260
261 if not hasattr(cdp, 'ri_ids') or len(cdp.ri_ids) == 0:
262 raise RelaxNoRiError(ri_id)
263
264
265 if len(cdp.ri_ids) <= 3:
266 raise RelaxError("Insufficient relaxation data, 4 or more data sets are essential for the execution of this script.")
267
268
269 for spin, spin_id in spin_loop(return_id=True):
270
271 if not spin.select:
272 continue
273
274
275 print("Checking spin '%s'." % spin_id)
276
277
278 if not hasattr(spin, 'r') or spin.r == None:
279 raise RelaxNoValueError("bond length")
280
281
282 if not hasattr(spin, 'csa') or spin.csa == None:
283 raise RelaxNoValueError("CSA")
284
285
286 if not hasattr(spin, 'heteronuc_type') or spin.heteronuc_type == None:
287 raise RelaxNoValueError("heteronucleus type")
288
289
290 if not hasattr(spin, 'proton_type') or spin.proton_type == None:
291 raise RelaxNoValueError("proton type")
292
293
294 if not isinstance(self.grid_inc, int):
295 raise RelaxError("The grid_inc user variable '%s' is incorrectly set. It should be an integer." % self.grid_inc)
296 if not isinstance(self.diff_tensor_grid_inc, dict):
297 raise RelaxError("The diff_tensor_grid_inc user variable '%s' is incorrectly set. It should be a dictionary." % self.diff_tensor_grid_inc)
298 for tensor in ['sphere', 'prolate', 'oblate', 'ellipsoid']:
299 if not self.diff_tensor_grid_inc.has_key(tensor):
300 raise RelaxError("The diff_tensor_grid_inc user variable '%s' is incorrectly set. It should contain the '%s' key." % (self.diff_tensor_grid_inc, tensor))
301 if not isinstance(self.diff_tensor_grid_inc[tensor], int):
302 raise RelaxError("The diff_tensor_grid_inc user variable '%s' is incorrectly set. The value corresponding to the key '%s' should be an integer." % (self.diff_tensor_grid_inc, tensor))
303 if not isinstance(self.min_algor, str):
304 raise RelaxError("The min_algor user variable '%s' is incorrectly set. It should be a string." % self.min_algor)
305 if not isinstance(self.mc_sim_num, int):
306 raise RelaxError("The mc_sim_num user variable '%s' is incorrectly set. It should be an integer." % self.mc_sim_num)
307
308
309 if not isinstance(self.conv_loop, bool):
310 raise RelaxError("The conv_loop user variable '%s' is incorrectly set. It should be one of the booleans True or False." % self.conv_loop)
311
312
314 """Test for the convergence of the global model."""
315
316
317 print("\n\n\n")
318 print("#####################")
319 print("# Convergence tests #")
320 print("#####################\n")
321
322
323 if self.max_iter and self.round > self.max_iter:
324 print("Maximum number of global iterations reached. Terminating the protocol before convergence has been reached.")
325 return True
326
327
328 self.conv_data.chi2.append(cdp.chi2)
329
330
331 curr_models = ''
332 for spin in spin_loop():
333 if hasattr(spin, 'model'):
334 if not spin.model == 'None':
335 curr_models = curr_models + spin.model
336 self.conv_data.models.append(curr_models)
337
338
339 self.conv_data.diff_vals.append([])
340 for param in self.conv_data.diff_params:
341
342 self.conv_data.diff_vals[-1].append(getattr(cdp.diff_tensor, param))
343
344
345 self.conv_data.mf_vals.append([])
346 self.conv_data.mf_params.append([])
347 self.conv_data.spin_ids.append([])
348 for spin, spin_id in spin_loop(return_id=True):
349
350 if not hasattr(spin, 'params'):
351 continue
352
353
354 self.conv_data.spin_ids[-1].append(spin_id)
355 self.conv_data.mf_params[-1].append([])
356 self.conv_data.mf_vals[-1].append([])
357
358
359 for j in xrange(len(spin.params)):
360
361 self.conv_data.mf_params[-1][-1].append(spin.params[j])
362 self.conv_data.mf_vals[-1][-1].append(getattr(spin, lower(spin.params[j])))
363
364
365 if self.round == 1:
366 print("First round of optimisation, skipping the convergence tests.\n\n\n")
367 return False
368
369
370 converged = False
371 for i in range(self.start_round, self.round - 1):
372
373 print("\n\n\n# Comparing the current iteration to iteration %i.\n" % (i+1))
374
375
376 index = i - self.start_round
377
378
379 print("Chi-squared test:")
380 print(" chi2 (iter %i): %s" % (i+1, self.conv_data.chi2[index]))
381 print(" (as an IEEE-754 byte array: %s)" % floatAsByteArray(self.conv_data.chi2[index]))
382 print(" chi2 (iter %i): %s" % (self.round, self.conv_data.chi2[-1]))
383 print(" (as an IEEE-754 byte array: %s)" % floatAsByteArray(self.conv_data.chi2[-1]))
384 print(" chi2 (difference): %s" % (self.conv_data.chi2[index] - self.conv_data.chi2[-1]))
385 if self.conv_data.chi2[index] == self.conv_data.chi2[-1]:
386 print(" The chi-squared value has converged.\n")
387 else:
388 print(" The chi-squared value has not converged.\n")
389 continue
390
391
392 print("Identical model-free models test:")
393 if self.conv_data.models[index] == self.conv_data.models[-1]:
394 print(" The model-free models have converged.\n")
395 else:
396 print(" The model-free models have not converged.\n")
397 continue
398
399
400 print("Identical diffusion tensor parameter test:")
401 params_converged = True
402 for k in range(len(self.conv_data.diff_params)):
403
404 if self.conv_data.diff_vals[index][k] != self.conv_data.diff_vals[-1][k]:
405 print(" Parameter: %s" % param)
406 print(" Value (iter %i): %s" % (i+1, self.conv_data.diff_vals[index][k]))
407 print(" (as an IEEE-754 byte array: %s)" % floatAsByteArray(self.conv_data.diff_vals[index][k]))
408 print(" Value (iter %i): %s" % (self.round, self.conv_data.diff_vals[-1][k]))
409 print(" (as an IEEE-754 byte array: %s)" % floatAsByteArray(self.conv_data.diff_vals[-1][k]))
410 print(" The diffusion parameters have not converged.\n")
411 params_converged = False
412 break
413 if not params_converged:
414 continue
415 print(" The diffusion tensor parameters have converged.\n")
416
417
418 print("\nIdentical model-free parameter test:")
419 if len(self.conv_data.spin_ids[index]) != len(self.conv_data.spin_ids[-1]):
420 print(" Different number of spins.")
421 continue
422 for j in range(len(self.conv_data.spin_ids[-1])):
423
424 for k in range(len(self.conv_data.mf_params[-1][j])):
425
426 if self.conv_data.mf_vals[index][j][k] != self.conv_data.mf_vals[-1][j][k]:
427 print(" Spin ID: %s" % self.conv_data.spin_ids[-1][j])
428 print(" Parameter: %s" % self.conv_data.mf_params[-1][j][k])
429 print(" Value (iter %i): %s" % (i+1, self.conv_data.mf_vals[index][j][k]))
430 print(" (as an IEEE-754 byte array: %s)" % floatAsByteArray(self.conv_data.mf_vals[index][j][k]))
431 print(" Value (iter %i): %s" % (self.round, self.conv_data.mf_vals[-1][j][k]))
432 print(" (as an IEEE-754 byte array: %s)" % floatAsByteArray(self.conv_data.mf_vals[index][j][k]))
433 print(" The model-free parameters have not converged.\n")
434 params_converged = False
435 break
436 if not params_converged:
437 continue
438 print(" The model-free parameters have converged.\n")
439
440
441 converged = True
442 break
443
444
445
446
447
448 print("\nConvergence:")
449 if converged:
450
451 status.auto_analysis[self.pipe_name].convergence = True
452
453
454 print(" [ Yes ]")
455
456
457 return True
458 else:
459
460 print(" [ No ]")
461
462
463 return False
464
465
467 """Function for returning the name of next round of optimisation."""
468
469
470 try:
471 dir_list = listdir(self.results_dir+sep+model)
472 except:
473 return 0
474
475
476 if 'init' not in dir_list:
477 return 0
478
479
480 rnd_dirs = []
481 for file in dir_list:
482 if search('^round_', file):
483 rnd_dirs.append(file)
484
485
486 numbers = []
487 for dir in rnd_dirs:
488 try:
489 numbers.append(int(dir[6:]))
490 except:
491 pass
492 numbers.sort()
493
494
495 if not len(numbers):
496 return 1
497
498
499 max_round = numbers[-1]
500
501
502 for i in range(max_round, -1, -1):
503
504 complete_round = i
505
506
507 file_root = self.results_dir + sep + model + sep + "round_%i" % i + sep + 'opt' + sep + 'results'
508
509
510 if access(file_root + '.bz2', F_OK):
511 break
512 if access(file_root + '.gz', F_OK):
513 break
514 if access(file_root, F_OK):
515 break
516
517
518 if complete_round == 0:
519 return 0
520
521
522 return complete_round + 1
523
524
526 """Execute the protocol."""
527
528
529
530
531 if self.diff_model == 'local_tm':
532
533 self.base_dir = self.results_dir+'local_tm'+sep
534
535
536 self.multi_model(local_tm=True)
537
538
539 self.model_selection(modsel_pipe='aic', dir=self.base_dir + 'aic')
540
541
542
543
544
545 elif self.diff_model == 'sphere' or self.diff_model == 'prolate' or self.diff_model == 'oblate' or self.diff_model == 'ellipsoid':
546
547 dir_list = listdir(self.results_dir)
548 if 'local_tm' not in dir_list:
549 raise RelaxError("The local_tm model must be optimised first.")
550
551
552 self.start_round = self.determine_rnd(model=self.diff_model)
553
554
555
556 while True:
557
558 self.round = self.determine_rnd(model=self.diff_model)
559 status.auto_analysis[self.pipe_name].round = self.round
560
561
562 if self.round == 0:
563
564 self.base_dir = self.results_dir+self.diff_model+sep+'init'+sep
565
566
567 name = self.diff_model
568
569
570 if has_pipe(name):
571 self.interpreter.pipe.delete(name)
572 self.interpreter.pipe.create(name, 'mf')
573
574
575 self.interpreter.results.read(file='results', dir=self.results_dir+'local_tm'+sep+'aic')
576
577
578 self.interpreter.model_free.remove_tm()
579
580
581 if self.diff_model == 'sphere':
582 self.interpreter.diffusion_tensor.init(10e-9, fixed=False)
583 inc = self.diff_tensor_grid_inc['sphere']
584 elif self.diff_model == 'prolate':
585 self.interpreter.diffusion_tensor.init((10e-9, 0, 0, 0), spheroid_type='prolate', fixed=False)
586 inc = self.diff_tensor_grid_inc['prolate']
587 elif self.diff_model == 'oblate':
588 self.interpreter.diffusion_tensor.init((10e-9, 0, 0, 0), spheroid_type='oblate', fixed=False)
589 inc = self.diff_tensor_grid_inc['oblate']
590 elif self.diff_model == 'ellipsoid':
591 self.interpreter.diffusion_tensor.init((10e-09, 0, 0, 0, 0, 0), fixed=False)
592 inc = self.diff_tensor_grid_inc['ellipsoid']
593
594
595 self.interpreter.fix('all_spins')
596 self.interpreter.grid_search(inc=inc)
597 self.interpreter.minimise(self.min_algor, func_tol=self.opt_func_tol, max_iterations=self.opt_max_iterations)
598
599
600 self.interpreter.results.write(file='results', dir=self.base_dir, force=True)
601
602
603
604 else:
605
606 self.base_dir = self.results_dir+self.diff_model + sep+'round_'+repr(self.round)+sep
607
608
609 self.load_tensor()
610
611
612 self.multi_model()
613
614
615 self.model_selection(modsel_pipe='aic', dir=self.base_dir + 'aic')
616
617
618 self.interpreter.fix('all', fixed=False)
619
620
621 self.interpreter.minimise(self.min_algor, func_tol=self.opt_func_tol, max_iterations=self.opt_max_iterations)
622
623
624 dir = self.base_dir + 'opt'
625 self.interpreter.results.write(file='results', dir=dir, force=True)
626
627
628 converged = self.convergence()
629
630
631 if converged or not self.conv_loop:
632 break
633
634
635 status.auto_analysis[self.pipe_name].round = None
636
637
638
639
640
641 elif self.diff_model == 'final':
642
643
644
645
646 self.pipes = ['local_tm', 'sphere', 'prolate', 'oblate', 'ellipsoid']
647
648
649 for name in pipe_names():
650 if name in self.pipes + self.mf_models + self.local_tm_models + ['aic', 'previous']:
651 self.interpreter.pipe.delete(name)
652
653
654 dir_list = listdir(self.results_dir)
655 for name in self.pipes:
656 if name not in dir_list:
657 raise RelaxError("The %s model must be optimised first." % name)
658
659
660 self.interpreter.pipe.create('local_tm', 'mf')
661
662
663 self.interpreter.results.read(file='results', dir=self.results_dir+'local_tm'+sep+'aic')
664
665
666 for model in ['sphere', 'prolate', 'oblate', 'ellipsoid']:
667
668 self.round = self.determine_rnd(model=model) - 1
669
670
671 if self.round < 1:
672
673 name = model
674 if model == 'prolate' or model == 'oblate':
675 name = name + ' spheroid'
676
677
678 raise RelaxError("Multiple rounds of optimisation of the " + name + " (between 8 to 15) are required for the proper execution of this script.")
679
680
681 self.interpreter.pipe.create(model, 'mf')
682
683
684 self.interpreter.results.read(file='results', dir=self.results_dir+model + sep+'round_'+repr(self.round)+sep+'opt')
685
686
687 self.model_selection(modsel_pipe='final', write_flag=False)
688
689
690
691
692
693
694 if hasattr(get_pipe('final'), 'diff_tensor'):
695 self.interpreter.fix('diff')
696
697
698 self.interpreter.monte_carlo.setup(number=self.mc_sim_num)
699 self.interpreter.monte_carlo.create_data()
700 self.interpreter.monte_carlo.initial_values()
701 self.interpreter.minimise(self.min_algor, func_tol=self.opt_func_tol, max_iterations=self.opt_max_iterations)
702 self.interpreter.eliminate()
703 self.interpreter.monte_carlo.error_analysis()
704
705
706
707
708
709
710 self.write_results()
711
712
713
714
715
716 else:
717 raise RelaxError("Unknown diffusion model, change the value of 'self.diff_model'")
718
719
735
736
748
749
791
792
794 """Initialise the status object."""
795
796
797 status.init_auto_analysis(self.pipe_name, type='dauvergne_protocol')
798 status.current_analysis = self.pipe_name
799
800
801 status.auto_analysis[self.pipe_name].diff_model = None
802
803
804 status.auto_analysis[self.pipe_name].round = None
805
806
807 status.auto_analysis[self.pipe_name].local_tm_models = self.local_tm_models
808
809
810 status.auto_analysis[self.pipe_name].mf_models = self.mf_models
811
812
813 status.auto_analysis[self.pipe_name].current_model = None
814
815
816 status.auto_analysis[self.pipe_name].max_iter = self.max_iter
817
818
819 status.auto_analysis[self.pipe_name].convergence = False
820
821
823 """Create Grace plots of the final model-free results."""
824
825
826 dir = self.results_dir + 'final'
827 self.interpreter.results.write(file='results', dir=dir, force=True)
828
829
830 dir = self.results_dir + 'final' + sep + 'grace'
831 self.interpreter.grace.write(x_data_type='spin', y_data_type='s2', file='s2.agr', dir=dir, force=True)
832 self.interpreter.grace.write(x_data_type='spin', y_data_type='s2f', file='s2f.agr', dir=dir, force=True)
833 self.interpreter.grace.write(x_data_type='spin', y_data_type='s2s', file='s2s.agr', dir=dir, force=True)
834 self.interpreter.grace.write(x_data_type='spin', y_data_type='te', file='te.agr', dir=dir, force=True)
835 self.interpreter.grace.write(x_data_type='spin', y_data_type='tf', file='tf.agr', dir=dir, force=True)
836 self.interpreter.grace.write(x_data_type='spin', y_data_type='ts', file='ts.agr', dir=dir, force=True)
837 self.interpreter.grace.write(x_data_type='spin', y_data_type='rex', file='rex.agr', dir=dir, force=True)
838 self.interpreter.grace.write(x_data_type='s2', y_data_type='te', file='s2_vs_te.agr', dir=dir, force=True)
839 self.interpreter.grace.write(x_data_type='s2', y_data_type='rex', file='s2_vs_rex.agr', dir=dir, force=True)
840 self.interpreter.grace.write(x_data_type='te', y_data_type='rex', file='te_vs_rex.agr', dir=dir, force=True)
841
842
843 dir = self.results_dir + 'final'
844 self.interpreter.value.write(param='s2', file='s2.txt', dir=dir, force=True)
845 self.interpreter.value.write(param='s2f', file='s2f.txt', dir=dir, force=True)
846 self.interpreter.value.write(param='s2s', file='s2s.txt', dir=dir, force=True)
847 self.interpreter.value.write(param='te', file='te.txt', dir=dir, force=True)
848 self.interpreter.value.write(param='tf', file='tf.txt', dir=dir, force=True)
849 self.interpreter.value.write(param='ts', file='ts.txt', dir=dir, force=True)
850 self.interpreter.value.write(param='rex', file='rex.txt', dir=dir, force=True)
851 self.interpreter.value.write(param='local_tm', file='local_tm.txt', dir=dir, force=True)
852
853
854 dir = self.results_dir + 'final' + sep + 'pymol'
855 self.interpreter.pymol.macro_write(data_type='s2', dir=dir, force=True)
856 self.interpreter.pymol.macro_write(data_type='s2f', dir=dir, force=True)
857 self.interpreter.pymol.macro_write(data_type='s2s', dir=dir, force=True)
858 self.interpreter.pymol.macro_write(data_type='amp_fast', dir=dir, force=True)
859 self.interpreter.pymol.macro_write(data_type='amp_slow', dir=dir, force=True)
860 self.interpreter.pymol.macro_write(data_type='te', dir=dir, force=True)
861 self.interpreter.pymol.macro_write(data_type='tf', dir=dir, force=True)
862 self.interpreter.pymol.macro_write(data_type='ts', dir=dir, force=True)
863 self.interpreter.pymol.macro_write(data_type='time_fast', dir=dir, force=True)
864 self.interpreter.pymol.macro_write(data_type='time_slow', dir=dir, force=True)
865 self.interpreter.pymol.macro_write(data_type='rex', dir=dir, force=True)
866
867
868 dir = self.results_dir + 'final' + sep + 'molmol'
869 self.interpreter.molmol.macro_write(data_type='s2', dir=dir, force=True)
870 self.interpreter.molmol.macro_write(data_type='s2f', dir=dir, force=True)
871 self.interpreter.molmol.macro_write(data_type='s2s', dir=dir, force=True)
872 self.interpreter.molmol.macro_write(data_type='amp_fast', dir=dir, force=True)
873 self.interpreter.molmol.macro_write(data_type='amp_slow', dir=dir, force=True)
874 self.interpreter.molmol.macro_write(data_type='te', dir=dir, force=True)
875 self.interpreter.molmol.macro_write(data_type='tf', dir=dir, force=True)
876 self.interpreter.molmol.macro_write(data_type='ts', dir=dir, force=True)
877 self.interpreter.molmol.macro_write(data_type='time_fast', dir=dir, force=True)
878 self.interpreter.molmol.macro_write(data_type='time_slow', dir=dir, force=True)
879 self.interpreter.molmol.macro_write(data_type='rex', dir=dir, force=True)
880
881
882 dir = self.results_dir + 'final'
883 self.interpreter.structure.create_diff_tensor_pdb(file="tensor.pdb", dir=dir, force=True)
884
885
886
888 """Empty container for data storage."""
889