コード例 #1
0
 def dereddenData(self):
     
     '''
     Deredden the data. 
     
     The interstellar extinction curve by Chiar and Tielens (2006) is used 
     with an Av to Ak conversion factor of 0.112.
     
     The correction is done by interpolating the curve, and extrapolating to
     longer wavelengths.
     
     The extrapolation is done with a power law fitted to the long
     wavelength region (lambda > 22 micron).
     
     For short wavelength points below 1.24 micron, the cardelli extinction
     curve is used.
     
     '''
 
     #- Read the extinction curve, then inter/extrapolate it
     ext_x,ext_y = getExtinctionCurve(self.gal_position,'chiar_tielens',\
                                      0.112)
     ext_car_x, ext_car_y = getExtinctionCurve(curve_type='cardelli',\
                                               av_to_ak_conv=0.112)
     #- Initial param guess for extrapolation of long wavelength extinction curve
     p0 = [ -2,  0.01 ,  1, -1]
     #- Assuming a power law for the extrapolation, and fitting from 22 mic  
     deredfunc = 'power'
     extrapol_xmin = 22.0
     chiar_min = ext_x[0]
     #- Fit the power law to the > 22 micron wavelength range
     plsq = leastsq(Interpol.getResiduals,p0,\
                    args=(ext_x[ext_x>=extrapol_xmin],\
                          ext_y[ext_x>=extrapol_xmin],\
                          deredfunc),maxfev=20000)[0]
     #- Calculate the extrapolation and interpolation for the datagrids
     #- Then combine and apply the correction to the data
     for (dt,fn),data in self.data_raw.items():
         if len(data) == 3: 
             data_x, data_y, data_ey = data[0], data[1], data[2]
         else:
             data_x, data_y = data[0], data[1]
         
         extra = Interpol.pEval(data_x[data_x>=extrapol_xmin],plsq,deredfunc)
         inter = interp1d(ext_x,ext_y)(data_x[(data_x<extrapol_xmin)\
                                                 *(data_x>=chiar_min)])
         short = interp1d(ext_car_x,ext_car_y)(data_x[data_x<chiar_min])
         corr = hstack([short,inter,extra])
         if self.plot_extrapol_extinction: 
             Plotting2.plotCols(x=[ext_x,data_x],y=[ext_y,corr],\
                                xlogscale=1,ylogscale=1)
         if len(data) == 3: 
             self.data[(dt,fn)] = (data_x,\
                                   data_y*10**(corr*self.ak*0.4),\
                                   data_ey*10**(corr*self.ak*0.4))
         else:
             self.data[(dt,fn)] = (data_x,data_y*10**(corr*self.ak*0.4))
コード例 #2
0
    def plotExtinction(self, star_grid=[], models=[], plot_default=1, cfg=''):
        """ 
        Plotting wavelength dependent extinction efficiencies wrt grain size.
        
        This always depends on a star_grid or one created from a list of MCMax 
        model ids.
        
        Plotted are the total efficiencies, including relative weights between 
        the included dust species. This is the input for GASTRoNOoM!
        
        @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 cfg: path to the Plotting2.plotCols config file. If default, 
                      the hard-coded default plotting options are used.
                          
                      (default: '')
        @type cfg: string
        
        """

        print '***********************************'
        print '** Plotting Q_ext/a.'
        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)
        x = []
        y = []
        keys = []
        for star in star_grid:
            try:
                inputfile = os.path.join(cc.path.gdata,
                                         star['TEMDUST_FILENAME'])
                opacities = DataIO.readCols(filename=inputfile)
                x.append(opacities[0])
                y.append(opacities[1])
                keys.append('$Q_\mathrm{ext}/a$ for MCMax %s'\
                            %star['LAST_MCMAX_MODEL'].replace('_','\_'))
            except IOError:
                pass
        filename = os.path.join(self.pplot,'gastronoom_opacities_%s'\
                                %star['LAST_MCMAX_MODEL'])
        title = 'GASTRoNOoM Extinction Efficiencies in %s'\
                 %(self.star_name_plots)
        filename = Plotting2.plotCols(x=x,y=y,cfg=cfg,filename=filename,\
                                      xaxis='$\lambda$ ($\mu$m)',keytags=keys,\
                                      yaxis='$Q_{ext}/a$ (cm$^{-1}$)',\
                                      plot_title=title,key_location=(0.7,0.6),\
                                      xlogscale=1,ylogscale=1,fontsize_key=20)
        print '** The extinction efficiency plot can be found at:'
        print filename
        print '***********************************'
コード例 #3
0
ファイル: PlotDust.py プロジェクト: FungKu01/ComboCode
 def plotExtinction(self,star_grid=[],models=[],plot_default=1,cfg=''):
     
     """ 
     Plotting wavelength dependent extinction efficiencies wrt grain size.
     
     This always depends on a star_grid or one created from a list of MCMax 
     model ids.
     
     Plotted are the total efficiencies, including relative weights between 
     the included dust species. This is the input for GASTRoNOoM!
     
     @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 cfg: path to the Plotting2.plotCols config file. If default, 
                   the hard-coded default plotting options are used.
                       
                   (default: '')
     @type cfg: string
     
     """
     
     print '***********************************'
     print '** Plotting Q_ext/a.'
     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)
     x = []
     y = []
     keys = []
     for star in star_grid:        
         try:
             inputfile = os.path.join(cc.path.gdata,star['TEMDUST_FILENAME'])
             opacities = DataIO.readCols(filename=inputfile)
             x.append(opacities[0])
             y.append(opacities[1])
             keys.append('$Q_\mathrm{ext}/a$ for MCMax %s'\
                         %star['LAST_MCMAX_MODEL'].replace('_','\_'))
         except IOError: 
             pass
     filename = os.path.join(self.pplot,'gastronoom_opacities_%s'\
                             %star['LAST_MCMAX_MODEL'])
     title = 'GASTRoNOoM Extinction Efficiencies in %s'\
              %(self.star_name_plots)
     filename = Plotting2.plotCols(x=x,y=y,cfg=cfg,filename=filename,\
                                   xaxis='$\lambda$ ($\mu$m)',keytags=keys,\
                                   yaxis='$Q_{ext}/a$ (cm$^{-1}$)',\
                                   plot_title=title,key_location=(0.7,0.6),\
                                   xlogscale=1,ylogscale=1,fontsize_key=20)
     print '** The extinction efficiency plot can be found at:'
     print filename
     print '***********************************'  
