Package specific_analyses :: Package relax_disp :: Module model
[hide private]
[frames] | no frames]

Source Code for Module specific_analyses.relax_disp.model

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2008,2013-2014,2019 Edward d'Auvergne                    # 
  4  # Copyright (C) 2006 Chris MacRaild                                           # 
  5  # Copyright (C) 2008-2009 Sebastien Morin                                     # 
  6  # Copyright (C) 2014 Troels E. Linnet                                         # 
  7  #                                                                             # 
  8  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  9  #                                                                             # 
 10  # This program is free software: you can redistribute it and/or modify        # 
 11  # it under the terms of the GNU General Public License as published by        # 
 12  # the Free Software Foundation, either version 3 of the License, or           # 
 13  # (at your option) any later version.                                         # 
 14  #                                                                             # 
 15  # This program is distributed in the hope that it will be useful,             # 
 16  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 17  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 18  # GNU General Public License for more details.                                # 
 19  #                                                                             # 
 20  # You should have received a copy of the GNU General Public License           # 
 21  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 22  #                                                                             # 
 23  ############################################################################### 
 24   
 25  # Module docstring. 
 26  """Functions for sorting and nesting the models in relaxation dispersion specific analysis.""" 
 27   
 28  # Python module imports. 
 29  from copy import deepcopy 
 30  from datetime import date 
 31  from functools import partial 
 32  from operator import attrgetter, ne 
 33   
 34  # relax module imports. 
 35  from lib.dispersion.variables import EQ_ANALYTIC, \ 
 36      EQ_NUMERIC, \ 
 37      EQ_SILICO, \ 
 38      EXP_TYPE_CPMG_MMQ, \ 
 39      EXP_TYPE_R1RHO, \ 
 40      EXP_TYPE_CPMG_SQ, \ 
 41      EXP_TYPE_NOREX, \ 
 42      EXP_TYPE_R2EFF, \ 
 43      MODEL_DESC, \ 
 44      MODEL_EQ, \ 
 45      MODEL_EXP_TYPE, \ 
 46      MODEL_NEST, \ 
 47      MODEL_PARAMS, \ 
 48      MODEL_PARAMS_LM63, \ 
 49      MODEL_PARAMS_LM63_3SITE, \ 
 50      MODEL_PARAMS_NS_MMQ_2SITE, \ 
 51      MODEL_PARAMS_NS_MMQ_3SITE, \ 
 52      MODEL_PARAMS_NS_MMQ_3SITE_LINEAR, \ 
 53      MODEL_PARAMS_NS_R1RHO_2SITE, \ 
 54      MODEL_PARAMS_NS_R1RHO_3SITE, \ 
 55      MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR, \ 
 56      MODEL_SITES, \ 
 57      MODEL_YEAR, \ 
 58      PARAMS_R1, \ 
 59      PARAMS_R20 
 60  from specific_analyses.relax_disp.data import is_r1_optimised 
 61   
 62   
 63  # Define class for describing the model. 
 64  # This class is defined to be able to make better sorting of the models. 
