1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """A module of special objects used within the analysis specific API."""
24
25
26 from re import search
27 from types import FunctionType, MethodType
28
29
30 from relax_errors import RelaxError
31
32
34 """A special object for handling global and spin parameters."""
35
37 """Set up the class.
38
39 @keyword spin_data: A flag which if True indicates that the specific analysis operates with spins.
40 @type spin_data: bool
41 """
42
43
44 self.spin_data = spin_data
45
46
47 self._names = []
48 self._scope = {}
49 self._string = {}
50 self._defaults = {}
51 self._units = {}
52 self._desc = {}
53 self._py_types = {}
54 self._conv_factor = {}
55 self._grace_string = {}
56 self._set = {}
57 self._err = {}
58 self._sim = {}
59
60
61 if self.spin_data:
62 self.add('select', scope='spin', desc='The spin selection flag', py_type=bool, sim=True)
63 self.add('fixed', scope='spin', desc='The fixed flag', py_type=bool)
64
65
66 - def add(self, name, scope=None, string=None, default=None, units=None, desc=None, py_type=None, set='generic', conv_factor=None, grace_string=None, err=False, sim=False):
67 """Add a parameter to the list.
68
69 @param name: The name of the parameter. This will be used as the variable name.
70 @type name: str
71 @keyword scope: The parameter scope. This can be set to 'global' for parameters located within the global scope of the current data pipe. Or set to 'spin' for spin specific parameters. Alternatively the value 'both' indicates that there are both global and specific versions of this parameter.
72 @type scope: str
73 @keyword string: The string representation of the parameter.
74 @type string: None or str
75 @keyword default: The default value of the parameter.
76 @type default: anything
77 @keyword units: A string representing the parameters units.
78 @type units: None or str
79 @keyword desc: The text description of the parameter.
80 @type desc: None or str
81 @keyword py_type: The Python type that this parameter should be.
82 @type py_type: Python type object
83 @keyword set: The set of object names. This can be set to 'all' for all names, to 'generic' for generic object names, 'params' for analysis specific parameter names, or to 'min' for minimisation specific object names.
84 @type set: str
85 @keyword conv_factor: The factor of conversion between different parameter units.
86 @type conv_factor: None, float or func
87 @keyword grace_string: The string used for the axes in Grace plots of the data.
88 @type grace_string: None or str
89 @keyword err: A flag which if True indicates that the parameter name + '_err' error data structure can exist.
90 @type err: bool
91 @keyword sim: A flag which if True indicates that the parameter name + '_sim' Monte Carlo simulation data structure can exist.
92 @type sim: bool
93 """
94
95
96 if scope == None:
97 raise RelaxError("The parameter scope must be set.")
98 if py_type == None:
99 raise RelaxError("The parameter type must be set.")
100 allowed_sets = ['all', 'generic', 'params', 'min']
101 if set not in allowed_sets:
102 raise RelaxError("The parameter set '%s' must be one of %s." % (set, allowed_sets))
103
104
105 self._names.append(name)
106 self._scope[name] = scope
107 self._defaults[name] = default
108 self._units[name] = units
109 self._desc[name] = desc
110 self._py_types[name] = py_type
111 self._set[name] = set
112 self._conv_factor[name] = conv_factor
113 self._err[name] = err
114 self._sim[name] = sim
115
116
117 if string:
118 self._string[name] = string
119 else:
120 self._string[name] = name
121
122
123 if grace_string:
124 self._grace_string[name] = grace_string
125 else:
126 self._grace_string[name] = name
127
128
129 - def add_min_data(self, min_stats_global=False, min_stats_spin=False):
130 """Add minimisation specific objects.
131
132 @keyword min_stats_global: A flag which if True will include the parameters 'chi2', 'iter', 'f_count', 'g_count', 'h_count', 'warning' in the list of global parameters.
133 @type min_stats_global: bool
134 @keyword min_stats_spin: A flag which if True will include the parameters 'chi2', 'iter', 'f_count', 'g_count', 'h_count', 'warning' in the list of spin parameters.
135 @type min_stats_spin: bool
136 """
137
138
139 self.min_stats_global = min_stats_global
140 self.min_stats_spin = min_stats_spin
141
142
143 if self.min_stats_global or self.min_stats_spin:
144
145 if self.min_stats_global and self.min_stats_spin:
146 scope = 'both'
147 elif self.min_stats_global:
148 scope = 'global'
149 else:
150 scope = 'spin'
151
152
153 self.add('chi2', scope=scope, desc='Chi-squared value', py_type=float, set='min', err=False, sim=True)
154 self.add('iter', scope=scope, desc='Optimisation iterations', py_type=int, set='min', err=False, sim=True)
155 self.add('f_count', scope=scope, desc='Number of function calls', py_type=int, set='min', err=False, sim=True)
156 self.add('g_count', scope=scope, desc='Number of gradient calls', py_type=int, set='min', err=False, sim=True)
157 self.add('h_count', scope=scope, desc='Number of Hessian calls', py_type=int, set='min', err=False, sim=True)
158 self.add('warning', scope=scope, desc='Optimisation warning', py_type=str, set='min', err=False, sim=True)
159
160
162 """An iterator method for looping over all the base parameters.
163
164 @keyword set: The set of object names to return. This can be set to 'all' for all names, to 'generic' for generic object names, 'params' for analysis specific parameter names, or to 'min' for minimisation specific object names.
165 @type set: str
166 @keyword scope: The scope of the parameter to return. If not set, then all will be returned. If set to 'global' or 'spin', then only the parameters within that scope will be returned.
167 @type scope: str or None
168 @returns: The parameter names.
169 @rtype: str
170 """
171
172
173 for name in self._names:
174
175 if set == 'generic' and self._set[name] != 'generic':
176 continue
177 if set == 'params' and self._set[name] != 'params':
178 continue
179 if set == 'min' and self._set[name] != 'min':
180 continue
181
182
183 if scope == 'global' and self._scope[name] == 'spin':
184 continue
185 if scope == 'spin' and self._scope[name] == 'global':
186 continue
187
188
189 yield name
190
191
193 """Check if the parameter exists.
194
195 @param name: The name of the parameter to search for.
196 @type name: str
197 @raises RelaxError: If the parameter does not exist.
198 """
199
200
201 if name not in self._names:
202 raise RelaxError("The parameter '%s' does not exist." % name)
203
204
206 """Determine if the given name is within the parameter list.
207
208 @param name: The name of the parameter to search for.
209 @type name: str
210 @return: True if the parameter is within the list, False otherwise.
211 @rtype: bool
212 """
213
214
215 if name in self._names:
216 return True
217
218
219 return False
220
221
223 """Return the conversion factor.
224
225 @param name: The name of the parameter.
226 @type name: str
227 @return: The conversion factor.
228 @rtype: float
229 """
230
231
232 self.check_param(name)
233
234
235 if self._conv_factor[name] == None:
236 return 1.0
237
238
239 if isinstance(self._conv_factor[name], FunctionType) or isinstance(self._conv_factor[name], MethodType):
240 return self._conv_factor[name]()
241
242
243 return self._conv_factor[name]
244
245
247 """Return the default value of the parameter.
248
249 @param name: The name of the parameter.
250 @type name: str
251 @return: The default value.
252 @rtype: None or str
253 """
254
255
256 self.check_param(name)
257
258
259 return self._defaults[name]
260
261
263 """Return the description of the parameter.
264
265 @param name: The name of the parameter.
266 @type name: str
267 @return: The description.
268 @rtype: None or str
269 """
270
271
272 if name not in ['ri_data_err'] and (search('_err$', name) or search('_sim$', name)):
273 return None
274
275
276 self.check_param(name)
277
278
279 return self._desc[name]
280
281
283 """Return the error flag for the parameter.
284
285 @param name: The name of the parameter.
286 @type name: str
287 @return: The error flag for the parameter.
288 @rtype: bool
289 """
290
291
292 self.check_param(name)
293
294
295 return self._err[name]
296
297
299 """Return the Grace string for the parameter.
300
301 @param name: The name of the parameter.
302 @type name: str
303 @return: The Grace string.
304 @rtype: str
305 """
306
307
308 self.check_param(name)
309
310
311 return self._grace_string[name]
312
313
315 """Return the parameter set that the parameter belongs to.
316
317 @param name: The name of the parameter.
318 @type name: str
319 @return: The parameter set.
320 @rtype: str
321 """
322
323
324 self.check_param(name)
325
326
327 return self._set[name]
328
329
331 """Return the Monte Carlo simulation flag for the parameter.
332
333 @param name: The name of the parameter.
334 @type name: str
335 @return: The Monte Carlo simulation flag for the parameter.
336 @rtype: bool
337 """
338
339
340 self.check_param(name)
341
342
343 return self._sim[name]
344
345
347 """Return the Python type for the parameter.
348
349 @param name: The name of the parameter.
350 @type name: str
351 @return: The Python type.
352 @rtype: Python type object
353 """
354
355
356 self.check_param(name)
357
358
359 return self._py_types[name]
360
361
363 """Return the units string for the parameter.
364
365 @param name: The name of the parameter.
366 @type name: str
367 @return: The units string.
368 @rtype: str
369 """
370
371
372 self.check_param(name)
373
374
375 if isinstance(self._conv_factor[name], FunctionType) or isinstance(self._conv_factor[name], MethodType):
376 return self._units[name]()
377
378
379 return self._units[name]
380
381
382 - def loop(self, set=None, scope=None, error_names=False, sim_names=False):
383 """An iterator method for looping over all the parameters.
384
385 @keyword set: The set of object names to return. This can be set to 'all' for all names, to 'generic' for generic object names, 'params' for analysis specific parameter names, or to 'min' for minimisation specific object names.
386 @type set: str
387 @keyword scope: The scope of the parameter to return. If not set, then all will be returned. If set to 'global' or 'spin', then only the parameters within that scope will be returned.
388 @type scope: str or None
389 @keyword error_names: A flag which if True will add the error object names as well.
390 @type error_names: bool
391 @keyword sim_names: A flag which if True will add the Monte Carlo simulation object names as well.
392 @type sim_names: bool
393 @returns: The parameter names.
394 @rtype: str
395 """
396
397
398 for name in self.base_loop(set=set, scope=scope):
399 yield name
400
401
402 if error_names:
403 for name in self.base_loop(set=set):
404 if self.get_err(name):
405 yield name + '_err'
406
407
408 if sim_names:
409 for name in self.base_loop(set=set):
410 if self.get_sim(name):
411 yield name + '_sim'
412