コード例 #4
0
    def show(self):
        '''
        Show the model calculations in a plot.
                
        '''

        x = []
        y = []
        keys = []
        for i, sed in enumerate(self.spec):
            x.append(self.cont_division['sws%i' % i]['w_feat'])
            y.append(self.cont_division['sws%i' % i]['f_division'])
            keys.append(sed.star_name_plots)
        for i, star in enumerate(self.star_grid):
            if star['LAST_MCMAX_MODEL']:
                x.append(self.cont_division[star['LAST_MCMAX_MODEL']]\
                                           ['w_feat'])
                y.append(self.cont_division[star['LAST_MCMAX_MODEL']]\
                                           ['f_division'])
                #star = [s
                #for s in self.star_grid
                #if k == s['LAST_MCMAX_MODEL']][0]
                keys.append(star['LAST_MCMAX_MODEL'].replace('_', '\_'))
                #keys.append(', '.join(['%s = %.2f'%(par.replace('_','\_'),\
                #star[par])
                #for par in star.keys()
                #if par[0:2] == 'A_' and \
                #self.species in par]))
        fn = Plotting2.plotCols(x=x,y=y,xmin=self.frmin*0.9,\
                                xmax=self.frmax*1.1,keytags=keys,\
                                key_location=(0.6,0.02),cfg=self.cfg)
        if fn <> None:
            print 'Your Continuum Division plot can be found at '
            print fn
コード例 #5
0
 def show(self):
     
     '''
     Show the model calculations in a plot.
             
     '''
     
     x = []
     y = []
     keys = []
     for i,sed in enumerate(self.spec):
         x.append(self.cont_division['sws%i'%i]['w_feat'])
         y.append(self.cont_division['sws%i'%i]['f_division'])
         keys.append(sed.star_name_plots)        
     for i,star in enumerate(self.star_grid):
         if star['LAST_MCMAX_MODEL']:
             x.append(self.cont_division[star['LAST_MCMAX_MODEL']]\
                                        ['w_feat'])
             y.append(self.cont_division[star['LAST_MCMAX_MODEL']]\
                                        ['f_division'])
             #star = [s 
                 #for s in self.star_grid 
                 #if k == s['LAST_MCMAX_MODEL']][0]
             keys.append(star['LAST_MCMAX_MODEL'].replace('_','\_'))
             #keys.append(', '.join(['%s = %.2f'%(par.replace('_','\_'),\
                                             #star[par]) 
                                 #for par in star.keys() 
                                 #if par[0:2] == 'A_' and \
                                     #self.species in par]))
     fn = Plotting2.plotCols(x=x,y=y,xmin=self.frmin*0.9,\
                             xmax=self.frmax*1.1,keytags=keys,\
                             key_location=(0.6,0.02),cfg=self.cfg)
     if not fn is None:
         print 'Your Continuum Division plot can be found at '
         print fn
コード例 #6
0
ファイル: Interpol.py プロジェクト: robinlombaert/ComboCode
def fitFunction(x_in,y_in,x_out,show=0,func='linear',initial=[1,0,0.5,-1.5],\
                maxfev=20000):
    '''
    Fit a template function to input data.
    
    @param x_in: The input x values
    @type x_in: list/array
    @param y_in: The input y values
    @type y_in: list/array
    @param x_out: The output x grid
    @type x_out: list/array

    @keyword show: show the fit result
    
                   (default: 0)
    @type show: bool
    @keyword func: The function template (see pEval)
    
                   (default: 'linear')
    @type func: string
    @keyword initial: initialisation parameters for your function, number of
                      parameters depends on type of function (see pEval)
    
                      (default: [1,0,0.5,-1.5])
    @type initial: list(float)
    @keyword maxfev: Maximum number of calls to the function for the leastsq 
                     method. Zero means (1+number of elements in x_in)*100
                     
                     (default: 20000)
    @return: The output y values
    @rtype: list/array
    
    '''

    p_lsq = leastsq(getResiduals,initial,args=(x_in,y_in,func),\
                    maxfev=20000)[0]
    y_out = pEval(x_out, p_lsq, func=func)
    if show:
        print p_lsq
        Plotting2.plotCols(x=[x_in,hstack([x_out,x_in])],\
                           y=[y_in,hstack([y_out,pEval(x_in,p_lsq,func=func)])],\
                           xlogscale=1,ylogscale=1)
    return y_out
コード例 #7
0
 def divideContinuum(self,w,f,dtype,frindex):
     
     '''
     Divide flux by the continuum flux in a dust feature. 
     
     @param w: The wavelength grid
     @type w: list/array
     @param f: The flux grid
     @type f: list/array
     @param dtype: data type (only 'model','sws' for now)
     @type dtype: string
     @param frindex: The index in the franges list for this entry.
     @type frindex: int
     
     @keyword plot: Show a plot of the continuum division 
     @type plot: bool
     
     '''
     
     fr1,fr2 = self.franges[frindex][0],self.franges[frindex][1]
     fr3,fr4 = self.franges[frindex][2],self.franges[frindex][3]
     w_in = list(w[(w>fr1) * (w<fr2)]) + list(w[(w>fr3) * (w<fr4)])
     f_in = list(f[(w>fr1) * (w<fr2)]) + list(f[(w>fr3) * (w<fr4)])
     w_cont = w[(w>self.frmin*0.9)*(w<self.frmax*1.1)]
     f_ori = f[(w>self.frmin*0.9)*(w<self.frmax*1.1)]
     f_cont = Interpol.fitFunction(x_in=w_in,y_in=f_in,x_out=w_cont,\
                                   func=self.func[frindex])
     
     self.cont_division[dtype] = dict()
     self.cont_division[dtype]['w_feat'] = w_cont
     self.cont_division[dtype]['f_feat'] = f_ori
     self.cont_division[dtype]['w_fitsel_feat'] = w_in
     self.cont_division[dtype]['f_fitsel_feat'] = f_in
     self.cont_division[dtype]['f_interp'] = f_cont
     self.cont_division[dtype]['f_division'] = f_ori/f_cont
     
     if self.plot:
         x = [w_cont,w_cont]
         y = [f_ori,f_cont]
         Plotting2.plotCols(x=x,y=y,xmin=self.frmin*0.9,xmax=self.frmax*1.1,\
                            ylogscale=0,xlogscale=0)
