1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 from Queue import Queue
25 from re import search
26
27
28 from thread_classes import RelaxParentThread, RelaxThread
29
30
33 """Class containing the calc, grid_search, minimise, and set functions."""
34
35 self.relax = relax
36
37
38 - def calc(self, run=None, print_flag=1):
67
68
69 - def grid_search(self, run=None, lower=None, upper=None, inc=None, constraints=1, print_flag=1):
70 """The grid search function."""
71
72
73 if not run in self.relax.data.run_names:
74 raise RelaxNoRunError, run
75
76
77 function_type = self.relax.data.run_types[self.relax.data.run_names.index(run)]
78
79
80 grid_search = self.relax.specific_setup.setup('grid_search', function_type)
81 overfit_deselect = self.relax.specific_setup.setup('overfit_deselect', function_type)
82
83
84 overfit_deselect(run)
85
86
87 if hasattr(self.relax.data, 'sim_state') and self.relax.data.sim_state.has_key(run) and self.relax.data.sim_state[run] == 1:
88
89 for i in xrange(self.relax.data.sim_number[run]):
90 if print_flag:
91 print "Simulation " + `i+1`
92 grid_search(run=run, lower=lower, upper=upper, inc=inc, constraints=constraints, print_flag=print_flag-1, sim_index=i)
93
94
95 else:
96 grid_search(run=run, lower=lower, upper=upper, inc=inc, constraints=constraints, print_flag=print_flag)
97
98
99 - def minimise(self, run=None, min_algor=None, min_options=None, func_tol=None, grad_tol=None, max_iterations=None, constraints=1, scaling=1, print_flag=1, sim_index=None):
100 """Minimisation function."""
101
102
103 if not run in self.relax.data.run_names:
104 raise RelaxNoRunError, run
105
106
107 function_type = self.relax.data.run_types[self.relax.data.run_names.index(run)]
108
109
110 minimise = self.relax.specific_setup.setup('minimise', function_type)
111 overfit_deselect = self.relax.specific_setup.setup('overfit_deselect', function_type)
112
113
114 overfit_deselect(run)
115
116
117 if sim_index != None:
118 minimise(run=run, min_algor=min_algor, min_options=min_options, func_tol=func_tol, grad_tol=grad_tol, max_iterations=max_iterations, constraints=constraints, scaling=scaling, print_flag=print_flag, sim_index=sim_index)
119
120
121 elif hasattr(self.relax.data, 'sim_state') and self.relax.data.sim_state.has_key(run) and self.relax.data.sim_state[run] == 1:
122
123 if self.relax.thread_data.status:
124
125 print "Threaded minimisation of Monte Carlo simulations.\n"
126
127
128 RelaxMinParentThread(self.relax, run, min_algor, min_options, func_tol, grad_tol, max_iterations, constraints, scaling, print_flag)
129
130
131 else:
132 for i in xrange(self.relax.data.sim_number[run]):
133 if print_flag:
134 print "Simulation " + `i+1`
135 minimise(run=run, min_algor=min_algor, min_options=min_options, func_tol=func_tol, grad_tol=grad_tol, max_iterations=max_iterations, constraints=constraints, scaling=scaling, print_flag=print_flag-1, sim_index=i)
136
137
138 else:
139 minimise(run=run, min_algor=min_algor, min_options=min_options, func_tol=func_tol, grad_tol=grad_tol, max_iterations=max_iterations, constraints=constraints, scaling=scaling, print_flag=print_flag)
140
141
143 """Function for resetting the minimisation statistics."""
144
145
146 self.run = run
147
148
149 if index == None:
150
151 if hasattr(self.relax.data, 'chi2') and self.relax.data.chi2.has_key(self.run):
152 self.relax.data.chi2[self.run] = None
153
154
155 if hasattr(self.relax.data, 'iter') and self.relax.data.iter.has_key(self.run):
156 self.relax.data.iter[self.run] = None
157
158
159 if hasattr(self.relax.data, 'f_count') and self.relax.data.f_count.has_key(self.run):
160 self.relax.data.f_count[self.run] = None
161
162
163 if hasattr(self.relax.data, 'g_count') and self.relax.data.g_count.has_key(self.run):
164 self.relax.data.g_count[self.run] = None
165
166
167 if hasattr(self.relax.data, 'h_count') and self.relax.data.h_count.has_key(self.run):
168 self.relax.data.h_count[self.run] = None
169
170
171 if hasattr(self.relax.data, 'warning') and self.relax.data.warning.has_key(self.run):
172 self.relax.data.warning[self.run] = None
173
174
175 else:
176
177 if hasattr(self.relax.data.res[self.run][index], 'chi2'):
178 self.relax.data.res[self.run][index].chi2 = None
179
180
181 if hasattr(self.relax.data.res[self.run][index], 'iter'):
182 self.relax.data.res[self.run][index].iter = None
183
184
185 if hasattr(self.relax.data.res[self.run][index], 'f_count'):
186 self.relax.data.res[self.run][index].f_count = None
187
188
189 if hasattr(self.relax.data.res[self.run][index], 'g_count'):
190 self.relax.data.res[self.run][index].g_count = None
191
192
193 if hasattr(self.relax.data.res[self.run][index], 'h_count'):
194 self.relax.data.res[self.run][index].h_count = None
195
196
197 if hasattr(self.relax.data.res[self.run][index], 'warning'):
198 self.relax.data.res[self.run][index].warning = None
199
200
202 """Dummy function for returning 1.0."""
203
204 return 1.0
205
206
208 """
209 Minimisation statistic data type string matching patterns
210 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
211
212 ____________________________________________________________________________________________
213 | | | |
214 | Data type | Object name | Patterns |
215 |________________________|______________|__________________________________________________|
216 | | | |
217 | Chi-squared statistic | 'chi2' | '^[Cc]hi2$' or '^[Cc]hi[-_ ][Ss]quare' |
218 | | | |
219 | Iteration count | 'iter' | '^[Ii]ter' |
220 | | | |
221 | Function call count | 'f_count' | '^[Ff].*[ -_][Cc]ount' |
222 | | | |
223 | Gradient call count | 'g_count' | '^[Gg].*[ -_][Cc]ount' |
224 | | | |
225 | Hessian call count | 'h_count' | '^[Hh].*[ -_][Cc]ount' |
226 |________________________|______________|__________________________________________________|
227
228 """
229
230
231 if search('^[Cc]hi2$', name) or search('^[Cc]hi[-_ ][Ss]quare', name):
232 return 'chi2'
233
234
235 if search('^[Ii]ter', name):
236 return 'iter'
237
238
239 if search('^[Ff].*[ -_][Cc]ount', name):
240 return 'f_count'
241
242
243 if search('^[Gg].*[ -_][Cc]ount', name):
244 return 'g_count'
245
246
247 if search('^[Hh].*[ -_][Cc]ount', name):
248 return 'h_count'
249
250
252 """Function for returning the Grace string representing the data type for axis labelling."""
253
254
255 object_name = self.return_data_name(stat_type)
256
257
258 if object_name == 'chi2':
259 grace_string = '\\xc\\S2'
260
261
262 elif object_name == 'iter':
263 grace_string = 'Iteration count'
264
265
266 elif object_name == 'f_count':
267 grace_string = 'Function call count'
268
269
270 elif object_name == 'g_count':
271 grace_string = 'Gradient call count'
272
273
274 elif object_name == 'h_count':
275 grace_string = 'Hessian call count'
276
277
278 return grace_string
279
280
282 """Dummy function which returns None as the stats have no units."""
283
284 return None
285
286
287 - def return_value(self, run, index=None, stat_type=None, sim=None):
288 """Function for returning the minimisation statistic corresponding to 'stat_type'."""
289
290
291 self.run = run
292
293
294 object_name = self.return_data_name(stat_type)
295
296
297 if not object_name:
298 raise RelaxError, "The statistic type " + `stat_type` + " does not exist."
299
300
301 object_sim = object_name + '_sim'
302
303
304 if index == None:
305
306 if sim == None:
307 if hasattr(self.relax.data, object_name) and getattr(self.relax.data.res[self.run][index], object_name).has_key(self.run):
308 stat = getattr(self.relax.data, object_name)[self.run]
309 else:
310 stat = None
311
312
313 else:
314 if hasattr(self.relax.data, object_sim) and getattr(self.relax.data.res[self.run][index], object_sim).has_key(self.run):
315 stat = getattr(self.relax.data, object_sim)[self.run][sim]
316 else:
317 stat = None
318
319
320 else:
321
322 if sim == None:
323 if hasattr(self.relax.data.res[self.run][index], object_name):
324 stat = getattr(self.relax.data.res[self.run][index], object_name)
325 else:
326 stat = None
327
328
329 else:
330 if hasattr(self.relax.data.res[self.run][index], object_sim):
331 stat = getattr(self.relax.data.res[self.run][index], object_sim)[sim]
332 else:
333 stat = None
334
335
336 return stat, None
337
338
339 - def set(self, run=None, value=None, error=None, param=None, scaling=None, index=None):
340 """
341 Minimisation statistic set details
342 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
343
344 This shouldn't really be executed by a user.
345 """
346
347
348 self.run = run
349
350
351 param_name = self.return_data_name(param)
352
353
354 if index == None:
355
356 if param_name == 'chi2':
357 self.relax.data.chi2[self.run] = value
358
359
360 elif param_name == 'iter':
361 self.relax.data.iter[self.run] = value
362
363
364 elif param_name == 'f_count':
365 self.relax.data.f_count[self.run] = value
366
367
368 elif param_name == 'g_count':
369 self.relax.data.g_count[self.run] = value
370
371
372 elif param_name == 'h_count':
373 self.relax.data.h_count[self.run] = value
374
375
376 else:
377
378 if param_name == 'chi2':
379 self.relax.data.res[self.run][index].chi2 = value
380
381
382 elif param_name == 'iter':
383 self.relax.data.res[self.run][index].iter = value
384
385
386 elif param_name == 'f_count':
387 self.relax.data.res[self.run][index].f_count = value
388
389
390 elif param_name == 'g_count':
391 self.relax.data.res[self.run][index].g_count = value
392
393
394 elif param_name == 'h_count':
395 self.relax.data.res[self.run][index].h_count = value
396
397
398
399
400
401
403 - def __init__(self, relax, parent_run, *min_args):
404 """Initialisation of the Monte Carlo simulation minimisation parent thread."""
405
406
407 self.relax = relax
408 self.parent_run = parent_run
409 self.min_args = min_args
410
411
412 RelaxParentThread.__init__(self)
413
414
415 self.num_jobs = self.relax.data.sim_number[self.parent_run]
416
417
418 self.run()
419
420
422 """Function for returning an initialised thread object."""
423
424
425 return RelaxMinimiseThread(self.relax, i, self.job_queue, self.results_queue, self.finished_jobs, self.job_locks, self.tag, self.parent_run, self.min_args)
426
427
428
429
430
431
433 - def __init__(self, relax, i, job_queue, results_queue, finished_jobs, job_locks, tag, parent_run, min_args):
434 """Initialisation of the thread."""
435
436
437 self.relax = relax
438 self.tag = tag
439 self.parent_run = parent_run
440 self.min_args = min_args
441
442
443 RelaxThread.__init__(self, i, job_queue, results_queue, finished_jobs, job_locks)
444
445
446 self.min_algor, self.min_options, self.func_tol, self.grad_tol, self.max_iterations, self.constraints, self.scaling, self.print_flag = self.min_args
447
448
450 """Function for generating the script for the thread to minimise sim `sim`."""
451
452
453 fn = []
454
455
456 fn.append("self.relax.generic.state.load(file='%s')" % self.save_state_file)
457
458
459 fn.append("self.relax.generic.minimise.minimise(run='%s', min_algor='%s', min_options=%s, func_tol=%s, grad_tol=%s, max_iterations=%s, constraints=%s, scaling=%s, print_flag=%s, sim_index=%s)" % (self.parent_run, self.min_algor, self.min_options, self.func_tol, self.grad_tol, self.max_iterations, self.constraints, self.scaling, self.print_flag, self.job_number))
460
461
462 fn.append("self.relax.IO.logging_off()")
463
464
465 text = ''
466 for i in xrange(len(fn)):
467 text = text + "\nprint \"\\n" + fn[i] + "\"\n"
468 text = text + fn[i] + "\n"
469
470
471 text = text + "self.relax.generic.results.display(run='%s')\n" % (self.parent_run)
472
473
474 cmd = "cat > %s" % self.script_file
475 cmd = self.remote_command(cmd=cmd, login_cmd=self.login_cmd)
476
477
478 self.child = RelaxPopen3(cmd, capturestderr=1)
479
480
481 self.child.tochild.write(text)
482 self.child.tochild.close()
483
484
485 err = self.child.childerr.readlines()
486
487
488 self.child.fromchild.close()
489 self.child.childerr.close()
490
491
492 if len(err):
493 raise RelaxError, "The command `%s` could not be executed." % cmd
494
495
497 """Code to run after locking the job."""
498
499
500 self.relax.generic.runs.create(run=self.thread_run, run_type=self.relax.data.run_types[self.relax.data.run_names.index(self.parent_run)])
501
502
503 self.relax.generic.results.read(run=self.thread_run, file_data=self.results, print_flag=0)
504
505
506 self.relax.generic.results.copy(run1=self.thread_run, run2=self.parent_run, sim=self.job_number)
507
508
509 self.relax.generic.runs.delete(self.thread_run)
510
511
512 print "Simulation: " + `self.job_number`
513