def readTelescopeProperties(telescope): """ Read the telescope properties from Telescope.dat. This currently includes the telescope size in m, and the default absolute flux calibration uncertainty. @param telescope: The telescope requested @type telescope: str @return: The telescope size and absolute flux calibration uncertainty @rtype: (float,float) """ all_telescopes = DataIO.getInputData(keyword="TELESCOPE", start_index=5, filename="Telescope.dat") if "PACS" in telescope: telescope = "PACS" else: telescope = telescope try: tel_index = all_telescopes.index(telescope) except ValueError: raise ValueError("%s not found in Telescope.dat." % telescope) size = DataIO.getInputData(keyword="SIZE", start_index=5, filename="Telescope.dat", rindex=tel_index) abs_err = DataIO.getInputData(keyword="ABS_ERR", start_index=5, filename="Telescope.dat", rindex=tel_index) return (size, abs_err)
def setStarPars(self): """ Set some standard stellar parameters such as Ak and galactic position. """ self.star_index = DataIO.getInputData().index(self.star_name) ll = DataIO.getInputData(keyword='LONG',rindex=self.star_index) bb = DataIO.getInputData(keyword='LAT',rindex=self.star_index) if self.distance <> None: self.ak = em.findext_marshall(ll=ll,bb=bb,distance=self.distance,\ norm='Ak') if self.ak is None: self.ak = em.findext_drimmel(lng=ll,lat=bb,norm='Ak',\ distance=self.distance) if self.ak is None: self.ak = DataIO.getInputData(keyword='A_K',rindex=self.star_index) snp = DataIO.getInputData(keyword='STAR_NAME_PLOTS',\ remove_underscore=1,rindex=self.star_index) self.star_name_plots = snp if (abs(ll) < 5.0 or ll > 355.0) and abs(bb) < 5.0: self.gal_position = 'GC' else: self.gal_position = 'ISM'
def readTelescopeProperties(telescope): """ Read the telescope properties from Telescope.dat. This currently includes the telescope size in m, and the default absolute flux calibration uncertainty. @param telescope: The telescope requested @type telescope: str @return: The telescope size and absolute flux calibration uncertainty @rtype: (float,float) """ all_telescopes = DataIO.getInputData(keyword='TELESCOPE',start_index=5,\ filename='Telescope.dat') if 'PACS' in telescope: telescope = 'PACS' else: telescope = telescope try: tel_index = all_telescopes.index(telescope) except ValueError: raise ValueError('%s not found in Telescope.dat.' % telescope) size = DataIO.getInputData(keyword='SIZE',start_index=5,\ filename='Telescope.dat',\ rindex=tel_index) abs_err = DataIO.getInputData(keyword='ABS_ERR',start_index=5,\ filename='Telescope.dat',\ rindex=tel_index) return (size, abs_err)
def readTelescopeProperties(self): """ Read the telescope properties from Telescope.dat. This currently includes the telescope size in m, and the default absolute flux calibration uncertainty. """ all_telescopes = DataIO.getInputData(keyword='TELESCOPE',start_index=5,\ filename='Telescope.dat') try: tel_index = all_telescopes.index(self.instrument.upper()) except ValueError: raise ValueError('%s not found in Telescope.dat.'\ %self.instrument.upper()) self.telescope_size = DataIO.getInputData(keyword='SIZE',start_index=5,\ filename='Telescope.dat',\ rindex=tel_index) self.absflux_err = DataIO.getInputData(keyword='ABS_ERR',start_index=5,\ filename='Telescope.dat',\ rindex=tel_index)
def setData(self, **kwargs): ''' Select available data. Based on the data file types in Sed.dat and the available data files. Also calls the buildPhotometry method to create a photometry file from the IvS Sed builder tool Any keywords required for buildPhotometry can be passed here. ''' data_types = DataIO.getInputData(keyword='DATA_TYPES',\ filename='Sed.dat') abs_errs = DataIO.getInputData(keyword='ABS_ERR', filename='Sed.dat') if 'Photometric_IvS' in data_types: buildPhotometry(self.star_name, **kwargs) self.data_types = [] self.data_filenames = [] self.abs_err = dict() for dt, ierr in zip(data_types, abs_errs): searchpath = os.path.join(cc.path.dsed,'%s_*%s*.dat'\ %(dt,self.star_name)) add_files = glob(searchpath) for ff in add_files: if ff not in self.data_filenames: self.data_filenames.append(ff) self.data_types.append(dt) self.abs_err[dt] = ierr
def setData(self,**kwargs): ''' Select available data. Based on the data file types in Sed.dat and the available data files. Also calls the buildPhotometry method to create a photometry file from the IvS Sed builder tool Any keywords required for buildPhotometry can be passed here. ''' data_types = DataIO.getInputData(keyword='DATA_TYPES',\ filename='Sed.dat') abs_errs = DataIO.getInputData(keyword='ABS_ERR',filename='Sed.dat') if 'Photometric_IvS' in data_types: buildPhotometry(self.star_name,**kwargs) self.data_types = [] self.data_filenames = [] self.abs_err = dict() for dt,ierr in zip(data_types,abs_errs): searchpath = os.path.join(cc.path.dsed,'%s_*%s*.dat'\ %(dt,self.star_name)) add_files = glob(searchpath) for ff in add_files: if ff not in self.data_filenames: self.data_filenames.append(ff) self.data_types.append(dt) self.abs_err[dt] = ierr
def makeOpa(self, mode='ZERO', **args): """ Making custom .particle files. Every method called here will put the results in self.output_data. @keyword mode: type of extrapolation (ZERO,FUNCTION,HONY,ZHANG) (default: 'ZERO') @type mode: string @keyword args: Optional keywords required for the other methods of the class @type args: dict """ self.output_data = [] mode = mode.upper() if hasattr(self, 'do' + mode): getattr(self, 'do' + mode)(**args) self.output_data = [ ' '.join(str(line)) for line in self.output_data ] output_filename = '_'.join(['customOpacity',mode] + \ sorted(args.values()) + \ [self.filename]) if self.opacity_file: output_filename.replace('.particle', '.opacity') DataIO.writeFile(filename=os.path.join(cc.path.mopac,\ output_filename),\ input_lines=self.output_data) new_short = self.species + mode #- filename is already present: the new file should have the same #- parameters and the short name can be kept, #- nothing is changed in the Dust.dat file try: DataIO.getInputData(keyword='PART_FILE',filename='Dust.dat')\ .index(output_filename) #- filename is not present: do the normal procedure, ie check if #- short name is already present except ValueError: i = 0 while ' '.join(DataIO.getInputData(keyword='SPECIES_SHORT',\ filename='Dust.dat'))\ .find(new_short) != -1: i += 1 new_short = new_short + str(i) adding_line = [new_short] + \ [str(DataIO.getInputData(keyword=key,\ filename='Dust.dat',\ rindex=self.index)) for key in ['SPEC_DENS','T_DES','T_DESA','T_DESB']] adding_line.insert(2, output_filename) adding_line = '\t\t'.join(adding_line) DataIO.writeFile(os.path.join(cc.path.usr,'Dust.dat'),\ [adding_line+'\n'],mode='a') else: print 'Mode "' + mode + '" not available. Aborting.'
def makeOpa(self,mode='ZERO',**args): """ Making custom .particle files. Every method called here will put the results in self.output_data. @keyword mode: type of extrapolation (ZERO,FUNCTION,HONY,ZHANG) (default: 'ZERO') @type mode: string @keyword args: Optional keywords required for the other methods of the class @type args: dict """ self.output_data = [] mode = mode.upper() if hasattr(self,'do' + mode): getattr(self,'do' + mode)(**args) self.output_data = [' '.join(str(line)) for line in self.output_data] output_filename = '_'.join(['customOpacity',mode] + \ sorted(args.values()) + \ [self.filename]) if self.opacity_file: output_filename.replace('.particle','.opacity') DataIO.writeFile(filename=os.path.join(cc.path.mopac,\ output_filename),\ input_lines=self.output_data) new_short = self.species + mode #- filename is already present: the new file should have the same #- parameters and the short name can be kept, #- nothing is changed in the Dust.dat file try: DataIO.getInputData(keyword='PART_FILE',filename='Dust.dat')\ .index(output_filename) #- filename is not present: do the normal procedure, ie check if #- short name is already present except ValueError: i=0 while ' '.join(DataIO.getInputData(keyword='SPECIES_SHORT',\ filename='Dust.dat'))\ .find(new_short) != -1: i+=1 new_short = new_short + str(i) adding_line = [new_short] + \ [str(DataIO.getInputData(keyword=key,\ filename='Dust.dat',\ rindex=self.index)) for key in ['SPEC_DENS','T_DES','T_DESA','T_DESB']] adding_line.insert(2,output_filename) adding_line = '\t\t'.join(adding_line) DataIO.writeFile(os.path.join(cc.path.usr,'Dust.dat'),\ [adding_line+'\n'],mode='a') else: print 'Mode "' + mode + '" not available. Aborting.'
def setStarPars(self): """ Set some standard stellar parameters such as Ak and galactic position. """ self.star_index = DataIO.getInputData().index(self.star_name) self.ll = DataIO.getInputData(keyword='LONG', rindex=self.star_index) self.bb = DataIO.getInputData(keyword='LAT', rindex=self.star_index) snp = DataIO.getInputData(keyword='STAR_NAME_PLOTS',\ remove_underscore=1,rindex=self.star_index) self.star_name_plots = snp
def setStarPars(self): """ Set some standard stellar parameters such as Ak and galactic position. """ self.star_index = DataIO.getInputData().index(self.star_name) self.ll = DataIO.getInputData(keyword='LONG',rindex=self.star_index) self.bb = DataIO.getInputData(keyword='LAT',rindex=self.star_index) snp = DataIO.getInputData(keyword='STAR_NAME_PLOTS',\ remove_underscore=1,rindex=self.star_index) self.star_name_plots = snp
def __init__(self): """ Initiating an instance of the KappaReader. """ self.lspecies = DataIO.getInputData(path=cc.path.usr, keyword="SPECIES_SHORT", filename="Dust.dat") self.lfilenames = DataIO.getInputData(path=cc.path.usr, keyword="PART_FILE", filename="Dust.dat") self.lspec_dens = DataIO.getInputData(path=cc.path.usr, keyword="SPEC_DENS", filename="Dust.dat") self.kappas = dict() self.qext_a = dict() self.waves = dict() self.fns = dict() self.spec_dens = dict()
def checkVlsr(self): """ Check if the Vlsr was set correctly. If not, it is taken from Star.dat. It is assumed the vlsr in the fits file is correct within 25%. If it is not, the value from Star.dat is used. """ try: star_index = DataIO.getInputData(keyword='STAR_NAME')\ .index(self.star_name) vlsr = DataIO.getInputData(keyword='V_LSR', rindex=star_index) except KeyError, ValueError: print 'Star not found in Star.dat for %s. '%(self.filename) + \ 'Add star to Star.dat!' raise IOError()
def addData(self,star_name,filename,trans): ''' Add a new file to the database with given transition definition. If the transition is already present in the database for this particular star, the filename is added to the dictionary for that transition. A single transition for a star can thus have multiple filenames associated with it! Note that this method does NOT automatically sync (ie save changes to the hard disk) the database. That must be done through an additional flag to avoid excess overhead. The transition definition is checked for correctness: single spaces between entries in the defintion, and a total of 11 entries: 1 molecule (shorthand) 8 quantum numbers, 1 offset The fit is not done here. Instead the filename key is added to the transition's dictionary with value None. @param star_name: The name of the star for which to add the data. @type star_name: str @param filename: The filename of the radio data to be added. Must be in the db folder! Only the filename is used. Any folder path is cut. @type filename: str @param trans: The transition definition. Must be in the correct format! @type trans: str ''' filename = os.path.split(filename)[1] if not self.has_key(star_name): self.addStar(star_name) entries = trans.split() trans = ' '.join(entries) defmolecs = DataIO.getInputData(keyword='TYPE_SHORT',\ filename='Molecule.dat') this_molec = entries[0].replace('TRANSITION=','',1) if this_molec not in defmolecs: print('Molecule %s unrecognized.'%this_molec) return if len(entries) != 11: print('Incorrect transition definition:') print(trans) return if self[star_name].has_key(trans): if filename not in self[star_name][trans].keys(): self[star_name][trans][filename] = None self.addChangedKey(star_name) else: self[star_name][trans] = dict([(filename,None)]) self.addChangedKey(star_name)
def addData(self, star_name, filename, trans): ''' Add a new file to the database with given transition definition. If the transition is already present in the database for this particular star, the filename is added to the dictionary for that transition. A single transition for a star can thus have multiple filenames associated with it! Note that this method does NOT automatically sync (ie save changes to the hard disk) the database. That must be done through an additional flag to avoid excess overhead. The transition definition is checked for correctness: single spaces between entries in the defintion, and a total of 11 entries: 1 molecule (shorthand) 8 quantum numbers, 1 offset The fit is not done here. Instead the filename key is added to the transition's dictionary with value None. @param star_name: The name of the star for which to add the data. @type star_name: str @param filename: The filename of the radio data to be added. Must be in the db folder! Only the filename is used. Any folder path is cut. @type filename: str @param trans: The transition definition. Must be in the correct format! @type trans: str ''' filename = os.path.split(filename)[1] if not self.has_key(star_name): self.addStar(star_name) entries = trans.split() trans = ' '.join(entries) defmolecs = DataIO.getInputData(keyword='TYPE_SHORT',\ filename='Molecule.dat') this_molec = entries[0].replace('TRANSITION=', '', 1) if this_molec not in defmolecs: print('Molecule %s unrecognized.' % this_molec) return if len(entries) != 11: print('Incorrect transition definition:') print(trans) return if self[star_name].has_key(trans): if filename not in self[star_name][trans].keys(): self[star_name][trans][filename] = None self.addChangedKey(star_name) else: self[star_name][trans] = dict([(filename, None)]) self.addChangedKey(star_name)
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 checkVlsr(self): """ Check if the Vlsr was set correctly. If not, it is taken from Star.dat. It is assumed the vlsr in the fits file is correct within 25%. If it is not, the value from Star.dat is used. """ try: star_index = DataIO.getInputData(keyword='STAR_NAME')\ .index(self.star_name) vlsr = DataIO.getInputData(keyword='V_LSR',rindex=star_index) except KeyError,ValueError: print 'Star not found in Star.dat for %s. '%(self.fn) + \ 'Add star to Star.dat!' raise IOError()
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 __init__(self): """ Initiating an instance of the KappaReader. """ self.lspecies = DataIO.getInputData(path=cc.path.usr,\ keyword='SPECIES_SHORT',\ filename='Dust.dat') self.lfilenames = DataIO.getInputData(path=cc.path.usr,\ keyword='PART_FILE',\ filename='Dust.dat') self.lspec_dens = DataIO.getInputData(path=cc.path.usr,\ keyword='SPEC_DENS',\ filename='Dust.dat') self.kappas = dict() self.qext_a = dict() self.waves = dict()
def getPacsResolution(self): ''' Get the Pacs resolution from cc aux file for all orders. @return: The resolution as a function of wavelength for the 3 orders @rtype: (list[list],list[list]) ''' reso_wave_list = [DataIO.getInputData(path=cc.path.aux,\ filename='Pacs_Resolution.dat',\ keyword='WAVE='+str(order)) for order in range(1,4)] reso_delta_list = [DataIO.getInputData(path=cc.path.aux,\ filename='Pacs_Resolution.dat',\ keyword='ORDER='+str(order)) for order in range(1,4)] return reso_wave_list,reso_delta_list
def setDataInfo(self): ''' Read data info from the ComboCode/usr/Data.dat file. Will return information such as sigma levels and wavelength range for determining the std value. ''' if not self.instrument: return self.data_info = dict() instbands = DataIO.getInputData(keyword='INSTRUMENT',\ filename='Data.dat') instbands = [band.upper() for band in instbands] indices = [i for i,band in enumerate(instbands) if band.find(self.instrument.instrument.upper()) == 0] bands = [band.replace('%s_'%self.instrument.instrument.upper(),'') for i,band in enumerate(instbands) if i in indices] w_std_min = [wmin for i,wmin in enumerate(DataIO.getInputData(\ keyword='W_STD_MIN',filename='Data.dat')) if i in indices] w_std_max = [wmax for i,wmax in enumerate(DataIO.getInputData(\ keyword='W_STD_MAX',filename='Data.dat')) if i in indices] sigmas = [sigma for i,sigma in enumerate(DataIO.getInputData(\ keyword='SIGMA',filename='Data.dat')) if i in indices] self.data_info['sigmas'] = sigmas self.data_info['bands'] = bands self.data_info['w_std_min'] = w_std_min self.data_info['w_std_max'] = w_std_max
def doHONY(self, wl1=1.0, wl2=2.0, wl3=10.0, a_mod=0.05, q_cst=1.0): """ Replace all opacities below a cut-off wavelength with values as assumed by Hony et al (2003, 2004) @keyword wl1: first discontinuity in micron (default: 1.0) @type wl1: float @keyword wl2: second discontinuity in micron (default: 2.0) @type wl2: float @keyword wl3: third discontinuity in micron (default: 10) @type wl3: float @keyword a_mod: model grain size, 0.01 according to Hony 2004 in micron (default: 0.05) @type a_mod: float @keyword q_cst: constant extinction efficiency at wavelengths < wl1 (default: 1.0) @type q_cst: float """ spec_dens = DataIO.getInputData(keyword='SPEC_DENS',rindex=self.index,\ filename='Dust.dat') opa_cst = q_cst / 4.0 * 3.0 / spec_dens / (a_mod * 10**(-4)) for line in self.input_data: if len(line) == 4 and float(line[0]) < wl1: self.output_data.append([line[0],str(opa_cst+1e-60),\ str(opa_cst),str(1e-60)]) elif len(line) == 4 and float(line[0]) >= wl1 and float( line[0]) < wl2: opa = Interpol.linInterpol([wl1,wl2],[opa_cst,1e-60],\ float(line[0])) self.output_data.append([line[0],str(opa+1e-60),str(opa),\ str(1e-60)]) elif len(line) == 4 and float(line[0]) >= wl2 and float( line[0]) < wl3: self.output_data.append([line[0],str(2e-60),str(1e-60),\ str(1e-60)]) else: self.output_data.append(line)
def doZHANG(self, wl=10.0, a_mod=0.05, q_cst=1.6, metallic=True): """ Replace all opacities below a cut-off wavelength with values as assumed by Zhang et al (2009) @keyword wl: wavelength of the discontinuity (default: 10.0) @type wl: float @keyword a_mod: model grain size, following Zhang et al 2009 (default: 0.05) @type a_mod: float @keyword q_cst: the constant extinction efficieny at short wavelengths (default: 1.6) @type q_cst: float @keyword metallic: if metallic dust, cut off wavelength is calculated differently than if dielectric dust (ie metallic=0) (default: True) @type metallic: bool """ spec_dens = DataIO.getInputData(keyword='SPEC_DENS',rindex=self.index,\ filename='Dust.dat') wl1 = metallic and pi * a_mod or 2 * pi * a_mod opa_cst = q_cst / 4.0 * 3.0 / spec_dens / (a_mod * 10**(-4)) i = 0 while float(self.input_data[i][0]) <= wl: i += 1 opa_10 = float(self.input_data[i][1]) for line in self.input_data: if len(line) == 4 and float(line[0]) <= wl1: self.output_data.append([line[0],str(opa_cst+1e-60),\ str(opa_cst),str(1e-60)]) elif len(line) == 4 and float(line[0]) > wl1 and float( line[0]) < wl: eps = min(1, float(line[0]) / wl) opa = (1 - eps) * opa_cst * wl1 / float(line[0]) + eps * opa_10 self.output_data.append([line[0],str(opa+1e-60),str(opa),\ str(1e-60)]) else: self.output_data.append(line)
def doZHANG(self,wl=10.0,a_mod=0.05,q_cst=1.6,metallic=True): """ Replace all opacities below a cut-off wavelength with values as assumed by Zhang et al (2009) @keyword wl: wavelength of the discontinuity (default: 10.0) @type wl: float @keyword a_mod: model grain size, following Zhang et al 2009 (default: 0.05) @type a_mod: float @keyword q_cst: the constant extinction efficieny at short wavelengths (default: 1.6) @type q_cst: float @keyword metallic: if metallic dust, cut off wavelength is calculated differently than if dielectric dust (ie metallic=0) (default: True) @type metallic: bool """ spec_dens = DataIO.getInputData(keyword='SPEC_DENS',rindex=self.index,\ filename='Dust.dat') wl1 = metallic and pi*a_mod or 2*pi*a_mod opa_cst = q_cst/4.0*3.0/spec_dens/(a_mod*10**(-4)) i = 0 while float(self.input_data[i][0]) <= wl: i += 1 opa_10 = float(self.input_data[i][1]) for line in self.input_data: if len(line) == 4 and float(line[0]) <= wl1: self.output_data.append([line[0],str(opa_cst+1e-60),\ str(opa_cst),str(1e-60)]) elif len(line)==4 and float(line[0]) > wl1 and float(line[0]) < wl: eps = min(1,float(line[0])/wl) opa = (1-eps) * opa_cst*wl1/float(line[0]) + eps*opa_10 self.output_data.append([line[0],str(opa+1e-60),str(opa),\ str(1e-60)]) else: self.output_data.append(line)
def doHONY(self,wl1 = 1.0,wl2=2.0,wl3=10.0,a_mod=0.05,q_cst=1.0): """ Replace all opacities below a cut-off wavelength with values as assumed by Hony et al (2003, 2004) @keyword wl1: first discontinuity in micron (default: 1.0) @type wl1: float @keyword wl2: second discontinuity in micron (default: 2.0) @type wl2: float @keyword wl3: third discontinuity in micron (default: 10) @type wl3: float @keyword a_mod: model grain size, 0.01 according to Hony 2004 in micron (default: 0.05) @type a_mod: float @keyword q_cst: constant extinction efficiency at wavelengths < wl1 (default: 1.0) @type q_cst: float """ spec_dens = DataIO.getInputData(keyword='SPEC_DENS',rindex=self.index,\ filename='Dust.dat') opa_cst = q_cst/4.0*3.0/spec_dens/(a_mod*10**(-4)) for line in self.input_data: if len(line) == 4 and float(line[0]) < wl1: self.output_data.append([line[0],str(opa_cst+1e-60),\ str(opa_cst),str(1e-60)]) elif len(line)==4 and float(line[0])>=wl1 and float(line[0]) < wl2: opa = Interpol.linInterpol([wl1,wl2],[opa_cst,1e-60],\ float(line[0])) self.output_data.append([line[0],str(opa+1e-60),str(opa),\ str(1e-60)]) elif len(line)==4 and float(line[0])>=wl2 and float(line[0]) < wl3: self.output_data.append([line[0],str(2e-60),str(1e-60),\ str(1e-60)]) else: self.output_data.append(line)
def addStar(self, star_name): ''' Add a new star to the database. A check is ran to see if the requested star is known in ~/ComboCode/usr/Star.dat. @param star_name: The name of the star (from Star.dat) @type star_name: str ''' if star_name in self.keys(): return known_stars = DataIO.getInputData(keyword='STAR_NAME') if star_name not in known_stars: print('Requested star %s is unknown in %s/Star.dat.'\ %(star_name,cc.path.usr)) return self[star_name] = dict()
def addStar(self, star_name): """ Add a new star to the database. A check is ran to see if the requested star is known in ~/ComboCode/usr/Star.dat. @param star_name: The name of the star (from Star.dat) @type star_name: str """ if star_name in self.keys(): return known_stars = DataIO.getInputData(keyword="STAR_NAME") if star_name not in known_stars: print ("Requested star %s is unknown in %s/Star.dat." % (star_name, cc.path.usr)) return self[star_name] = dict()
def getAbunFactor(self): ''' Return the abundance factor of the molecule, with respect to its main isotope/ortho version. ''' raw_factors = DataIO.getInputData(keyword='ABUN_FACTOR',\ filename='Molecule.dat',\ rindex=self.molecule_index) factors = [factor == '1' and 1 or float(getattr(self,factor.lower())) for factor in raw_factors.split('*')] #-- abun_factor should only take into account isotope/OPR factors #if float(self.enhance_abundance_factor): # factors.append(float(self.enhance_abundance_factor)) total_factor = 1 while factors: total_factor *= factors.pop() return total_factor
def __init__(self, molecule): ''' Initializing an instance of the Radiat class. @param molecule: The molecule (short hand name) for which radiat info is loaded. @type molecule: Molecule() ''' self.molecule = molecule if self.molecule.use_indices_dat: fn = DataIO.getInputData(path=cc.path.usr,keyword='RADIAT',\ filename='Indices.dat',start_index=4,\ rindex=self.molecule.indices_index) self.filename = os.path.join(cc.path.gdata, 'radiat_backup', fn) else: self.filename = os.path.join(cc.path.gdata,\ '%s_radiat.dat'%self.molecule.molecule) self.c = 2.99792458e10 #in cm/s self.__read()
def writeIntIntTable(filename,stars,trans,instrument='PACS',ddict=dict(),\ searchstring='os2_us3',\ mark_trans=[],extra_marker=r'\tablefootmark{f}',\ blend_mark=r'\tablefootmark{$\star$}',print_summary=0,\ sort_freq=1): ''' Write a table with integrated line intensities and their uncertainties for multiple stars. The table - for now - is only available in LaTeX format. Can be used for unresolved line strengths from PACS and SPIRE measurements. @param filename: The filename of the to be written table. @type filename: string @param stars: The stars for which the table is created. @type stars: list[string] @param trans: The transitions for which the integrated intensities are selected from the PACS line fit results of each star. @type trans: list[Transition()] @keyword instrument: The name of the instrument for which this is done. For now only 'PACS' and 'SPIRE'. (default: 'PACS') @type instrument: str @keyword ddict: The data objects for PACS or SPIRE for each star. If not given, they are generated automatically with path_linefit 'lineFit', oversampling 6 (for PACS) or 4 (for SPIRE), and resolution of 0.04 (for SPIRE). (default: None) @type ddict: dict(Instrument()) @keyword blend_mark: The marker used for blended lines. (default: \tablefootmark{$\star$}) @type blend_mark: string @keyword mark_trans: If a subset of transitions has to be marked with an extra mark, they are included in this list. (default: []) @type mark_trans: list @keyword extra_marker: The marker used for the subset mark_trans (default: \tablefootmark{f}) @type extra_marker: string @keyword searchstring: the searchstring conditional for the auto-search, if data have not been read into given Pacs objects or if new Pacs objects are generated. (default: 'os2_us3') @type searchstring: string @keyword sort_freq: Sort the transitions on frequency. Otherwise sort on wavelength. (default: 1) @type sort_freq: bool @keyword print_summary: Print a summary at the end. (default: 0) @type print_summary: bool ''' #-- Check what instrument is requested if ddict: all_instr = [dd.instrument for dd in ddict.values()] if len(set(all_instr)) > 1: print "Too many instruments defined. Make sure only PACS or SPIRE"+\ " are requested." return instrument = all_instr[0].upper() if isinstance(stars,str): stars = [stars] #-- Note that keeping track of transitions per star is not necessary. Here, # we look at data, and these are kept track of by the filename which # includes the star name. There is no confusion possible. trans = sorted(trans,\ key=lambda x: sort_freq and x.frequency or x.wavelength) if set([t.vup for t in trans]) == set([0]): no_vib = 1 else: no_vib = 0 #-- Reset the integrated line strength info in the transitions, in case it # was already set previously. There's no way to be sure for every trans # individually if the match-up has been done before. And in addition, it # needs to be done for every star separately. So play safe, and reset in # the sample transition list. for tr in trans: tr.unreso = dict() tr.unreso_err = dict() tr.unreso_blends = dict() for star in stars: if not ddict.has_key(star): if instrument == 'PACS': ddict[star] = Pacs(star,6,path_linefit='lineFit') elif instrument == 'SPIRE': ddict[star] = Spire(star,resolution=0.04,oversampling=4,\ path_linefit='lineFit') ddict[star].setData(searchstring=searchstring) for ifn in range(len(ddict[star].data_filenames)): ddict[star].intIntMatch(trans,ifn) istars = [DataIO.getInputData().index(star) for star in stars] pstars = [DataIO.getInputData(keyword='STAR_NAME_PLOTS',rindex=istar) for istar in istars] pstars = [s.replace('_',' ') for s in pstars] all_molecs = DataIO.getInputData(keyword='TYPE_SHORT',make_float=0,\ filename='Molecule.dat') all_pmolecs = DataIO.getInputData(keyword='NAME_PLOT',make_float=0,\ filename='Molecule.dat') inlines = [] inlines.append('&'.join(['']*(no_vib and 4 or 5)+pstars[:-1]+\ [r'%s \\\hline'%pstars[-1]])) line_els = [instrument,'Molecule'] if not no_vib: line_els.append('Vibrational') line_els.extend(['Rotational','$\lambda_0$',\ r'\multicolumn{%i}{c}{$F_\mathrm{int}$} \\'%len(pstars)]) inlines.append('&'.join(line_els)) line_els = ['band',''] if not no_vib: line_els.append('state') line_els.extend(['transition',r'$\mu$m',\ r'\multicolumn{%i}{c}{(W m$^-2$))} \\\hline'%len(pstars)]) inlines.append('&'.join(line_els)) all_bands = ['SLW','SSW','R1B','R1A','B2B','B2A','B3A'] bands = set([ib for v in ddict.values() for ib in v.data_ordernames]) bands = [ib for ib in all_bands if ib in bands] if not sort_freq: bands.reverse() line_counter = dict() for s in stars: line_counter[s] = 0 for band in bands: #inlines.append(r'\multicolumn{4}{c}{PACS Band: %s} & \multicolumn{%i}{c}{} \\\hline'\ #%(band,len(pstars))) new_band = 1 for it,t in enumerate(trans): #-- Check if there's any actual line strength result for any star # for this particular band; in any filename in this band. # Otherwise, exclude the line from the table. If there's no # spectrum for this band at all, the line is excluded as well. # In this case, the band will not be added to the table at all. # Just look at the keys of t.unreso. If there's none of the # given band, then exclude the transition. All stars are # included in the same Transition() objects. all_keys = [k for k in t.unreso.keys() if band in os.path.split(k)[1].split('_')] if not all_keys: continue #-- There's at least one star with a measured line strength in this # band, so add a column. col1 = all_pmolecs[all_molecs.index(t.molecule.molecule)] #-- If the band has not had a line added before, add the band now if new_band: col0 = band new_band = 0 else: col0 = '' #-- Define the input for the table. parts = [col0,\ col1] if not no_vib: parts.append(t.makeLabel(return_vib=1)) parts.extend([t.makeLabel(inc_vib=0),'%.2f'%(t.wavelength*10**4)]) #-- For every star, add the measured line strength of the # transition, if available. For now, it is assumed only one line # strength measurement is available per star per band. (This is # not strictly true, for instance for overlapping line scans, but # the line integration tool makes it impossible to discern # between multiple measurements of the same line in the same # band) for s in stars: #-- Grab the filename available in the transition object for # the measured line strength. If multiple filenames with the # correct band are available, only the first is taken. all_fn = [sfn for sfn in t.unreso.keys() if band in os.path.split(sfn)[1].split('_')\ and s in os.path.split(sfn)[1].split('_')] #-- Possibly, for this star, no datafiles of given band are # present. Then just add no flux measurement and continue to # the next star. if not all_fn: parts.append(r'/') continue else: fn = all_fn[0] #-- The filename is present, and thus should have a line # strength indicated, or be flagged as a blend. If not, an # error will be raised, but this should not happen! fint,finterr,fintblend = t.getIntIntUnresolved(fn) if fint == 'inblend': parts.append('Blended') else: line_counter[s] += 1 parts.append('%s%s%.2e (%.1f%s)'\ %(t in mark_trans and extra_marker or r'',\ fint<0 and blend_mark or r'',abs(fint),\ finterr*100,r'\%')) parts[-1] = parts[-1] + r'\\' inlines.append('&'.join(parts)) if not new_band and band != bands[-1]: inlines[-1] = inlines[-1] + r'\hline' DataIO.writeFile(filename,input_lines=inlines) if print_summary: print('Summary') for s in stars: print('%s: %i lines measured'%(s,len(ddict[s].linefit.wave_fit))+\ ', of which %i lines have been identified.'%line_counter[s])
def writeIntIntTable(filename,stars,trans,dpacs=dict(),searchstring='os2_us3',\ mark_trans=[],extra_marker=r'\tablefootmark{f}',\ blend_mark=r'\tablefootmark{$\star$}',print_summary=0,\ sort_freq=1): ''' Write a table with integrated line intensities and their uncertainties for multiple stars. The table - for now - is only available in LaTeX format. @param filename: The filename of the to be written table. @type filename: string @param stars: The stars for which the table is created. @type stars: list[string] @param trans: The transitions for which the integrated intensities are selected from the PACS line fit results of each star. @type trans: list[Transition()] @keyword path_pacs: full path to PACS data folder, excluding star_name Only needed when PACS data objects are created from scratch. (default: ~/Data/PACS/) @type path_pacs: string @keyword dpacs: The data objects for PACS for each star. If not given, they are generated automatically with path_linefit 'lineFit', oversampling 6 and given path_pacs. (default: None) @type dpacs: dict(Pacs()) @keyword blend_mark: The marker used for blended lines. (default: \tablefootmark{$\star$}) @type blend_mark: string @keyword mark_trans: If a subset of transitions has to be marked with an extra mark, they are included in this list. (default: []) @type mark_trans: list @keyword extra_marker: The marker used for the subset mark_trans (default: \tablefootmark{f}) @type extra_marker: string @keyword searchstring: the searchstring conditional for the auto-search, if data have not been read into given Pacs objects or if new Pacs objects are generated. (default: 'os2_us3') @type searchstring: string @keyword sort_freq: Sort the transitions on frequency. Otherwise sort on wavelength. (default: 1) @type sort_freq: bool @keyword print_summary: Print a summary at the end. (default: 0) @type print_summary: bool ''' if type(stars) is types.StringType: stars = [stars] #-- Note that keeping track of transitions per star is not necessary. Here, # we look at data, and these are kept track of by the filename which # includes the star name. There is no confusion possible. trans = sorted(trans,\ key=lambda x: sort_freq and x.frequency or x.wavelength) if set([t.vup for t in trans]) == set([0]): no_vib = 1 else: no_vib = 0 #-- Reset the integrated line strength info in the transitions, in case it # was already set previously. There's no way to be sure for every trans # individually if the match-up has been done before. And in addition, it # needs to be done for every star separately. So play safe, and reset in # the sample transition list. for tr in trans: tr.unreso = dict() tr.unreso_err = dict() tr.unreso_blends = dict() for star in stars: if not dpacs.has_key(star): dpacs[star] = Pacs(star,6,path_linefit='lineFit') dpacs[star].setData(searchstring=searchstring) for ifn in range(len(dpacs[star].data_filenames)): dpacs[star].intIntMatch(trans,ifn) istars = [DataIO.getInputData().index(star) for star in stars] pstars = [DataIO.getInputData(keyword='STAR_NAME_PLOTS',rindex=istar) for istar in istars] pstars = [s.replace('_',' ') for s in pstars] all_molecs = DataIO.getInputData(keyword='TYPE_SHORT',make_float=0,\ filename='Molecule.dat') all_pmolecs = DataIO.getInputData(keyword='NAME_PLOT',make_float=0,\ filename='Molecule.dat') inlines = [] inlines.append('&'.join(['']*(no_vib and 4 or 5)+pstars[:-1]+\ [r'%s \\\hline'%pstars[-1]])) line_els = ['PACS','Molecule'] if not no_vib: line_els.append('Vibrational') line_els.extend(['Rotational','$\lambda_0$',\ r'\multicolumn{%i}{c}{$F_\mathrm{int}$} \\'%len(pstars)]) inlines.append('&'.join(line_els)) line_els = ['band',''] if not no_vib: line_els.append('state') line_els.extend(['transition',r'$\mu$m',\ r'\multicolumn{%i}{c}{(W m$^-2$))} \\\hline'%len(pstars)]) inlines.append('&'.join(line_els)) bands = ['R1B','R1A','B2B','B2A','B3A'] if not sort_freq: bands.reverse() line_counter = dict() for s in stars: line_counter[s] = 0 for band in bands: #inlines.append(r'\multicolumn{4}{c}{PACS Band: %s} & \multicolumn{%i}{c}{} \\\hline'\ #%(band,len(pstars))) new_band = 1 for it,t in enumerate(trans): #-- Check if there's any actual line strength result for any star # for this particular band; in any filename in this band. # Otherwise, exclude the line from the table. If there's no # spectrum for this band at all, the line is excluded as well. # In this case, the band will not be added to the table at all. # Just look at the keys of t.unreso. If there's none of the # given band, then exclude the transition. All stars are # included in the same Transition() objects. all_keys = [k for k in t.unreso.keys() if band in os.path.split(k)[1].split('_')] if not all_keys: continue #-- There's at least one star with a measured line strength in this # band, so add a column. col1 = all_pmolecs[all_molecs.index(t.molecule.molecule)] #-- If the band has not had a line added before, add the band now if new_band: col0 = band new_band = 0 else: col0 = '' #-- Define the input for the table. parts = [col0,\ col1] if not no_vib: parts.append(t.makeLabel(return_vib=1)) parts.extend([t.makeLabel(inc_vib=0),'%.2f'%(t.wavelength*10**4)]) #-- For every star, add the measured line strength of the # transition, if available. For now, it is assumed only one line # strength measurement is available per star per band. (This is # not strictly true, for instance for overlapping line scans, but # the line integration tool makes it impossible to discern # between multiple measurements of the same line in the same # band) for s in stars: #-- Grab the filename available in the transition object for # the measured line strength. If multiple filenames with the # correct band are available, only the first is taken. all_fn = [sfn for sfn in t.unreso.keys() if band in os.path.split(sfn)[1].split('_')\ and s in os.path.split(sfn)[1].split('_')] #-- Possibly, for this star, no datafiles of given band are # present. Then just add no flux measurement and continue to # the next star. if not all_fn: parts.append(r'/') continue else: fn = all_fn[0] #-- The filename is present, and thus should have a line # strength indicated, or be flagged as a blend. If not, an # error will be raised, but this should not happen! fint,finterr,fintblend = t.getIntIntUnresolved(fn) if fint == 'inblend': parts.append('Blended') else: line_counter[s] += 1 parts.append('%s%s%.2e (%.1f%s)'\ %(t in mark_trans and extra_marker or r'',\ fint<0 and blend_mark or r'',abs(fint),\ finterr*100,r'\%')) parts[-1] = parts[-1] + r'\\' inlines.append('&'.join(parts)) if not new_band and band != bands[-1]: inlines[-1] = inlines[-1] + r'\hline' DataIO.writeFile(filename,input_lines=inlines) if print_summary: print('Summary') for s in stars: print('%s: %i lines measured'%(s,len(dpacs[s].linefit.wave_fit))+\ ', of which %i lines have been identified.'%line_counter[s])
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,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 __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,star_name,instrument_name,oversampling,\ code='GASTRoNOoM',path=None,intrinsic=1,path_linefit='',\ blend_factor=1.2): """ Initializing an instance of Instrument. @param star_name: The name of the star from Star.py @type star_name: string @param instrument_name: The name of the instrument (SPIRE or PACS) @type instrument_name: string @param oversampling: The instrumental oversampling, for correct convolution of the Sphinx output. @type oversampling: int @keyword code: The radiative transfer code used to model the data (default: 'GASTRoNOoM') @type code: string @keyword path: Output folder in the code's home folder. Used to locate eg PACS database. If None, no model info required (eg for line measurement matching/identification) (default: None) @type path: string @keyword intrinsic: Use the intrinsic Sphinx line profiles for convolving with the spectral resolution? Otherwise the beam convolved line profiles are used. (default: 1) @type intrinsic: bool @keyword path_linefit: The folder name for linefit results from Hipe (created by Pierre, assuming his syntax). The folder is located in $path_pacs$/$star_name$/. If no folder is given, no linefits are processed. (default: '') @type path_linefit: string @keyword blend_factor: The relative factor with respect to the intrinsic instrumental FWHM that is compared with the fitted Gaussian FWHM to determine whether an emission line may be blended. (default: 1.2) @type blend_factor: float """ self.path = path self.code = code self.star_name = star_name self.path_linefit = path_linefit self.instrument = instrument_name.lower() self.path_instrument = getattr(cc.path,'d%s'%self.instrument) self.intrinsic = intrinsic self.oversampling = int(oversampling) self.blend_factor = float(blend_factor) self.data_filenames = [] istar = DataIO.getInputData(keyword='STAR_NAME').index(star_name) #-- Set relevant velocities in cm/s self.c = 2.99792458e10 self.vlsr = float(DataIO.getInputData(keyword='V_LSR',rindex=istar))*10**5 if not self.path is None: pp = getattr(cc.path,self.code.lower()) DataIO.testFolderExistence(os.path.join(pp,self.path,'stars')) DataIO.testFolderExistence(os.path.join(pp,self.path,'stars',\ self.star_name)) self.readTelescopeProperties()
def buildPhotometry(star_name,fn='Photometric_IvS',remove=[]): ''' Retrieve the photometry of a star through the IvS repo's SED builder. Save the photometry in a target location. @param star_name: Name of the star (cc name from Star.dat) @type star_name: str @keyword fn: Output filename of the photometry file. Always appends '_STAR.dat' where STAR is star_name. The file is saved in dp. (default: 'Photometric_IvS') @type fn: str @keyword remove: Photometry to be removed from the output file. e.g. ['WISE','DENIS'] (default: []) @type remove: list[str] ''' #-- Get the SIMBAD name of the star si = DataIO.getInputData(filename='Star.dat').index(star_name) sn_sim = DataIO.getInputData(keyword='STAR_NAME_PLOTS')[si] sn_sim = sn_sim.replace('$','').replace('\\','') #-- Define the outputfolder of the Raw data ofn_raw = os.path.join(cc.path.dphot,'_'.join([star_name,'phot.txt'])) ## Retrieve p = builder.SED() star = builder.SED(sn_sim,photfile=ofn_raw) star.get_photometry() ## Read in photometric data columns = ['wave', 'meas', 'emeas', 'photband', 'bibcode', 'comments'] data = np.genfromtxt(star.photfile,usecols = (9,10,11,4,15,16),\ names=columns,dtype = None) #-- Find and remove WISE and DENIS data for photband in remove: selection = rfind(data['photband'],photband) data = data[np.where(selection==-1)] #-- Remove colour measurements (NaN in wavelength) data = data[np.where(np.isfinite(data['wave']))] #-- Fill photbands with whitespace for formatting data['photband'] = ljust(data['photband'],15) #-- Flux: erg/s/cm**2/AA -> Jy (10**-23 erg/s/cm**2/Hz) # From http://astro.wku.edu/strolger/UNITS.txt (non-linear!) c = 2.99792458e18 # in AA/s data['meas'] = data['meas']*data['wave']**2/c*1e23 data['emeas'] = data['emeas']*data['wave']**2/c*1e23 #-- Wavelength: angstrom -> micron data['wave'] = data['wave']*10**-4 #-- Sort the data on wavelength data.sort() ofn_final = os.path.join(cc.path.dsed,'_'.join([fn,star_name+'.dat'])) hdr = 'Photometry extracted with ivs.sed.builder. \nWave (micron) Flux '+\ '(Jy) Error Flux (Jy) Photband Bibcode Comments' np.savetxt(ofn_final,data,fmt=['%.8e']*3+['%s']*3,header=hdr)
def __init__(self,star_name,instrument_name,oversampling,absflux_err,\ code='GASTRoNOoM',path=None,intrinsic=1,path_linefit=''): """ Initializing an instance of Instrument. @param star_name: The name of the star from Star.py @type star_name: string @param instrument_name: The name of the instrument (SPIRE or PACS) @type instrument_name: string @param oversampling: The instrumental oversampling, for correct convolution of the Sphinx output. @type oversampling: int @param absflux_err: The absolute flux calibration uncertainty of the instrument. @type absflux_err: float @keyword code: The radiative transfer code used to model the data (default: 'GASTRoNOoM') @type code: string @keyword path: Output folder in the code's home folder. Used to locate eg PACS database. If None, no model info required (eg for line measurement matching/identification) (default: None) @type path: string @keyword intrinsic: Use the intrinsic Sphinx line profiles for convolving with the spectral resolution? Otherwise the beam convolved line profiles are used. (default: 1) @type intrinsic: bool @keyword path_linefit: The folder name for linefit results from Hipe (created by Pierre, assuming his syntax). The folder is located in $path_pacs$/$star_name$/. If no folder is given, no linefits are processed. (default: '') @type path_linefit: string """ self.path = path self.code = code self.star_name = star_name self.path_linefit = path_linefit self.instrument = instrument_name.lower() self.path_instrument = getattr(cc.path, 'd%s' % self.instrument) self.intrinsic = intrinsic self.absflux_err = absflux_err self.oversampling = int(oversampling) self.data_filenames = [] istar = DataIO.getInputData(keyword='STAR_NAME').index(star_name) #-- Set relevant velocities in cm/s self.c = 2.99792458e10 self.vlsr = DataIO.getInputData(keyword='V_LSR', rindex=istar) * 10**5 if self.path <> None: pp = getattr(cc.path, self.code.lower()) DataIO.testFolderExistence(os.path.join(pp, self.path, 'stars')) DataIO.testFolderExistence(os.path.join(pp,self.path,'stars',\ self.star_name))
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 parseFolder(self): ''' Parse the db folder and add filenames to recognized transitions. Includes: - CO and its isotopologues - SiO and its isotopologues - SiS and its isotopologues - H2O and pH2O - SO2 - CS - PO and PN Particularly excludes: (because no naming convention/too complex) - SO - H2O and pH2O isotopologues - H2CO - CN - HCN and its isotopologues - HCO+ ''' ggf = sorted( glob(self.folder + '/*.dat') + glob(self.folder + '/*.fits')) ggf = [os.path.split(ff)[1] for ff in ggf] ggf = [ff for ff in ggf if '_' in ff] ggf = [ff for ff in ggf if ff[0] != '_'] fsplit = [ff.split('_') for ff in ggf] #-- Convention: star names come first stars = [ff.pop(0) for ff in fsplit] #-- Convention: telescope names are at end of filename before extension telescopes = [os.path.splitext(ff.pop(-1))[0] for ff in fsplit] #-- Convention: vibrational states != 0 in second place in filename. # Vibrational states v1 are added automatically. Others are not, for # now. vibs = [(ff[0][0] == 'v' and len(ff[0]) == 2) and ff.pop(0)[1] or '0' for ff in fsplit] #-- Convention: molecule names always first in the molecule tag molec_trans = ['_'.join(ff) for ff in fsplit] defmolecs = DataIO.getInputData(keyword='TYPE_SHORT',\ filename='Molecule.dat') defmolecs_short = DataIO.getInputData(keyword='NAME_SHORT',\ filename='Molecule.dat') defspec_indices = DataIO.getInputData(keyword='SPEC_INDICES',\ filename='Molecule.dat') for ff, s, mt, tel, vib in zip(ggf, stars, molec_trans, telescopes, vibs): if vib not in ['1', '0']: continue this_dm, this_dms, this_dsi = None, None, None for dm, dms, dsi in zip(defmolecs, defmolecs_short, defspec_indices): if mt[:len(dms)] == dms: this_dm = dm this_dms = dms this_dsi = dsi break #-- Don't bother with these molecules: not clear how they are used # as input for GASTRoNOoM. #-- Note that the parser can already detect decimal quantum numbers # as required by CN evil = ['cn', 'hcn', 'h13cn', 'hco+'] #-- If molecule is not found, or is an evil molecule, or is not of # spectral index type 0, 1, or 2, then skip the entry. if this_dm == None or this_dms in evil or this_dsi not in [ 0, 1, 2 ]: continue mt = mt.replace(this_dms, '', 1) #-- Create the regular expression for the filename convention # Allows co32, h2o123132, h2o-1_2_3-1_3_2 p = re.compile('\d{2,}|-[\d\.?\d_?]+-[\d\.?\d_?]+') parsed = p.match(mt).group().rstrip('_').split('-') #-- if parsed contains one element, several options are possible if len(parsed) == 1: #-- dsi == 1 can only take 6 quantum numbers, 3 per level if len(parsed[0]) == 6 and this_dsi == 1: tupper = parsed[0][0:3] tlower = parsed[0][3:6] #-- dsi == 2 can only take 4 quantum numbers, 2 per level elif len(parsed[0]) == 4 and this_dsi == 2: tupper = parsed[0][0:2] tlower = parsed[0][2:4] #-- dsi == 0 can only take 2 quantum numbers, 1 per level # several combinations are possible for multiple digit levels elif len(parsed[0]) == 6 and this_dsi == 0: tupper = [parsed[0][0:3]] tlower = [parsed[0][3:6]] elif len(parsed[0]) == 5 and this_dsi == 0: tupper = [parsed[0][0:3]] tlower = [parsed[0][3:5]] elif len(parsed[0]) == 4 and this_dsi == 0: tupper = [parsed[0][0:2]] tlower = [parsed[0][2:4]] elif len(parsed[0]) == 3 and this_dsi == 0: tupper = [parsed[0][0:2]] tlower = [parsed[0][2:3]] elif len(parsed[0]) == 2 and this_dsi == 0: tupper = [parsed[0][0]] tlower = [parsed[0][1]] #-- Any other combinations are not possible, and must be # separated with '_', '-' in the filename else: continue #-- If there are three elements, the second and third give the # upper and lower level respectively, each quantum number # separated by '_' elif len(parsed) == 3: #-- parsed[0] is just an empty string tupper = parsed[1].split('_') tlower = parsed[2].split('_') #-- Double check if the correct amount of quantum numbers are # given for each type if (this_dsi == 0 and len(tupper) != 1) or \ (this_dsi == 1 and len(tupper) != 3) or \ (this_dsi == 2 and len(tupper) != 2): continue #-- If neither, continue without adding anything to the db else: continue if this_dsi == 2: trans = 'TRANSITION=%s %s %s %s 0 %s %s %s 0 %s 0.0'\ %(this_dm,vib,tupper[0],tupper[1],\ vib,tlower[0],tlower[1],tel) elif this_dsi == 1: trans = 'TRANSITION=%s 0.0'\ %(' '.join([this_dm,vib,tupper[0],tupper[1],tupper[2],\ vib,tlower[0],tlower[1],tlower[2],tel])) elif this_dsi == 0: trans = 'TRANSITION=%s %s %s 0 0 %s %s 0 0 %s 0.0'\ %(this_dm,vib,tupper[0],vib,tlower[0],tel) self.addData(star_name=s, trans=trans, filename=ff)
def parseFolder(self): """ Parse the db folder and add filenames to recognized transitions. Includes: - CO and its isotopologues - SiO and its isotopologues - SiS and its isotopologues - H2O and pH2O, and their isotopologues - SO2 and SO - CS - PO and PN - H2CO Particularly excludes: (because no naming convention/too complex) - CN - HCN and its isotopologues - HCO+ """ ggf = sorted(glob(self.folder + "/*.dat") + glob(self.folder + "/*.fits")) ggf = [os.path.split(ff)[1] for ff in ggf] ggf = [ff for ff in ggf if "_" in ff] ggf = [ff for ff in ggf if ff[0] != "_"] fsplit = [ff.split("_") for ff in ggf] # -- Convention: star names come first stars = [ff.pop(0) for ff in fsplit] # -- Convention: telescope names are at end of filename before extension telescopes = [os.path.splitext(ff.pop(-1))[0] for ff in fsplit] # -- Convention: vibrational states != 0 in second place in filename. # Vibrational states v1 are added automatically. Others are not, for # now. vibs = [(ff[0][0] == "v" and len(ff[0]) == 2) and ff.pop(0)[1] or "0" for ff in fsplit] # -- Convention: molecule names always first in the molecule tag molec_trans = ["_".join(ff) for ff in fsplit] defmolecs = DataIO.getInputData(keyword="TYPE_SHORT", filename="Molecule.dat") defmolecs_short = DataIO.getInputData(keyword="NAME_SHORT", filename="Molecule.dat") defspec_indices = DataIO.getInputData(keyword="SPEC_INDICES", filename="Molecule.dat") for ff, s, mt, tel, vib in zip(ggf, stars, molec_trans, telescopes, vibs): if vib not in ["1", "0"]: continue this_dm, this_dms, this_dsi = None, None, None for dm, dms, dsi in zip(defmolecs, defmolecs_short, defspec_indices): if mt[: len(dms)] == dms: this_dm = dm this_dms = dms this_dsi = dsi break # -- Don't bother with these molecules: not clear how they are used # as input for GASTRoNOoM. # -- Note that the parser can already detect decimal quantum numbers # as required by CN evil = ["cn", "hcn", "h13cn", "hco+", "oh"] # -- If molecule is not found, or is an evil molecule, or is not of # spectral index type 0, 1, or 2, then skip the entry. if this_dm == None or this_dms in evil or this_dsi not in [0, 1, 2]: continue mt = mt.replace(this_dms, "", 1) # -- Create the regular expression for the filename convention # Allows co32, h2o123132, h2o-1_2_3-1_3_2 p = re.compile("\d{2,}|-[\d\.?\d_?]+-[\d\.?\d_?]+") parsed = p.match(mt).group().rstrip("_").split("-") # -- Note that if a NoneType AttributeError occurs, it's probably # because the molecule has not been added to the convention list # yet, and is therefore considered evil. Added it to the evil list # -- if parsed contains one element, several options are possible if len(parsed) == 1: # -- dsi == 1 can only take 6 quantum numbers, 3 per level if len(parsed[0]) == 6 and this_dsi == 1: tupper = parsed[0][0:3] tlower = parsed[0][3:6] # -- dsi == 2 can only take 4 quantum numbers, 2 per level elif len(parsed[0]) == 4 and this_dsi == 2: tupper = parsed[0][0:2] tlower = parsed[0][2:4] # -- dsi == 0 can only take 2 quantum numbers, 1 per level # several combinations are possible for multiple digit levels elif len(parsed[0]) == 6 and this_dsi == 0: tupper = [parsed[0][0:3]] tlower = [parsed[0][3:6]] elif len(parsed[0]) == 5 and this_dsi == 0: tupper = [parsed[0][0:3]] tlower = [parsed[0][3:5]] elif len(parsed[0]) == 4 and this_dsi == 0: tupper = [parsed[0][0:2]] tlower = [parsed[0][2:4]] elif len(parsed[0]) == 3 and this_dsi == 0: tupper = [parsed[0][0:2]] tlower = [parsed[0][2:3]] elif len(parsed[0]) == 2 and this_dsi == 0: tupper = [parsed[0][0]] tlower = [parsed[0][1]] # -- Any other combinations are not possible, and must be # separated with '_', '-' in the filename else: continue # -- If there are three elements, the second and third give the # upper and lower level respectively, each quantum number # separated by '_' elif len(parsed) == 3: # -- parsed[0] is just an empty string tupper = parsed[1].split("_") tlower = parsed[2].split("_") # -- Double check if the correct amount of quantum numbers are # given for each type if ( (this_dsi == 0 and len(tupper) != 1) or (this_dsi == 1 and len(tupper) != 3) or (this_dsi == 2 and len(tupper) != 2) ): continue # -- If neither, continue without adding anything to the db else: continue if this_dsi == 2: trans = "TRANSITION=%s %s %s %s 0 %s %s %s 0 %s 0.0" % ( this_dm, vib, tupper[0], tupper[1], vib, tlower[0], tlower[1], tel, ) elif this_dsi == 1: trans = "TRANSITION=%s 0.0" % ( " ".join([this_dm, vib, tupper[0], tupper[1], tupper[2], vib, tlower[0], tlower[1], tlower[2], tel]) ) elif this_dsi == 0: trans = "TRANSITION=%s %s %s 0 0 %s %s 0 0 %s 0.0" % (this_dm, vib, tupper[0], vib, tlower[0], tel) self.addData(star_name=s, trans=trans, filename=ff)
def plotSed(self,star_grid=[],cfg='',iterative=0,no_models=0,\ fn_add_star=0): """ Creating an SED with 0, 1 or more models and data. Includes data preparation on the spot. @keyword star_grid: list of Star() models to plot. If star_grid is [], only data are plotted. (default: []) @type star_grid: list[Star()] @keyword cfg: path to the Plotting2.plotCols config file. If default, the hard-coded default plotting options are used. (default: '') @type cfg: string @keyword iterative: add an extra suffix to the filename for each iteratively calculated model, with this number giving the model muber (index in star_grid), 0 if not used. (default: 0) @type iterative: int @keyword no_models: Only show data. (default: 0) @type no_models: bool @keyword fn_add_star: Add the star name to the requested plot filename. (default: 1) @type fn_add_star: bool """ if self.sed is None: print 'No dsed given in Path.dat. Cannot plot SED. Aborting...' return print '***********************************' print '** Creating SED plot.' cfg_dict = Plotting2.readCfg(cfg) if cfg_dict.has_key('no_models'): no_models = cfg_dict['no_models'] if cfg_dict.has_key('fn_add_star'): fn_add_star = bool(cfg_dict['fn_add_star']) if cfg_dict.has_key('filename'): fn_plt = cfg_dict['filename'] del cfg_dict['filename'] else: fn_plt = '' data_labels = dict([(dt,(n,ls)) for n,dt,ls in zip(DataIO.getInputData(path=cc.path.usr,\ keyword='PLOT_NAMES',\ filename='Sed.dat',\ remove_underscore=1),\ DataIO.getInputData(path=cc.path.usr,\ keyword='DATA_TYPES',\ filename='Sed.dat'),\ DataIO.getInputData(path=cc.path.usr,\ keyword='LINE_TYPES',\ filename='Sed.dat'))]) #- filename settings and copying inputfiles to plot output folder if not fn_plt: fn_plt = os.path.join(self.pplot,'SED_%s'%self.star_name) if fn_add_star: fn_plt = '_'.join([fn_plt,self.star_name]) if iterative: fn_plt = fn_plt + '_iterative_%i'%iterative if self.inputfilename <> None: ipfn = os.path.split(self.inputfilename)[1] subprocess.call(['cp ' + self.inputfilename + ' ' + \ os.path.join(self.pplot,ipfn)],\ shell=True) plot_title='SED %s'%self.star_name_plots #- prepare and collect data, keytags and line types keytags = [] data_x = [] data_y = [] data_err = [] line_types = [] for (dt,fn),tdata in sorted([dset for dset in self.sed.data.items() if 'PHOT' not in dset[0][0].upper()]): keytags.append(data_labels[dt][0]) data_x.append(tdata[0]) data_y.append(tdata[1]) #data_err.append(tdata[2]) #-- For now, no error bars for spectra. data_err.append(None) line_types.append(data_labels[dt][1]) for (dt,fn),(w,f,err) in sorted([dset for dset in self.sed.data.items() if 'PHOT' in dset[0][0].upper()]): keytags.append(data_labels[dt][0]) data_x.append(w) data_y.append(f) data_err.append(err) line_types.append(data_labels[dt][1]) #- Collect model data as well as keytags and set line types model_ids_mcm = [s['LAST_MCMAX_MODEL'] for s in star_grid if s['LAST_MCMAX_MODEL']] #- Only if the model_ids list is not empty, MCMax models are available #- Otherwise the ray tracing keyword is unnecessary. if no_models: model_ids_mcm = [] if model_ids_mcm: rt_sed = star_grid[0]['RT_SED'] for model_id in model_ids_mcm: dpath = os.path.join(cc.path.mout,'models',model_id) w,f = MCMax.readModelSpectrum(dpath,rt_sed) data_x.append(w) data_y.append(f) data_err.append(None) keytags.append(model_id.replace('_','\_')) line_types += [0]*len(star_grid) keytags = [tag.replace('#','') for tag in keytags] extra_pars = dict() try: extra_pars['ymax'] = 1.3*max([max(dy) for dy in data_y]) except ValueError: pass try: extra_pars['ymin'] = 0.5*min([min(dy) for dy in data_y]) except ValueError: pass filename = Plotting2.plotCols(x=data_x,y=data_y,yerr=data_err,\ filename=fn_plt,\ figsize=(20,10),number_subplots=1,\ plot_title=plot_title,fontsize_axis=20,\ keytags=keytags,fontsize_title=24,\ linewidth=3,key_location=(0.0,0.75),\ xlogscale=1,transparent=0,cfg=cfg_dict,\ line_types=line_types,ylogscale=0,\ fontsize_ticklabels=20,fontsize_key=18,\ xmin=2,xmax=200,extension='.pdf',\ **extra_pars) print '** Your SED plots can be found at:' print filename print '***********************************'
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 __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 plotSed(self,star_grid=[],cfg='',iterative=0,no_models=0,\ fn_add_star=0): """ Creating an SED with 0, 1 or more models and data. Includes data preparation on the spot. @keyword star_grid: list of Star() models to plot. If star_grid is [], only data are plotted. (default: []) @type star_grid: list[Star()] @keyword cfg: path to the Plotting2.plotCols config file. If default, the hard-coded default plotting options are used. (default: '') @type cfg: string @keyword iterative: add an extra suffix to the filename for each iteratively calculated model, with this number giving the model muber (index in star_grid), 0 if not used. (default: 0) @type iterative: int @keyword no_models: Only show data. (default: 0) @type no_models: bool @keyword fn_add_star: Add the star name to the requested plot filename. (default: 1) @type fn_add_star: bool """ if self.sed is None: print 'No dsed given in Path.dat. Cannot plot SED. Aborting...' return print '***********************************' print '** Creating SED plot.' cfg_dict = Plotting2.readCfg(cfg) if cfg_dict.has_key('no_models'): no_models = cfg_dict['no_models'] if cfg_dict.has_key('fn_add_star'): fn_add_star = bool(cfg_dict['fn_add_star']) if cfg_dict.has_key('filename'): fn_plt = cfg_dict['filename'] del cfg_dict['filename'] else: fn_plt = '' data_labels = dict([(dt,(n,ls)) for n,dt,ls in zip(DataIO.getInputData(path=cc.path.usr,\ keyword='PLOT_NAMES',\ filename='Sed.dat',\ remove_underscore=1),\ DataIO.getInputData(path=cc.path.usr,\ keyword='DATA_TYPES',\ filename='Sed.dat'),\ DataIO.getInputData(path=cc.path.usr,\ keyword='LINE_TYPES',\ filename='Sed.dat'))]) #- filename settings and copying inputfiles to plot output folder if not fn_plt: fn_plt = os.path.join(self.pplot, 'SED_%s' % self.star_name) if fn_add_star: fn_plt = '_'.join([fn_plt, self.star_name]) if iterative: fn_plt = fn_plt + '_iterative_%i' % iterative if self.inputfilename <> None: ipfn = os.path.split(self.inputfilename)[1] subprocess.call(['cp ' + self.inputfilename + ' ' + \ os.path.join(self.pplot,ipfn)],\ shell=True) plot_title = 'SED %s' % self.star_name_plots #- prepare and collect data, keytags and line types keytags = [] data_x = [] data_y = [] data_err = [] line_types = [] for (dt, fn), tdata in sorted([ dset for dset in self.sed.data.items() if 'PHOT' not in dset[0][0].upper() ]): keytags.append(data_labels[dt][0]) data_x.append(tdata[0]) data_y.append(tdata[1]) #data_err.append(tdata[2]) #-- For now, no error bars for spectra. data_err.append(None) line_types.append(data_labels[dt][1]) for (dt, fn), (w, f, err) in sorted([ dset for dset in self.sed.data.items() if 'PHOT' in dset[0][0].upper() ]): keytags.append(data_labels[dt][0]) data_x.append(w) data_y.append(f) data_err.append(err) line_types.append(data_labels[dt][1]) #- Collect model data as well as keytags and set line types model_ids_mcm = [ s['LAST_MCMAX_MODEL'] for s in star_grid if s['LAST_MCMAX_MODEL'] ] #- Only if the model_ids list is not empty, MCMax models are available #- Otherwise the ray tracing keyword is unnecessary. if no_models: model_ids_mcm = [] if model_ids_mcm: rt_sed = star_grid[0]['RT_SED'] for model_id in model_ids_mcm: dpath = os.path.join(cc.path.mout, 'models', model_id) w, f = MCMax.readModelSpectrum(dpath, rt_sed) data_x.append(w) data_y.append(f) data_err.append(None) keytags.append(model_id.replace('_', '\_')) line_types += [0] * len(star_grid) keytags = [tag.replace('#', '') for tag in keytags] extra_pars = dict() try: extra_pars['ymax'] = 1.3 * max([max(dy) for dy in data_y]) except ValueError: pass try: extra_pars['ymin'] = 0.5 * min([min(dy) for dy in data_y]) except ValueError: pass filename = Plotting2.plotCols(x=data_x,y=data_y,yerr=data_err,\ filename=fn_plt,\ figsize=(20,10),number_subplots=1,\ plot_title=plot_title,fontsize_axis=20,\ keytags=keytags,fontsize_title=24,\ linewidth=3,key_location=(0.0,0.75),\ xlogscale=1,transparent=0,cfg=cfg_dict,\ line_types=line_types,ylogscale=0,\ fontsize_ticklabels=20,fontsize_key=18,\ xmin=2,xmax=200,extension='.pdf',\ **extra_pars) print '** Your SED plots can be found at:' print filename print '***********************************'