コード例 #8
0
    def divideContinuum(self, w, f, dtype, frindex):
        '''
        Divide flux by the continuum flux in a dust feature. 
        
        @param w: The wavelength grid
        @type w: list/array
        @param f: The flux grid
        @type f: list/array
        @param dtype: data type (only 'model','sws' for now)
        @type dtype: string
        @param frindex: The index in the franges list for this entry.
        @type frindex: int
        
        @keyword plot: Show a plot of the continuum division 
        @type plot: bool
        
        '''

        fr1, fr2 = self.franges[frindex][0], self.franges[frindex][1]
        fr3, fr4 = self.franges[frindex][2], self.franges[frindex][3]
        w_in = list(w[(w > fr1) * (w < fr2)]) + list(w[(w > fr3) * (w < fr4)])
        f_in = list(f[(w > fr1) * (w < fr2)]) + list(f[(w > fr3) * (w < fr4)])
        w_cont = w[(w > self.frmin * 0.9) * (w < self.frmax * 1.1)]
        f_ori = f[(w > self.frmin * 0.9) * (w < self.frmax * 1.1)]
        f_cont = Interpol.fitFunction(x_in=w_in,y_in=f_in,x_out=w_cont,\
                                      func=self.func[frindex])

        self.cont_division[dtype] = dict()
        self.cont_division[dtype]['w_feat'] = w_cont
        self.cont_division[dtype]['f_feat'] = f_ori
        self.cont_division[dtype]['w_fitsel_feat'] = w_in
        self.cont_division[dtype]['f_fitsel_feat'] = f_in
        self.cont_division[dtype]['f_interp'] = f_cont
        self.cont_division[dtype]['f_division'] = f_ori / f_cont

        if self.plot:
            x = [w_cont, w_cont]
            y = [f_ori, f_cont]
            Plotting2.plotCols(x=x,y=y,xmin=self.frmin*0.9,xmax=self.frmax*1.1,\
                               ylogscale=0,xlogscale=0)
コード例 #9
0
    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 '***********************************'
コード例 #10
0
ファイル: PlotDust.py プロジェクト: FungKu01/ComboCode
 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 '***********************************'
コード例 #11
0
ファイル: PlotDust.py プロジェクト: FungKu01/ComboCode
    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 '***********************************'
コード例 #12
0
ファイル: PlotChem.py プロジェクト: robinlombaert/ComboCode
    def plotVelocity(self,
                     star_grid=[],
                     models=[],
                     fn_plt='',
                     force_plot=0,
                     cfg=''):
        '''
        Plot velocity versus radius for every model in star_grid.
        
        @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 fn_plt: A base plot filename. Includes folder. If not, a 
                         default is added
                         
                         (default: '')
        @type fn_plt: 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
        
        '''

        print '***********************************'
        print '** Plotting Gas Velocity 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

        cfg_dict = Plotting2.readCfg(cfg)
        if cfg_dict.has_key('filename'):
            fn_plt = cfg_dict.pop('filename')

        if len(star_grid) < 20 or force_plot:

            valid_sg = [
                star for star in star_grid if star['LAST_CHEMISTRY_MODEL']
            ]

            folders = [os.path.join(cc.path.cout,'models',\
                    star['LAST_CHEMISTRY_MODEL'])+'/' for star in valid_sg]

            radii = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'RADIUS') \
                for folder in folders]
            temps = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'VELOCITY') \
                for folder in folders]

            if temps:
                keytags = [
                    star['LAST_CHEMISTRY_MODEL'].replace('_', '\_')
                    for star in valid_sg
                ]

                #-- Set filenames
                pfn = fn_plt if fn_plt else 'velocity_profiles'
                pfn = self.setFnPlt(pfn)

                #-- Run the two plots
                keys_cm = [
                    'Model %i' % (i + 1) for i in xrange(len(star_grid))
                ]
                pfn = Plotting2.plotCols(x=radii,y=temps,cfg=cfg_dict,\
                        filename=pfn,xaxis='$r$ (cm)',\
                        yaxis=r'$v$ (km s$^{-1}$)',\
                        figsize=(12.5,8),fontsize_ticklabels=26,\
                        key_location=(0.05,0.05),xlogscale=1,ylogscale=1,\
                        keytags=keys_cm,fontsize_axis=26,fontsize_key=26)
                print '** Plots can be found at:'
                print pfn
                print '***********************************'
