def plotRatioWav(self,inputfilename,no_peak=False): ''' Plot peak ratios as a function of their central wavelength. @param inputfilename: the input filename for the grid, which will be attached to the final plot filename @type inputfilename: string @keyword no_peak: Hide the peak ratios. (default: False) @type no_peak: bool ''' if not self.chi2_inttot: print "No Sphinx models calculated. Aborting statistics plot. " return this_grid = self.sortStarGrid() plot_filenames = [] inst = self.instrument for star in this_grid: this_id = star['LAST_%s_MODEL'%inst.instrument.upper()] lp = [] waves = [] ratios = [] ratios_err = [] #-- the ratios included in the statistics if not no_peak: this_wav_inc = self.getRatios(data_type='central_wav',\ this_id=this_id) this_ratio_inc = self.getRatios(this_id=this_id) if list(this_wav_inc): waves.append(this_wav_inc) ratios.append(this_ratio_inc) ratios_err.append(None) lp.append('ob') #-- ratios replaced by lower limits if data point is in the noise # ie data point can only be smaller than or equal to used value this_wav_lower = self.getRatios(data_type='central_wav',\ this_id=this_id,\ return_negative=1) this_ratio_lower = self.getRatios(return_negative=1,\ this_id=this_id) this_ratio_lower = [abs(r) for r in this_ratio_lower] if list(this_wav_lower): waves.append(this_wav_lower) ratios.append(this_ratio_lower) ratios_err.append(None) lp.append('dg') if inst.linefit <> None: #-- If integrated intensities are available for the instrument, get # the integrated intensity ratios this_wav_int = self.getRatios(sel_type='int_ratios',\ data_type='central_wav',\ this_id=this_id) this_ratio_int = self.getRatios(sel_type='int_ratios',\ data_type='int_ratios',\ this_id=this_id) this_ratio_int_err = self.getRatios(sel_type='int_ratios',\ data_type='int_ratios_err',\ this_id=this_id) if list(this_wav_int): waves.append(this_wav_int) ratios.append(this_ratio_int) ratios_err.append(this_ratio_int_err) lp.append('or') #-- Get the ratios that are lower limits due to line blends. # Line blends detected due to fitted FHWM/PACS FHWM > 120% # ie model int can only be larger than or equal to used value this_wav_lowerint = self.getRatios(sel_type='int_ratios',\ data_type='central_wav',\ this_id=this_id,\ return_negative=1) this_ratio_lowerint = self.getRatios(sel_type='int_ratios',\ data_type='int_ratios',\ this_id=this_id,\ return_negative=1) this_ratio_lowerint_err = self.getRatios(sel_type='int_ratios',\ data_type='int_ratios_err',\ this_id=this_id,\ return_negative=1) this_ratio_lowerint = [abs(r) for r in this_ratio_lowerint] if list(this_wav_lowerint): waves.append(this_wav_lowerint) ratios.append(this_ratio_lowerint) ratios_err.append(this_ratio_lowerint_err) lp.append('dm') #- prepping input for the plot command xmin = min([min(x) for x in waves]) xmax = max([max(x) for x in waves]) waves.extend([[0.5*xmin,1.5*xmax]]*3) ratios.extend([[1,1],\ [1-inst.absflux_err,\ 1-inst.absflux_err],\ [1+inst.absflux_err,\ 1+inst.absflux_err]]) ratios_err.extend([None,None,None]) lp.extend(['-k','--k','--k']) plot_filename = os.path.join(getattr(cc.path,self.code.lower()),\ self.path_code,'stars',\ self.star_name,\ '%s_results_'%inst.instrument+\ 'ratio_wav_%s'%str(this_id)) labels = [('Mdot = %.2e Msolar/yr'%star['MDOT_GAS'],0.05,0.05),\ ('Teff = %.1f K'%star['T_STAR'],0.05,0.1),\ ('$\psi$ = %0.2e'%star['DUST_TO_GAS_CHANGE_ML_SP'],0.05,\ 0.15),\ ('A$_{H_2O}$/A$_{H_2}$ = %0.2e'%star['F_H2O'],0.05,0.2),\ ('R$_(o,H_2O)$ = %i'%int(star['R_OUTER_H2O']),0.05,0.25)] if star.getMolecule('1H1H16O') \ and star.getMolecule('1H1H16O').set_keyword_change_abundance: labels.append(('$H_2O$ profile = %s'\ %os.path.split(star.getMolecule('1H1H16O')\ .change_fraction_filename\ .replace('_','\_'))[1],\ 0.05,0.30)) plot_title = '%s: $\chi^2_\mathrm{con}$ %.4f'\ %(str(this_id).replace('_','\_'),\ self.chi2_con[this_id]) if self.chi2_inttot[this_id]: plot_title += ', $\chi^2_\mathrm{int}$ %.4f'\ %(self.chi2_inttot[this_id]) plot_filenames.append(Plotting2.plotCols(\ filename=plot_filename,x=waves,y=ratios,yerr=ratios_err,\ yaxis=r'$F_{\nu,p,m}/F_{\nu,p,d}$',\ plot_title=plot_title,labels=labels,extension='pdf',\ xlogscale=0,ylogscale=1,line_types=lp,xmin=xmin*0.9,\ xmax=xmax*1.03,figsize=(10.*scipy.sqrt(2.), 10.),\ linewidth=2,fontsize_title=20,fontsize_label=16)) inputf_short = os.path.splitext(os.path.split(inputfilename)[1])[0] new_filename = os.path.join(getattr(cc.path,self.code.lower()),\ self.path_code,'stars',self.star_name,\ '%s_results_'%inst.instrument+\ 'ratio_wav_%s.pdf'%inputf_short) DataIO.joinPdf(old=plot_filenames,new=new_filename) print '** Stat plots can be found at:' print new_filename print '***********************************'
def plotOpacities(self,star_grid=[],scaling=1,species=['AMC'],\ cfg='',index=0,*args,**kwargs): """ Plotting wavelength dependent mass extinction coefficients (ie opacities). If based on star_grid or modelslist, they are scaled with abundances if wanted. If no model info is given, the input opacities are plotted. Args and kwargs can be given straight to the plot command. @keyword star_grid: The input Star() models. If default, the MCMax input opacities are plotted. (default: []) @type star_grid: list(Star()) @keyword scaling: allow species abundance scaling of opacities (default: 1) @type scaling: bool @keyword species: If no star_grid or model list are given, this gives the species requested to be plotted from Dust.dat (default: ['AMC']) @type species: list(string) @keyword cfg: path to the Plotting2.plotCols config file. If default, the hard-coded default plotting options are used. (default: '') @type cfg: string @keyword index: The index of the kappas in the .opacity/.particle file. 0: extinction, 1: absorption, 2: scattering (default: 0) @type index: int """ print '***********************************' print '** Starting to plot dust opacities.' #-- Set the filename cfg_dict = Plotting2.readCfg(cfg) ppars = dict() if cfg_dict.has_key('filename'): fn_plt = cfg_dict['filename'] del cfg_dict['filename'] elif kwargs.has_key('filename'): fn_plt = kwargs['filename'] del kwargs['filename'] elif not star_grid: fn_plt = os.path.join(cc.path.mopac,\ 'dust_opacities_%s'%'_'.join(species)) else: fn_plt = os.path.join(self.pplot, 'opacities_species') #-- Set some plot parameters ppars['xaxis'] = '$\lambda$ ($\mu \mathrm{m}$)' ppars['yaxis'] = '$\kappa_\lambda$ ($\mathrm{cm}^2\mathrm{/g}$)' ppars['fontsize_key'] = 20 ppars['xlogscale'] = 1 ppars['ylogscale'] = 1 ppars['key_location'] = (0.05, 0.05) ppars.update(kwargs) ppars.update(cfg_dict) #-- Check if raw opacities or modeling results are requested if not star_grid: kr = KappaReader.KappaReader() wl_list = [kr.getKappas(sp)[0] for sp in species] q_list = [kr.getKappas(sp)[1] for sp in species] fn_plt = Plotting2.plotCols(x=wl_list,y=q_list,filename=fn_plt,\ plot_title = 'Dust Opacities',\ keytags=species,*args,**ppars) print '** Your plot can be found at:' print fn_plt else: fns = [] for star in star_grid: try: wave, opacities = star.readKappas() except IOError: continue opacities = [ (opacities[i] + opacities[i + len(star.getDustList())]) for i, species in enumerate(star.getDustList()) ] if scaling: opacities = [ opa * star['A_%s' % sp] for opa, sp in zip(opacities, species) ] fn_mplt = '_'.join(fn_plt, star['LAST_MCMAX_MODEL']) title = 'Dust Opacities in %s (%s)' \ %(self.star_name_plots,\ star['LAST_MCMAX_MODEL'].replace('_','\_')) keys = ['%s with $A$ = %s and $T_{des} = %i$ K'\ %(sp,str(star['A_%s'%sp]),int(star['T_DES_%s'%sp])) for sp in star.getDustList()] fns.append(Plotting2.plotCols(x=wave,y=opacities,keytags=keys,\ plot_title=title,\ filename=fn_mplt,*args,**ppars)) if len(fns) != len(star_grid): print 'At least one of the models requested does not yet ' + \ 'have a MCMax model.' print '** Your plots can be found at:' if fns[-1][-4] == '.pdf': fn_plt = fn_plt + '.pdf' DataIO.joinPdf(old=fns, new=fn_plt) print fn_plt else: print '\n'.join(fns) print '***********************************'
def plotAbundanceProfiles(self,star_grid=[],models=[],force_plot=0,cfg='',\ fn_plt='',molecules=[],per_molecule=0,frac=1): ''' Plot abundance profiles for all molecules in every model. @keyword star_grid: List of Star() instances. If default, model ids have to be given. (default: []) @type star_grid: list[Star()] @keyword models: The model ids, only required if star_grid is [] (default: []) @type models: list[string] @keyword force_plot: force a plotting if more than models are requested (default: 0) @type force_plot: bool @keyword cfg: path to the Plotting2.plotCols config file. If default, the hard-coded default plotting options are used. (default: '') @type cfg: string @keyword fn_plt: A base plot filename. Includes folder. If not, a default is added (default: '') @type fn_plt: string @keyword molecules: Molecules to be plotted. (default: []) @type molecules: bool @keyword per_molecule: Plot one molecule for all models in one figure. (default: 0) @type per_molecule: bool @keyword per_model: Plot all molecules for one model in one figure. (default: 0) @type per_model: bool @keyword frac: Plot the fractional abundances. If not frac, plot number densities. (default: 1) @type frac: bool ''' print '***********************************' print '** Plotting Abundance Profiles' if not star_grid and models: star_grid = self.makeStars(models=models) elif (not models and not star_grid) or (models and star_grid): print '** Input is undefined or doubly defined. Aborting.' return pfns = [] cfg_dict = Plotting2.readCfg(cfg) if cfg_dict.has_key('filename'): fn_plt = cfg_dict.pop('filename') if cfg_dict.has_key('molecules'): molecules = cfg_dict.pop('molecules') if cfg_dict.has_key('per_molecule'): per_molecule = cfg_dict['per_molecule'] if cfg_dict.has_key('per_model'): per_model = cfg_dict['per_model'] #-- Some general plot settings extra_pars = dict() extra_pars['ymin'] = 1e-9 extra_pars['ymax'] = 1e-3 extra_pars['ylogscale'] = 1 extra_pars['xlogscale'] = 1 extra_pars['figsize'] = (12.5, 8.5) extra_pars['xaxis'] = 'cm' #-- Dict to keep track of all data ddata = dict() for istar, star in enumerate(star_grid): if not star['LAST_CHEMISTRY_MODEL']: continue ddata[istar] = dict() folder = os.path.join(cc.path.cout,'models',\ star['LAST_CHEMISTRY_MODEL'])+'/' ddata[istar]['rad'] = DataIO.getChemistryPhysPar(folder+\ 'csphyspar.out', 'RADIUS') ddata[istar]['id'] = star['LAST_CHEMISTRY_MODEL'] if frac: species = DataIO.getChemistryAbundances(folder + 'csfrac.out') else: species = DataIO.getChemistryAbundances(folder + 'csnum.out') for molec in molecules: ddata[istar][molec] = species[molec] if not per_molecule: #-- Collect all data radii = [ddata[istar]['rad']] * len(molecules) abuns = [ddata[istar][molec] for molec in molecules] keytags = molecules #ids = star['LAST_CHEMISTRY_MODEL'] ids = ddata[istar]['id'] #-- Set the yaxis tag yaxis = '$n_\mathrm{molec}/n_{\mathrm{H}_2}$' #-- Set filename pfn = fn_plt if fn_plt else 'abundance_profiles' suff = '_'.join(list(set(ids))) pfn = self.setFnPlt(pfn, fn_suffix=suff) pfns.append(Plotting2.plotCols(x=radii,y=abuns,cfg=cfg_dict,\ filename=pfn,keytags=keytags,\ plot_title=ids.replace('_','\_'),\ yaxis=yaxis,**extra_pars)) if per_molecule: #-- Collect all data #molecs = list(set([molec for istar in ddata.keys() #for molec in ddata[istar].keys()])) for molec in molecules: #-- Collect data radii = [dstar['rad'] for istar, dstar in ddata.items()] abuns = [dstar[molec] for istar, dstar in ddata.items()] keytags = [ dstar['id'].replace('_', '\_') for istar, dstar in ddata.items() ] #-- Set the y axis tag #strmolec = ddata[0][molec]['key'] yaxis = '$n_\mathrm{%s}/n_{\mathrm{H}_2}$' % str(molec) #-- Make filename pfn = fn_plt if fn_plt else 'abundance_profiles' pfn = self.setFnPlt(pfn, fn_suffix=molec) pfns.append(Plotting2.plotCols(x=radii,y=abuns,yaxis=yaxis,\ filename=pfn,keytags=keytags,\ cfg=cfg_dict,**extra_pars)) if not per_molecule and pfns and pfns[0][-4:] == '.pdf': pfn = fn_plt if fn_plt else 'abundance_profiles' pfn = self.setFnPlt(pfn) + '.pdf' DataIO.joinPdf(old=pfns, new=pfn) print '** Plots can be found at:' print pfn print '***********************************' else: print '** Plots can be found at:' print '\n'.join(pfns) print '***********************************'
def plotTempSpecies(self,star_grid=[],models=[],include_total=1,\ power=[1],fn_plt='',cfg=''): """ Plotting the temperature stratification of the dust for the species separately, per model. @keyword star_grid: parameter sets, if [], the parameter sets are determined from the model ids (default: []) @type star_grid: list[Star()] @keyword models: The model_ids, if [], the parameter sets are expected in star_grid (default: []) @type models: list[string] @keyword include_total: Include the sum of all temperature profiles as well for comparison. (default: 0) @type include_total: bool @keyword power: A list of values for s in below formula. If [] no power law is included. Power law parameters are taken from star_grid[0]. See Thesis p32, where power is s in T(r) = T_eff*(2*r/R_STAR)**(-2/(4+s)). (default: [1]) @type power: list @keyword fn_plt: A plot filename for the tiled plot. (default: '') @type fn_plt: string @keyword cfg: path to the Plotting2.plotCols config file. If default, the hard-coded default plotting options are used. (default: '') @type cfg: string """ print '***********************************' print '** Starting to plot dust temperature for separate species.' if not star_grid and not models: print 'Input is undefined. Aborting.' return elif not star_grid and models: star_grid = self.makeMCMaxStars(models=models, id_type='MCMax') raise IOError('Reading dust species temperatures from a model id'+\ ' list only, not yet implemented.') #- Requires star.dust_list and T_CONTACT to be taken from the log file. #- It's possible, but needs some programming cfg_dict = Plotting2.readCfg(cfg) if cfg_dict.has_key('power'): power = cfg_dict['power'] if cfg_dict.has_key('filename'): fn_plt = cfg_dict['filename'] del cfg_dict['filename'] else: fn_plt = os.path.join(self.pplot, 'Td_species') plot_filenames = [] for star in star_grid: if not int(star['T_CONTACT']): rads = [ star.getDustRad(species=species) for species in star.getDustList() ] temps = [ star.getDustTemperature(species=species) for species in star.getDustList() ] rads = [ r[t <= star['T_DES_%s' % sp]] for r, t, sp in zip(rads, temps, star.getDustList()) ] temps = [ t[t <= star['T_DES_%s' % sp]] for t, sp in zip(temps, star.getDustList()) ] keytags = list(star.getDustList()) else: include_total = 1 print 'Thermal contact is on. All dust species share the ' + \ 'same temperature profile. Vertical lines indicate ' + \ 'inner radii of dust species.' rads, temps, keytags = [], [], [] if include_total: rad = star.getDustRad() temp, key = star.getDustTemperature(add_key=1) rads.append(rad[rad>star['R_INNER_DUST']\ *star.Rsun*star['R_STAR']]) temps.append(temp[rad>star['R_INNER_DUST']\ *star.Rsun*star['R_STAR']]) keytags.append(key) #-- Add power laws if requested for s in power: rad = star_grid[0].getDustRad(unit='rstar') tstar = star_grid[0]['T_STAR'] temp,key = Profiler.dustTemperaturePowerLaw(rad=rad,add_key=1,\ tstar=tstar,s=s) rads.append(rad) temps.append(temp) keytags.append(key) filename = '_'.join([fn_plt, star['LAST_MCMAX_MODEL']]) plot_filenames.append(Plotting2.plotCols(x=rads,y=temps,\ cfg=cfg_dict,filename=filename,xaxis='$r$ (cm)',\ yaxis='$T_\mathrm{d}$ (K)',keytags=keytags,\ xmax=star['R_OUTER_DUST']*star.Rsun*star['R_STAR'],\ xmin=star['R_STAR']*star.Rsun,fontsize_axis=26,\ xlogscale=1,ylogscale=1,fontsize_key=16,\ figsize=(12.5,8),transparent=0,linewidth=3,\ fontsize_ticklabels=26,\ vert_lines=[star['R_INNER_DUST']\ *star.Rsun*star['R_STAR']])) if len(plot_filenames) != len(star_grid): print 'At least one of the models does not yet have a MCMax model.' if plot_filenames[0][-4:] == '.pdf': new_filename = fn_plt + '.pdf' DataIO.joinPdf(old=plot_filenames, new=new_filename) print '** Your plots can be found at:' print new_filename print '***********************************' else: print '** Plots can be found at:' print '\n'.join(plot_filenames) print '***********************************'
def plotRatioWav(self, inputfilename, no_peak=False): ''' Plot peak ratios as a function of their central wavelength. @param inputfilename: the input filename for the grid, which will be attached to the final plot filename @type inputfilename: string @keyword no_peak: Hide the peak ratios. (default: False) @type no_peak: bool ''' if not self.chi2_inttot: print "No Sphinx models calculated. Aborting statistics plot. " return this_grid = self.sortStarGrid() plot_filenames = [] inst = self.instrument for star in this_grid: this_id = star['LAST_%s_MODEL' % inst.instrument.upper()] lp = [] waves = [] ratios = [] ratios_err = [] #-- the ratios included in the statistics if not no_peak: this_wav_inc = self.getRatios(data_type='central_wav',\ this_id=this_id) this_ratio_inc = self.getRatios(this_id=this_id) if list(this_wav_inc): waves.append(this_wav_inc) ratios.append(this_ratio_inc) ratios_err.append(None) lp.append('ob') #-- ratios replaced by lower limits if data point is in the noise # ie data point can only be smaller than or equal to used value this_wav_lower = self.getRatios(data_type='central_wav',\ this_id=this_id,\ return_negative=1) this_ratio_lower = self.getRatios(return_negative=1,\ this_id=this_id) this_ratio_lower = [abs(r) for r in this_ratio_lower] if list(this_wav_lower): waves.append(this_wav_lower) ratios.append(this_ratio_lower) ratios_err.append(None) lp.append('dg') if inst.linefit <> None: #-- If integrated intensities are available for the instrument, get # the integrated intensity ratios this_wav_int = self.getRatios(sel_type='int_ratios',\ data_type='central_wav',\ this_id=this_id) this_ratio_int = self.getRatios(sel_type='int_ratios',\ data_type='int_ratios',\ this_id=this_id) this_ratio_int_err = self.getRatios(sel_type='int_ratios',\ data_type='int_ratios_err',\ this_id=this_id) if list(this_wav_int): waves.append(this_wav_int) ratios.append(this_ratio_int) ratios_err.append(this_ratio_int_err) lp.append('or') #-- Get the ratios that are lower limits due to line blends. # Line blends detected due to fitted FHWM/PACS FHWM > 120% # ie model int can only be larger than or equal to used value this_wav_lowerint = self.getRatios(sel_type='int_ratios',\ data_type='central_wav',\ this_id=this_id,\ return_negative=1) this_ratio_lowerint = self.getRatios(sel_type='int_ratios',\ data_type='int_ratios',\ this_id=this_id,\ return_negative=1) this_ratio_lowerint_err = self.getRatios(sel_type='int_ratios',\ data_type='int_ratios_err',\ this_id=this_id,\ return_negative=1) this_ratio_lowerint = [abs(r) for r in this_ratio_lowerint] if list(this_wav_lowerint): waves.append(this_wav_lowerint) ratios.append(this_ratio_lowerint) ratios_err.append(this_ratio_lowerint_err) lp.append('dm') #- prepping input for the plot command xmin = min([min(x) for x in waves]) xmax = max([max(x) for x in waves]) waves.extend([[0.5 * xmin, 1.5 * xmax]] * 3) ratios.extend([[1,1],\ [1-inst.absflux_err,\ 1-inst.absflux_err],\ [1+inst.absflux_err,\ 1+inst.absflux_err]]) ratios_err.extend([None, None, None]) lp.extend(['-k', '--k', '--k']) plot_filename = os.path.join(getattr(cc.path,self.code.lower()),\ self.path_code,'stars',\ self.star_name,\ '%s_results_'%inst.instrument+\ 'ratio_wav_%s'%str(this_id)) labels = [('Mdot = %.2e Msolar/yr'%star['MDOT_GAS'],0.05,0.05),\ ('Teff = %.1f K'%star['T_STAR'],0.05,0.1),\ ('$\psi$ = %0.2e'%star['DUST_TO_GAS_CHANGE_ML_SP'],0.05,\ 0.15),\ ('A$_{H_2O}$/A$_{H_2}$ = %0.2e'%star['F_H2O'],0.05,0.2),\ ('R$_(o,H_2O)$ = %i'%int(star['R_OUTER_H2O']),0.05,0.25)] if star.getMolecule('1H1H16O') \ and star.getMolecule('1H1H16O').set_keyword_change_abundance: labels.append(('$H_2O$ profile = %s'\ %os.path.split(star.getMolecule('1H1H16O')\ .change_fraction_filename\ .replace('_','\_'))[1],\ 0.05,0.30)) plot_title = '%s: $\chi^2_\mathrm{con}$ %.4f'\ %(str(this_id).replace('_','\_'),\ self.chi2_con[this_id]) if self.chi2_inttot[this_id]: plot_title += ', $\chi^2_\mathrm{int}$ %.4f'\ %(self.chi2_inttot[this_id]) plot_filenames.append(Plotting2.plotCols(\ filename=plot_filename,x=waves,y=ratios,yerr=ratios_err,\ yaxis=r'$F_{\nu,p,m}/F_{\nu,p,d}$',\ plot_title=plot_title,labels=labels,extension='pdf',\ xlogscale=0,ylogscale=1,line_types=lp,xmin=xmin*0.9,\ xmax=xmax*1.03,figsize=(10.*scipy.sqrt(2.), 10.),\ linewidth=2,fontsize_title=20,fontsize_label=16)) inputf_short = os.path.splitext(os.path.split(inputfilename)[1])[0] new_filename = os.path.join(getattr(cc.path,self.code.lower()),\ self.path_code,'stars',self.star_name,\ '%s_results_'%inst.instrument+\ 'ratio_wav_%s.pdf'%inputf_short) DataIO.joinPdf(old=plot_filenames, new=new_filename) print '** Stat plots can be found at:' print new_filename print '***********************************'
def plotAbundanceProfiles(self,star_grid=[],models=[],force_plot=0,cfg='',\ fn_plt='',molecules=[],per_molecule=0,frac=1): ''' Plot abundance profiles for all molecules in every model. @keyword star_grid: List of Star() instances. If default, model ids have to be given. (default: []) @type star_grid: list[Star()] @keyword models: The model ids, only required if star_grid is [] (default: []) @type models: list[string] @keyword force_plot: force a plotting if more than models are requested (default: 0) @type force_plot: bool @keyword cfg: path to the Plotting2.plotCols config file. If default, the hard-coded default plotting options are used. (default: '') @type cfg: string @keyword fn_plt: A base plot filename. Includes folder. If not, a default is added (default: '') @type fn_plt: string @keyword molecules: Molecules to be plotted. (default: []) @type molecules: bool @keyword per_molecule: Plot one molecule for all models in one figure. (default: 0) @type per_molecule: bool @keyword per_model: Plot all molecules for one model in one figure. (default: 0) @type per_model: bool @keyword frac: Plot the fractional abundances. If not frac, plot number densities. (default: 1) ''' print '***********************************' print '** Plotting Abundance Profiles' if not star_grid and models: star_grid = self.makeStars(models=models) elif (not models and not star_grid) or (models and star_grid): print '** Input is undefined or doubly defined. Aborting.' return pfns = [] cfg_dict = Plotting2.readCfg(cfg) if cfg_dict.has_key('filename'): fn_plt = cfg_dict.pop('filename') if cfg_dict.has_key('molecules'): molecules = cfg_dict.pop('molecules') if cfg_dict.has_key('per_molecule'): per_molecule = cfg_dict['per_molecule'] if cfg_dict.has_key('per_model'): per_model = cfg_dict['per_model'] #-- Some general plot settings extra_pars = dict() extra_pars['ymin'] = 1e-9 extra_pars['ymax'] = 1e-3 extra_pars['ylogscale'] = 1 extra_pars['xlogscale'] = 1 extra_pars['figsize'] = (12.5,8.5) extra_pars['xaxis'] = 'cm' #-- Dict to keep track of all data ddata = dict() for istar,star in enumerate(star_grid): if not star['LAST_CHEMISTRY_MODEL']: continue ddata[istar] = dict() folder = os.path.join(cc.path.cout,'models',\ star['LAST_CHEMISTRY_MODEL'])+'/' ddata[istar]['rad'] = CodeIO.getChemistryPhysPar(folder+\ 'csphyspar.out', 'RADIUS') ddata[istar]['id'] = star['LAST_CHEMISTRY_MODEL'] if frac: species = CodeIO.getChemistryAbundances(folder+'csfrac.out') else: species = CodeIO.getChemistryAbundances(folder+'csnum.out') for molec in molecules: ddata[istar][molec] = species[molec] if not per_molecule: #-- Collect all data radii = [ddata[istar]['rad']]*len(molecules) abuns = [ddata[istar][molec] for molec in molecules] keytags = molecules #ids = star['LAST_CHEMISTRY_MODEL'] ids = ddata[istar]['id'] #-- Set the yaxis tag yaxis = '$n_\mathrm{molec}/n_{\mathrm{H}_2}$' #-- Set filename pfn = fn_plt if fn_plt else 'abundance_profiles' suff = '_'.join(list(set(ids))) pfn = self.setFnPlt(pfn,fn_suffix=suff) pfns.append(Plotting2.plotCols(x=radii,y=abuns,cfg=cfg_dict,\ filename=pfn,keytags=keytags,\ plot_title=ids.replace('_','\_'),\ yaxis=yaxis,**extra_pars)) if per_molecule: #-- Collect all data #molecs = list(set([molec for istar in ddata.keys() #for molec in ddata[istar].keys()])) for molec in molecules: #-- Collect data radii = [dstar['rad'] for istar,dstar in ddata.items()] abuns = [dstar[molec] for istar,dstar in ddata.items()] keytags = [dstar['id'].replace('_','\_') for istar,dstar in ddata.items()] #-- Set the y axis tag #strmolec = ddata[0][molec]['key'] yaxis = '$n_\mathrm{%s}/n_{\mathrm{H}_2}$'%str(molec) #-- Make filename pfn = fn_plt if fn_plt else 'abundance_profiles' pfn = self.setFnPlt(pfn,fn_suffix=molec) pfns.append(Plotting2.plotCols(x=radii,y=abuns,yaxis=yaxis,\ filename=pfn,keytags=keytags,\ cfg=cfg_dict,**extra_pars)) if not per_molecule and pfns and pfns[0][-4:] == '.pdf': pfn = fn_plt if fn_plt else 'abundance_profiles' pfn = self.setFnPlt(pfn) + '.pdf' DataIO.joinPdf(old=pfns,new=pfn) print '** Plots can be found at:' print pfn print '***********************************' else: print '** Plots can be found at:' print '\n'.join(pfns) print '***********************************'
def plotOpacities(self,star_grid=[],scaling=1,species=['AMC'],\ cfg='',index=0,*args,**kwargs): """ Plotting wavelength dependent mass extinction coefficients (ie opacities). If based on star_grid or modelslist, they are scaled with abundances if wanted. If no model info is given, the input opacities are plotted. Args and kwargs can be given straight to the plot command. @keyword star_grid: The input Star() models. If default, the MCMax input opacities are plotted. (default: []) @type star_grid: list(Star()) @keyword scaling: allow species abundance scaling of opacities (default: 1) @type scaling: bool @keyword species: If no star_grid or model list are given, this gives the species requested to be plotted from Dust.dat (default: ['AMC']) @type species: list(string) @keyword cfg: path to the Plotting2.plotCols config file. If default, the hard-coded default plotting options are used. (default: '') @type cfg: string @keyword index: The index of the kappas in the .opacity/.particle file. 0: extinction, 1: absorption, 2: scattering (default: 0) @type index: int """ print '***********************************' print '** Starting to plot dust opacities.' #-- Set the filename cfg_dict = Plotting2.readCfg(cfg) ppars = dict() if cfg_dict.has_key('filename'): fn_plt = cfg_dict['filename'] del cfg_dict['filename'] elif kwargs.has_key('filename'): fn_plt = kwargs['filename'] del kwargs['filename'] elif not star_grid: fn_plt = os.path.join(cc.path.mopac,\ 'dust_opacities_%s'%'_'.join(species)) else: fn_plt = os.path.join(self.pplot,'opacities_species') #-- Set some plot parameters ppars['xaxis'] = '$\lambda$ ($\mu \mathrm{m}$)' ppars['yaxis'] = '$\kappa_\lambda$ ($\mathrm{cm}^2\mathrm{/g}$)' ppars['fontsize_key'] = 20 ppars['xlogscale'] = 1 ppars['ylogscale'] = 1 ppars['key_location'] = (0.05,0.05) ppars.update(kwargs) ppars.update(cfg_dict) #-- Check if raw opacities or modeling results are requested if not star_grid: kr = KappaReader.KappaReader() wl_list = [kr.getKappas(sp)[0] for sp in species] q_list = [kr.getKappas(sp)[1] for sp in species] fn_plt = Plotting2.plotCols(x=wl_list,y=q_list,filename=fn_plt,\ plot_title = 'Dust Opacities',\ keytags=species,*args,**ppars) print '** Your plot can be found at:' print fn_plt else: fns = [] for star in star_grid: try: wave,opacities = star.readKappas() except IOError: continue opacities = [(opacities[i]+opacities[i+len(star.getDustList())]) for i,species in enumerate(star.getDustList())] if scaling: opacities = [opa*star['A_%s'%sp] for opa,sp in zip(opacities,species)] fn_mplt = '_'.join(fn_plt,star['LAST_MCMAX_MODEL']) title = 'Dust Opacities in %s (%s)' \ %(self.star_name_plots,\ star['LAST_MCMAX_MODEL'].replace('_','\_')) keys = ['%s with $A$ = %s and $T_{des} = %i$ K'\ %(sp,str(star['A_%s'%sp]),int(star['T_DES_%s'%sp])) for sp in star.getDustList()] fns.append(Plotting2.plotCols(x=wave,y=opacities,keytags=keys,\ plot_title=title,\ filename=fn_mplt,*args,**ppars)) if len(fns) != len(star_grid): print 'At least one of the models requested does not yet ' + \ 'have a MCMax model.' print '** Your plots can be found at:' if fns[-1][-4] == '.pdf': fn_plt = fn_plt+'.pdf' DataIO.joinPdf(old=fns,new=fn_plt) print fn_plt else: print '\n'.join(fns) print '***********************************'
def plotTempSpecies(self,star_grid=[],models=[],include_total=1,\ power=[1],fn_plt='',cfg=''): """ Plotting the temperature stratification of the dust for the species separately, per model. @keyword star_grid: parameter sets, if [], the parameter sets are determined from the model ids (default: []) @type star_grid: list[Star()] @keyword models: The model_ids, if [], the parameter sets are expected in star_grid (default: []) @type models: list[string] @keyword include_total: Include the sum of all temperature profiles as well for comparison. (default: 0) @type include_total: bool @keyword power: A list of values for s in below formula. If [] no power law is included. Power law parameters are taken from star_grid[0]. See Thesis p32, where power is s in T(r) = T_eff*(2*r/R_STAR)**(-2/(4+s)). (default: [1]) @type power: list @keyword fn_plt: A plot filename for the tiled plot. (default: '') @type fn_plt: string @keyword cfg: path to the Plotting2.plotCols config file. If default, the hard-coded default plotting options are used. (default: '') @type cfg: string """ print '***********************************' print '** Starting to plot dust temperature for separate species.' if not star_grid and not models: print 'Input is undefined. Aborting.' return elif not star_grid and models: star_grid = self.makeMCMaxStars(models=models,id_type='MCMax') raise IOError('Reading dust species temperatures from a model id'+\ ' list only, not yet implemented.') #- Requires star.dust_list and T_CONTACT to be taken from the log file. #- It's possible, but needs some programming cfg_dict = Plotting2.readCfg(cfg) if cfg_dict.has_key('power'): power = cfg_dict['power'] if cfg_dict.has_key('filename'): fn_plt = cfg_dict['filename'] del cfg_dict['filename'] else: fn_plt = os.path.join(self.pplot,'Td_species') plot_filenames = [] for star in star_grid: if not int(star['T_CONTACT']): rads = [star.getDustRad(species=species) for species in star.getDustList()] temps = [star.getDustTemperature(species=species) for species in star.getDustList()] rads = [r[t<=star['T_DES_%s'%sp]] for r,t,sp in zip(rads,temps,star.getDustList())] temps = [t[t<=star['T_DES_%s'%sp]] for t,sp in zip(temps,star.getDustList())] keytags = list(star.getDustList()) else: include_total = 1 print 'Thermal contact is on. All dust species share the ' + \ 'same temperature profile. Vertical lines indicate ' + \ 'inner radii of dust species.' rads, temps, keytags = [], [], [] if include_total: rad = star.getDustRad() temp, key = star.getDustTemperature(add_key=1) rads.append(rad[rad>star['R_INNER_DUST']\ *star.Rsun*star['R_STAR']]) temps.append(temp[rad>star['R_INNER_DUST']\ *star.Rsun*star['R_STAR']]) keytags.append(key) #-- Add power laws if requested for s in power: rad = star_grid[0].getDustRad(unit='rstar') tstar = star_grid[0]['T_STAR'] temp,key = Profiler.dustTemperaturePowerLaw(rad=rad,add_key=1,\ tstar=tstar,s=s) rads.append(rad) temps.append(temp) keytags.append(key) filename = '_'.join([fn_plt,star['LAST_MCMAX_MODEL']]) plot_filenames.append(Plotting2.plotCols(x=rads,y=temps,\ cfg=cfg_dict,filename=filename,xaxis='$r$ (cm)',\ yaxis='$T_\mathrm{d}$ (K)',keytags=keytags,\ xmax=star['R_OUTER_DUST']*star.Rsun*star['R_STAR'],\ xmin=star['R_STAR']*star.Rsun,fontsize_axis=26,\ xlogscale=1,ylogscale=1,fontsize_key=16,\ figsize=(12.5,8),transparent=0,linewidth=3,\ fontsize_ticklabels=26,\ vert_lines=[star['R_INNER_DUST']\ *star.Rsun*star['R_STAR']])) if len(plot_filenames) != len(star_grid): print 'At least one of the models does not yet have a MCMax model.' if plot_filenames[0][-4:] == '.pdf': new_filename = fn_plt + '.pdf' DataIO.joinPdf(old=plot_filenames,new=new_filename) print '** Your plots can be found at:' print new_filename print '***********************************' else: print '** Plots can be found at:' print '\n'.join(plot_filenames) print '***********************************'