Package ComboCode :: Package cc :: Package modeling :: Package codes :: Module Chemistry
[hide private]
[frames] | no frames]

Source Code for Module ComboCode.cc.modeling.codes.Chemistry

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  Running Chemistry and managing output from Chemistry. 
  5   
  6  Author: M. Van de Sande (based on MCMax.py of R. Lombaert) 
  7   
  8  """ 
  9   
 10  import os 
 11  import subprocess 
 12  from glob import glob 
 13   
 14  import cc.path 
 15  from cc.tools.io import DataIO, Database 
 16  from cc.modeling.codes.ModelingSession import ModelingSession 
 17   
 18   
 19        
 20   
21 -class Chemistry(ModelingSession):
22 23 """ 24 Class that includes all methods required for creating an Chemistry model. 25 26 """ 27
28 - def __init__(self,path_chemistry='runTest',replace_db_entry=0,db=None,\ 29 single_session=0):
30 31 """ 32 Initializing an instance of ModelingSession. 33 34 @keyword db: the Chemistry database 35 36 (default: None) 37 @type db: Database() 38 @keyword replace_db_entry: replace an entry in the Chemistry database with 39 a newly calculated model with a new model id 40 (for instance if some general data not 41 included in the inputfiles is changed) 42 43 (default: 0) 44 @type replace_db_entry: bool 45 @keyword path_chemistry: modeling folder in Chemistry home 46 47 (default: 'runTest') 48 @type path_chemistry: string 49 @keyword new_entries: The new model_ids when replace_db_entry is 1 50 of other models in the grid. These are not 51 replaced! 52 53 (default: []) 54 @type new_entries: list[str] 55 @keyword single_session: If this is the only CC session. Speeds up db 56 check. 57 58 (default: 0) 59 @type single_session: bool 60 61 """ 62 63 super(Chemistry, self).__init__(code='Chemistry',path=path_chemistry,\ 64 replace_db_entry=replace_db_entry,\ 65 single_session=single_session) 66 #-- Convenience path 67 cc.path.cout = os.path.join(cc.path.chemistry,self.path) 68 #DataIO.testFolderExistence(os.path.join(cc.path.mout,\ 69 #'data_for_gastronoom')) 70 self.db = db 71 72 #-- If an chemistry model is in progress, the model manager will hold until 73 # the other cc session is finished. 74 self.in_progress = False 75 76 #- Read standard input file with all parameters that should be included 77 #- as well as some dust specific information 78 self.inputfilename = os.path.join(cc.path.aux,'inputChemistry.dat') 79 self.standard_inputfile = DataIO.readDict(self.inputfilename,\ 80 convert_floats=1,\ 81 convert_ints=1,\ 82 comment_chars=['#','*']) 83 chemistry_keys = os.path.join(cc.path.aux,'Input_Keywords_Chemistry.dat') 84 self.chemistry_keywords = [line.strip() 85 for line in DataIO.readFile(chemistry_keys) 86 if line]
87 88 89 90
91 - def setCommandKey(self,comm_key,star,star_key=None,alternative=None):
92 93 ''' 94 Try setting a key in the command_list from a star instance. 95 96 If the key is unknown, it is left open and will be filled in from the 97 standard gastronoom inputfile. 98 99 @param comm_key: the name of the keyword in the command list 100 @type comm_key: string 101 @param star: Parameter set for this session 102 @type star: Star() 103 104 @keyword star_key: the name of the keyword in Star() (minus '_%s' 105 %key_type (DUST or GAS), which is added as well in a 106 second attempt if the first without the addition is 107 not found). If None, it's equal to comm_key 108 109 (default: None) 110 @type star_key: string 111 @keyword alternative: a default value passed from the standard 112 inputfile that is used if the keyword or the 113 keyword + '_%s'%key_type is not found in Star(). 114 115 (default: None) 116 @type alternative: string 117 118 @return: Success? 119 @rtype: bool 120 121 ''' 122 123 keyword_int_list = ['PERFORM_ROUTINE'] 124 if comm_key.lower() in keyword_int_list: make_int = 1 125 else: make_int = 0 126 return super(Chemistry, self).setCommandKey(comm_key,star,'DUST',\ 127 star_key,alternative,\ 128 make_int)
129 130 131 132 133
134 - def cCL(self,*args,**kwargs):
135 136 ''' 137 Short-hand helper function for compareCommandLists. 138 139 ''' 140 141 return self.compareCommandLists(*args,**kwargs)
142 143 144
145 - def checkDatabase(self):
146 147 """ 148 Checking Chemistry database. 149 150 @return: The presence of the Chemistry model in the database 151 @rtype: bool 152 153 """ 154 155 #-- Lock the Chemistry database by opening it in read mode. It's closed 156 # once the database check is finalised. Note that in a case of a crash 157 # during the for loop, the python shell must be exited to unlock the 158 # sphinx database again. The sync() is now done only once at the very 159 # end since the file on the disk will not change. 160 if not self.single_session: self.db.sync() 161 chem_dbfile = self.db._open('r') 162 db_ids = sorted(self.db.keys()) 163 for i,model_id in enumerate(db_ids): 164 chem_dict = self.db[model_id] 165 model_bool = self.compareCommandLists(self.command_list.copy(),\ 166 chem_dict, 'chemistry') 167 if model_bool: 168 if chem_dict.has_key('IN_PROGRESS'): 169 self.in_progress = True 170 print 'Chemistry model is currently being calculated in a ' +\ 171 'different CC modeling session with ID %s'\ 172 %(model_id) 173 self.model_id = model_id 174 finished = 1 175 break 176 elif self.replace_db_entry \ 177 and model_id not in self.new_entries: 178 print 'Replacing Chemistry database entry for old ID %s'\ 179 %model_id 180 del self.db[model_id] 181 finished = 0 182 break 183 else: 184 print 'Chemistry model has been calculated ' + \ 185 'before with ID %s'%model_id 186 self.model_id = model_id 187 finished = 1 188 break 189 190 #-- Reached the end of db without match. Make new entry in db, in 191 # progress. Cant combine this with next line in case the last 192 # model gives a match. 193 if i == len(self.db)-1: 194 print 'No match found in Chemistry database. ' + \ 195 'Calculating new model.' 196 finished = 0 197 198 #-- In case of an empty db, the above loop is not accessed. 199 if not self.db.keys(): 200 print 'No match found in Chemistry database. Calculating new model.' 201 finished = 0 202 203 #-- Add the model in progress to the Chemistry db 204 if finished == 0: 205 self.model_id = self.makeNewId() 206 self.db[self.model_id] = self.command_list.copy() 207 self.db[self.model_id]['IN_PROGRESS'] = 1 208 209 #-- In case of an empty db, the above loop is not accessed. 210 if not self.db.keys(): 211 print 'No match found in Chemistry database. Calculating new model.' 212 finished = 0 213 214 #-- Synchronize and unlock db. 215 chem_dbfile.close() 216 if not self.single_session: self.db.sync() 217 return finished
218 219 220
221 - def doChemistry(self,star):
222 223 """ 224 Running Chemistry. 225 226 @param star: The parameter set for this session 227 @type star: Star() 228 229 """ 230 231 print '***********************************' 232 #- Create the input dictionary for this Chemistry run 233 print '** Making input file for Chemistry' 234 #-- Add the previous model_id to the list of new entries, so it does 235 # not get deleted if replace_db_entry == 1. 236 if self.model_id: 237 self.new_entries.append(self.model_id) 238 self.model_id = '' 239 self.command_list = dict() 240 # Bijzonder gevallen hier ipv in loop over orig 241 # Dan is input_lines/command_list wat er in de database staat 242 # input_lines = d 243 244 if star['PERFORM_ROUTINE'] == 0: 245 self.command_list['ROUTINE_RADIUS'] = 0 246 else: 247 self.command_list['ROUTINE_RADIUS'] = star['ROUTINE_RADIUS'] 248 #*star['R_STAR']*star.Rsun 249 self.command_list['R_STAR'] = star['R_STAR']*star.Rsun 250 #self.command_list['R_INNER_CHEM'] = star['R_INNER_CHEM']*\ 251 #star['R_STAR']*star.Rsun 252 #self.command_list['R_OUTER_CHEM'] = star['R_OUTER_CHEM']*\ 253 #star['R_STAR']*star.Rsun 254 255 self.command_list['REACTIONS_FILE'] = '"'+os.path.join(cc.path.csource,\ 256 'rates',star['REACTIONS_FILE'])+'"' 257 self.command_list['SPECIES_FILE'] = '"'+os.path.join(cc.path.csource,\ 258 'specs',star['SPECIES_FILE'])+'"' 259 self.command_list['FILECO'] = '"'+os.path.join(cc.path.csource,\ 260 'shielding',star['FILECO'])+'"' 261 self.command_list['FILEN2'] = '"'+os.path.join(cc.path.csource,\ 262 star['FILEN2'])+'"' 263 264 add_keys = [k 265 for k in self.standard_inputfile.keys() 266 if not self.command_list.has_key(k)] 267 [self.setCommandKey(k,star,star_key=k.upper(),\ 268 alternative=self.standard_inputfile[k]) 269 for k in add_keys] 270 271 print '** DONE!' 272 print '***********************************' 273 274 #-- Check the Chemistry database if the model was calculated before 275 modelbool = self.checkDatabase() 276 277 #-- if no match found in database, calculate new model with new model id 278 #-- if the calculation did not fail, add entry to database for new model 279 if not modelbool: 280 input_dict = self.command_list.copy() 281 input_lines = [] 282 orig = DataIO.readFile(self.inputfilename) 283 for i,s in enumerate(orig): 284 split = s.split() 285 if s[0] == '!': 286 input_lines.append(s) 287 else: 288 input_lines.append(" ".join(split[0:2])+' '+\ 289 str(self.command_list[split[0]])) 290 output_folder = os.path.join(cc.path.cout,'models',self.model_id) 291 DataIO.testFolderExistence(output_folder) 292 input_lines.append('OUTPUT_FOLDER = "' +\ 293 output_folder+'/"') 294 295 input_filename = os.path.join(cc.path.cout,'models',\ 296 'inputChemistry_%s.txt'%self.model_id) 297 298 DataIO.writeFile(filename=input_filename,input_lines=input_lines) 299 300 #subprocess.call(' '.join([cc.path.ccode,input_filename]),shell=True) 301 subprocess.call(' '.join([os.path.join(cc.path.csource,'csmodel'),input_filename]),shell=True) 302 303 304 # files die worden aangemaakt op einde, test of successvol 305 testf1 = os.path.join(output_folder,'cscoldens.out') 306 testf2 = os.path.join(output_folder,'csfrac.out') 307 if os.path.exists(testf1) and os.path.exists(testf2) and \ 308 os.path.isfile(testf1) and os.path.isfile(testf2): 309 del self.db[self.model_id]['IN_PROGRESS'] 310 self.db.addChangedKey(self.model_id) 311 else: 312 print '** Model calculation failed. No entry is added to ' + \ 313 'the database.' 314 del self.db[self.model_id] 315 self.model_id = '' 316 if not self.single_session: self.db.sync() 317 318 #- Note that the model manager now adds/changes MUTABLE input keys, 319 #- which MAY be overwritten by the input file inputComboCode.dat 320 print '***********************************'
321