コード例 #13
0
def fitLP(filename=None,lprof=None,theory=0,show=0,cfg='',convert_ms_kms=0,\
          vary_pars=['vexp'],i_vexp=15.0,i_gamma=1.0,do_gauss=0):
    '''
    Fit a line profile with a soft parabola, and a Gaussian component if 
    required. 
    
    The method automatically checks if a second component is needed (eg an 
    extra absorption component). An estimate of the expansion velocity (width 
    of the profile) and an improved guess of the vlsr are given. 
    
    A guess for the gas terminal velocity is returned, as well as its error and
    the fitted profile (sp/gaussian, and if applicable extra gaussian and the 
    full fit). 
    
    @keyword filename: The filename to the data file of the line profile. If 
                       None a line profile object is expected. 
                       
                       (default: None)
    @type filename: string
    @keyword lprof: A line profile object (LPDataReader or inheriting classes)
                    If None, a filename is expected! If not None, the results
                    are saved in this object as well as returned upon method 
                    call
                    
                    (default: None)
    @type lprof: LPDataReader()
    @keyword convert_ms_kms: Convert velocity grid from m/s to km/s.
    
                             (default: 0)
    @type convert_ms_kms: bool
    @keyword theory: If theoretical profile, and filename is given, set vlsr to
                     0 and read two columns. lprof not relevant if True.
                     
                     (default: 0)
    @type theory: bool
    @keyword vary_pars: The soft parabola parameters varied (can only be vexp
                        or gamma for now). The initial values for parameters
                        listed here are not used. If 'gamma' is requested, a 
                        reasonable guess for i_vexp when calling the method 
                        will improve the fitting results. This is done for the 
                        first guess only! If a Gaussian absorption is present
                        improving these first guesses won't make much of a 
                        difference. However, the first guess value for gamma
                        is still used. Vexp is always varied if absorption is 
                        present.
                        
                        (default: ['vexp'])                        
    @type vary_pars: list[string]
    @keyword i_vexp: The initial guess for the expansion velocity. Not relevant
                     if vexp is included in vary_pars.
                     
                     (default: 15.0)
    @type i_vexp: float
    @keyword i_gamma: The initial guess for the gamma parameter of soft parab.
                      Not relevant if gamma is included in vary_pars.
                      
                      (default: 1.0)
    @type i_gamma: float
    @keyword do_gauss: Force a Gaussian fit regardless of soft parabola fit 
                       results. Still does the soft parabola fit first to allow
                       for comparison of parameters.
                        
                       (default: 0)
    @type do_gauss: bool
    @keyword show: Show the results of the fit
                    
                   (default: 0)
    @type show: bool
    
    @return: dictionary including [vexp,evexp,gamma,egamma,fitprof,gaussian,\
             fullfit,dintint,fgintint] 
    @rtype: dict[float,float,float,float,funclib.Function(),\
                 funclib.Function(),funclib.Function()]
    
    '''

    print '*******************************************'
    if theory and filename <> None:
        d = DataIO.readCols(filename=filename)
        vel = d[0]
        flux = d[1]
        vlsr = 0.0
    else:
        if filename is None:
            filename = lprof.filename
        print '** Fitting line profile in %s.' % filename
        if lprof is None:
            lprof = readLineProfile(filename)
        vel = lprof.getVelocity()
        flux = lprof.getFlux()
        vel = vel[-np.isnan(flux)]
        flux = flux[-np.isnan(flux)]
        vlsr = lprof.getVlsr()

    if convert_ms_kms:
        vel = vel / 1000.
    #-- Initial values: [peak tmb,vlsr,vexp,gamma]
    #   For the central peak value, get a first guess from the data
    #   Attempt multiple vexp values and return the best fitting case.
    #   The initial values are given, with an arbitrary value for the vexp key
    i_mid = argmin(np.abs(vel - vlsr))
    peak = mean(flux[i_mid - 2:i_mid + 3])

    #-- Vary vexp or gamma if requested. If not requested i_vexp or i_gamma are
    #   used.
    #   Multiple values for gamma are tried and the best fitting model
    #   is then chosen based on the relative error of the fitted gamma.
    if 'gamma' in vary_pars:
        igammas = array([-0.5, -0.1, 0.1, 0.5, 1.0, 2.0, 4.0])
        firstguess = varyInitialFit(vel,flux,[peak,vlsr,i_vexp,0.0],index=3,\
                                    values=igammas,vary_window=1,vary=[1,1,1,1],\
                                    function=funclib.soft_parabola)
        i_gamma = firstguess.get_parameters()[0][3]
    #-- varyInitialFit adapts the velocity window itself. No more
    #   assumptions needed for the expansion velocity
    ivexps = array([50., 40., 30., 25., 20., 15., 10.])
    if 'vexp' in vary_pars:
        firstguess = varyInitialFit(vel,flux,[peak,vlsr,0.,i_gamma],index=2,\
                                    values=ivexps,vary_window=1,vary=[1,1,1,1],\
                                    function=funclib.soft_parabola)

    vexp = abs(firstguess.get_parameters()[0][2])
    window = 2.
    print 'First guess fit, using a soft parabola:'
    print firstguess.param2str(accuracy=5)

    #-- If vexp > 100, replace with 50. This value is unrealistic, and might be
    #   improved with an extra Gaussian. If not, it will be replaced with a
    #   full Gaussian fit anyway
    if vexp > 100: vexp = 50.
    #-- Check whether irregularities are present in the profile.
    #   Initial parameters for a gaussian are returned if true.
    #   For this, a broad selection is made of the profile, to allow for a
    #   decent noise determination outside the line profile
    keep = np.abs(vel - vlsr) <= (2 * window * vexp)
    velsel, fluxsel = vel[keep], flux[keep]
    include_gauss = checkLPShape(velsel,
                                 fluxsel,
                                 vlsr,
                                 vexp,
                                 window,
                                 show=show)

    #-- Do the fit of the line again, including an extra gaussian if
    #   irregularities are present.
    if include_gauss <> None:
        #-- fit soft para model + gaussian
        #   1. Set up new soft parabola for several guesses of vexp
        ivexps = list(ivexps)
        initial = [peak, vlsr, 0., i_gamma]
        all_init = [[p] * len(ivexps) for i, p in enumerate(initial) if i != 2]
        all_init.insert(2, ivexps)
        functions = [funclib.soft_parabola() for i in ivexps]
        [
            ff.setup_parameters(values=initi)
            for ff, initi in zip(functions, zip(*all_init))
        ]
        #   2. setup gaussian
        gaussians = [funclib.gauss() for ff in functions]
        #   initial guesses assuming an interstellar absorption line from the
        #   checkLPShape method
        [
            gg.setup_parameters(values=include_gauss,
                                vary=[True, True, True, False])
            for gg in gaussians
        ]
        #   3. combine soft para + gaussian, and minimize fit
        mymodels = [
            fit.Model(functions=[ff, gg])
            for ff, gg in zip(functions, gaussians)
        ]
        [fit.minimize(vel[np.abs(vel-vlsr)<=(init[2]*1.5)],\
                      flux[np.abs(vel-vlsr)<=(init[2]*1.5)],\
                      mymodel)
         for mymodel,init in zip(mymodels,zip(*all_init))]
        #   4. Select the best fitting result based on the error on vexp
        mymodels = [fg for fg in mymodels if fg.get_parameters()[1][2] != 0.]
        functions = [
            ff for fg, ff in zip(mymodels, functions)
            if fg.get_parameters()[1][2] != 0.
        ]
        gaussians = [
            gg for fg, gg in zip(mymodels, gaussians)
            if fg.get_parameters()[1][2] != 0.
        ]
        fitvalues = array([fg.get_parameters()[0][2] for fg in mymodels])
        fiterrors = array([fg.get_parameters()[1][2] for fg in mymodels])
        mymodel = mymodels[argmin(abs(fiterrors / fitvalues))]
        finalfit = functions[argmin(abs(fiterrors / fitvalues))]
        gaussian = gaussians[argmin(abs(fiterrors / fitvalues))]
        print 'Improved fit, including extra Gaussian:'
        print mymodel.param2str(accuracy=5)
    else:
        #-- if gamma is requested to be varied, allow another iteration on
        #   gamma with the best vexp guess we already have.
        if 'gamma' in vary_pars:
            finalfit = varyInitialFit(vel,flux,[peak,vlsr,vexp,0.0],\
                                      index=3,values=igammas,vary_window=1,\
                                      function=funclib.soft_parabola,\
                                      vary=[True,True,True,True])
            print 'Final fit with soft parabola, second gamma iteration:'
            print finalfit.param2str(accuracy=5)
        #-- firstguess is best we can do at the moment
        else:
            finalfit = firstguess

    #-- If the relative error on vexp is larger than 30%, usually something
    #   funky is going on in the emission line. Try a Gaussian instead.
    fvlsr = finalfit.get_parameters()[0][1]
    fevlsr = finalfit.get_parameters()[1][1]
    vexp = abs(finalfit.get_parameters()[0][2])
    evexp = abs(finalfit.get_parameters()[1][2])
    gamma = finalfit.get_parameters()[0][3]
    egamma = finalfit.get_parameters()[1][3]
    #-- Gamma has to be positive. If it isnt, dont bother with Gaussian
    #   (double peaked line profile will not be fitted well with a Gaussian!)
    if (evexp/vexp > 0.40 and gamma > 0) or (evexp/vexp > 0.20 and vexp> 30.) \
            or do_gauss:
        #-- Go back to default window to try a Gaussian fit
        #keep = np.abs(vel-vlsr)<=(80)
        #velselg,fluxselg = vel[keep],flux[keep]
        do_gauss = 1
        include_gauss = None
        #-- FWHM is twice vexp!
        sigmas = 2 * ivexps / (2. * sqrt(2. * log(2.)))
        finalfit = varyInitialFit(vel,flux,[peak,vlsr,0.,0.],index=2,\
                                  values=sigmas,function=funclib.gauss,\
                                  vary_window=1,vary=[True,True,True,False])
        vexp = abs(
            finalfit.get_parameters()[0][2]) * (2. * sqrt(2. * log(2.))) / 2.
        evexp = abs(
            finalfit.get_parameters()[1][2]) * (2. * sqrt(2. * log(2.))) / 2.
        fvlsr = finalfit.get_parameters()[0][1]
        fevlsr = finalfit.get_parameters()[1][1]
        gamma, egamma = None, None
        window = 3.
        print 'Improved fit, using a gaussian instead of soft parabola:'
        print finalfit.param2str(accuracy=5)

    #-- Compute numerical integrations.
    #   After fitting, window for integration should be 0.6*window. vexp is
    #   not expected to be too small anymore as in checkLPShape
    keep = np.abs(vel - vlsr) <= (0.6 * window * vexp)
    velsel = vel[keep]
    flux_first = firstguess.evaluate(velsel)
    flux_final = finalfit.evaluate(velsel)
    dimb = trapz(y=flux[keep], x=velsel)
    fi_final = trapz(y=flux_final, x=velsel)
    print('I_mb (emission line data): %f'\
          %dimb)
    print('I_mb (SP -- initial guess): %f'\
          %trapz(y=flux_first,x=velsel))
    print('I_mb (SP -- final guess): %f'\
          %fi_final)
    if include_gauss <> None:
        fitted_flux = mymodel.evaluate(velsel)
        print('I_mb (SP + Gauss fit): %f'\
              %trapz(y=fitted_flux,x=velsel))
    print('Final v_exp guess: %.4f +/- %.4f km/s' % (vexp, evexp))
    if gamma <> None:
        print('Final gamma guess: %.4f +/- %.4f' % (gamma, egamma))
    print('Final vlsr guess: %.4f +/- %.4f' % (fvlsr, fevlsr))
    fwhm = getLPDataFWHM(lprof)
    print('The FWHM is %.2f km/s.' % (fwhm))

    #-- plot
    if show or cfg:
        plt.clf()
        #-- improve velocity window for plotting
        keep = np.abs(vel - vlsr) <= (1.5 * window * vexp)
        velsel, fluxsel = vel[keep], flux[keep]
        vel_highres = np.linspace(velsel[0], velsel[-1], 10000)
        flux_final_highres = finalfit.evaluate(vel_highres)
        flux_first_highres = firstguess.evaluate(vel_highres)
        if include_gauss <> None:
            flux_full_highres = mymodel.evaluate(vel_highres)
        if show:
            plt.step(velsel,fluxsel,'-r',where='mid',lw=3,\
                     label='Observed profile')
            plt.plot(vel_highres,flux_first_highres,'b-',lw=3,\
                     label='First guess')
            plt.plot(vel_highres,flux_final_highres,'g--',lw=3,\
                     label='Improved guess')
            if include_gauss <> None:
                plt.plot(vel_highres,flux_full_highres,'g-',lw=2,\
                         label='Full fit (including Gaussian)')
            leg = plt.legend(loc='best', fancybox=True)
            leg.get_frame().set_alpha(0.5)
            plt.show()
        if cfg:
            pf = '%s_fitted_%s'%(do_gauss and 'gaussFit' or 'SPFit',\
                                 os.path.split(filename)[1])
            keytags = ['Observed profile', 'Improved guess']
            line_types = [
                '-r',
                '-b',
            ]
            x = [velsel, vel_highres]
            y = [fluxsel, flux_final_highres]
            if include_gauss <> None:
                line_types.append('g--')
                x.append(vel_highres)
                y.append(flux_full_highres)
                keytags.append('Full fit (including Gaussian)')
            pf = Plotting2.plotCols(x=x,y=y,filename=pf,cfg=cfg,linewidth=5,\
                                    yaxis='$T_\mathrm{mb}\ (\mathrm{K})$',\
                                    xaxis='$v (\mathrm{km}/\mathrm{s})$',\
                                    keytags=keytags,line_types=line_types,\
                                    histoplot=[0])
            print 'Your figure can be found at %s .' % pf
    #-- Collecting all relevant results and returning.
    results = dict()
    #-- If a Gaussian was used for the main profile fit
    results['do_gauss'] = do_gauss
    #-- Fitted parameters and errors
    results['vlsr'] = fvlsr
    results['evlsr'] = fevlsr
    results['vexp'] = vexp
    results['evexp'] = evexp
    results['fwhm'] = fwhm
    #-- Gamma is None if no soft parabola was fitted
    results['gamma'] = gamma
    results['egamma'] = egamma

    #-- Integrated line strengths: main line fit, data themselves, fit window
    results['fgintint'] = fi_final
    results['dintint'] = dimb
    results['intwindow'] = window * 0.6

    #-- Saving parameters for later evaluation. Full fit is accessible by
    #   making the functions separately and setting pars, then using fit.Model
    results['fitprof'] = (do_gauss and 'gauss' or 'soft_parabola',\
                          list(finalfit.get_parameters()[0]))
    if include_gauss <> None:
        results['fitabs'] = ('gauss', list(gaussian.get_parameters()[0]))
    else:
        results['fitabs'] = None

    return results
