Package generic_fns :: Module minimise
[hide private]
[frames] | no frames]

Source Code for Module generic_fns.minimise

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003, 2004 Edward d'Auvergne                                  # 
  4  #                                                                             # 
  5  # This file is part of the program relax.                                     # 
  6  #                                                                             # 
  7  # relax is free software; you can redistribute it and/or modify               # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation; either version 2 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # relax is distributed in the hope that it will be useful,                    # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with relax; if not, write to the Free Software                        # 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23   
 24  from Queue import Queue 
 25   
 26  from processes import RelaxPopen3 
 27  from thread_classes import RelaxParentThread, RelaxThread 
 28   
 29   
30 -class Minimise:
31 - def __init__(self, relax):
32 """Class containing the calc, grid_search, minimise, and set functions.""" 33 34 self.relax = relax
35 36
37 - def calc(self, run=None, print_flag=1):
38 """Function for calculating the function value.""" 39 40 # Test if the run exists. 41 if not run in self.relax.data.run_names: 42 raise RelaxNoRunError, run 43 44 # Function type. 45 function_type = self.relax.data.run_types[self.relax.data.run_names.index(run)] 46 47 # Specific calculate function setup. 48 calculate = self.relax.specific_setup.setup('calculate', function_type) 49 50 # Monte Carlo simulation calculation. 51 if hasattr(self.relax.data, 'sim_state') and self.relax.data.sim_state.has_key(run) and self.relax.data.sim_state[run] == 1: 52 # Loop over the simulations. 53 for i in xrange(self.relax.data.sim_number[run]): 54 if print_flag: 55 print "Simulation " + `i+1` 56 calculate(run=run, print_flag=print_flag-1, sim_index=i) 57 58 # Minimisation. 59 else: 60 calculate(run=run, print_flag=print_flag)
61 62
63 - def grid_search(self, run=None, lower=None, upper=None, inc=None, constraints=1, print_flag=1):
64 """The grid search function.""" 65 66 # Test if the run exists. 67 if not run in self.relax.data.run_names: 68 raise RelaxNoRunError, run 69 70 # Function type. 71 function_type = self.relax.data.run_types[self.relax.data.run_names.index(run)] 72 73 # Specific grid search function. 74 grid_search = self.relax.specific_setup.setup('grid_search', function_type) 75 76 # Monte Carlo simulation grid search. 77 if hasattr(self.relax.data, 'sim_state') and self.relax.data.sim_state.has_key(run) and self.relax.data.sim_state[run] == 1: 78 # Loop over the simulations. 79 for i in xrange(self.relax.data.sim_number[run]): 80 if print_flag: 81 print "Simulation " + `i+1` 82 grid_search(run=run, lower=lower, upper=upper, inc=inc, constraints=constraints, print_flag=print_flag-1, sim_index=i) 83 84 # Grid search. 85 else: 86 grid_search(run=run, lower=lower, upper=upper, inc=inc, constraints=constraints, print_flag=print_flag)
87 88
89 - 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):
90 """Minimisation function.""" 91 92 # Test if the run exists. 93 if not run in self.relax.data.run_names: 94 raise RelaxNoRunError, run 95 96 # Function type. 97 function_type = self.relax.data.run_types[self.relax.data.run_names.index(run)] 98 99 # Specific minimisation function. 100 minimise = self.relax.specific_setup.setup('minimise', function_type) 101 102 # Single Monte Carlo simulation. 103 if sim_index != None: 104 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) 105 106 # Monte Carlo simulation minimisation. 107 elif hasattr(self.relax.data, 'sim_state') and self.relax.data.sim_state.has_key(run) and self.relax.data.sim_state[run] == 1: 108 # Threaded minimisation of simulations. 109 if self.relax.thread_data.status: 110 # Print out. 111 print "Threaded minimisation of Monte Carlo simulations.\n" 112 113 # Run the main threading loop. 114 RelaxMinParentThread(self.relax, run, min_algor, min_options, func_tol, grad_tol, max_iterations, constraints, scaling, print_flag) 115 116 # Non-threaded minimisation of simulations. 117 else: 118 for i in xrange(self.relax.data.sim_number[run]): 119 if print_flag: 120 print "Simulation " + `i+1` 121 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) 122 123 # Standard minimisation. 124 else: 125 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)
126 127 128 129 130 # Main threading loop for the minimisation of Monte Carlo simulations. 131 ###################################################################### 132
133 -class RelaxMinParentThread(RelaxParentThread):
134 - def __init__(self, relax, parent_run, *min_args):
135 """Initialisation of the Monte Carlo simulation minimisation parent thread.""" 136 137 # Arguments. 138 self.relax = relax 139 self.parent_run = parent_run 140 self.min_args = min_args 141 142 # Run the RelaxParentThread __init__ function. 143 RelaxParentThread.__init__(self) 144 145 # The number of jobs. 146 self.num_jobs = self.relax.data.sim_number[self.parent_run] 147 148 # Run the main loop. 149 self.run()
150 151
152 - def thread_object(self, i):
153 """Function for returning an initialised thread object.""" 154 155 # Return the thread object. 156 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)
157 158 159 160 # Threads for the minimisation of Monte Carlo simulations. 161 ########################################################## 162
163 -class RelaxMinimiseThread(RelaxThread):
164 - def __init__(self, relax, i, job_queue, results_queue, finished_jobs, job_locks, tag, parent_run, min_args):
165 """Initialisation of the thread.""" 166 167 # Arguments. 168 self.relax = relax 169 self.tag = tag 170 self.parent_run = parent_run 171 self.min_args = min_args 172 173 # Run the RelaxThread __init__ function (this is 'asserted' by the Thread class). 174 RelaxThread.__init__(self, i, job_queue, results_queue, finished_jobs, job_locks) 175 176 # Expand the minimisation arguments. 177 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
178 179
180 - def generate_script(self):
181 """Function for generating the script for the thread to minimise sim `sim`.""" 182 183 # Function array. 184 fn = [] 185 186 # Function: Load the program state. 187 fn.append("self.relax.generic.state.load(file='%s')" % self.save_state_file) 188 189 # Function: Minimise. 190 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)) 191 192 # Function: Turn logging off. This is so that the results can come back through the child's stdout pipe. 193 fn.append("self.relax.IO.logging_off()") 194 195 # Generate the main text of the script file. 196 text = '' 197 for i in xrange(len(fn)): 198 text = text + "\nprint \"\\n" + fn[i] + "\"\n" 199 text = text + fn[i] + "\n" 200 201 # Function: Write the results to stdout. 202 text = text + "self.relax.generic.results.display(run='%s')\n" % (self.parent_run) 203 204 # Cat the text into the script file. 205 cmd = "cat > %s" % self.script_file 206 cmd = self.remote_command(cmd=cmd, login_cmd=self.login_cmd) 207 208 # Start the child process. 209 self.child = RelaxPopen3(cmd, capturestderr=1) 210 211 # Write the text to the child's stdin, then close it. 212 self.child.tochild.write(text) 213 self.child.tochild.close() 214 215 # Catch errors. 216 err = self.child.childerr.readlines() 217 218 # Close all pipes. 219 self.child.fromchild.close() 220 self.child.childerr.close() 221 222 # The file could not be copied. 223 if len(err): 224 raise RelaxError, "The command `%s` could not be executed." % cmd
225 226
227 - def post_locked_code(self):
228 """Code to run after locking the job.""" 229 230 # Create a run in the parent to temporarily store the data prior to copying into the main run. 231 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)]) 232 233 # Read the data into the run. 234 self.relax.generic.results.read(run=self.thread_run, file_data=self.results, print_flag=0) 235 236 # Copy the results from the thread run to the parent run. 237 self.relax.generic.results.copy(run1=self.thread_run, run2=self.parent_run, sim=self.job_number) 238 239 # Delete the thread run. 240 self.relax.generic.runs.delete(self.thread_run) 241 242 # Print out. 243 print "Simulation: " + `self.job_number`
244