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) 2014 Troels E. Linnet                                         # 
  4  # Copyright (C) 2014 Edward d'Auvergne                                        # 
  5  #                                                                             # 
  6  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  7  #                                                                             # 
  8  # This program is free software: you can redistribute it and/or modify        # 
  9  # it under the terms of the GNU General Public License as published by        # 
 10  # the Free Software Foundation, either version 3 of the License, or           # 
 11  # (at your option) any later version.                                         # 
 12  #                                                                             # 
 13  # This program is distributed in the hope that it will be useful,             # 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 16  # GNU General Public License for more details.                                # 
 17  #                                                                             # 
 18  # You should have received a copy of the GNU General Public License           # 
 19  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """Functions for sorting and nesting the models in relaxation dispersion specific analysis.""" 
 25   
 26  # Python module imports. 
 27  from datetime import date 
 28  from functools import partial 
 29  from operator import attrgetter, ne 
 30   
 31  # relax module imports. 
 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  # Define class for describing the model. 
 39  # This class is defined to be able to make better sorting of the models. 
40 -class Model_class:
41 - def __init__(self, model=None):
42 """Class for storing model information. 43 44 @keyword model: Current model 45 @type model: str 46 """ 47 48 # Save the info to variables. 49 self.model = model 50 51 # model description. 52 self.desc = MODEL_DESC[self.model] 53 54 # model equation type: analytic, silico or numeric. 55 self.eq = MODEL_EQ[self.model] 56 57 # The model experiment type. 58 self.exp_type = MODEL_EXP_TYPE[self.model] 59 60 # model parameters. 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 # model number of parameters. 66 self.params_nr = len(self.params) 67 68 # The number of chemical sites. 69 self.sites = MODEL_SITES[self.model] 70 71 # year where model was developed or published. 72 self.year = MODEL_YEAR[self.model] 73 74 # Ordered lists of models to nest from. 75 nest_list = MODEL_NEST[self.model] 76 77 # Remove the model itself from the list. 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 # Define the order of how exp type ranks. 85 order_exp_type = [EXP_TYPE_R2EFF, EXP_TYPE_NOREX, EXP_TYPE_CPMG_SQ, EXP_TYPE_CPMG_MMQ, EXP_TYPE_R1RHO] 86 87 # Save the index of current model to order of equation type. 88 self.exp_type_i = order_exp_type.index(self.exp_type) 89 90 # Define the order of how equation type ranks. 91 order_eq = [EQ_NUMERIC, EQ_SILICO, EQ_ANALYTIC] 92 93 # Save the index of current model to order of equation type. 94 self.eq_i = order_eq.index(self.eq) 95 96 # Define the order of how equation type ranks, when sorting before auto analyses. 97 order_s = [EQ_SILICO, EQ_ANALYTIC, EQ_NUMERIC] 98 99 # Save the index of current model to order of equation type. 100 self.eq_s = order_s.index(self.eq) 101 102 # Save the difference in year from now, to implemented model. 103 self.year_diff = date.today().year - self.year
104 105 # Make a readable presentation of the class object. Here a tuple.
106 - def __repr__(self):
107 return repr((self.model, self.desc, self.exp_type, self.eq, self.sites, self.year, self.params, self.params_nr))
108 109 110 # Define function, to return model info.
111 -def models_info(models=None):
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 # Define list of return. 121 models_info = [] 122 123 # Loop over models. 124 for model in models: 125 # Append to the list, the class instance of model info. 126 models_info.append(Model_class(model=model)) 127 128 # Return the list of model info. 129 return models_info
130 131 132 # Define function, to determine which model to nest from.
133 -def nesting_model(self_models=None, model=None):
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 # Get the list index for the current model in all models. 146 model_index = self_models.index(model) 147 148 # Define the list of models which can be tested. This is the number of models which have already been tested. 149 completed_models = self_models[:model_index] 150 151 # Get the current models information. 152 model_info = models_info([model])[0] 153 154 # Get the info of the completed models. 155 completed_models_info = models_info(completed_models) 156 157 # Sort the models according to: exp_type, equation type, chemical sites, year for model, number of parameters. 158 completed_models_info = sorted(completed_models_info, key=attrgetter('exp_type_i', 'eq_i', 'sites', 'year_diff', 'params_nr')) 159 160 # If no nest model list is specified, return None. 161 if model_info.nest_list == None: 162 return model_info, None 163 164 else: 165 # Loop over ordered list of possible nested models. 166 for nest_model in model_info.nest_list: 167 # Then loop over list of completed models, and its associated information. 168 for completed_model_info in completed_models_info: 169 # If the nested model is in list of completed models, then return that model. 170 if nest_model == completed_model_info.model: 171 return model_info, completed_model_info 172 173 # If nothing is found, return None. 174 return model_info, None
175 176 177 # Define function, to determine which parameters to nest/copy over.
178 -def nesting_param(model_params=None, nested_model_params=None):
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 # Define dictionary. 190 par_dic = {} 191 192 # Loop over the parameters in the model parameters. 193 for param in model_params: 194 # The R20 parameters. 195 if param in PARAMS_R20: 196 # If both models have same parameter. 197 if param in nested_model_params: 198 par_dic[param] = param 199 200 # If copying from a simple model to a complex model. 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 # If copying from a complex model to a simple model. 208 elif param == 'r2' and 'r2a' in nested_model_params: 209 par_dic[param] = 'r2a' 210 211 # All other parameters. 212 elif param in nested_model_params: 213 par_dic[param] = param 214 215 else: 216 par_dic[param] = None 217 218 ## The LM63 3-site model parameters. 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 ## The 'MODEL_PARAMS_NS_R1RHO_3SITE' model parameters from 'MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR'. 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 ## The 'MODEL_PARAMS_NS_R1RHO_3SITE_LINEAR' model parameters from R1RHO 2SITE. 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 ## The 'MODEL_PARAMS_NS_R1RHO_3SITE' model parameters from R1RHO 2SITE. 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 ## The 'MODEL_PARAMS_NS_MMQ_3SITE' model parameters from 'MODEL_PARAMS_NS_MMQ_3SITE_LINEAR'. 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 ## The 'MODEL_PARAMS_NS_MMQ_3SITE_LINEAR' model parameters from 'MODEL_PARAMS_NS_MMQ_2'. 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 ## The 'MODEL_PARAMS_NS_MMQ_3SITE' model parameters from 'MODEL_PARAMS_NS_MMQ_2'. 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 # Return the dictionary of conversion. 336 return par_dic
337 338 339 # Define function, to sort models.
340 -def sort_models(models=None):
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 # Get the info of the models selected for analysis. 350 all_models_info = models_info(models) 351 352 # Sort the models according to: exp_type, equation type, chemical sites, year for model, number of parameters. 353 all_models_info_sorted = sorted(all_models_info, key=attrgetter('exp_type_i', 'eq_s', 'sites', 'year_diff', 'params_nr')) 354 355 # Define list of sorted models. 356 sorted_models = [] 357 358 # Loop over the models info, and extract model. 359 for model_info in all_models_info_sorted: 360 sorted_models.append(model_info.model) 361 362 # Return sorted list of models. 363 return sorted_models
364