コード例 #14
0
ファイル: PlotChem.py プロジェクト: MarieVdS/ComboCode
    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 '***********************************'
コード例 #15
0
ファイル: PlotChem.py プロジェクト: robinlombaert/ComboCode
    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 '***********************************'
コード例 #16
0
ファイル: PlotDust.py プロジェクト: FungKu01/ComboCode
 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 '***********************************'
コード例 #17
0
ファイル: PlotChem.py プロジェクト: MarieVdS/ComboCode
    def plotVelocity(self,star_grid=[],models=[],fn_plt='',force_plot=0,cfg=''):
        
        '''
        Plot velocity versus radius for every model in star_grid.
        
        @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 fn_plt: A base plot filename. Includes folder. If not, a 
                         default is added
                         
                         (default: '')
        @type fn_plt: 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
        
        '''
        
        print '***********************************'
        print '** Plotting Gas Velocity 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
        
        cfg_dict = Plotting2.readCfg(cfg)
        if cfg_dict.has_key('filename'):
            fn_plt = cfg_dict.pop('filename')
        
        if len(star_grid) < 20 or force_plot:
            
            valid_sg = [star for star in star_grid 
                        if star['LAST_CHEMISTRY_MODEL']]
            
            folders = [os.path.join(cc.path.cout,'models',\
                    star['LAST_CHEMISTRY_MODEL'])+'/' for star in valid_sg]
            
            radii = [CodeIO.getChemistryPhysPar(folder+'csphyspar.out', 'RADIUS') \
                for folder in folders]
            temps = [CodeIO.getChemistryPhysPar(folder+'csphyspar.out', 'VELOCITY') \
                for folder in folders]

            if temps:    
                keytags = [star['LAST_CHEMISTRY_MODEL'].replace('_','\_')
                                for star in valid_sg]
                
                #-- Set filenames
                pfn = fn_plt if fn_plt else 'velocity_profiles'
                pfn = self.setFnPlt(pfn)
                
                #-- Run the two plots
                keys_cm = ['Model %i'%(i+1)
                           for i in xrange(len(star_grid))]
                pfn = Plotting2.plotCols(x=radii,y=temps,cfg=cfg_dict,\
                        filename=pfn,xaxis='$r$ (cm)',\
                        yaxis=r'$v$ (km s$^{-1}$)',\
                        figsize=(12.5,8),fontsize_ticklabels=26,\
                        key_location=(0.05,0.05),xlogscale=1,ylogscale=1,\
                        keytags=keys_cm,fontsize_axis=26,fontsize_key=26)
                print '** Plots can be found at:'
                print pfn
                print '***********************************'