65 -class Model_class:
66 - def __init__(self, model=None):
67 """Class for storing model information. 68 69 @keyword model: Current model 70 @type model: str 71 """ 72 73 # Save the info to variables. 74 self.model = model 75 76 # model description. 77 self.desc = deepcopy(MODEL_DESC[self.model]) 78 79 # model equation type: analytic, silico or numeric. 80 self.eq = deepcopy(MODEL_EQ[self.model]) 81 82 # The model experiment type. 83 self.exp_type = deepcopy(MODEL_EXP_TYPE[self.model]) 84 85 # model parameters. 86 self.params = deepcopy(MODEL_PARAMS[self.model]) 87 if is_r1_optimised(model=model) and 'r1' not in self.params: 88 self.params.insert(0, 'r1') 89 90 # model number of parameters. 91 self.params_nr = len(self.params) 92 93 # The number of chemical sites. 94 self.sites = deepcopy(MODEL_SITES[self.model]) 95 96 # year where model was developed or published. 97 self.year = deepcopy(MODEL_YEAR[self.model]) 98 99 # Ordered lists of models to nest from. 100 nest_list = deepcopy(MODEL_NEST[self.model]) 101 102 # Remove the model itself from the list. 103 if nest_list == None: 104 self.nest_list = nest_list 105 else: 106 nest_list = list(filter(partial(ne, self.model), nest_list)) 107 self.nest_list = nest_list 108 109 # Define the order of how exp type ranks. 110 order_exp_type = [EXP_TYPE_R2EFF, EXP_TYPE_NOREX, EXP_TYPE_CPMG_SQ, EXP_TYPE_CPMG_MMQ, EXP_TYPE_R1RHO] 111 112 # Save the index of current model to order of equation type. 113 self.exp_type_i = order_exp_type.index(self.exp_type) 114 115 # Define the order of how equation type ranks. 116 order_eq = [EQ_NUMERIC, EQ_SILICO, EQ_ANALYTIC] 117 118 # Save the index of current model to order of equation type. 119 self.eq_i = order_eq.index(self.eq) 120 121 # Define the order of how equation type ranks, when sorting before auto analyses. 122 order_s = [EQ_SILICO, EQ_ANALYTIC, EQ_NUMERIC] 123 124 # Save the index of current model to order of equation type. 125 self.eq_s = order_s.index(self.eq) 126 127 # Save the difference in year from now, to implemented model. 128 self.year_diff = date.today().year - self.year
129 130 # Make a readable presentation of the class object. Here a tuple.
131 - def __repr__(self):
132 return repr((self.model, self.desc, self.exp_type, self.eq, self.sites, self.year, self.params, self.params_nr))
133 134 135 # Define function, to return model info.
136 -def models_info(models=None):
137 """Get model info for list of models. 138 139 @keyword model: The list of all models analysed. 140 @type model: list of str 141 @return: List of tuples, where each tuple contains model info. 142 @rtype: List of tuples with str. 143 """ 144 145 # Define list of return. 146 models_info = [] 147 148 # Loop over models. 149 for model in models: 150 # Append to the list, the class instance of model info. 151 models_info.append(Model_class(model=model)) 152 153 # Return the list of model info. 154 return models_info
155 156 157 # Define function, to determine which model to nest from.
158 -def nesting_model(self_models=None, model=None):
159 """Determine if the current model can use nested results from any of the previous analysed models. 160 161 @keyword self_models: The list of all models analysed. 162 @type self_models: list of str 163 @keyword model: The current model to analyse. 164 @type model: str 165 @return: The current model info, the possible nest model info. 166 @rtype: class, class 167 """ 168 169 170 # Get the list index for the current model in all models. 171 model_index = self_models.index(model) 172 173 # Define the list of models which can be tested. This is the number of models which have already been tested. 174 completed_models = self_models[:model_index] 175 176 # Get the current models information. 177 model_info = models_info([model])[0] 178 179 # Get the info of the completed models. 180 completed_models_info = models_info(completed_models) 181 182 # Sort the models according to: exp_type, equation type, chemical sites, year for model, number of parameters. 183 completed_models_info = sorted(completed_models_info, key=attrgetter('exp_type_i', 'eq_i', 'sites', 'year_diff', 'params_nr')) 184 185 # If no nest model list is specified, return None. 186 if model_info.nest_list == None: 187 return model_info, None 188 189 else: 190 # Loop over ordered list of possible nested models. 191 for nest_model in model_info.nest_list: 192 # Then loop over list of completed models, and its associated information. 193 for completed_model_info in completed_models_info: 194 # If the nested model is in list of completed models, then return that model. 195 if nest_model == completed_model_info.model: 196 return model_info, completed_model_info 197 198 # If nothing is found, return None. 199 return model_info, None
200 201 202 # Define function, to determine which parameters to nest/copy over.
203 -def nesting_param(model_params=None, nested_model_params=None):
204 """Determine the conversion from the nested models params, to the current model params. 205 206 @keyword model_params: The list of the current model parameters. 207 @type model_params: list of str 208 @keyword nested_model_params: The list of the nested model parameters. 209 @type nested_model_params: list of str 210 @return: A dictionary of parameter conversion for the current model params. 211 @rtype: dictionary 212 """ 213 214 # Define dictionary. 215 par_dic = {} 216 217 # Loop over the parameters in the model parameters. 218 for param in model_params: 219 # The R20 parameters. 220 if param in PARAMS_R20: 221 # If both models have same parameter. 222 if param in nested_model_params: 223 par_dic[param] = param 224 225 # If copying from a simple model to a complex model. 226 elif param == 'r2a' and 'r2' in nested_model_params: 227 par_dic[param] = 'r2' 228 229 elif param == 'r2b' and 'r2' in nested_model_params: 230 par_dic[param] = 'r2' 231 232 # If copying from a complex model to a simple model. 233 elif param == 'r2' and 'r2a' in nested_model_params: 234 par_dic[param] = 'r2a' 235 236 # The R1 parameter. 237 elif param in PARAMS_R1: 238 par_dic[param] = param 239 240 # All other parameters. 241 elif param in nested_model_params: 242 par_dic[param] = param 243 244 else: 245 par_dic[param] = None 246 247 ## The LM63 3-site model parameters. 248 if set(model_params) == set(MODEL_PARAMS_LM63_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_LM63): 249 for param in model_params: 250 if param == 'phi_ex_B': 251 par_dic[param] = 'phi_ex' 252 253 elif param == 'phi_ex_C': 254 par_dic[param] = 'phi_ex' 255 256 elif param == 'kB': 257 par_dic[param] = 'kex' 258 259 elif param == 'kC': 260 par_dic[param] = 'kex' 261 262 ## The 'MODEL_PARAMS_NS_R1RHO_3SITE' model parameters from 'MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR'. 263 elif set(model_params) == set(MODEL_PARAMS_NS_R1RHO_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR): 264 for param in model_params: 265 if param == 'kex_AC': 266 par_dic[param] = '0.0' 267 268 ## The 'MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR' model parameters from R1RHO 2SITE. 269 elif set(model_params) == set(MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR) and set(nested_model_params) == set(MODEL_PARAMS_NS_R1RHO_2SITE): 270 for param in model_params: 271 if param == 'dw_AB': 272 par_dic[param] = 'dw' 273 274 elif param == 'kex_AB': 275 par_dic[param] = 'kex' 276 277 elif param == 'dw_BC': 278 par_dic[param] = 'dw' 279 280 elif param == 'kex_BC': 281 par_dic[param] = 'kex' 282 283 elif param == 'pB': 284 par_dic[param] = '1 - pA' 285 286 ## The 'MODEL_PARAMS_NS_R1RHO_3SITE' model parameters from R1RHO 2SITE. 287 elif set(model_params) == set(MODEL_PARAMS_NS_R1RHO_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_NS_R1RHO_2SITE): 288 for param in model_params: 289 if param == 'dw_AB': 290 par_dic[param] = 'dw' 291 292 elif param == 'kex_AB': 293 par_dic[param] = 'kex' 294 295 elif param == 'dw_BC': 296 par_dic[param] = 'dw' 297 298 elif param == 'kex_BC': 299 par_dic[param] = 'kex' 300 301 elif param == 'kex_AC': 302 par_dic[param] = 'kex' 303 304 elif param == 'pB': 305 par_dic[param] = '1 - pA' 306 307 ## The 'MODEL_PARAMS_NS_MMQ_3SITE' model parameters from 'MODEL_PARAMS_NS_MMQ_3SITE_LINEAR'. 308 elif set(model_params) == set(MODEL_PARAMS_NS_MMQ_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_NS_MMQ_3SITE_LINEAR): 309 for param in model_params: 310 if param == 'kex_AC': 311 par_dic[param] = '0.0' 312 313 ## The 'MODEL_PARAMS_NS_MMQ_3SITE_LINEAR' model parameters from 'MODEL_PARAMS_NS_MMQ_2'. 314 elif set(model_params) == set(MODEL_PARAMS_NS_MMQ_3SITE_LINEAR) and set(nested_model_params) == set(MODEL_PARAMS_NS_MMQ_2SITE): 315 for param in model_params: 316 if param == 'dw_AB': 317 par_dic[param] = 'dw' 318 319 elif param == 'dwH_AB': 320 par_dic[param] = 'dwH' 321 322 elif param == 'kex_AB': 323 par_dic[param] = 'kex' 324 325 elif param == 'dw_BC': 326 par_dic[param] = 'dw' 327 328 elif param == 'dwH_BC': 329 par_dic[param] = 'dwH' 330 331 elif param == 'kex_BC': 332 par_dic[param] = 'kex' 333 334 elif param == 'pB': 335 par_dic[param] = '1 - pA' 336 337 ## The 'MODEL_PARAMS_NS_MMQ_3SITE' model parameters from 'MODEL_PARAMS_NS_MMQ_2'. 338 elif set(model_params) == set(MODEL_PARAMS_NS_MMQ_3SITE) and set(nested_model_params) == set(MODEL_PARAMS_NS_MMQ_2SITE): 339 for param in model_params: 340 if param == 'dw_AB': 341 par_dic[param] = 'dw' 342 343 elif param == 'dwH_AB': 344 par_dic[param] = 'dwH' 345 346 elif param == 'kex_AB': 347 par_dic[param] = 'kex' 348 349 elif param == 'dw_BC': 350 par_dic[param] = 'dw' 351 352 elif param == 'dwH_BC': 353 par_dic[param] = 'dwH' 354 355 elif param == 'kex_BC': 356 par_dic[param] = 'kex' 357 358 elif param == 'kex_AC': 359 par_dic[param] = 'kex' 360 361 elif param == 'pB': 362 par_dic[param] = '1 - pA' 363 364 # Return the dictionary of conversion. 365 return par_dic
366 367 368 # Define function, to sort models.
369 -def sort_models(models=None):
370 """Determine how to order the models for analyses. 371 372 @keyword models: The list of all models to be analysed. 373 @type models: list of str 374 @return: The ordered list how models should be analysed. 375 @rtype: list of str 376 """ 377 378 # Get the info of the models selected for analysis. 379 all_models_info = models_info(models) 380 381 # Sort the models according to: exp_type, equation type, chemical sites, year for model, number of parameters. 382 all_models_info_sorted = sorted(all_models_info, key=attrgetter('exp_type_i', 'eq_s', 'sites', 'year_diff', 'params_nr')) 383 384 # Define list of sorted models. 385 sorted_models = [] 386 387 # Loop over the models info, and extract model. 388 for model_info in all_models_info_sorted: 389 sorted_models.append(model_info.model) 390 391 # Return sorted list of models. 392 return sorted_models
393