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