コード例 #18
0
ファイル: LPTools.py プロジェクト: FungKu01/ComboCode
def fitLP(
    filename=None,
    lprof=None,
    theory=0,
    show=0,
    cfg="",
    convert_ms_kms=0,
    vary_pars=["vexp"],
    i_vexp=15.0,
    i_gamma=1.0,
    do_gauss=0,
):

    """
    Fit a line profile with a soft parabola, and a Gaussian component if 
    required. 
    
    The method automatically checks if a second component is needed (eg an 
    extra absorption component). An estimate of the expansion velocity (width 
    of the profile) and an improved guess of the vlsr are given. 
    
    A guess for the gas terminal velocity is returned, as well as its error and
    the fitted profile (sp/gaussian, and if applicable extra gaussian and the 
    full fit). 
    
    @keyword filename: The filename to the data file of the line profile. If 
                       None a line profile object is expected. 
                       
                       (default: None)
    @type filename: string
    @keyword lprof: A line profile object (LPDataReader or inheriting classes)
                    If None, a filename is expected! If not None, the results
                    are saved in this object as well as returned upon method 
                    call
                    
                    (default: None)
    @type lprof: LPDataReader()
    @keyword convert_ms_kms: Convert velocity grid from m/s to km/s.
    
                             (default: 0)
    @type convert_ms_kms: bool
    @keyword theory: If theoretical profile, and filename is given, set vlsr to
                     0 and read two columns. lprof not relevant if True.
                     
                     (default: 0)
    @type theory: bool
    @keyword vary_pars: The soft parabola parameters varied (can only be vexp
                        or gamma for now). The initial values for parameters
                        listed here are not used. If 'gamma' is requested, a 
                        reasonable guess for i_vexp when calling the method 
                        will improve the fitting results. This is done for the 
                        first guess only! If a Gaussian absorption is present
                        improving these first guesses won't make much of a 
                        difference. However, the first guess value for gamma
                        is still used. Vexp is always varied if absorption is 
                        present.
                        
                        (default: ['vexp'])                        
    @type vary_pars: list[string]
    @keyword i_vexp: The initial guess for the expansion velocity. Not relevant
                     if vexp is included in vary_pars.
                     
                     (default: 15.0)
    @type i_vexp: float
    @keyword i_gamma: The initial guess for the gamma parameter of soft parab.
                      Not relevant if gamma is included in vary_pars.
                      
                      (default: 1.0)
    @type i_gamma: float
    @keyword do_gauss: Force a Gaussian fit regardless of soft parabola fit 
                       results. Still does the soft parabola fit first to allow
                       for comparison of parameters.
                        
                       (default: 0)
    @type do_gauss: bool
    @keyword show: Show the results of the fit
                    
                   (default: 0)
    @type show: bool
    
    @return: dictionary including [vexp,evexp,gamma,egamma,fitprof,gaussian,\
             fullfit,dintint,fgintint] 
    @rtype: dict[float,float,float,float,funclib.Function(),\
                 funclib.Function(),funclib.Function()]
    
    """

    print "*******************************************"
    if theory and filename <> None:
        d = DataIO.readCols(filename=filename)
        vel = d[0]
        flux = d[1]
        vlsr = 0.0
    else:
        if filename is None:
            filename = lprof.filename
        print "** Fitting line profile in %s." % filename
        if lprof is None:
            lprof = readLineProfile(filename)
        vel = lprof.getVelocity()
        flux = lprof.getFlux()
        vel = vel[-np.isnan(flux)]
        flux = flux[-np.isnan(flux)]
        vlsr = lprof.getVlsr()

    if convert_ms_kms:
        vel = vel / 1000.0
    # -- Initial values: [peak tmb,vlsr,vexp,gamma]
    #   For the central peak value, get a first guess from the data
    #   Attempt multiple vexp values and return the best fitting case.
    #   The initial values are given, with an arbitrary value for the vexp key
    i_mid = argmin(np.abs(vel - vlsr))
    peak = mean(flux[i_mid - 2 : i_mid + 3])

    # -- Vary vexp or gamma if requested. If not requested i_vexp or i_gamma are
    #   used.
    #   Multiple values for gamma are tried and the best fitting model
    #   is then chosen based on the relative error of the fitted gamma.
    if "gamma" in vary_pars:
        igammas = array([-0.5, -0.1, 0.1, 0.5, 1.0, 2.0, 4.0])
        firstguess = varyInitialFit(
            vel,
            flux,
            [peak, vlsr, i_vexp, 0.0],
            index=3,
            values=igammas,
            vary_window=1,
            vary=[1, 1, 1, 1],
            function=funclib.soft_parabola,
        )
        i_gamma = firstguess.get_parameters()[0][3]
    # -- varyInitialFit adapts the velocity window itself. No more
    #   assumptions needed for the expansion velocity
    ivexps = array([50.0, 40.0, 30.0, 25.0, 20.0, 15.0, 10.0])
    if "vexp" in vary_pars:
        firstguess = varyInitialFit(
            vel,
            flux,
            [peak, vlsr, 0.0, i_gamma],
            index=2,
            values=ivexps,
            vary_window=1,
            vary=[1, 1, 1, 1],
            function=funclib.soft_parabola,
        )

    vexp = abs(firstguess.get_parameters()[0][2])
    window = 2.0
    print "First guess fit, using a soft parabola:"
    print firstguess.param2str(accuracy=5)

    # -- If vexp > 100, replace with 50. This value is unrealistic, and might be
    #   improved with an extra Gaussian. If not, it will be replaced with a
    #   full Gaussian fit anyway
    if vexp > 100:
        vexp = 50.0
    # -- Check whether irregularities are present in the profile.
    #   Initial parameters for a gaussian are returned if true.
    #   For this, a broad selection is made of the profile, to allow for a
    #   decent noise determination outside the line profile
    keep = np.abs(vel - vlsr) <= (2 * window * vexp)
    velsel, fluxsel = vel[keep], flux[keep]
    include_gauss = checkLPShape(velsel, fluxsel, vlsr, vexp, window, show=show)

    # -- Do the fit of the line again, including an extra gaussian if
    #   irregularities are present.
    if include_gauss <> None:
        # -- fit soft para model + gaussian
        #   1. Set up new soft parabola for several guesses of vexp
        ivexps = list(ivexps)
        initial = [peak, vlsr, 0.0, i_gamma]
        all_init = [[p] * len(ivexps) for i, p in enumerate(initial) if i != 2]
        all_init.insert(2, ivexps)
        functions = [funclib.soft_parabola() for i in ivexps]
        [ff.setup_parameters(values=initi) for ff, initi in zip(functions, zip(*all_init))]
        #   2. setup gaussian
        gaussians = [funclib.gauss() for ff in functions]
        #   initial guesses assuming an interstellar absorption line from the
        #   checkLPShape method
        [gg.setup_parameters(values=include_gauss, vary=[True, True, True, False]) for gg in gaussians]
        #   3. combine soft para + gaussian, and minimize fit
        mymodels = [fit.Model(functions=[ff, gg]) for ff, gg in zip(functions, gaussians)]
        [
            fit.minimize(
                vel[np.abs(vel - vlsr) <= (init[2] * 1.5)], flux[np.abs(vel - vlsr) <= (init[2] * 1.5)], mymodel
            )
            for mymodel, init in zip(mymodels, zip(*all_init))
        ]
        #   4. Select the best fitting result based on the error on vexp
        mymodels = [fg for fg in mymodels if fg.get_parameters()[1][2] != 0.0]
        functions = [ff for fg, ff in zip(mymodels, functions) if fg.get_parameters()[1][2] != 0.0]
        gaussians = [gg for fg, gg in zip(mymodels, gaussians) if fg.get_parameters()[1][2] != 0.0]
        fitvalues = array([fg.get_parameters()[0][2] for fg in mymodels])
        fiterrors = array([fg.get_parameters()[1][2] for fg in mymodels])
        mymodel = mymodels[argmin(abs(fiterrors / fitvalues))]
        finalfit = functions[argmin(abs(fiterrors / fitvalues))]
        gaussian = gaussians[argmin(abs(fiterrors / fitvalues))]
        print "Improved fit, including extra Gaussian:"
        print mymodel.param2str(accuracy=5)
    else:
        # -- if gamma is requested to be varied, allow another iteration on
        #   gamma with the best vexp guess we already have.
        if "gamma" in vary_pars:
            finalfit = varyInitialFit(
                vel,
                flux,
                [peak, vlsr, vexp, 0.0],
                index=3,
                values=igammas,
                vary_window=1,
                function=funclib.soft_parabola,
                vary=[True, True, True, True],
            )
            print "Final fit with soft parabola, second gamma iteration:"
            print finalfit.param2str(accuracy=5)
        # -- firstguess is best we can do at the moment
        else:
            finalfit = firstguess

    # -- If the relative error on vexp is larger than 30%, usually something
    #   funky is going on in the emission line. Try a Gaussian instead.
    fvlsr = finalfit.get_parameters()[0][1]
    fevlsr = finalfit.get_parameters()[1][1]
    vexp = abs(finalfit.get_parameters()[0][2])
    evexp = abs(finalfit.get_parameters()[1][2])
    gamma = finalfit.get_parameters()[0][3]
    egamma = finalfit.get_parameters()[1][3]
    # -- Gamma has to be positive. If it isnt, dont bother with Gaussian
    #   (double peaked line profile will not be fitted well with a Gaussian!)
    if (evexp / vexp > 0.40 and gamma > 0) or (evexp / vexp > 0.20 and vexp > 30.0) or do_gauss:
        # -- Go back to default window to try a Gaussian fit
        # keep = np.abs(vel-vlsr)<=(80)
        # velselg,fluxselg = vel[keep],flux[keep]
        do_gauss = 1
        include_gauss = None
        # -- FWHM is twice vexp!
        sigmas = 2 * ivexps / (2.0 * sqrt(2.0 * log(2.0)))
        finalfit = varyInitialFit(
            vel,
            flux,
            [peak, vlsr, 0.0, 0.0],
            index=2,
            values=sigmas,
            function=funclib.gauss,
            vary_window=1,
            vary=[True, True, True, False],
        )
        vexp = abs(finalfit.get_parameters()[0][2]) * (2.0 * sqrt(2.0 * log(2.0))) / 2.0
        evexp = abs(finalfit.get_parameters()[1][2]) * (2.0 * sqrt(2.0 * log(2.0))) / 2.0
        fvlsr = finalfit.get_parameters()[0][1]
        fevlsr = finalfit.get_parameters()[1][1]
        gamma, egamma = None, None
        window = 3.0
        print "Improved fit, using a gaussian instead of soft parabola:"
        print finalfit.param2str(accuracy=5)

    # -- Compute numerical integrations.
    #   After fitting, window for integration should be 0.6*window. vexp is
    #   not expected to be too small anymore as in checkLPShape
    keep = np.abs(vel - vlsr) <= (0.6 * window * vexp)
    velsel = vel[keep]
    flux_first = firstguess.evaluate(velsel)
    flux_final = finalfit.evaluate(velsel)
    dimb = trapz(y=flux[keep], x=velsel)
    fi_final = trapz(y=flux_final, x=velsel)
    print ("I_mb (emission line data): %f" % dimb)
    print ("I_mb (SP -- initial guess): %f" % trapz(y=flux_first, x=velsel))
    print ("I_mb (SP -- final guess): %f" % fi_final)
    if include_gauss <> None:
        fitted_flux = mymodel.evaluate(velsel)
        print ("I_mb (SP + Gauss fit): %f" % trapz(y=fitted_flux, x=velsel))
    print ("Final v_exp guess: %.4f +/- %.4f km/s" % (vexp, evexp))
    if gamma <> None:
        print ("Final gamma guess: %.4f +/- %.4f" % (gamma, egamma))
    print ("Final vlsr guess: %.4f +/- %.4f" % (fvlsr, fevlsr))
    fwhm = getLPDataFWHM(lprof)
    print ("The FWHM is %.2f km/s." % (fwhm))

    # -- plot
    if show or cfg:
        plt.clf()
        # -- improve velocity window for plotting
        keep = np.abs(vel - vlsr) <= (1.5 * window * vexp)
        velsel, fluxsel = vel[keep], flux[keep]
        vel_highres = np.linspace(velsel[0], velsel[-1], 10000)
        flux_final_highres = finalfit.evaluate(vel_highres)
        flux_first_highres = firstguess.evaluate(vel_highres)
        if include_gauss <> None:
            flux_full_highres = mymodel.evaluate(vel_highres)
        if show:
            plt.step(velsel, fluxsel, "-r", where="mid", lw=3, label="Observed profile")
            plt.plot(vel_highres, flux_first_highres, "b-", lw=3, label="First guess")
            plt.plot(vel_highres, flux_final_highres, "g--", lw=3, label="Improved guess")
            if include_gauss <> None:
                plt.plot(vel_highres, flux_full_highres, "g-", lw=2, label="Full fit (including Gaussian)")
            leg = plt.legend(loc="best", fancybox=True)
            leg.get_frame().set_alpha(0.5)
            plt.show()
        if cfg:
            pf = "%s_fitted_%s" % (do_gauss and "gaussFit" or "SPFit", os.path.split(filename)[1])
            keytags = ["Observed profile", "Improved guess"]
            line_types = ["-r", "-b"]
            x = [velsel, vel_highres]
            y = [fluxsel, flux_final_highres]
            if include_gauss <> None:
                line_types.append("g--")
                x.append(vel_highres)
                y.append(flux_full_highres)
                keytags.append("Full fit (including Gaussian)")
            pf = Plotting2.plotCols(
                x=x,
                y=y,
                filename=pf,
                cfg=cfg,
                linewidth=5,
                yaxis="$T_\mathrm{mb}\ (\mathrm{K})$",
                xaxis="$v (\mathrm{km}/\mathrm{s})$",
                keytags=keytags,
                line_types=line_types,
                histoplot=[0],
            )
            print "Your figure can be found at %s ." % pf
    # -- Collecting all relevant results and returning.
    results = dict()
    # -- If a Gaussian was used for the main profile fit
    results["do_gauss"] = do_gauss
    # -- Fitted parameters and errors
    results["vlsr"] = fvlsr
    results["evlsr"] = fevlsr
    results["vexp"] = vexp
    results["evexp"] = evexp
    results["fwhm"] = fwhm
    # -- Gamma is None if no soft parabola was fitted
    results["gamma"] = gamma
    results["egamma"] = egamma

    # -- Integrated line strengths: main line fit, data themselves, fit window
    results["fgintint"] = fi_final
    results["dintint"] = dimb
    results["intwindow"] = window * 0.6

    # -- Saving parameters for later evaluation. Full fit is accessible by
    #   making the functions separately and setting pars, then using fit.Model
    results["fitprof"] = (do_gauss and "gauss" or "soft_parabola", list(finalfit.get_parameters()[0]))
    if include_gauss <> None:
        results["fitabs"] = ("gauss", list(gaussian.get_parameters()[0]))
    else:
        results["fitabs"] = None

    return results
