def __readCDMS(self): ''' Read data from CDMS line list catalogs for a specific molecule. ''' data = DataIO.readFile(self.fn,\ replace_spaces=0) print 'Reading data from CDMS database for' print self.fn #-- If the uncertainties are negative, change the unit of min/max to # cm-1 uncertainties = [float(line[13:21]) for line in data] if min(uncertainties) < 0 and max(uncertainties) == 0: self.x_min = self.x_min.to(1. / u.cm, equivalencies=u.spectral()) self.x_max = self.x_max.to(1. / u.cm, equivalencies=u.spectral()) elif min(uncertainties) < 0 and max(uncertainties) > 0: raise ValueError('Uncertainties in CDMS input file for ' + \ 'file %s are ambiguous.'\ %self.fn) data = self.__parseCatalog(data) #-- If unit was changed, change the f values to MHz, the default unit rcm = u.Unit("1 / cm") if self.x_min.unit == rcm: data = sorted([[ (entry * rcm).to(u.MHz, equivalencies=u.spectral()) if not i else entry for i, entry in enumerate(line) ] for line in data]) self.line_list = data
def getKey(k,data=None,fn=None): ''' Retrieve data from an ALI inputfile. Returns the line following the line that contains the given key. @param k: The unique input key word for which the ALI inputfile is searched. @type k: str @keyword data: The data, ie a file read by readFile with delimiter set to '' A filename must be given if data is None. (default: None) @type data: list[str] @keyword fn: The ALI input filename. Only used if data is None. (default: None) @type fn: str @return: The line following the line that contains given key @rtype: str ''' if data is None: data = DataIO.readFile(filename=fn,delimiter=None,replace_spaces=0) i = DataIO.findKey(0,data,k) return data[i+1].replace('\n','')
def __readCDMS(self): ''' Read data from CDMS line list catalogs for a specific molecule. ''' data = DataIO.readFile(self.fn,\ replace_spaces=0) print 'Reading data from CDMS database for' print self.fn #-- If the uncertainties are negative, change the unit of min/max to # cm-1 uncertainties = [float(line[13:21]) for line in data] if min(uncertainties) < 0 and max(uncertainties) == 0: self.x_min = self.x_min.to(1./u.cm,equivalencies=u.spectral()) self.x_max = self.x_max.to(1./u.cm,equivalencies=u.spectral()) elif min(uncertainties) < 0 and max(uncertainties) > 0: raise ValueError('Uncertainties in CDMS input file for ' + \ 'file %s are ambiguous.'\ %self.fn) data = self.__parseCatalog(data) #-- If unit was changed, change the f values to MHz, the default unit rcm = u.Unit("1 / cm") if self.x_min.unit == rcm: data = sorted([[(entry*rcm).to(u.MHz,equivalencies=u.spectral()) if not i else entry for i,entry in enumerate(line)] for line in data]) self.line_list = data
def readFile(self, wildcard="*", *args, **kwargs): """ Read a filename and store its contents in the Reader object. The contents are stored in a dictionary, with the filename as key. Note that one filename can refer to multiple files with the use of a wildcard character. This character can be replaced upon calling this method. The contents can be returned with the method getFile. If the file is not found, an empty list is stored instead. Additional args/kwargs are passed to DataIO.readFile (such as delimiter and replace_spaces) @keyword wildcard: if a wildcard character is present in the filename, it can be replaced here. (default: '*') @type wildcard: string """ # -- Replace the wildcard if it is present. fn = self.fn.replace("*", wildcard) # -- Read the file self["contents"][fn] = DataIO.readFile(fn, *args, **kwargs)
def readCDMS(self): ''' Read data from CDMS line list catalogs for a specific molecule. ''' data = DataIO.readFile(os.path.join(cc.path.ll,\ self.molecule.molecule+'_CDMS.dat'),\ replace_spaces=0) print 'Reading data from CDMS database for %s.' % self.molecule.molecule uncertainties = [float(line[13:21]) for line in data] if min(uncertainties) < 0 and max(uncertainties) == 0: input_xmin = self.x_min input_xmax = self.x_max self.x_min = (self.c / (input_xmin * 10**6))**-1 self.x_max = (self.c / (input_xmax * 10**6))**-1 self.input_unit = 'cm-1' elif min(uncertainties) < 0 and max(uncertainties) > 0: raise ValueError('Uncertainties in CDMS input file for ' + \ 'molecule %s are ambiguous.'\ %self.molecule.molecule) data = self.parseStandardCatalog(data, 'CDMS') if self.input_unit == 'cm-1': data = sorted([[i == 0 \ and self.c*entry*10**-6 \ or entry \ for i,entry in enumerate(line)] for line in data]) self.line_list.extend(data)
def readFile(self, wildcard='*', *args, **kwargs): ''' Read a filename and store its contents in the Reader object. The contents are stored in a dictionary, with the filename as key. Note that one filename can refer to multiple files with the use of a wildcard character. This character can be replaced upon calling this method. The contents can be returned with the method getFile. If the file is not found, an empty list is stored instead. Additional args/kwargs are passed to DataIO.readFile (such as delimiter and replace_spaces) @keyword wildcard: if a wildcard character is present in the filename, it can be replaced here. (default: '*') @type wildcard: string ''' #-- Replace the wildcard if it is present. fn = self.fn.replace('*', wildcard) #-- Read the file self['contents'][fn] = DataIO.readFile(fn, *args, **kwargs)
def readCDMS(self): ''' Read data from CDMS line list catalogs for a specific molecule. ''' data = DataIO.readFile(os.path.join(cc.path.ll,\ self.molecule.molecule+'_CDMS.dat'),\ replace_spaces=0) print 'Reading data from CDMS database for %s.'%self.molecule.molecule uncertainties = [float(line[13:21]) for line in data] if min(uncertainties) < 0 and max(uncertainties) == 0: input_xmin = self.x_min input_xmax = self.x_max self.x_min = (self.c/(input_xmin*10**6))**-1 self.x_max = (self.c/(input_xmax*10**6))**-1 self.input_unit = 'cm-1' elif min(uncertainties) < 0 and max(uncertainties) > 0: raise ValueError('Uncertainties in CDMS input file for ' + \ 'molecule %s are ambiguous.'\ %self.molecule.molecule) data = self.parseStandardCatalog(data,'CDMS') if self.input_unit == 'cm-1': data = sorted([[i == 0 \ and self.c*entry*10**-6 \ or entry \ for i,entry in enumerate(line)] for line in data]) self.line_list.extend(data)
def __init__(self,path_chemistry='runTest',replace_db_entry=0,db=None,\ single_session=0): """ Initializing an instance of ModelingSession. @keyword db: the Chemistry database (default: None) @type db: Database() @keyword replace_db_entry: replace an entry in the Chemistry database with a newly calculated model with a new model id (for instance if some general data not included in the inputfiles is changed) (default: 0) @type replace_db_entry: bool @keyword path_chemistry: modeling folder in Chemistry home (default: 'runTest') @type path_chemistry: string @keyword new_entries: The new model_ids when replace_db_entry is 1 of other models in the grid. These are not replaced! (default: []) @type new_entries: list[str] @keyword single_session: If this is the only CC session. Speeds up db check. (default: 0) @type single_session: bool """ super(Chemistry, self).__init__(code='Chemistry',path=path_chemistry,\ replace_db_entry=replace_db_entry,\ single_session=single_session) #-- Convenience path cc.path.cout = os.path.join(cc.path.chemistry,self.path) #DataIO.testFolderExistence(os.path.join(cc.path.mout,\ #'data_for_gastronoom')) self.db = db #-- If an chemistry model is in progress, the model manager will hold until # the other cc session is finished. self.in_progress = False #- Read standard input file with all parameters that should be included #- as well as some dust specific information self.inputfilename = os.path.join(cc.path.aux,'inputChemistry.dat') self.standard_inputfile = DataIO.readDict(self.inputfilename,\ convert_floats=1,\ convert_ints=1,\ comment_chars=['#','*']) chemistry_keys = os.path.join(cc.path.aux,'Input_Keywords_Chemistry.dat') self.chemistry_keywords = [line.strip() for line in DataIO.readFile(chemistry_keys) if line]
def __readJPL(self): ''' Read data from JPL line list catalogs for a specific molecule. ''' data = DataIO.readFile(self.fn,\ replace_spaces=0) print 'Reading data from JPL database for' print self.fn data = self.__parseCatalog(data) self.line_list = data
def getExtinctionCurve(gal_position='ism',curve_type='chiar_tielens',\ av_to_ak_conv=0.112): """ Read extinction curve. @keyword gal_position: galactic position star: 'ism' or 'gc'. Difference of extinction curve for ISM or galactic center (as for chiar_tielens), if no difference (as for cardelli) this parameter is ignored. (default: 'ism') @type gal_position: string @keyword curve_type: type of extinction curve ('chiar_tielens' or 'cardelli') (default: 'chiar_tielens') @type curve_type: string @keyword av_to_ak_conv: V-band to K-band conversion factor for extinction correction (default: 0.112) @type av_to_ak_conv: float @return: The wavelength grid and extinction curve values @rtype: (array,array) """ extcurve_input = DataIO.readFile(os.path.join(cc.path.aux,\ curve_type + '.dat'),\ delimiter=' ') extcurve_x = [float(row[0]) for row in extcurve_input if row[0][0] != '#'] if gal_position.lower() == 'ism' and curve_type.lower() == 'chiar_tielens': extcurve_y = [float(row[2]) for row in extcurve_input if row[0][0] != '#' and len(row) == 3] #- Cut off excess wavelengths extcurve_x = extcurve_x[:len(extcurve_y)] elif curve_type.lower() == 'cardelli': #- putting wavelength in micron extcurve_x = array(extcurve_x)*10**(-4) extcurve_y = [float(row[1]) for row in extcurve_input if row[0][0] != '#'] #- Put values to Alambda/Ak extcurve_y = array(extcurve_y)/(3.1*av_to_ak_conv) else: extcurve_y = [float(row[1]) for row in extcurve_input if row[0][0] != '#'] return (array(extcurve_x),array(extcurve_y))
def readJPL(self): ''' Read data from JPL line list catalogs for a specific molecule. ''' data = DataIO.readFile(os.path.join(cc.path.ll,\ self.molecule.molecule+'_JPL.dat'),\ replace_spaces=0) print 'Reading data from JPL database for %s.' % self.molecule.molecule data = self.parseStandardCatalog(data, 'JPL') self.line_list.extend(data)
def readJPL(self): ''' Read data from JPL line list catalogs for a specific molecule. ''' data = DataIO.readFile(os.path.join(cc.path.ll,\ self.molecule.molecule+'_JPL.dat'),\ replace_spaces=0) print 'Reading data from JPL database for %s.'%self.molecule.molecule data = self.parseStandardCatalog(data,'JPL') self.line_list.extend(data)
def __init__(self,code,path,replace_db_entry=0,new_entries=[],\ single_session=0): """ Initializing an instance of ModelingSession. @param code: code for which the modelingsession is created @type code: string @param path: modeling output folder in the code's home folder @type path: string @keyword replace_db_entry: replace an entry in the database with a newly calculated model with a new model id (eg if some general data not included in the inputfiles is changed) (default: 0) @type replace_db_entry: bool @keyword new_entries: The new model_ids when replace_db_entry is 1 of other models in the grid. These are not replaced! (default: []) @type new_entries: list[str] @keyword single_session: If this is the only CC session. Speeds up db check. (default: 0) @type single_session: bool """ self.path = path self.code = code self.model_id = '' self.replace_db_entry = replace_db_entry self.new_entries = new_entries self.single_session = single_session if code == 'Chemistry': self.mutable = [] else: mutablefile = os.path.join(cc.path.aux,\ 'Mutable_Parameters_%s.dat'%code) self.mutable = [ line[0] for line in DataIO.readFile(mutablefile, delimiter=' ') if ' '.join(line) ] self.mutable = [line for line in self.mutable if line[0] != '#'] fout = os.path.join(getattr(cc.path, self.code.lower()), self.path) DataIO.testFolderExistence(os.path.join(fout, 'models'))
def __init__(self,code,path,replace_db_entry=0,new_entries=[],\ single_session=0): """ Initializing an instance of ModelingSession. @param code: code for which the modelingsession is created @type code: string @param path: modeling output folder in the code's home folder @type path: string @keyword replace_db_entry: replace an entry in the database with a newly calculated model with a new model id (eg if some general data not included in the inputfiles is changed) (default: 0) @type replace_db_entry: bool @keyword new_entries: The new model_ids when replace_db_entry is 1 of other models in the grid. These are not replaced! (default: []) @type new_entries: list[str] @keyword single_session: If this is the only CC session. Speeds up db check. (default: 0) @type single_session: bool """ self.path = path self.code = code self.model_id = '' self.replace_db_entry = replace_db_entry self.new_entries = new_entries self.single_session = single_session if code == 'Chemistry': self.mutable = [] else: mutablefile = os.path.join(cc.path.aux,\ 'Mutable_Parameters_%s.dat'%code) self.mutable = [line[0] for line in DataIO.readFile(mutablefile,delimiter=' ') if ' '.join(line)] self.mutable = [line for line in self.mutable if line[0] != '#'] fout = os.path.join(getattr(cc.path,self.code.lower()),self.path) DataIO.testFolderExistence(os.path.join(fout,'models'))
def setSpecies(self, species): """ Change the species of the current CustomOpacity instance. @param species: the species short name @type species: string """ self.species = species self.index = DataIO.getInputData(keyword='SPECIES_SHORT',\ filename='Dust.dat')\ .index(self.species) self.filename = DataIO.getInputData(keyword='PART_FILE',\ filename='Dust.dat',\ rindex=self.index) fn = os.path.join(cc.path.mopac, self.filename) self.input_data = DataIO.readFile(filename=fn, delimiter=' ')
def setSpecies(self,species): """ Change the species of the current CustomOpacity instance. @param species: the species short name @type species: string """ self.species = species self.index = DataIO.getInputData(keyword='SPECIES_SHORT',\ filename='Dust.dat')\ .index(self.species) self.filename = DataIO.getInputData(keyword='PART_FILE',\ filename='Dust.dat',\ rindex=self.index) fn = os.path.join(cc.path.mopac,self.filename) self.input_data = DataIO.readFile(filename=fn,delimiter=' ')
def readFile(self, filename, delimiter = ' '): ''' Read a filename and store its contents in the OutputReader. The contents are stored in a dictionary, with the filename as key. The contents can be returned when running getFile. @param filename: The filename of the outputfile, including filepath @type filename: string @keyword delimiter: The delimiter character used in this file. (default: ' ') @type delimiter: string ''' try: self.contents[filename] = DataIO.readFile(filename, delimiter) except IOError: self.contents[filename] = None
def readKappas(self,species): """ Read kappas (cm2/g) and Q_ext/a (cm-1) for a dust species from the MCMax INPUT files. This also reads the absorption and scattering kappas separately. @param species: The dust species (from Dust.dat) @type species: string """ if self.waves.has_key(species): return try: ispecies = self.lspecies.index(species) except ValueError: print 'Species not found in Dust.dat.' return fn = os.path.join(cc.path.mopac,self.lfilenames[ispecies]) sd = self.lspec_dens[ispecies] if fn[-9:] == '.particle': part_file = DataIO.readFile(filename=fn,delimiter=' ') wav = array([float(q[0]) for q in part_file if len(q) == 4]) kappa = [array([float(q[1]) for q in part_file if len(q) == 4]), array([float(q[2]) for q in part_file if len(q) == 4]), array([float(q[3]) for q in part_file if len(q) == 4])] else: part_file = DataIO.readCols(filename=fn) wav = part_file[0] kappa = part_file[1:] self.waves[species] = wav self.kappas[species] = kappa self.qext_a[species] = array(kappa) * 4/3. * sd
def readKappas(self, species): """ Read kappas (cm2/g) and Q_ext/a (cm-1) for a dust species from the MCMax INPUT files. This also reads the absorption and scattering kappas separately. @param species: The dust species (from Dust.dat) @type species: string """ if self.waves.has_key(species): return try: ispecies = self.lspecies.index(species) except ValueError: print "Species not found in Dust.dat." return fn = os.path.join(cc.path.mopac, self.lfilenames[ispecies]) sd = self.lspec_dens[ispecies] if fn[-9:] == ".particle": part_file = DataIO.readFile(filename=fn, delimiter=" ") wav = array([float(q[0]) for q in part_file if len(q) == 4]) kappa = [ array([float(q[1]) for q in part_file if len(q) == 4]), array([float(q[2]) for q in part_file if len(q) == 4]), array([float(q[3]) for q in part_file if len(q) == 4]), ] else: part_file = DataIO.readCols(filename=fn) wav = part_file[0] kappa = part_file[1:] self.spec_dens[species] = sd self.fns[species] = fn self.waves[species] = wav self.kappas[species] = kappa self.qext_a[species] = array(kappa) * 4 / 3.0 * sd
def readAnalyse(self, star): ''' Reads the output of the analyse routine performed. @keyword star: Star object containing the chemistry model @type star: Star() @return: Dictionary containing the analyse output for every molecule, eg analyse['SiO']. The analyse radius is also included (analyse['radius']). @rtype: dict() ''' #- Read in analyse.out filename = os.path.join(cc.path.cout,'models',\ star['LAST_CHEMISTRY_MODEL'],'analyse.out') data = DataIO.readFile(filename) data = [x.split() for x in data] #- Initialise output dictionary analyse = dict() #- Determine and save routine radius radius = float(data[0][-2]) index = np.where([len(i)==2 for i in data])[0] analyse['radius'] = radius #- Save analyse routine output in dictionary per molecule for ii in range(len(index[:-1])): name = data[index[ii]][1][1:] analyse[name] = dict() analyse[name]['MAIN'] = data[index[ii]+1:index[ii+1]-1] analyse[name]['DRATE'] = data[index[ii+1]-1][1] analyse[name]['PRATE'] = data[index[ii+1]-1][3] return analyse
def changeKey(k,v,data=None,fn=None): ''' Update an ALI inputfile with new information. Takes an input key and value. The file is searched for the key, and the value is inserted on the next line. The content is then returned. This method does not save the file. @param k: The unique input key word for which the ALI inputfile is searched. @type k: str @param v: The value inserted on the next line after key. Must be a formatted string; no formatting is done here. @type v: str @keyword data: The data, ie a file read by readFile with delimiter set to '' A filename must be given if data is None. (default: None) @type data: list[str] @keyword fn: The ALI input filename. Only used if data is None. (default: None) @type fn: str @return: The data as read from a file or as adapted from the original @rtype: list[str] ''' if data is None: data = DataIO.readFile(filename=fn,delimiter=None,replace_spaces=0) data = [line.replace('\n','') for line in data] i = DataIO.findKey(0,data,k) data[i+1] = v return data
def readAnalyse(self, star): ''' Reads the output of the analyse routine performed. @keyword star: Star object containing the chemistry model @type star: Star() @return: Dictionary containing the analyse output for every molecule, eg analyse['SiO']. The analyse radius is also included (analyse['radius']). @rtype: dict() ''' #- Read in analyse.out filename = os.path.join(cc.path.cout,'models',\ star['LAST_CHEMISTRY_MODEL'],'analyse.out') data = DataIO.readFile(filename) data = [x.split() for x in data] #- Initialise output dictionary analyse = dict() #- Determine and save routine radius radius = float(data[0][-2]) index = np.where([len(i) == 2 for i in data])[0] analyse['radius'] = radius #- Save analyse routine output in dictionary per molecule for ii in range(len(index[:-1])): name = data[index[ii]][1][1:] analyse[name] = dict() analyse[name]['MAIN'] = data[index[ii] + 1:index[ii + 1] - 1] analyse[name]['DRATE'] = data[index[ii + 1] - 1][1] analyse[name]['PRATE'] = data[index[ii + 1] - 1][3] return analyse
def read(self): ''' Read the Lamda file, including molecular spectroscopy and collision rates. Each level and transition is stored as an index, following the prescription of MolReader and CollisReader. ''' #-- Read the files lines, and set the single number properties. d = DataIO.readFile(self.fn) self['pars'] = dict() pars = ['molecule','mol_weight','ny'] dtypes = [str,float,int] indices = [1,3,5] for i,p,dt in zip(indices,pars,dtypes): self['pars'][p] = dt(d[i].split()[0]) #-- Read the levels and their properties. Swap columns 1 and 2 to match # MlineReader's format. d1 = np.genfromtxt(self.fn,skip_header=7,max_rows=self['pars']['ny'],\ dtype='i8,f8,f8',usecols=(0,2,1),\ names=['index','weight','energy']) self['level'] = d1 #-- Determine the index from ny and preset lines index = 7 + self['pars']['ny'] + 1 self['pars']['nline'] = int(d[index].split()[0]) #-- Read the transitions and their properties. Swap columns 3 and 4 to # match MlineReader's format. d2 = np.genfromtxt(self.fn,usecols=[0,1,2,4,3],dtype='i8,i8,i8,f8,f8',\ skip_header=index+2,max_rows=self['pars']['nline'],\ names=['index','lup','llow','frequency','einsteinA']) self['trans'] = d2 #-- Continue single line parameters. index += 1 + self['pars']['nline'] + 2 self['pars']['npartners'] = int(d[index].split()[0]) index += 2 self['pars']['partners'] = d[index:index+self['pars']['npartners']] index += self['pars']['npartners'] + 1 self['pars']['ncoll_trans'] = int(d[index].split()[0]) index += 2 self['pars']['ncoll_temp'] = int(d[index].split()[0]) index += 2 self['coll_temp'] = np.array(d[index].split(),dtype=float) #-- Read the collision rates. d3 = np.genfromtxt(self.fn,usecols=[0,1,2],dtype='i8,i8,i8',\ skip_header=index+2,names=['index','lup','llow']) d4 = np.genfromtxt(self.fn,skip_header=index+2,\ usecols=range(3,3+self['pars']['ncoll_temp'])) dtype = [('index',int),('lup',int),('llow',int),('rates',np.ndarray)] self['coll_trans'] = np.empty(shape=(self['pars']['ncoll_trans'],),\ dtype=dtype) self['coll_trans']['index'] = d3['index'] self['coll_trans']['lup'] = d3['lup'] self['coll_trans']['llow'] = d3['llow'] for i in range(self['pars']['ncoll_trans']): self['coll_trans']['rates'][i] = d4[i,:]
def __init__(self,path_gastronoom='runTest',vic=None,sphinx=0,\ replace_db_entry=0,cool_db=None,ml_db=None,sph_db=None,\ skip_cooling=0,recover_sphinxfiles=0,\ new_entries=[]): """ Initializing an instance of a GASTRoNOoM modeling session. A single cooling model and a given set of molecules and transitions are calculated here or are retrieved from the databases. @keyword path_gastronoom: modeling folder in GASTRoNOoM home (default: 'runTest') @type path_gastronoom: string @keyword vic: the vic manager for running sphinx models on VIC3 (default: None) @type vic: Vic() @keyword sphinx: Running Sphinx? (default: 0) @type sphinx: bool @keyword replace_db_entry: replace an entry in the databases with a newly calculated model with a new model id (e.g. if some general data not included in the inputfiles is changed) (default: 0) @type replace_db_entry: bool @keyword new_entries: The new model_ids when replace_db_entry is 1 of other models in the grid. These are not replaced! (default: []) @type new_entries: list[str] @keyword skip_cooling: Skip running cooling in case a model is not found in the database, for instance if it is already known that the model will fail (default: 0) @type skip_cooling: bool @keyword recover_sphinxfiles: Try to recover sphinx files from the disk in case they were correctly calculated, but not saved to the database for one reason or another. (default: 0) @type recover_sphinxfiles: bool @keyword cool_db: the cooling database (default: None) @type cool_db: Database() @keyword ml_db: the mline database (default: None) @type ml_db: Database() @keyword sph_db: the sphinx database (default: None) @type sph_db: Database() """ super(Gastronoom,self).__init__(code='GASTRoNOoM',\ path=path_gastronoom,\ replace_db_entry=replace_db_entry,\ new_entries=new_entries) #-- Convenience path cc.path.gout = os.path.join(cc.path.gastronoom,self.path) self.vic = vic self.trans_in_progress = [] self.sphinx = sphinx cool_keys = os.path.join(cc.path.aux,'Input_Keywords_Cooling.dat') ml_keys = os.path.join(cc.path.aux,'Input_Keywords_Mline.dat') sph_keys = os.path.join(cc.path.aux,'Input_Keywords_Sphinx.dat') self.cooling_keywords = [line.strip() for line in DataIO.readFile(cool_keys) if line] self.mline_keywords = [line.strip() for line in DataIO.readFile(ml_keys) if line] self.sphinx_keywords = [line.strip() for line in DataIO.readFile(sph_keys) if line] DataIO.testFolderExistence(os.path.join(cc.path.gout,'data_for_mcmax')) self.trans_bools = [] self.mline_done = False self.cool_done = False self.cooling_molec_keys = ['ENHANCE_ABUNDANCE_FACTOR',\ 'ABUNDANCE_FILENAME',\ 'NUMBER_INPUT_ABUNDANCE_VALUES',\ 'KEYWORD_TABLE','MOLECULE_TABLE',\ 'ISOTOPE_TABLE'] self.no_ab_molecs = ['12C16O','13C16O','1H1H16O','p1H1H16O',\ '1H1H17O','p1H1H17O','1H1H18O','p1H1H18O'] #- Read standard input file with all parameters that should be included filename = os.path.join(cc.path.aux,'inputGASTRoNOoM.dat') self.standard_inputfile = DataIO.readDict(filename,\ comment_chars=['#','!']) self.skip_cooling = skip_cooling self.recover_sphinxfiles = recover_sphinxfiles self.cool_db = cool_db self.ml_db = ml_db self.sph_db = sph_db
def __init__(self,star_name='model',inputfilename=None,\ path='codeJun2010',code='GASTRoNOoM'): """ Initializing an instance of PlottingSession. @keyword star_name: name of the star from Star.dat, use default only when never using any star model specific things (default: "model") @type star_name: string @keyword path: Output modeling folder in code home folder (default: 'codeJun2010') @type path: string @keyword inputfilename: name of inputfile that is also copied to the output folder of the plots, if None nothing is copied (default: None) @type inputfilename: string @keyword code: the modeling code (default: GASTRoNOoM) @type code: string """ self.inputfilename = inputfilename self.star_name = star_name self.star_index = DataIO.getInputData(path=cc.path.usr)\ .index(self.star_name) self.star_name_plots = DataIO.getInputData(path=cc.path.usr, keyword='STAR_NAME_PLOTS',\ remove_underscore=1,\ rindex=self.star_index) #-- Can't use convenience paths here through cc.path, because the # module is not code specific. Within a single pything session, there # may be multiple instances of PlottingSession self.path = path fn_mcm = os.path.join(cc.path.aux, 'Mutable_Parameters_MCMax.dat') self.mutable_mcmax = [ line[0] for line in DataIO.readFile(fn_mcm, delimiter=' ') if ''.join(line).strip() ] self.mutable_mcmax = [ line for line in self.mutable_mcmax if line[0] != '#' ] fn_gas = os.path.join(cc.path.aux, 'Mutable_Parameters_GASTRoNOoM.dat') self.mutable_gastronoom = [line[0] for line in DataIO.readFile(fn_gas,\ delimiter=' ') if ''.join(line).strip()] self.mutable_gastronoom = [ line for line in self.mutable_gastronoom if line[0] != '#' ] self.mutable = self.mutable_mcmax + self.mutable_gastronoom self.plot_id = 'plot_%.4i-%.2i-%.2ih%.2i-%.2i-%.2i' \ %(gmtime()[0],gmtime()[1],gmtime()[2],\ gmtime()[3],gmtime()[4],gmtime()[5]) self.code = code #-- Folder management and copying inputfile to plot output folder pout = os.path.join(getattr(cc.path,self.code.lower()),self.path,\ 'stars') pstar = os.path.join(pout, self.star_name) self.pplot = os.path.join(pstar, self.plot_id) for pp in [pout, pstar, self.pplot]: DataIO.testFolderExistence(pp) if self.inputfilename <> None: ipfn = os.path.split(self.inputfilename)[1] newf = os.path.join(self.pplot, ipfn) subprocess.call(['cp %s %s' % (self.inputfilename, newf)], shell=True)
def makeJobFile(self): ''' Make the job file that will run the loop on VIC3 and copy the cooling and mline output to VIC3. @return: to be printed strings once all the copying is done, which shows how many transitions are being calculated for which sphinx model id @rtype: list[string] ''' model_id = self.models[self.current_model] vic_server = '*****@*****.**'%self.account jobfiles = [] printing = [] for model_id_sphinx in self.sphinx_model_ids[self.current_model]: these_trans = [trans for trans in self.transitions[self.current_model] if trans.getModelId() == model_id_sphinx] models_in_job = (int(log10(len(these_trans))))**2 if not models_in_job: models_in_job = 1 job_number = len(these_trans)%models_in_job==0.0 \ and len(these_trans)/models_in_job \ or int(len(these_trans)/models_in_job)+1 #- job_number: this is the number of jobs you want to queue job_number = job_number/8+1 time_per_job = self.time_per_sphinx*models_in_job walltimestring = '%.2i:00:00'%(int(time_per_job/60)+1) #- Create job file jobfile = DataIO.readFile(os.path.join(cc.path.gastronoom,\ 'vic_job_example.sh')) new_jobfile = [] for line in jobfile: #if line.find('#PBS -l nodes=1:ppn=8') != -1: # new_line = line.replace('ppn=8','ppn=%i'%) if line.split('=')[0].find('#PBS -l walltime') != -1: new_line = '='.join([line.split('=')[0],walltimestring]) elif line.split('=')[0].find('export COCODEHOME') != -1: new_line = line.replace('vsc30226',self.account)\ .replace('/302/','/%s/'%self.disk) elif line.split('=')[0].find('export COCODEDATA') != -1: new_line = '='.join([line.split('=')[0],\ os.path.join(line.split('=')[1],model_id+'_'+\ str(self.current_model)+'/')])\ .replace('vsc30226',self.account)\ .replace('/302/','/%s/'%self.disk) elif line.find('for i in $(seq 1 1)') != -1: new_line = 'for i in $(seq 1 %i)'%models_in_job elif line.split('=')[0].find('export MODELNUMBER') != -1: new_line = '='.join([line.split('=')[0],line.split('=')[1]\ .replace('model_id',model_id_sphinx)]) else: new_line = line new_jobfile.append(new_line) #- Save job file, change permission and copy to VIC local_folder = os.path.join(cc.path.gastronoom,\ self.path,'models',model_id_sphinx) jobfilename_vic = '/user/leuven/'+self.disk+'/' + self.account + \ '/COCode/vic_job_' + model_id_sphinx + '.sh' jobfilename_local = os.path.join(local_folder,'vic_input',\ 'vic_job_%s.sh'%model_id_sphinx) DataIO.writeFile(jobfilename_local,new_jobfile) subprocess.call(['chmod +x %s'%jobfilename_local],shell=True) subprocess.call(['scp %s %s:%s'%(jobfilename_local,vic_server,\ jobfilename_vic)],shell=True) jobfiles.append((jobfilename_vic,job_number)) #- Make the output folder on VIC vic_folder = '/data/leuven/%s/%s/COCode/output/%s/'\ %(self.disk,self.account,model_id_sphinx) subprocess.call('ssh %s mkdir %s'%(vic_server,vic_folder),\ shell=True) #-copy required GASTRoNOoM files, molecule specific. these_molecules = set(['sampling'] + \ [trans.molecule.molecule for trans in these_trans]) to_be_copied = ['coolfgr*','input%s.dat'%model_id_sphinx] to_be_copied.extend(['cool*_%s.dat'%molec for molec in these_molecules]) to_be_copied.extend(['ml*_%s.dat'%molec for molec in these_molecules if molec != 'sampling']) for filecopy in to_be_copied: subprocess.call(['scp %s %s:%s.'\ %(os.path.join(local_folder,filecopy),\ vic_server,vic_folder)], shell=True) #- number of nodes*number of cpus=amount of times to queue it printing.append('Running %i jobs with %i models each for ID %s.' \ %(job_number*7, models_in_job,model_id_sphinx)) #- Create the run-jobs file. runjobsfile = DataIO.readFile(os.path.join(cc.path.gastronoom,\ 'vic_run_jobs_example.sh')) new_runjobsfile = [] for i,job in enumerate(jobfiles): for line in runjobsfile: if line.find('#!/bin/bash -l') != -1 and i == 0: new_line = line elif line.find('cd COCode') != -1 and i == 0: new_line = 'cd /user/leuven/'+self.disk+'/'+ self.account+\ '/COCode/' elif line.find('module load worker') != -1 and i == 0: new_line = line elif line.find('for i in $(seq 1 1) ;') != -1: new_line = 'for i in $(seq 1 %i) ;' %(job[1]) elif line.find('do wsub -A dummy -t 1-8 -batch') != -1: new_line = line.replace('vic_job_example.sh',\ os.path.split(job[0])[1]) if not self.credits_acc is None: new_line = new_line.replace('-A dummy',\ '-A %s'%self.credits_acc) else: new_line = new_line.replace('-A dummy ','') elif line.find('done') != -1: new_line = line else: new_line = '' new_runjobsfile.append(new_line) #- Run-jobs file: Write, change permission and copy to VIC runjobsfilename_local = os.path.join(cc.path.gastronoom,self.path,\ 'models',model_id,'vic_input',\ 'vic_run_jobs_%s_%s.sh'\ %(model_id,\ str(self.current_model))) runjobsfilename_vic = '/user/leuven/%s/%s/COCode/vic_run_jobs_%s_%s.sh'\ %(self.disk,self.account,model_id,\ str(self.current_model)) DataIO.writeFile(runjobsfilename_local,new_runjobsfile) subprocess.call(['chmod +x %s'%runjobsfilename_local],shell=True) subprocess.call(['scp %s %s:%s'\ %(runjobsfilename_local,vic_server,\ runjobsfilename_vic)],shell=True) return printing
def makeJobFile(self): ''' Make the job file that will run the loop on VIC3 and copy the cooling and mline output to VIC3. @return: to be printed strings once all the copying is done, which shows how many transitions are being calculated for which sphinx model id @rtype: list[string] ''' model_id = self.models[self.current_model] vic_server = '*****@*****.**' % self.account jobfiles = [] printing = [] for model_id_sphinx in self.sphinx_model_ids[self.current_model]: these_trans = [ trans for trans in self.transitions[self.current_model] if trans.getModelId() == model_id_sphinx ] models_in_job = (int(log10(len(these_trans))))**2 if not models_in_job: models_in_job = 1 job_number = len(these_trans)%models_in_job==0.0 \ and len(these_trans)/models_in_job \ or int(len(these_trans)/models_in_job)+1 #- job_number: this is the number of jobs you want to queue job_number = job_number / 8 + 1 time_per_job = self.time_per_sphinx * models_in_job walltimestring = '%.2i:00:00' % (int(time_per_job / 60) + 1) #- Create job file jobfile = DataIO.readFile(os.path.join(cc.path.gastronoom,\ 'vic_job_example.sh')) new_jobfile = [] for line in jobfile: #if line.find('#PBS -l nodes=1:ppn=8') != -1: # new_line = line.replace('ppn=8','ppn=%i'%) if line.split('=')[0].find('#PBS -l walltime') != -1: new_line = '='.join([line.split('=')[0], walltimestring]) elif line.split('=')[0].find('export COCODEHOME') != -1: new_line = line.replace('vsc30226',self.account)\ .replace('/302/','/%s/'%self.disk) elif line.split('=')[0].find('export COCODEDATA') != -1: new_line = '='.join([line.split('=')[0],\ os.path.join(line.split('=')[1],model_id+'_'+\ str(self.current_model)+'/')])\ .replace('vsc30226',self.account)\ .replace('/302/','/%s/'%self.disk) elif line.find('for i in $(seq 1 1)') != -1: new_line = 'for i in $(seq 1 %i)' % models_in_job elif line.split('=')[0].find('export MODELNUMBER') != -1: new_line = '='.join([line.split('=')[0],line.split('=')[1]\ .replace('model_id',model_id_sphinx)]) else: new_line = line new_jobfile.append(new_line) #- Save job file, change permission and copy to VIC local_folder = os.path.join(cc.path.gastronoom,\ self.path,'models',model_id_sphinx) jobfilename_vic = '/user/leuven/'+self.disk+'/' + self.account + \ '/COCode/vic_job_' + model_id_sphinx + '.sh' jobfilename_local = os.path.join(local_folder,'vic_input',\ 'vic_job_%s.sh'%model_id_sphinx) DataIO.writeFile(jobfilename_local, new_jobfile) subprocess.call(['chmod +x %s' % jobfilename_local], shell=True) subprocess.call(['scp %s %s:%s'%(jobfilename_local,vic_server,\ jobfilename_vic)],shell=True) jobfiles.append((jobfilename_vic, job_number)) #- Make the output folder on VIC vic_folder = '/data/leuven/%s/%s/COCode/output/%s/'\ %(self.disk,self.account,model_id_sphinx) subprocess.call('ssh %s mkdir %s'%(vic_server,vic_folder),\ shell=True) #-copy required GASTRoNOoM files, molecule specific. these_molecules = set(['sampling'] + \ [trans.molecule.molecule for trans in these_trans]) to_be_copied = ['coolfgr*', 'input%s.dat' % model_id_sphinx] to_be_copied.extend( ['cool*_%s.dat' % molec for molec in these_molecules]) to_be_copied.extend([ 'ml*_%s.dat' % molec for molec in these_molecules if molec != 'sampling' ]) for filecopy in to_be_copied: subprocess.call(['scp %s %s:%s.'\ %(os.path.join(local_folder,filecopy),\ vic_server,vic_folder)], shell=True) #- number of nodes*number of cpus=amount of times to queue it printing.append('Running %i jobs with %i models each for ID %s.' \ %(job_number*7, models_in_job,model_id_sphinx)) #- Create the run-jobs file. runjobsfile = DataIO.readFile(os.path.join(cc.path.gastronoom,\ 'vic_run_jobs_example.sh')) new_runjobsfile = [] for i, job in enumerate(jobfiles): for line in runjobsfile: if line.find('#!/bin/bash -l') != -1 and i == 0: new_line = line elif line.find('cd COCode') != -1 and i == 0: new_line = 'cd /user/leuven/'+self.disk+'/'+ self.account+\ '/COCode/' elif line.find('module load worker') != -1 and i == 0: new_line = line elif line.find('for i in $(seq 1 1) ;') != -1: new_line = 'for i in $(seq 1 %i) ;' % (job[1]) elif line.find('do wsub -A dummy -t 1-8 -batch') != -1: new_line = line.replace('vic_job_example.sh',\ os.path.split(job[0])[1]) if self.credits_acc <> None: new_line = new_line.replace('-A dummy',\ '-A %s'%self.credits_acc) else: new_line = new_line.replace('-A dummy ', '') elif line.find('done') != -1: new_line = line else: new_line = '' new_runjobsfile.append(new_line) #- Run-jobs file: Write, change permission and copy to VIC runjobsfilename_local = os.path.join(cc.path.gastronoom,self.path,\ 'models',model_id,'vic_input',\ 'vic_run_jobs_%s_%s.sh'\ %(model_id,\ str(self.current_model))) runjobsfilename_vic = '/user/leuven/%s/%s/COCode/vic_run_jobs_%s_%s.sh'\ %(self.disk,self.account,model_id,\ str(self.current_model)) DataIO.writeFile(runjobsfilename_local, new_runjobsfile) subprocess.call(['chmod +x %s' % runjobsfilename_local], shell=True) subprocess.call(['scp %s %s:%s'\ %(runjobsfilename_local,vic_server,\ runjobsfilename_vic)],shell=True) return printing
def __init__(self,star_name='model',inputfilename=None,\ path='codeJun2010',code='GASTRoNOoM'): """ Initializing an instance of PlottingSession. @keyword star_name: name of the star from Star.dat, use default only when never using any star model specific things (default: "model") @type star_name: string @keyword path: Output modeling folder in code home folder (default: 'codeJun2010') @type path: string @keyword inputfilename: name of inputfile that is also copied to the output folder of the plots, if None nothing is copied (default: None) @type inputfilename: string @keyword code: the modeling code (default: GASTRoNOoM) @type code: string """ self.inputfilename = inputfilename self.star_name = star_name self.star_index = DataIO.getInputData(path=cc.path.usr)\ .index(self.star_name) self.star_name_plots = DataIO.getInputData(path=cc.path.usr, keyword='STAR_NAME_PLOTS',\ remove_underscore=1,\ rindex=self.star_index) #-- Can't use convenience paths here through cc.path, because the # module is not code specific. Within a single pything session, there # may be multiple instances of PlottingSession self.path = path fn_mcm = os.path.join(cc.path.aux,'Mutable_Parameters_MCMax.dat') self.mutable_mcmax = [line[0] for line in DataIO.readFile(fn_mcm,delimiter=' ') if ''.join(line).strip()] self.mutable_mcmax = [line for line in self.mutable_mcmax if line[0] != '#'] fn_gas = os.path.join(cc.path.aux,'Mutable_Parameters_GASTRoNOoM.dat') self.mutable_gastronoom = [line[0] for line in DataIO.readFile(fn_gas,\ delimiter=' ') if ''.join(line).strip()] self.mutable_gastronoom = [line for line in self.mutable_gastronoom if line[0] != '#'] self.mutable = self.mutable_mcmax + self.mutable_gastronoom self.plot_id = 'plot_%.4i-%.2i-%.2ih%.2i-%.2i-%.2i' \ %(gmtime()[0],gmtime()[1],gmtime()[2],\ gmtime()[3],gmtime()[4],gmtime()[5]) self.code = code #-- Folder management and copying inputfile to plot output folder pout = os.path.join(getattr(cc.path,self.code.lower()),self.path,\ 'stars') pstar = os.path.join(pout,self.star_name) self.pplot = os.path.join(pstar,self.plot_id) for pp in [pout,pstar,self.pplot]: DataIO.testFolderExistence(pp) if self.inputfilename <> None: ipfn = os.path.split(self.inputfilename)[1] newf = os.path.join(self.pplot,ipfn) subprocess.call(['cp %s %s'%(self.inputfilename,newf)],shell=True)
def makeMoleculeFromDb(molec_id,molecule,path_gastronoom='codeSep2010',\ mline_db=None): ''' Make a Molecule() from a database, based on model_id and molec_id. Returns None if the molecule is not available in the database. @param molec_id: the model_id of the molecule @type molec_id: string @param molecule: the short hand name of the molecule @type molecule: string @keyword path_gastronoom: the output path in the ~/GASTRoNOoM/. directory (default: codeSep2010) @type path_gastronoom: string @keyword mline_db: The mline database, which can be passed in case one wants to reduce overhead. Not required though. (default: None) @type mline_db: Database() @return: the molecule with all its information embedded @rtype: Molecule() ''' #-- Convenience path cc.path.gout = os.path.join(cc.path.gastronoom,path_gastronoom) #-- Retrieve cooling id log cooling_log = os.path.join(cc.path.gout,'models',molec_id,'cooling_id.log') if os.path.isfile(cooling_log): model_id = DataIO.readFile(cooling_log)[0] #- ie mline id is the same as model id, the first calced for this id else: model_id = molec_id if mline_db is None: molec_db = Database(os.path.join(cc.path.gout,\ 'GASTRoNOoM_mline_models.db')) else: molec_db = mline_db if not molec_db.has_key(model_id) \ or not molec_db[model_id].has_key(molec_id) \ or not molec_db[model_id][molec_id].has_key(molecule): return None molec_dict = molec_db[model_id][molec_id][molecule].copy() extra_pars = molec_dict['MOLECULE'].split()[1:] for k,v in zip(['ny_low','ny_up','nline','n_impact','n_impact_extra'],\ extra_pars): molec_dict[k] = int(v) for key in ['MOLECULE','CHANGE_DUST_TO_GAS_FOR_ML_SP',\ 'NUMBER_INPUT_ABUNDANCE_VALUES','KEYWORD_TABLE',\ 'MOLECULE_TABLE','ISOTOPE_TABLE']: if molec_dict.has_key(key): del molec_dict[key] molec_dict = dict([(k.lower(),v) for k,v in molec_dict.items()]) molec_dict['path_gastronoom'] = path_gastronoom molec = Molecule(molecule=molecule,**molec_dict) molec.setModelId(molec_id) return molec
def __init__(self,molecule,ny_up=0,ny_low=0,nline=0,n_impact=0,\ n_impact_extra=0,abun_molec=1.0e-10,abun_molec_rinner=1.0e-10,\ abun_molec_re=1.0e-10,rmax_molec=1.,itera=0,lte_request=None,\ use_collis_radiat_switch=0,dust_to_gas_change_ml_sp=0,\ use_no_maser_option=0,use_maser_in_sphinx=1,\ fehler=1e-4,xdex=2.,n_freq=30,start_approx=0,\ use_fraction_level_corr=1,fraction_level_corr=0.8,\ number_level_max_corr=1e-12,\ ratio_12c_to_13c=0,ratio_16o_to_17o=0,ratio_16o_to_18o=0,\ opr=0,r_outer=0,outer_r_mode='MAMON',abundance_filename=None,\ change_fraction_filename=None,set_keyword_change_abundance=0,\ set_keyword_change_temperature=0,enhance_abundance_factor=0,\ new_temperature_filename=None,linelist=0,starfile='',\ path_gastronoom=None): ''' Initiate a Molecule class, setting all values for the allowed transition parameters to zero (by default). @param molecule: shorthand name of the molecule @type molecule: string @keyword ny_up: number of levels in first vibration state v=1 (default: 0) @type ny_up: int @keyword ny_low: number of levels in the ground vibration state v=0 (default: 0) @type ny_low: int @keyword nline: number of allowed transitions in molecule (default: 0) @type nline: int @keyword n_impact: number of depth points in radius mesh (default: 0) @type n_impact: int @keyword n_impact_extra: number of depth points in radius_mesh (< n_impact) used for variable mass-loss (0 if constant mdot) (default: 0) @type n_impact_extra: int @keyword itera: number of iterations in mline for molecule, LTE approximation if zero (default: 0) @type itera: string @keyword abun_molec: molecular abundance at the stellar radius. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec: float @keyword abun_molec_rinner: molecular abundance at inner shell radius. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec_rinner: float @keyword abun_molec_re: molecular abundance at rmax_molec. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec_re: float @keyword rmax_molec: The radius from which the Willacy abundance profiles are used. They are rescaled to abun_molec_re. Default is arbitrary, and used if molecule is co or h2o. (default: 1.) @type rmax_molec: float @keyword use_collis_radiat_switch: in case of unstable mline, such as for para h2o sometimes (default: 0) @type use_collis_radiat_switch: bool @keyword fehler: convergence criterium in mline (default: 1e-4) @type fehler: float @keyword xdex: Controls the distribution of the impact parameters in the interval between R_STAR and R_OUTER. (default: 2.) @type xdex: float @keyword n_freq: Number of frequency points in line profile (default: 30) @type n_freq: int @keyword start_approx: set to 0 when one wants to start with LTE-approx as starting n(NY,N_IMPACT); set to 1 when starting from another model - with same NY, N_IMPACT, ... (default: 0) @type start_approx: bool @keyword use_fraction_level_corr: set to 1 if one wants to put a limit on the level-population correction (BES3). (default: 1) @type use_fraction_level_corr: bool @keyword fraction_level_corr: user-defined fraction for maximum change in level-population correction; useful in case of H2O (default: 0.8) @type fraction_level_corr: float @keyword number_level_max_corr: user-defined level population. Only the level corrections for levels with a higher level population will be used to determine convergence criterion (default: 1e-12) @type number_level_max_corr: float @keyword ratio_12c_to_13c: 12c/13c ratio, only relevant for 13co and other molecules with that isotope (default: 0) @type ratio_12c_to_13c: int @keyword ratio_16o_to_17o: 16o/17o ratio, only relevant for h2_17o and other molecules with that isotope (default: 0) @type ratio_16o_to_17o: int @keyword ratio_16o_to_18o: 16o/18o ratio, only relevant for h2_18o and other molecules with that isotope (default: 0) @type ratio_16o_to_18o: int @keyword opr: ortho-to-para water ratio, only relevant for ph2o, ph2_17o,ph2_18o and other molecules with para h2o (default: 0) @type opr: int @keyword r_outer: the outer radius of the shell for this molecule, 0 if MAMON (default: 0) @type r_outer: float @keyword lte_request: using LTE in mline only (with or without collision rates: determined by itera), if default lte_request is 0 if itera != 0 and 1 if itera ==0 (default: 0) @type lte_request: bool @keyword outer_r_mode: the mode used for calculating r_outer (FIXED or MAMON) (default: 'MAMON') @type outer_r_mode: string @keyword dust_to_gas_change_ml_sp: if 0 not used, otherwise this is an alternative value for the dust-to-gas ratio in mline/sphinx for this molecule and its transitions. (default: 0) @type dust_to_gas_change_ml_sp: float @keyword abundance_filename: if enhance_abundance_factor is not zero, this includes the filename and/or path to the file that includes the profile. (default: None) @type abundance_filename: string @keyword enhance_abundance_factor: if 0 the Willacy abundance profiles are uses, if not zero the abundance_filename is used and scaled with the factor given here. THIS DOES NOT RESCALE ABUNDANCES BY WILLACY! Only used for filename abundances, hence why this parameter also turns this feature on/off (default: 0) @type enhance_abundance_factor: float @keyword set_keyword_change_abundance: Change the abundance calculated in cooling by a radius dependent factor (default: 0) @type set_keyword_change_abundance: bool @keyword change_fraction_filename: the filename of the enhancement factors if set_keyword_change_abundance != 0 (default: None) @type change_fraction_filename: string @keyword set_keyword_change_temperature: Use a different temperature structure in mline and sphinx (default: 0) @type set_keyword_change_temperature: bool @keyword new_temperature_filename: the filename for the temperature structure if set_keyword_change_temperature != 0 (default: None) @type new_temperature_filename: string @keyword use_no_maser_option: Do not allow masers (neg opacs) in mline RT by setting negative line opacs to 1e-60 If use_maser_in_sphinx is on, mline will do a final run including masers anyway to see what would happen if they were inluded by allowing negative opacs for the line profile calculations in sphinx (but not for the convergence in mline). (default: 0) @type use_no_maser_option: bool @keyword use_maser_in_sphinx: When on, does a final mline run including masers, allowing negative opacities. When off, sets the masing line opacities to 1e-60 when writing out the ml3 file. (default: 1) @type use_maser_in_sphinx: bool @keyword linelist: The molecule is created for the LineList module. No radiative information is read from GASTRoNOoM input files. (default: 0) @type linelist: bool @keyword starfile: input filename for a stellar input spectrum (either user defined or from a model atmosphere spectrum) (default: '') @type starfile: str @keyword path_gastronoom: model output folder in the GASTRoNOoM home (default: None) @type path_gastronoom: string ''' self.molecule = str(molecule) self.ny_up = int(ny_up) self.ny_low = int(ny_low) self.nline = int(nline) self.n_impact = int(n_impact) self.n_impact_extra = int(n_impact_extra) self.path_gastronoom = path_gastronoom self.molecule_index = DataIO.getInputData(keyword='TYPE_SHORT',\ filename='Molecule.dat')\ .index(self.molecule) mdata = ['MOLEC_TYPE','NAME_SHORT','NAME_PLOT',\ 'SPEC_INDICES','USE_INDICES_DAT'] attrs = ['molecule_full','molecule_short','molecule_plot',\ 'spec_indices','use_indices_dat'] mfloat = [0,0,0,1,1] for k,a,mf in zip(mdata,attrs,mfloat): setattr(self,a,DataIO.getInputData(keyword=k,make_float=mf,\ filename='Molecule.dat',\ rindex=self.molecule_index,)) self.itera = int(itera) #- lte_request may be undefined, but then it would be faulty input, #- where we do want the code to crash... if self.itera==0 and lte_request is None: self.lte_request = 1 #- Normally u never use lte if taking into account collision rates elif self.itera != 0: self.lte_request = 0 elif self.itera==0 and lte_request is not None: self.lte_request = lte_request self.abun_molec = abun_molec self.abun_molec_rinner = abun_molec_rinner self.abun_molec_re = abun_molec_re self.rmax_molec = rmax_molec self.use_collis_radiat_switch = int(use_collis_radiat_switch) self.ratio_12c_to_13c = ratio_12c_to_13c self.ratio_16o_to_17o = ratio_16o_to_17o self.ratio_16o_to_18o = ratio_16o_to_18o self.opr = opr self.dust_to_gas_change_ml_sp = float(dust_to_gas_change_ml_sp) self.use_no_maser_option = int(use_no_maser_option) self.use_maser_in_sphinx = int(use_maser_in_sphinx) self.fehler = fehler self.xdex = xdex self.n_freq = int(n_freq) self.start_approx = int(start_approx) self.use_fraction_level_corr = int(use_fraction_level_corr) self.fraction_level_corr = fraction_level_corr self.number_level_max_corr = number_level_max_corr #-- Set the molecule inputfiles for abundance and temperature, applying # the path from Path.dat if the file does not exist or the path to the # file is not given. (eg a subfolder might be given, but that works) for k in ['abundance_filename','change_fraction_filename',\ 'new_temperature_filename']: fn = locals()[k] if fn and not (os.path.isfile(fn) and os.path.split(fn)[0]): fn = os.path.join(cc.path.molf,fn) setattr(self,k,fn) else: setattr(self,k,fn) self.enhance_abundance_factor = float(enhance_abundance_factor) self.set_keyword_change_abundance = int(set_keyword_change_abundance) self.set_keyword_change_temperature = \ int(set_keyword_change_temperature) #-- Mainly for plotting purposes: The relative, multiplicative abundance # factor with respect to main isotope (and OPR) is calculated # This does not take into account enhance_abundance_factor! self.abun_factor = self.getAbunFactor() self.outer_r_mode = outer_r_mode if self.outer_r_mode == 'MAMON': self.r_outer = 0 else: self.r_outer = float(r_outer) self.__model_id = None if not linelist: if self.use_indices_dat: tag = '_'.join([self.molecule,str(self.ny_low),\ str(self.ny_up),str(self.nline)]) i = DataIO.getInputData(start_index=4,keyword='MOLECULE',\ filename='Indices.dat').index(tag) fn = DataIO.getInputData(path=cc.path.usr,keyword='RADIAT',\ filename='Indices.dat',start_index=4,\ rindex=i) fn = os.path.join(cc.path.gdata,'radiat_backup',fn) else: fn = os.path.join(cc.path.gdata,'%s_radiat.dat'%self.molecule) self.radiat = RadiatReader.RadiatReader(fn=fn,nline=self.nline, ny=self.ny_up+self.ny_low) if self.spec_indices: if self.use_indices_dat: f = DataIO.getInputData(path=cc.path.usr,start_index=4,\ keyword='INDICES',rindex=i,\ filename='Indices.dat') filename = os.path.join(cc.path.gdata,'indices_backup',f) else: filename = os.path.join(cc.path.gdata,\ '{}_indices.dat'.format(self.molecule)) rf = DataIO.readFile(filename,' ') self.radiat_indices = [[int(i) for i in line] for line in rf] else: self.radiat = None self.radiat_indices = None self.starfile = starfile self.mline = None
def __init__(self,star_name='model',inputfilename=None,\ path='',code='GASTRoNOoM',fn_add_star=1): """ Initializing an instance of PlottingSession. @keyword star_name: name of the star from Star.dat, use default only when never using any star model specific things (default: "model") @type star_name: string @keyword path: Output modeling folder in code home folder (default: '') @type path: string @keyword inputfilename: name of inputfile that is also copied to the output folder of the plots, if None nothing is copied (default: None) @type inputfilename: string @keyword code: the modeling code (default: GASTRoNOoM) @type code: string @keyword fn_add_star: Add the star name to the requested plot filename. Only relevant if fn_plt is given in a sub method. (default: 1) @type fn_add_star: bool """ self.inputfilename = inputfilename self.star_name = star_name self.star_index = DataIO.getInputData( path=cc.path.usr).index(star_name) self.star_name_plots = DataIO.getInputData(path=cc.path.usr, keyword='STAR_NAME_PLOTS',\ remove_underscore=1,\ rindex=self.star_index) #-- Can't use convenience paths here through cc.path, because the # module is not code specific. Within a single python session, there # may be multiple instances of PlottingSession if not path: print('Warning! %s model output folder not set.' % code) self.path = path fn_mcm = os.path.join(cc.path.aux, 'Mutable_Parameters_MCMax.dat') self.mutable_mcmax = [ line[0] for line in DataIO.readFile(fn_mcm, delimiter=' ') if ''.join(line).strip() ] self.mutable_mcmax = [ line for line in self.mutable_mcmax if line[0] != '#' ] fn_gas = os.path.join(cc.path.aux, 'Mutable_Parameters_GASTRoNOoM.dat') self.mutable_gastronoom = [line[0] for line in DataIO.readFile(fn_gas,\ delimiter=' ') if ''.join(line).strip()] self.mutable_gastronoom = [ line for line in self.mutable_gastronoom if line[0] != '#' ] self.mutable = self.mutable_mcmax + self.mutable_gastronoom self.plot_id = 'plot_%.4i-%.2i-%.2ih%.2i-%.2i-%.2i' \ %(gmtime()[0],gmtime()[1],gmtime()[2],\ gmtime()[3],gmtime()[4],gmtime()[5]) self.code = code #-- Folder management and copying inputfile to plot output folder pout = os.path.join(getattr(cc.path,self.code.lower()),self.path,\ 'stars') pstar = os.path.join(pout, self.star_name) self.pplot = os.path.join(pstar, self.plot_id) for pp in [pout, pstar]: DataIO.testFolderExistence(pp) self.fn_add_star = fn_add_star
def __init__(self,molecule,ny_up=0,ny_low=0,nline=0,n_impact=0,\ n_impact_extra=0,abun_molec=1.0e-10,abun_molec_rinner=1.0e-10,\ abun_molec_re=1.0e-10,rmax_molec=1.,itera=0,lte_request=None,\ use_collis_radiat_switch=0,dust_to_gas_change_ml_sp=0,\ ratio_12c_to_13c=0,ratio_16o_to_17o=0,ratio_16o_to_18o=0,\ opr=0,r_outer=0,outer_r_mode='MAMON',abundance_filename=None,\ change_fraction_filename=None,set_keyword_change_abundance=0,\ set_keyword_change_temperature=0,enhance_abundance_factor=0,\ new_temperature_filename=None,linelist=0,starfile=''): ''' Initiate a Molecule class, setting all values for the allowed transition parameters to zero (by default). @param molecule: shorthand name of the molecule @type molecule: string @keyword ny_up: number of levels in first vibration state v=1 (default: 0) @type ny_up: int @keyword ny_low: number of levels in the ground vibration state v=0 (default: 0) @type ny_low: int @keyword nline: number of allowed transitions in molecule (default: 0) @type nline: int @keyword n_impact: number of depth points in radius mesh (default: 0) @type n_impact: int @keyword n_impact_extra: number of depth points in radius_mesh (< n_impact) used for variable mass-loss (0 if constant mdot) (default: 0) @type n_impact_extra: int @keyword itera: number of iterations in mline for molecule, LTE approximation if zero (default: 0) @type itera: string @keyword abun_molec: molecular abundance at the stellar radius. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec: float @keyword abun_molec_rinner: molecular abundance at inner shell radius. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec_rinner: float @keyword abun_molec_re: molecular abundance at rmax_molec. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec_re: float @keyword rmax_molec: The radius from which the Willacy abundance profiles are used. They are rescaled to abun_molec_re. Default is arbitrary, and used if molecule is co or h2o. (default: 1.) @type rmax_molec: float @keyword use_collis_radiat_switch: in case of unstable mline, such as for para h2o sometimes (default: 0) @type use_collis_radiat_switch: bool @keyword ratio_12c_to_13c: 12c/13c ratio, only relevant for 13co and other molecules with that isotope (default: 0) @type ratio_12c_to_13c: int @keyword ratio_16o_to_17o: 16o/17o ratio, only relevant for h2_17o and other molecules with that isotope (default: 0) @type ratio_16o_to_17o: int @keyword ratio_16o_to_18o: 16o/18o ratio, only relevant for h2_18o and other molecules with that isotope (default: 0) @type ratio_16o_to_18o: int @keyword opr: ortho-to-para water ratio, only relevant for ph2o, ph2_17o,ph2_18o and other molecules with para h2o (default: 0) @type opr: int @keyword r_outer: the outer radius of the shell for this molecule, 0 if MAMON (default: 0) @type r_outer: float @keyword lte_request: using LTE in mline only (with or without collision rates: determined by itera), if default lte_request is 0 if itera != 0 and 1 if itera ==0 (default: 0) @type lte_request: bool @keyword outer_r_mode: the mode used for calculating r_outer (FIXED or MAMON) (default: 'MAMON') @type outer_r_mode: string @keyword dust_to_gas_change_ml_sp: if 0 not used, otherwise this is an alternative value for the dust-to-gas ratio in mline/sphinx for this molecule and its transitions. (default: 0) @type dust_to_gas_change_ml_sp: float @keyword abundance_filename: if enhance_abundance_factor is not zero, this includes the filename and/or path to the file that includes the profile. (default: None) @type abundance_filename: string @keyword enhance_abundance_factor: if 0 the Willacy abundance profiles are uses, if not zero the abundance_filename is used and scaled with the factor given here. THIS DOES NOT RESCALE ABUNDANCES BY WILLACY! Only used for filename abundances, hence why this parameter also turns this feature on/off (default: 0) @type enhance_abundance_factor: float @keyword set_keyword_change_abundance: Change the abundance calculated in cooling by a radius dependent factor (default: 0) @type set_keyword_change_abundance: bool @keyword change_fraction_filename: the filename of the enhancement factors if set_keyword_change_abundance != 0 (default: None) @type change_fraction_filename: string @keyword set_keyword_change_temperature: Use a different temperature structure in mline and sphinx (default: 0) @type set_keyword_change_temperature: bool @keyword new_temperature_filename: the filename for the temperature structure if set_keyword_change_temperature != 0 (default: None) @type new_temperature_filename: string @keyword linelist: The molecule is created for the LineList module. No radiative information is read from GASTRoNOoM input files. (default: 0) @type linelist: bool @keyword starfile: input filename for a stellar input spectrum (either user defined or from a model atmosphere spectrum) (default: '') @type starfile: str ''' self.molecule = str(molecule) self.ny_up = int(ny_up) self.ny_low = int(ny_low) self.nline = int(nline) self.n_impact = int(n_impact) self.n_impact_extra = int(n_impact_extra) self.molecule_index = DataIO.getInputData(keyword='TYPE_SHORT',\ filename='Molecule.dat')\ .index(self.molecule) mdata = ['MOLEC_TYPE','NAME_SHORT','NAME_PLOT',\ 'SPEC_INDICES','USE_INDICES_DAT'] attrs = ['molecule_full','molecule_short','molecule_plot',\ 'spec_indices','use_indices_dat'] mfloat = [0, 0, 0, 1, 1] for k, a, mf in zip(mdata, attrs, mfloat): setattr(self,a,DataIO.getInputData(keyword=k,make_float=mf,\ filename='Molecule.dat',\ rindex=self.molecule_index,)) self.itera = int(itera) #- lte_request may be undefined, but then it would be faulty input, #- where we do want the code to crash... if self.itera == 0 and lte_request is None: self.lte_request = 1 #- Normally u never use lte if taking into account collision rates elif self.itera != 0: self.lte_request = 0 elif self.itera == 0 and lte_request is not None: self.lte_request = lte_request self.abun_molec = abun_molec self.abun_molec_rinner = abun_molec_rinner self.abun_molec_re = abun_molec_re self.rmax_molec = rmax_molec self.use_collis_radiat_switch = use_collis_radiat_switch self.ratio_12c_to_13c = ratio_12c_to_13c self.ratio_16o_to_17o = ratio_16o_to_17o self.ratio_16o_to_18o = ratio_16o_to_18o self.opr = opr self.dust_to_gas_change_ml_sp = float(dust_to_gas_change_ml_sp) self.enhance_abundance_factor = float(enhance_abundance_factor) self.abundance_filename = abundance_filename #-- Mainly for plotting purposes: The relative, multiplicative abundance # factor with respect to main isotope (and OPR) is calculated # This does not take into account enhance_abundance_factor! self.abun_factor = self.getAbunFactor() self.outer_r_mode = outer_r_mode if self.outer_r_mode == 'MAMON': self.r_outer = 0 else: self.r_outer = float(r_outer) self.set_keyword_change_abundance = int(set_keyword_change_abundance) self.change_fraction_filename = change_fraction_filename self.set_keyword_change_temperature = \ int(set_keyword_change_temperature) self.new_temperature_filename = new_temperature_filename self.__model_id = None if not linelist: if self.use_indices_dat: tag = '_'.join([self.molecule,str(self.ny_low),\ str(self.ny_up),str(self.nline)]) i = DataIO.getInputData(start_index=4,keyword='MOLECULE',\ filename='Indices.dat').index(tag) self.indices_index = i self.radiat = Radiat.Radiat(molecule=self) if self.spec_indices: if self.use_indices_dat: f = DataIO.getInputData(path=cc.path.usr,start_index=4,\ keyword='INDICES',rindex=i,\ filename='Indices.dat') filename = os.path.join(cc.path.gdata, 'indices_backup', f) else: filename = os.path.join(cc.path.gdata,\ '%s_indices.dat'%self.molecule) rf = DataIO.readFile(filename, ' ') self.radiat_indices = [[int(i) for i in line] for line in rf] else: self.radiat = None self.radiat_indices = None self.starfile = starfile
def __init__(self,path_gastronoom='runTest',vic=None,sphinx=0,\ replace_db_entry=0,cool_db=None,ml_db=None,sph_db=None,\ skip_cooling=0,recover_sphinxfiles=0,\ new_entries=[]): """ Initializing an instance of a GASTRoNOoM modeling session. A single cooling model and a given set of molecules and transitions are calculated here or are retrieved from the databases. @keyword path_gastronoom: modeling folder in GASTRoNOoM home (default: 'runTest') @type path_gastronoom: string @keyword vic: the vic manager for running sphinx models on VIC3 (default: None) @type vic: Vic() @keyword sphinx: Running Sphinx? (default: 0) @type sphinx: bool @keyword replace_db_entry: replace an entry in the databases with a newly calculated model with a new model id (e.g. if some general data not included in the inputfiles is changed) (default: 0) @type replace_db_entry: bool @keyword new_entries: The new model_ids when replace_db_entry is 1 of other models in the grid. These are not replaced! (default: []) @type new_entries: list[str] @keyword skip_cooling: Skip running cooling in case a model is not found in the database, for instance if it is already known that the model will fail (default: 0) @type skip_cooling: bool @keyword recover_sphinxfiles: Try to recover sphinx files from the disk in case they were correctly calculated, but not saved to the database for one reason or another. (default: 0) @type recover_sphinxfiles: bool @keyword cool_db: the cooling database (default: None) @type cool_db: Database() @keyword ml_db: the mline database (default: None) @type ml_db: Database() @keyword sph_db: the sphinx database (default: None) @type sph_db: Database() """ super(Gastronoom,self).__init__(code='GASTRoNOoM',\ path=path_gastronoom,\ replace_db_entry=replace_db_entry,\ new_entries=new_entries) #-- Convenience path cc.path.gout = os.path.join(cc.path.gastronoom, self.path) self.vic = vic self.trans_in_progress = [] self.sphinx = sphinx cool_keys = os.path.join(cc.path.aux, 'Input_Keywords_Cooling.dat') ml_keys = os.path.join(cc.path.aux, 'Input_Keywords_Mline.dat') sph_keys = os.path.join(cc.path.aux, 'Input_Keywords_Sphinx.dat') self.cooling_keywords = [ line.strip() for line in DataIO.readFile(cool_keys) if line ] self.mline_keywords = [ line.strip() for line in DataIO.readFile(ml_keys) if line ] self.sphinx_keywords = [ line.strip() for line in DataIO.readFile(sph_keys) if line ] DataIO.testFolderExistence(os.path.join(cc.path.gout, 'data_for_mcmax')) self.trans_bools = [] self.mline_done = False self.cool_done = False self.cooling_molec_keys = ['ENHANCE_ABUNDANCE_FACTOR',\ 'ABUNDANCE_FILENAME',\ 'NUMBER_INPUT_ABUNDANCE_VALUES',\ 'KEYWORD_TABLE','MOLECULE_TABLE',\ 'ISOTOPE_TABLE'] self.no_ab_molecs = ['12C16O','13C16O','1H1H16O','p1H1H16O',\ '1H1H17O','p1H1H17O','1H1H18O','p1H1H18O'] #- Read standard input file with all parameters that should be included filename = os.path.join(cc.path.aux, 'inputGASTRoNOoM.dat') self.standard_inputfile = DataIO.readDict(filename,\ comment_chars=['#','!']) self.skip_cooling = skip_cooling self.recover_sphinxfiles = recover_sphinxfiles self.cool_db = cool_db self.ml_db = ml_db self.sph_db = sph_db
def makeMoleculeFromDb(molec_id,molecule,path_gastronoom='codeSep2010',\ mline_db=None): ''' Make a Molecule() from a database, based on model_id and molec_id. Returns None if the molecule is not available in the database. @param molec_id: the model_id of the molecule @type molec_id: string @param molecule: the short hand name of the molecule @type molecule: string @keyword path_gastronoom: the output path in the ~/GASTRoNOoM/. directory (default: codeSep2010) @type path_gastronoom: string @keyword mline_db: The mline database, which can be passed in case one wants to reduce overhead. Not required though. (default: None) @type mline_db: Database() @return: the molecule with all its information embedded @rtype: Molecule() ''' #-- Convenience path cc.path.gout = os.path.join(cc.path.gastronoom,path_gastronoom) #-- Retrieve cooling id log cooling_log = os.path.join(cc.path.gout,'models',molec_id,'cooling_id.log') if os.path.isfile(cooling_log): model_id = DataIO.readFile(cooling_log)[0] #- ie mline id is the same as model id, the first calced for this id else: model_id = molec_id if mline_db is None: molec_db = Database(os.path.join(cc.path.gout,\ 'GASTRoNOoM_mline_models.db')) else: molec_db = mline_db if not molec_db.has_key(model_id) \ or not molec_db[model_id].has_key(molec_id) \ or not molec_db[model_id][molec_id].has_key(molecule): return None molec_dict = molec_db[model_id][molec_id][molecule].copy() extra_pars = molec_dict['MOLECULE'].split()[1:] for k,v in zip(['ny_low','ny_up','nline','n_impact','n_impact_extra'],\ extra_pars): molec_dict[k] = int(v) for key in ['MOLECULE','CHANGE_DUST_TO_GAS_FOR_ML_SP',\ 'NUMBER_INPUT_ABUNDANCE_VALUES','KEYWORD_TABLE',\ 'MOLECULE_TABLE','ISOTOPE_TABLE']: if molec_dict.has_key(key): del molec_dict[key] molec_dict = dict([(k.lower(),v) for k,v in molec_dict.items()]) molec = Molecule(molecule=molecule,**molec_dict) molec.setModelId(molec_id) return molec
def __init__(self,star_name='model',inputfilename=None,\ path='',code='GASTRoNOoM',fn_add_star=1): """ Initializing an instance of PlottingSession. @keyword star_name: name of the star from Star.dat, use default only when never using any star model specific things (default: "model") @type star_name: string @keyword path: Output modeling folder in code home folder (default: '') @type path: string @keyword inputfilename: name of inputfile that is also copied to the output folder of the plots, if None nothing is copied (default: None) @type inputfilename: string @keyword code: the modeling code (default: GASTRoNOoM) @type code: string @keyword fn_add_star: Add the star name to the requested plot filename. Only relevant if fn_plt is given in a sub method. (default: 1) @type fn_add_star: bool """ self.inputfilename = inputfilename self.star_name = star_name self.star_index = DataIO.getInputData(path=cc.path.usr).index(star_name) self.star_name_plots = DataIO.getInputData(path=cc.path.usr, keyword='STAR_NAME_PLOTS',\ remove_underscore=1,\ rindex=self.star_index) #-- Can't use convenience paths here through cc.path, because the # module is not code specific. Within a single python session, there # may be multiple instances of PlottingSession if not path: print('Warning! %s model output folder not set.'%code) self.path = path fn_mcm = os.path.join(cc.path.aux,'Mutable_Parameters_MCMax.dat') self.mutable_mcmax = [line[0] for line in DataIO.readFile(fn_mcm,delimiter=' ') if ''.join(line).strip()] self.mutable_mcmax = [line for line in self.mutable_mcmax if line[0] != '#'] fn_gas = os.path.join(cc.path.aux,'Mutable_Parameters_GASTRoNOoM.dat') self.mutable_gastronoom = [line[0] for line in DataIO.readFile(fn_gas,\ delimiter=' ') if ''.join(line).strip()] self.mutable_gastronoom = [line for line in self.mutable_gastronoom if line[0] != '#'] self.mutable = self.mutable_mcmax + self.mutable_gastronoom self.plot_id = 'plot_%.4i-%.2i-%.2ih%.2i-%.2i-%.2i' \ %(gmtime()[0],gmtime()[1],gmtime()[2],\ gmtime()[3],gmtime()[4],gmtime()[5]) self.code = code #-- Folder management and copying inputfile to plot output folder pout = os.path.join(getattr(cc.path,self.code.lower()),self.path,\ 'stars') pstar = os.path.join(pout,self.star_name) self.pplot = os.path.join(pstar,self.plot_id) for pp in [pout,pstar]: DataIO.testFolderExistence(pp) self.fn_add_star = fn_add_star
def read(self): ''' Read the Lamda file, including molecular spectroscopy and collision rates. Each level and transition is stored as an index, following the prescription of MolReader and CollisReader. ''' #-- Read the files lines, and set the single number properties. d = DataIO.readFile(self.fn) self['pars'] = dict() pars = ['molecule', 'mol_weight', 'ny'] dtypes = [str, float, int] indices = [1, 3, 5] for i, p, dt in zip(indices, pars, dtypes): self['pars'][p] = dt(d[i].split()[0]) #-- Read the levels and their properties. Swap columns 1 and 2 to match # MlineReader's format. d1 = np.genfromtxt(self.fn,skip_header=7,max_rows=self['pars']['ny'],\ dtype='i8,f8,f8',usecols=(0,2,1),\ names=['index','weight','energy']) self['level'] = d1 #-- Determine the index from ny and preset lines index = 7 + self['pars']['ny'] + 1 self['pars']['nline'] = int(d[index].split()[0]) #-- Read the transitions and their properties. Swap columns 3 and 4 to # match MlineReader's format. d2 = np.genfromtxt(self.fn,usecols=[0,1,2,4,3],dtype='i8,i8,i8,f8,f8',\ skip_header=index+2,max_rows=self['pars']['nline'],\ names=['index','lup','llow','frequency','einsteinA']) self['trans'] = d2 #-- Continue single line parameters. index += 1 + self['pars']['nline'] + 2 self['pars']['npartners'] = int(d[index].split()[0]) index += 2 self['pars']['partners'] = d[index:index + self['pars']['npartners']] index += self['pars']['npartners'] + 1 self['pars']['ncoll_trans'] = int(d[index].split()[0]) index += 2 self['pars']['ncoll_temp'] = int(d[index].split()[0]) index += 2 self['coll_temp'] = np.array(d[index].split(), dtype=float) #-- Read the collision rates. d3 = np.genfromtxt(self.fn,usecols=[0,1,2],dtype='i8,i8,i8',\ skip_header=index+2,names=['index','lup','llow']) d4 = np.genfromtxt(self.fn,skip_header=index+2,\ usecols=range(3,3+self['pars']['ncoll_temp'])) dtype = [('index', int), ('lup', int), ('llow', int), ('rates', np.ndarray)] self['coll_trans'] = np.empty(shape=(self['pars']['ncoll_trans'],),\ dtype=dtype) self['coll_trans']['index'] = d3['index'] self['coll_trans']['lup'] = d3['lup'] self['coll_trans']['llow'] = d3['llow'] for i in range(self['pars']['ncoll_trans']): self['coll_trans']['rates'][i] = d4[i, :]
def __init__(self,molecule,ny_up=0,ny_low=0,nline=0,n_impact=0,\ n_impact_extra=0,abun_molec=1.0e-10,abun_molec_rinner=1.0e-10,\ abun_molec_re=1.0e-10,rmax_molec=1.,itera=0,lte_request=None,\ use_collis_radiat_switch=0,dust_to_gas_change_ml_sp=0,\ ratio_12c_to_13c=0,ratio_16o_to_17o=0,ratio_16o_to_18o=0,\ opr=0,r_outer=0,outer_r_mode='MAMON',abundance_filename=None,\ change_fraction_filename=None,set_keyword_change_abundance=0,\ set_keyword_change_temperature=0,enhance_abundance_factor=0,\ new_temperature_filename=None,linelist=0,starfile=''): ''' Initiate a Molecule class, setting all values for the allowed transition parameters to zero (by default). @param molecule: shorthand name of the molecule @type molecule: string @keyword ny_up: number of levels in first vibration state v=1 (default: 0) @type ny_up: int @keyword ny_low: number of levels in the ground vibration state v=0 (default: 0) @type ny_low: int @keyword nline: number of allowed transitions in molecule (default: 0) @type nline: int @keyword n_impact: number of depth points in radius mesh (default: 0) @type n_impact: int @keyword n_impact_extra: number of depth points in radius_mesh (< n_impact) used for variable mass-loss (0 if constant mdot) (default: 0) @type n_impact_extra: int @keyword itera: number of iterations in mline for molecule, LTE approximation if zero (default: 0) @type itera: string @keyword abun_molec: molecular abundance at the stellar radius. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec: float @keyword abun_molec_rinner: molecular abundance at inner shell radius. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec_rinner: float @keyword abun_molec_re: molecular abundance at rmax_molec. Default is arbitrary, and used if molecule is co or h2o. (default: 1.0e-10) @type abun_molec_re: float @keyword rmax_molec: The radius from which the Willacy abundance profiles are used. They are rescaled to abun_molec_re. Default is arbitrary, and used if molecule is co or h2o. (default: 1.) @type rmax_molec: float @keyword use_collis_radiat_switch: in case of unstable mline, such as for para h2o sometimes (default: 0) @type use_collis_radiat_switch: bool @keyword ratio_12c_to_13c: 12c/13c ratio, only relevant for 13co and other molecules with that isotope (default: 0) @type ratio_12c_to_13c: int @keyword ratio_16o_to_17o: 16o/17o ratio, only relevant for h2_17o and other molecules with that isotope (default: 0) @type ratio_16o_to_17o: int @keyword ratio_16o_to_18o: 16o/18o ratio, only relevant for h2_18o and other molecules with that isotope (default: 0) @type ratio_16o_to_18o: int @keyword opr: ortho-to-para water ratio, only relevant for ph2o, ph2_17o,ph2_18o and other molecules with para h2o (default: 0) @type opr: int @keyword r_outer: the outer radius of the shell for this molecule, 0 if MAMON (default: 0) @type r_outer: float @keyword lte_request: using LTE in mline only (with or without collision rates: determined by itera), if default lte_request is 0 if itera != 0 and 1 if itera ==0 (default: 0) @type lte_request: bool @keyword outer_r_mode: the mode used for calculating r_outer (FIXED or MAMON) (default: 'MAMON') @type outer_r_mode: string @keyword dust_to_gas_change_ml_sp: if 0 not used, otherwise this is an alternative value for the dust-to-gas ratio in mline/sphinx for this molecule and its transitions. (default: 0) @type dust_to_gas_change_ml_sp: float @keyword abundance_filename: if enhance_abundance_factor is not zero, this includes the filename and/or path to the file that includes the profile. (default: None) @type abundance_filename: string @keyword enhance_abundance_factor: if 0 the Willacy abundance profiles are uses, if not zero the abundance_filename is used and scaled with the factor given here. THIS DOES NOT RESCALE ABUNDANCES BY WILLACY! Only used for filename abundances, hence why this parameter also turns this feature on/off (default: 0) @type enhance_abundance_factor: float @keyword set_keyword_change_abundance: Change the abundance calculated in cooling by a radius dependent factor (default: 0) @type set_keyword_change_abundance: bool @keyword change_fraction_filename: the filename of the enhancement factors if set_keyword_change_abundance != 0 (default: None) @type change_fraction_filename: string @keyword set_keyword_change_temperature: Use a different temperature structure in mline and sphinx (default: 0) @type set_keyword_change_temperature: bool @keyword new_temperature_filename: the filename for the temperature structure if set_keyword_change_temperature != 0 (default: None) @type new_temperature_filename: string @keyword linelist: The molecule is created for the LineList module. No radiative information is read from GASTRoNOoM input files. (default: 0) @type linelist: bool @keyword starfile: input filename for a stellar input spectrum (either user defined or from a model atmosphere spectrum) (default: '') @type starfile: str ''' self.molecule = str(molecule) self.ny_up = int(ny_up) self.ny_low = int(ny_low) self.nline = int(nline) self.n_impact = int(n_impact) self.n_impact_extra = int(n_impact_extra) self.molecule_index = DataIO.getInputData(keyword='TYPE_SHORT',\ filename='Molecule.dat')\ .index(self.molecule) mdata = ['MOLEC_TYPE','NAME_SHORT','NAME_PLOT',\ 'SPEC_INDICES','USE_INDICES_DAT'] attrs = ['molecule_full','molecule_short','molecule_plot',\ 'spec_indices','use_indices_dat'] mfloat = [0,0,0,1,1] for k,a,mf in zip(mdata,attrs,mfloat): setattr(self,a,DataIO.getInputData(keyword=k,make_float=mf,\ filename='Molecule.dat',\ rindex=self.molecule_index,)) self.itera = int(itera) #- lte_request may be undefined, but then it would be faulty input, #- where we do want the code to crash... if self.itera==0 and lte_request is None: self.lte_request = 1 #- Normally u never use lte if taking into account collision rates elif self.itera != 0: self.lte_request = 0 elif self.itera==0 and lte_request is not None: self.lte_request = lte_request self.abun_molec = abun_molec self.abun_molec_rinner = abun_molec_rinner self.abun_molec_re = abun_molec_re self.rmax_molec = rmax_molec self.use_collis_radiat_switch = use_collis_radiat_switch self.ratio_12c_to_13c = ratio_12c_to_13c self.ratio_16o_to_17o = ratio_16o_to_17o self.ratio_16o_to_18o = ratio_16o_to_18o self.opr = opr self.dust_to_gas_change_ml_sp = float(dust_to_gas_change_ml_sp) self.enhance_abundance_factor = float(enhance_abundance_factor) self.abundance_filename = abundance_filename #-- Mainly for plotting purposes: The relative, multiplicative abundance # factor with respect to main isotope (and OPR) is calculated # This does not take into account enhance_abundance_factor! self.abun_factor = self.getAbunFactor() self.outer_r_mode = outer_r_mode if self.outer_r_mode == 'MAMON': self.r_outer = 0 else: self.r_outer = float(r_outer) self.set_keyword_change_abundance = int(set_keyword_change_abundance) self.change_fraction_filename = change_fraction_filename self.set_keyword_change_temperature = \ int(set_keyword_change_temperature) self.new_temperature_filename = new_temperature_filename self.__model_id = None if not linelist: if self.use_indices_dat: tag = '_'.join([self.molecule,str(self.ny_low),\ str(self.ny_up),str(self.nline)]) i = DataIO.getInputData(start_index=4,keyword='MOLECULE',\ filename='Indices.dat').index(tag) self.indices_index = i self.radiat = Radiat.Radiat(molecule=self) if self.spec_indices: if self.use_indices_dat: f = DataIO.getInputData(path=cc.path.usr,start_index=4,\ keyword='INDICES',rindex=i,\ filename='Indices.dat') filename = os.path.join(cc.path.gdata,'indices_backup',f) else: filename = os.path.join(cc.path.gdata,\ '%s_indices.dat'%self.molecule) rf = DataIO.readFile(filename,' ') self.radiat_indices = [[int(i) for i in line] for line in rf] else: self.radiat = None self.radiat_indices = None self.starfile = starfile
def appendResults(self): ''' Append results at the end of the inputfile. ''' print '** Appending results to inputfile and copying to output folders.' print '***********************************' #-- Check if the transition was intended to be calculated, and if it was #-- successful (ie don't add if it had already been done) timestring = '%.4i-%.2i-%.2ih%.2i-%.2i-%.2i'\ %(time.gmtime()[0],time.gmtime()[1],time.gmtime()[2],\ time.gmtime()[3],time.gmtime()[4],time.gmtime()[5]) appendage = [] if self.model_manager.trans_bool_list: model_ids_list = [list(set([(trans.molecule.molecule,\ trans.getModelId()) for boolean,trans in zip(trans_bool,\ star['GAS_LINES']) if trans.getModelId() \ and (not trans_bool \ or self.append_results)])) for star,trans_bool in zip(self.star_grid,\ self.model_manager.trans_bool_list)] #-- all unique molecules over all stars molec_list = list(set([molec for model_ids in model_ids_list for molec,model_id in model_ids if model_ids])) #-- all unique modelids for every star separately model_id_unique = [list(set([model_id for molec,model_id in model_ids])) for model_ids in model_ids_list] if [modelids for modelids in model_ids_list if modelids] != []: appendage += \ ['#########################################',\ '## Successfully calculated transition model_ids on %s:'\ %timestring] appendage.extend(['## molecule %s'%molec for molec in molec_list]) for i,(star,model_ids) in enumerate(zip(self.star_grid,\ model_ids_list)): if model_ids: appendage += ['## For Model %i : cooling id %s'\ %(i+1,star['LAST_GASTRONOOM_MODEL'])] + \ ['#molecule %s #%s' %(molecule,model_id) for molecule,model_id in model_ids] + \ ['########'] for star,model_ids in zip(self.star_grid,model_id_unique): for model_id in model_ids: try: i = 0 while True: dummy = DataIO.readFile(\ os.path.join(cc.path.gout,'models',model_id,\ os.path.split(self.inputfilename)[1]+\ '_%s_%i'%(model_id,i))) i += 1 except IOError: subprocess.call(['cp %s %s'%(self.inputfilename,\ os.path.join(cc.path.gout,\ 'models',model_id,\ os.path.split(self.inputfilename)[1]+\ '_%s_%i'%(model_id,i)))],shell=True) if self.model_manager.mcmax_done_list: model_ids = [star['LAST_MCMAX_MODEL'] for star,boolean in zip(self.star_grid,\ self.model_manager.mcmax_done_list) if boolean or self.append_results] if model_ids: appendage += ['#########################################',\ '## MCMax model_ids associated with this grid on %s:'\ %timestring] appendage += ['#%s'%model_id for model_id in model_ids] for model_id in model_ids: try: i = 0 while True: dummy = DataIO.readFile(os.path.join(\ cc.path.mout,'models',model_id,\ os.path.split(self.inputfilename)[1]+\ '_%s_%i'%(model_id,i))) i += 1 except IOError: subprocess.call(['cp %s %s'%(self.inputfilename,os.path.join(\ cc.path.mout,'models',model_id,\ os.path.split(self.inputfilename)[1]+\ '_%s_%i'%(model_id,i)))],shell=True) if appendage: DataIO.writeFile(filename=self.inputfilename,\ input_lines=appendage+['\n'],mode='a')
def doChemistry(self,star): """ Running Chemistry. @param star: The parameter set for this session @type star: Star() """ print '***********************************' #- Create the input dictionary for this Chemistry run print '** Making input file for Chemistry' #-- Add the previous model_id to the list of new entries, so it does # not get deleted if replace_db_entry == 1. if self.model_id: self.new_entries.append(self.model_id) self.model_id = '' self.command_list = dict() # Bijzonder gevallen hier ipv in loop over orig # Dan is input_lines/command_list wat er in de database staat # input_lines = d if star['PERFORM_ROUTINE'] == 0: self.command_list['ROUTINE_RADIUS'] = 0 else: self.command_list['ROUTINE_RADIUS'] = star['ROUTINE_RADIUS'] #*star['R_STAR']*star.Rsun self.command_list['R_STAR'] = star['R_STAR']*star.Rsun #self.command_list['R_INNER_CHEM'] = star['R_INNER_CHEM']*\ #star['R_STAR']*star.Rsun #self.command_list['R_OUTER_CHEM'] = star['R_OUTER_CHEM']*\ #star['R_STAR']*star.Rsun self.command_list['REACTIONS_FILE'] = '"'+os.path.join(cc.path.csource,\ 'rates',star['REACTIONS_FILE'])+'"' self.command_list['SPECIES_FILE'] = '"'+os.path.join(cc.path.csource,\ 'specs',star['SPECIES_FILE'])+'"' self.command_list['FILECO'] = '"'+os.path.join(cc.path.csource,\ 'shielding',star['FILECO'])+'"' self.command_list['FILEN2'] = '"'+os.path.join(cc.path.csource,\ star['FILEN2'])+'"' add_keys = [k for k in self.standard_inputfile.keys() if not self.command_list.has_key(k)] [self.setCommandKey(k,star,star_key=k.upper(),\ alternative=self.standard_inputfile[k]) for k in add_keys] print '** DONE!' print '***********************************' #-- Check the Chemistry database if the model was calculated before modelbool = self.checkDatabase() #-- if no match found in database, calculate new model with new model id #-- if the calculation did not fail, add entry to database for new model if not modelbool: input_dict = self.command_list.copy() input_lines = [] orig = DataIO.readFile(self.inputfilename) for i,s in enumerate(orig): split = s.split() if s[0] == '!': input_lines.append(s) else: input_lines.append(" ".join(split[0:2])+' '+\ str(self.command_list[split[0]])) output_folder = os.path.join(cc.path.cout,'models',self.model_id) DataIO.testFolderExistence(output_folder) input_lines.append('OUTPUT_FOLDER = "' +\ output_folder+'/"') input_filename = os.path.join(cc.path.cout,'models',\ 'inputChemistry_%s.txt'%self.model_id) DataIO.writeFile(filename=input_filename,input_lines=input_lines) #subprocess.call(' '.join([cc.path.ccode,input_filename]),shell=True) subprocess.call(' '.join([os.path.join(cc.path.csource,'csmodel'),input_filename]),shell=True) # files die worden aangemaakt op einde, test of successvol testf1 = os.path.join(output_folder,'cscoldens.out') testf2 = os.path.join(output_folder,'csfrac.out') if os.path.exists(testf1) and os.path.exists(testf2) and \ os.path.isfile(testf1) and os.path.isfile(testf2): del self.db[self.model_id]['IN_PROGRESS'] self.db.addChangedKey(self.model_id) else: print '** Model calculation failed. No entry is added to ' + \ 'the database.' del self.db[self.model_id] self.model_id = '' if not self.single_session: self.db.sync() #- Note that the model manager now adds/changes MUTABLE input keys, #- which MAY be overwritten by the input file inputComboCode.dat print '***********************************'