1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """Functions for sorting and nesting the models in relaxation dispersion specific analysis."""
25
26
27 from datetime import date
28 from functools import partial
29 from operator import attrgetter, ne
30
31
32 from lib.dispersion.variables import EQ_ANALYTIC, EQ_NUMERIC, EQ_SILICO, EXP_TYPE_CPMG_MMQ, EXP_TYPE_R1RHO, EXP_TYPE_CPMG_SQ, EXP_TYPE_NOREX, EXP_TYPE_R2EFF, MODEL_DESC, MODEL_EQ, MODEL_EXP_TYPE, MODEL_LIST_ANALYTIC_CPMG, MODEL_LIST_NUMERIC_CPMG, MODEL_LIST_R1RHO_OFF_RES, MODEL_CR72, MODEL_DPL94, MODEL_IT99, MODEL_LM63, MODEL_LM63_3SITE, MODEL_MMQ_CR72, MODEL_NEST, MODEL_NOREX, MODEL_NS_MMQ_2SITE, MODEL_NS_MMQ_3SITE, MODEL_NS_MMQ_3SITE_LINEAR, MODEL_NS_R1RHO_2SITE, MODEL_NS_R1RHO_3SITE, MODEL_NS_R1RHO_3SITE_LINEAR, MODEL_PARAMS, MODEL_PARAMS_LM63, MODEL_PARAMS_LM63_3SITE, MODEL_PARAMS_NS_MMQ_2SITE, MODEL_PARAMS_NS_MMQ_3SITE, MODEL_PARAMS_NS_MMQ_3SITE_LINEAR, MODEL_PARAMS_NS_R1RHO_2SITE, MODEL_PARAMS_NS_R1RHO_3SITE, MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR, MODEL_R2EFF, MODEL_SITES, MODEL_YEAR, PARAMS_R20
33 from lib.errors import RelaxError
34 from specific_analyses.relax_disp.checks import check_missing_r1
35 from specific_analyses.relax_disp.data import is_r1_optimised
36
37
38
39
42 """Class for storing model information.
43
44 @keyword model: Current model
45 @type model: str
46 """
47
48
49 self.model = model
50
51
52 self.desc = MODEL_DESC[self.model]
53
54
55 self.eq = MODEL_EQ[self.model]
56
57
58 self.exp_type = MODEL_EXP_TYPE[self.model]
59
60
61 self.params = MODEL_PARAMS[self.model]
62 if is_r1_optimised(model=model) and 'r1' not in self.params:
63 self.params.insert(0, 'r1')
64
65
66 self.params_nr = len(self.params)
67
68
69 self.sites = MODEL_SITES[self.model]
70
71
72 self.year = MODEL_YEAR[self.model]
73
74
75 nest_list = MODEL_NEST[self.model]
76
77
78 if nest_list == None:
79 self.nest_list = nest_list
80 else:
81 nest_list = list(filter(partial(ne, self.model), nest_list))
82 self.nest_list = nest_list
83
84
85 order_exp_type = [EXP_TYPE_R2EFF, EXP_TYPE_NOREX, EXP_TYPE_CPMG_SQ, EXP_TYPE_CPMG_MMQ, EXP_TYPE_R1RHO]
86
87
88 self.exp_type_i = order_exp_type.index(self.exp_type)
89
90
91 order_eq = [EQ_NUMERIC, EQ_SILICO, EQ_ANALYTIC]
92
93
94 self.eq_i = order_eq.index(self.eq)
95
96
97 order_s = [EQ_SILICO, EQ_ANALYTIC, EQ_NUMERIC]
98
99
100 self.eq_s = order_s.index(self.eq)
101
102
103 self.year_diff = date.today().year - self.year
104
105
107 return repr((self.model, self.desc, self.exp_type, self.eq, self.sites, self.year, self.params, self.params_nr))
108
109
110
112 """Get model info for list of models.
113
114 @keyword model: The list of all models analysed.
115 @type model: list of str
116 @return: List of tuples, where each tuple contains model info.
117 @rtype: List of tuples with str.
118 """
119
120
121 models_info = []
122
123
124 for model in models:
125
126 models_info.append(Model_class(model=model))
127
128
129 return models_info
130
131
132
134 """Determine if the current model can use nested results from any of the previous analysed models.
135
136 @keyword self_models: The list of all models analysed.
137 @type self_models: list of str
138 @keyword model: The current model to analyse.
139 @type model: str
140 @return: The current model info, the possible nest model info.
141 @rtype: class, class
142 """
143
144
145
146 model_index = self_models.index(model)
147
148
149 completed_models = self_models[:model_index]
150
151
152 model_info = models_info([model])[0]
153
154
155 completed_models_info = models_info(completed_models)
156
157
158 completed_models_info = sorted(completed_models_info, key=attrgetter('exp_type_i', 'eq_i', 'sites', 'year_diff', 'params_nr'))
159
160
161 if model_info.nest_list == None:
162 return model_info, None
163
164 else:
165
166 for nest_model in model_info.nest_list:
167
168 for completed_model_info in completed_models_info:
169
170 if nest_model == completed_model_info.model:
171 return model_info, completed_model_info
172
173
174 return model_info, None
175
176
177
179 """Determine the conversion from the nested models params, to the current model params.
180
181 @keyword model_params: The list of the current model parameters.
182 @type model_params: list of str
183 @keyword nested_model_params: The list of the nested model parameters.
184 @type nested_model_params: list of str
185 @return: A dictionary of parameter conversion for the current model params.
186 @rtype: dictionary
187 """
188
189
190 par_dic = {}
191
192
193 for param in model_params:
194
195 if param in PARAMS_R20:
196
197 if param in nested_model_params:
198 par_dic[param] = param
199
200
201 elif param == 'r2a' and 'r2' in nested_model_params:
202 par_dic[param] = 'r2'
203
204 elif param == 'r2b' and 'r2' in nested_model_params:
205 par_dic[param] = 'r2'
206
207
208 elif param == 'r2' and 'r2a' in nested_model_params:
209 par_dic[param] = 'r2a'
210
211
212 elif param in nested_model_params:
213 par_dic[param] = param
214
215 else:
216 par_dic[param] = None
217
218
219 if set(model_params) == set(MODEL_PARAMS_LM63_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_LM63):
220 for param in model_params:
221 if param == 'phi_ex_B':
222 par_dic[param] = 'phi_ex'
223
224 elif param == 'phi_ex_C':
225 par_dic[param] = 'phi_ex'
226
227 elif param == 'kB':
228 par_dic[param] = 'kex'
229
230 elif param == 'kC':
231 par_dic[param] = 'kex'
232
233
234 elif set(model_params) == set(MODEL_PARAMS_NS_R1RHO_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR):
235 for param in model_params:
236 if param == 'kex_AC':
237 par_dic[param] = '0.0'
238
239
240 elif set(model_params) == set(MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR) and set(nested_model_params) == set(MODEL_PARAMS_NS_R1RHO_2SITE):
241 for param in model_params:
242 if param == 'dw_AB':
243 par_dic[param] = 'dw'
244
245 elif param == 'kex_AB':
246 par_dic[param] = 'kex'
247
248 elif param == 'dw_BC':
249 par_dic[param] = 'dw'
250
251 elif param == 'kex_BC':
252 par_dic[param] = 'kex'
253
254 elif param == 'pB':
255 par_dic[param] = '1 - pA'
256
257
258 elif set(model_params) == set(MODEL_PARAMS_NS_R1RHO_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_NS_R1RHO_2SITE):
259 for param in model_params:
260 if param == 'dw_AB':
261 par_dic[param] = 'dw'
262
263 elif param == 'kex_AB':
264 par_dic[param] = 'kex'
265
266 elif param == 'dw_BC':
267 par_dic[param] = 'dw'
268
269 elif param == 'kex_BC':
270 par_dic[param] = 'kex'
271
272 elif param == 'kex_AC':
273 par_dic[param] = 'kex'
274
275 elif param == 'pB':
276 par_dic[param] = '1 - pA'
277
278
279 elif set(model_params) == set(MODEL_PARAMS_NS_MMQ_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_NS_MMQ_3SITE_LINEAR):
280 for param in model_params:
281 if param == 'kex_AC':
282 par_dic[param] = '0.0'
283
284
285 elif set(model_params) == set(MODEL_PARAMS_NS_MMQ_3SITE_LINEAR) and set(nested_model_params) == set(MODEL_PARAMS_NS_MMQ_2SITE):
286 for param in model_params:
287 if param == 'dw_AB':
288 par_dic[param] = 'dw'
289
290 elif param == 'dwH_AB':
291 par_dic[param] = 'dwH'
292
293 elif param == 'kex_AB':
294 par_dic[param] = 'kex'
295
296 elif param == 'dw_BC':
297 par_dic[param] = 'dw'
298
299 elif param == 'dwH_BC':
300 par_dic[param] = 'dwH'
301
302 elif param == 'kex_BC':
303 par_dic[param] = 'kex'
304
305 elif param == 'pB':
306 par_dic[param] = '1 - pA'
307
308
309 elif set(model_params) == set(MODEL_PARAMS_NS_MMQ_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_NS_MMQ_2SITE):
310 for param in model_params:
311 if param == 'dw_AB':
312 par_dic[param] = 'dw'
313
314 elif param == 'dwH_AB':
315 par_dic[param] = 'dwH'
316
317 elif param == 'kex_AB':
318 par_dic[param] = 'kex'
319
320 elif param == 'dw_BC':
321 par_dic[param] = 'dw'
322
323 elif param == 'dwH_BC':
324 par_dic[param] = 'dwH'
325
326 elif param == 'kex_BC':
327 par_dic[param] = 'kex'
328
329 elif param == 'kex_AC':
330 par_dic[param] = 'kex'
331
332 elif param == 'pB':
333 par_dic[param] = '1 - pA'
334
335
336 return par_dic
337
338
339
341 """Determine how to order the models for analyses.
342
343 @keyword models: The list of all models to be analysed.
344 @type models: list of str
345 @return: The ordered list how models should be analysed.
346 @rtype: list of str
347 """
348
349
350 all_models_info = models_info(models)
351
352
353 all_models_info_sorted = sorted(all_models_info, key=attrgetter('exp_type_i', 'eq_s', 'sites', 'year_diff', 'params_nr'))
354
355
356 sorted_models = []
357
358
359 for model_info in all_models_info_sorted:
360 sorted_models.append(model_info.model)
361
362
363 return sorted_models
364