コード例 #19
0
    def plotTemp(self, star_grid=[], models=[], power=[1], fn_plt='', cfg=''):
        """ 
        Plotting the temperature stratification of the dust.
        
        All models are shown in one plot.
        
        @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 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 stratification.'
        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)
        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_avg')
        rads = []
        temps = []
        keytags = []
        for star in star_grid:
            rad = star.getDustRad()
            temp, key = star.getDustTemperature(add_key=1)
            rads.append(rad)
            temps.append(temp)
            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)

        title = 'Average Dust Temperature Stratification for %s'\
                %(self.star_name_plots)
        filename = Plotting2.plotCols(x=rads,y=temps,filename=fn_plt,\
                                      yaxis='$T_\mathrm{d}$ (K)',\
                                      plot_title=title,xaxis='$R$ (cm)',\
                                      key_location=(0.05,0.05),cfg=cfg_dict,\
                                      xlogscale=1,ylogscale=1,fontsize_key=20,\
                                      keytags=keytags,fontsize_axis=26,\
                                      figsize=(12.5,8),linewidth=3,\
                                      fontsize_ticklabels=26,)
        print '** Your plots can be found at:'
        print filename
        print '***********************************'
コード例 #20
0
    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 '***********************************'
コード例 #21
0
    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 '***********************************'
コード例 #22
0
    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 '***********************************'
コード例 #23
0
ファイル: UnresoStats.py プロジェクト: FungKu01/ComboCode
 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 '***********************************'
コード例 #24
0
ファイル: PlotDust.py プロジェクト: FungKu01/ComboCode
 def plotTemp(self,star_grid=[],models=[],power=[1],fn_plt='',cfg=''):
     
     """ 
     Plotting the temperature stratification of the dust.
     
     All models are shown in one plot.
     
     @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 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 stratification.'
     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)
     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_avg')
     rads = []
     temps = []
     keytags = []
     for star in star_grid:
         rad = star.getDustRad()
         temp,key = star.getDustTemperature(add_key=1) 
         rads.append(rad)
         temps.append(temp)
         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)
         
     title = 'Average Dust Temperature Stratification for %s'\
             %(self.star_name_plots)
     filename = Plotting2.plotCols(x=rads,y=temps,filename=fn_plt,\
                                   yaxis='$T_\mathrm{d}$ (K)',\
                                   plot_title=title,xaxis='$R$ (cm)',\
                                   key_location=(0.05,0.05),cfg=cfg_dict,\
                                   xlogscale=1,ylogscale=1,fontsize_key=20,\
                                   keytags=keytags,fontsize_axis=26,\
                                   figsize=(12.5,8),linewidth=3,\
                                   fontsize_ticklabels=26,)
     print '** Your plots can be found at:'
     print filename
     print '***********************************'