示例#1
0
    def diff(self, l=None, alpha=2.):
        '''
        Evaluate the derivative of the profile function at a coordinate point.
        
        l can be any value or array. No warning is printed in case of 
        extrapolation, which is done with a power law at small or large l values
        
        The default y-grid is returned if l is None and alpha is 2 (the default)
                
        @keyword l: The coordinate point(s). If None, the default 
                    coordinate grid is used.
                    
                    (default: None)
        @type l: array/float
        @keyword alpha: The exponent of the wavelength-dependent power law
                        extrapolation, such that kappa ~ lambda^-alpha
        
                        (default: 2.)
        @type alpha: float
                
        @return: The derivative evaluated at l
        @rtype: array/float
        
        '''

        #-- Return self.y since l was given as None
        if l is None and alpha == self.alpha:
            return self.dydx

        #-- l can still be None. Apparently different alpha requested. So calc.
        if l is None:
            l = self.l

        #-- First retrieve the original profile. Don't warn since we re-do the
        #   extrapolation anyway. This will have the wrong alpha if alpha is not
        #   2, but we re-do the extrapolation anyway. The original profile will
        #   be untouched.
        dydl = super(Opacity, self).diff(l, warn=0)

        #-- If self.func or self.dfunc is not an interpolator, no warnings
        #   needed, and no extrapolation needed either.
        if not (self.interp_dfunc and self.interp_func): return dydl

        #-- Determine the regions where extrapolation is done, i.e. outside the
        #   original l-grid's range.
        lmin, lmax = self.xin[0], self.xin[-1]
        ymin, ymax = self.yin[0], self.yin[-1]

        #-- Replace the extrapolated values with the new power law. Make sure l
        #   and y are an array for this.
        larr, dydl = Data.arrayify(l), Data.arrayify(dydl)
        dydl[larr < lmin] = ymin * (larr[larr < lmin] /
                                    lmin)**(-alpha - 1.) * -alpha / lmin
        dydl[larr > lmax] = ymax * (larr[larr > lmax] /
                                    lmax)**(-alpha - 1.) * -alpha / lmax

        return dydl if isinstance(l, collections.Iterable) else dydl[0]
示例#2
0
 def diff(self,l=None,alpha=2.):
     
     '''
     Evaluate the derivative of the profile function at a coordinate point.
     
     l can be any value or array. No warning is printed in case of 
     extrapolation, which is done with a power law at small or large l values
     
     The default y-grid is returned if l is None and alpha is 2 (the default)
             
     @keyword l: The coordinate point(s). If None, the default 
                 coordinate grid is used.
                 
                 (default: None)
     @type l: array/float
     @keyword alpha: The exponent of the wavelength-dependent power law
                     extrapolation, such that kappa ~ lambda^-alpha
     
                     (default: 2.)
     @type alpha: float
             
     @return: The derivative evaluated at l
     @rtype: array/float
     
     '''
     
     #-- Return self.y since l was given as None
     if l is None and alpha == self.alpha:
         return self.dydx
     
     #-- l can still be None. Apparently different alpha requested. So calc.
     if l is None: 
         l = self.l
     
     #-- First retrieve the original profile. Don't warn since we re-do the
     #   extrapolation anyway. This will have the wrong alpha if alpha is not
     #   2, but we re-do the extrapolation anyway. The original profile will
     #   be untouched.
     dydl = super(Opacity,self).diff(l,warn=0)
     
     #-- If self.func or self.dfunc is not an interpolator, no warnings 
     #   needed, and no extrapolation needed either.
     if not (self.interp_dfunc and self.interp_func): return dydl
     
     #-- Determine the regions where extrapolation is done, i.e. outside the
     #   original l-grid's range. 
     lmin, lmax = self.xin[0], self.xin[-1]
     ymin, ymax = self.yin[0], self.yin[-1]
     
     #-- Replace the extrapolated values with the new power law. Make sure l
     #   and y are an array for this.
     larr, dydl = Data.arrayify(l), Data.arrayify(dydl)
     dydl[larr<lmin] = ymin*(larr[larr<lmin]/lmin)**(-alpha-1.)*-alpha/lmin
     dydl[larr>lmax] = ymax*(larr[larr>lmax]/lmax)**(-alpha-1.)*-alpha/lmax
     
     return dydl if isinstance(l,collections.Iterable) else dydl[0]
示例#3
0
 def eval(self,l=None,alpha=2.):
     
     '''
     Evaluate the profile function at a coordinate point.
     
     l can be any value or array. No warning is printed in case of 
     extrapolation, which is done with a power law at small or large l values
     
     The default y-grid is returned if l is None and alpha is 2 (the default)
   
     @keyword l: The coordinate point(s). If None, the default 
                 coordinate grid is used.
     
                 (default: None)
     @type l: array/float
     @keyword alpha: The exponent of the wavelength-dependent power law
                     extrapolation, such that kappa ~ lambda^-alpha
     
                     (default: 2.)
     @type alpha: float
             
     @return: The profile evaluated at l
     @rtype: array/float
     
     '''
     
     #-- Return self.y since l was given as None
     if l is None and alpha == self.alpha:
         return self.y
     
     #-- l can still be None. Apparently different alpha requested. So calc.
     if l is None: 
         l = self.l
     
     #-- First retrieve the original profile. Don't warn since we re-do the
     #   extrapolation anyway. If this is the first call from the __init__
     #   method of Opacity(), this will be the standard grid.
     y = super(Opacity,self).eval(l,warn=0)
     
     #-- If self.func is not an interpolator, no warnings needed, and no 
     #   extrapolation needed either.
     if not self.interp_func: return y
     
     #-- Determine the regions where extrapolation is done, i.e. outside the
     #   original l-grid's range. 
     lmin, lmax = self.xin[0], self.xin[-1]
     ymin, ymax = self.yin[0], self.yin[-1]
     
     #-- Replace the extrapolated values with the new power law. Make sure l
     #   and y are an array for this.
     larr, y = Data.arrayify(l), Data.arrayify(y)
     y[larr<lmin] = ymin*(larr[larr<lmin]/lmin)**(-alpha)
     y[larr>lmax] = ymax*(larr[larr>lmax]/lmax)**(-alpha)
     
     return y if isinstance(l,collections.Iterable) else y[0]
示例#4
0
    def eval(self, l=None, alpha=2.):
        '''
        Evaluate the profile function at a coordinate point.
        
        l can be any value or array. No warning is printed in case of 
        extrapolation, which is done with a power law at small or large l values
        
        The default y-grid is returned if l is None and alpha is 2 (the default)
      
        @keyword l: The coordinate point(s). If None, the default 
                    coordinate grid is used.
        
                    (default: None)
        @type l: array/float
        @keyword alpha: The exponent of the wavelength-dependent power law
                        extrapolation, such that kappa ~ lambda^-alpha
        
                        (default: 2.)
        @type alpha: float
                
        @return: The profile evaluated at l
        @rtype: array/float
        
        '''

        #-- Return self.y since l was given as None
        if l is None and alpha == self.alpha:
            return self.y

        #-- l can still be None. Apparently different alpha requested. So calc.
        if l is None:
            l = self.l

        #-- First retrieve the original profile. Don't warn since we re-do the
        #   extrapolation anyway. If this is the first call from the __init__
        #   method of Opacity(), this will be the standard grid.
        y = super(Opacity, self).eval(l, warn=0)

        #-- If self.func is not an interpolator, no warnings needed, and no
        #   extrapolation needed either.
        if not self.interp_func: return y

        #-- Determine the regions where extrapolation is done, i.e. outside the
        #   original l-grid's range.
        lmin, lmax = self.xin[0], self.xin[-1]
        ymin, ymax = self.yin[0], self.yin[-1]

        #-- Replace the extrapolated values with the new power law. Make sure l
        #   and y are an array for this.
        larr, y = Data.arrayify(l), Data.arrayify(y)
        y[larr < lmin] = ymin * (larr[larr < lmin] / lmin)**(-alpha)
        y[larr > lmax] = ymax * (larr[larr > lmax] / lmax)**(-alpha)

        return y if isinstance(l, collections.Iterable) else y[0]
示例#5
0
 def eval(self,x=None,y=None,warn=1):
     
     '''
     Evaluate the profile function at a coordinate point.
     
     x/y can be any value or array. If func is an interpolation object, it is
     in principle limited by the x/y-range of the interpolator. It is advised
     not to extend much beyond the given x/y-range.
     
     If one of the two variables is None, it is replaced by the default grid.
             
     @keyword x: The primary coordinate point(s). If None, the default 
                 coordinate grid is used.
     
                 (default: None)
     @type x: array/float
     @keyword y: The secondary coordinate point(s). If None, the default 
                 coordinate grid is used.
     
                 (default: None)
     @type y: array/float
     @keyword warn: Warn when extrapolation occurs.
     
                    (default: 1)
     @type warn: bool
             
     @return: The profile evaluated at x and y
     @rtype: array/float
     
     '''
     
     #-- Select the actual x/y arrays
     xarr = self.x if x is None else x
     yarr = self.y if y is None else y
         
     #-- Run the boundary check for interpolators
     if self.interp_func and warn:
         #-- Are all requested values in range of the original grid?
         if np.any((xarr>self.x[-1])|(xarr<self.x[0])) \
                 or np.any((yarr>self.y[-1])|(yarr<self.y[0])):
             m = 'Warning! There were values outside of 2D interpolation '+\
                 'range in module {}.'.format(sys.modules[self.__module__])
             xvals, yvals = Data.arrayify(xarr), Data.arrayify(yarr)
             xsel = xvals[(xvals>self.x[-1])|(xvals<self.x[0])]
             ysel = yvals[(yvals>self.y[-1])|(yvals<self.y[0])]
             m += '\nx: {}, \ny: {}'.format(str(xsel),str(ysel))
             print(m)
     
     #-- Return self.z since x and y were given as None
     if x is None and y is None: 
         return self.z
     
     #-- call the interpolator or the function
     return self.func(xarr,yarr,*self._args,**self._kwargs)
示例#6
0
    def eval(self, x=None, y=None, warn=1):
        '''
        Evaluate the profile function at a coordinate point.
        
        x/y can be any value or array. If func is an interpolation object, it is
        in principle limited by the x/y-range of the interpolator. It is advised
        not to extend much beyond the given x/y-range.
        
        If one of the two variables is None, it is replaced by the default grid.
                
        @keyword x: The primary coordinate point(s). If None, the default 
                    coordinate grid is used.
        
                    (default: None)
        @type x: array/float
        @keyword y: The secondary coordinate point(s). If None, the default 
                    coordinate grid is used.
        
                    (default: None)
        @type y: array/float
        @keyword warn: Warn when extrapolation occurs.
        
                       (default: 1)
        @type warn: bool
                
        @return: The profile evaluated at x and y
        @rtype: array/float
        
        '''

        #-- Select the actual x/y arrays
        xarr = self.x if x is None else x
        yarr = self.y if y is None else y

        #-- Run the boundary check for interpolators
        if self.interp_func and warn:
            #-- Are all requested values in range of the original grid?
            if np.any((xarr>self.x[-1])|(xarr<self.x[0])) \
                    or np.any((yarr>self.y[-1])|(yarr<self.y[0])):
                m = 'Warning! There were values outside of 2D interpolation '+\
                    'range in module {}.'.format(sys.modules[self.__module__])
                xvals, yvals = Data.arrayify(xarr), Data.arrayify(yarr)
                xsel = xvals[(xvals > self.x[-1]) | (xvals < self.x[0])]
                ysel = yvals[(yvals > self.y[-1]) | (yvals < self.y[0])]
                m += '\nx: {}, \ny: {}'.format(str(xsel), str(ysel))
                print(m)

        #-- Return self.z since x and y were given as None
        if x is None and y is None:
            return self.z

        #-- call the interpolator or the function
        return self.func(xarr, yarr, *self._args, **self._kwargs)
示例#7
0
 def setNoise(self,vexp=None):
     
     """
     Calculate the noise of the dataset, by taking the standard deviation
     of the velocity range lower than v_lsr - 2*vexp. 
     
     If this is not available, the velocity range is taken to be where it is
     smaller than 1.1*vexp.
     
     If the size of the above selection still is too small, None is 
     returned.
     
     The gas terminal velocity has to have been set previously or passed to
     this method as a keyword.
     
     @keyword vexp: The terminal gas velocity, only required if vexp is not 
                    set yet for this LPDataReader object!
                    
                    (default: None)
     @type vexp: float
     
     @return: The noise of the dataset
     @rtype: float
     
     """
     
     if not vexp is None and not self['contents'].has_key('vexp'):
         self['contents']['vexp'] = float(vexp)
     if not self['contents'].has_key('vexp'):
         print 'Cannot set noise without an estimate for the terminal gas'+\
               ' velocity. Pass as keyword to this method!'
         return None
     vel = self['contents']['velocity']
     flux = self['contents']['flux']
     vlsr = self['contents']['vlsr']
     vexp = self['contents']['vexp']
     noise = Data.getStd(wave=vel,flux=flux,wmin=vlsr-5*vexp,\
                         wmax=vlsr-2*vexp,minsize=10)
     if noise is None:
         noise = Data.getStd(wave=vel,flux=flux,wmin=vlsr-3*vexp,\
                             wmax=vlsr-1.8*vexp,minsize=10)
     if noise is None:
         noise = Data.getStd(wave=vel,flux=flux,wmin=vlsr-3*vexp,\
                             wmax=vlsr-1.1*vexp,minsize=10)
     if noise is None:
         noise = Data.getStd(wave=vel,flux=flux,wmin=vlsr-3*vexp,\
                             wmax=vlsr-1.1*vexp,minsize=5)
     if noise is None:
         print 'WARNING! Noise cannot be determined, not enough data ' + \
               'points outside the emission line.'
     self['contents']['noise'] = noise
     
示例#8
0
    def __convolveSphinx(self,star):
        
        '''
        Convolve the Sphinx output with the SPIRE resolution. The convolution
        is done in wave number (cm^-1).
        
        @param star: The Star() object for which Sphinx profiles are loaded
        @type star: Star()
        
        '''     

        #- Get sphinx model output and merge, for all star models in star_grid
        if not self.resolution: 
            print '* Resolution is undefined. Cannot convolve Sphinx.'
            return
        print '* Reading Sphinx model and merging.'
        sphinx_wav,sphinx_flux = star['LAST_GASTRONOOM_MODEL'] \
                                        and self.mergeSphinx(star) \
                                        or [[],[]]
        if not sphinx_wav: 
            print '* No Sphinx data found.'
            return
        sphinx_wav = 1./array(sphinx_wav)*10**(4)
        sphinx_flux = array(sphinx_flux)
        sphinx_wav = sphinx_wav[::-1]
        sphinx_flux = sphinx_flux[::-1]
        
        #-- eliminate some of the zeroes in the grid to reduce calculation time
        #   (can reduce the array by a factor up to 100!!)
        s = self.sigma
        lcs = array(sorted([1./line.wavelength 
                            for line in star['GAS_LINES']]))
        new_wav, new_flux = [sphinx_wav[0]],[sphinx_flux[0]]
        for w,f in zip(sphinx_wav[1:],sphinx_flux[1:]):
            if f != 0 or (w < 5*s+lcs[argmin(abs(lcs-w))] \
                                and w > lcs[argmin(abs(lcs-w))]-5*s):
                new_wav.append(w)
                new_flux.append(f)
        new_wav, new_flux = array(new_wav), array(new_flux)
        
        #-- convolve the model fluxes with a gaussian and constant sigma(spire)
        print '* Convolving Sphinx model for SPIRE.'
        convolution = Data.convolveArray(new_wav,new_flux,s)
        
        for data_wav,fn in zip(self.data_wave_list,self.data_filenames):
            rebinned = []
            #-- Convert wavelengths to wave number for integration, and reverse
            data_cm = data_wav[::-1]
            data_cm = 1./data_cm*10**4
            rebinned = [trapz(y=convolution[abs(new_wav-wavi)<=self.resolution/self.oversampling],\
                              x=new_wav[abs(new_wav-wavi)<=self.resolution/self.oversampling])\
                            /(self.resolution/self.oversampling)
                        for wavi in data_cm]
            #-- Reverse the rebinned fluxes so they match up with the 
            #   wavelength grid.
            rebinned = array(rebinned)[::-1]
            self.sphinx_convolution[star['LAST_SPIRE_MODEL']][fn] = rebinned
示例#9
0
 def diff(self,r=None,warn=1,inner_eps=None):
     
     '''
     Evaluate the derivative of the profile function at a coordinate point.
     
     r can be any value or array. 
     
     The default y-grid is returned if r is None and inner_eps is 0.5 
     (the default).
     
     @keyword r: The coordinate point(s). If None, the default 
                 coordinate grid is used.
     
                 (default: None)
     @type r: array/float        
     @keyword warn: Warn when extrapolation occurs.
     
                    (default: 1)
     @type warn: bool
     @keyword inner_eps: The exponent of the Teps power law inner wind
                         extrapolation. If default, the inner_eps defined
                         upon initialisation is used.
     
                         (default: None)
     @type inner_eps: float
             
     @return: The derivative evaluated at r
     @rtype: array/float
     
     '''
     
     #-- First retrieve the original profile. If this is the first call from 
     #   the __init__ method of Opacity(), this will be the standard grid.        
     dydx = super(Temperature,self).diff(r,warn=warn)
     
     #-- No inner power law requested, just pass on the original 
     if not self.inner: 
         return dydx
         
     #-- Return self.dydr since r was given as None, if the eps is correct
     if inner_eps is None: inner_eps = self.inner_eps
     if r is None and inner_eps == self.inner_eps:
         return self.y
     
     #-- r can still be None. Apparently different inner_eps requested.
     #   So calc the profile anew with the inner wind law. Need r defined.
     if r is None: 
         r = self.r
         
     #-- Replace the extrapolated values in the inner wind with the new power
     #   law. Make sure r is an array for this.
     rarr = Data.arrayify(r)
     dy_fac = Teps(rarr[rarr<self.r0],T0=self.T0,r0=self.r0,\
                   epsilon=inner_eps-1)
     dydx[rarr<self.r0] = -dy_fac*inner_eps/self.r0
     
     return dydx if isinstance(r,collections.Iterable) else dydx[0]
示例#10
0
    def __convolveSphinx(self, star):
        '''
        Convolve the Sphinx output with the SPIRE resolution. The convolution
        is done in wave number (cm^-1).
        
        @param star: The Star() object for which Sphinx profiles are loaded
        @type star: Star()
        
        '''

        #- Get sphinx model output and merge, for all star models in star_grid
        if not self.resolution:
            print '* Resolution is undefined. Cannot convolve Sphinx.'
            return
        print '* Reading Sphinx model and merging.'
        sphinx_wav,sphinx_flux = star['LAST_GASTRONOOM_MODEL'] \
                                        and self.mergeSphinx(star) \
                                        or [[],[]]
        if not sphinx_wav:
            print '* No Sphinx data found.'
            return
        sphinx_wav = 1. / array(sphinx_wav) * 10**(4)
        sphinx_flux = array(sphinx_flux)
        sphinx_wav = sphinx_wav[::-1]
        sphinx_flux = sphinx_flux[::-1]

        #-- eliminate some of the zeroes in the grid to reduce calculation time
        #   (can reduce the array by a factor up to 100!!)
        s = self.sigma
        lcs = array(
            sorted([1. / line.wavelength for line in star['GAS_LINES']]))
        new_wav, new_flux = [sphinx_wav[0]], [sphinx_flux[0]]
        for w, f in zip(sphinx_wav[1:], sphinx_flux[1:]):
            if f != 0 or (w < 5*s+lcs[argmin(abs(lcs-w))] \
                                and w > lcs[argmin(abs(lcs-w))]-5*s):
                new_wav.append(w)
                new_flux.append(f)
        new_wav, new_flux = array(new_wav), array(new_flux)

        #-- convolve the model fluxes with a gaussian and constant sigma(spire)
        print '* Convolving Sphinx model for SPIRE.'
        convolution = Data.convolveArray(new_wav, new_flux, s)

        for data_wav, fn in zip(self.data_wave_list, self.data_filenames):
            rebinned = []
            #-- Convert wavelengths to wave number for integration, and reverse
            data_cm = data_wav[::-1]
            data_cm = 1. / data_cm * 10**4
            rebinned = [trapz(y=convolution[abs(new_wav-wavi)<=self.resolution/self.oversampling],\
                              x=new_wav[abs(new_wav-wavi)<=self.resolution/self.oversampling])\
                            /(self.resolution/self.oversampling)
                        for wavi in data_cm]
            #-- Reverse the rebinned fluxes so they match up with the
            #   wavelength grid.
            rebinned = array(rebinned)[::-1]
            self.sphinx_convolution[star['LAST_SPIRE_MODEL']][fn] = rebinned
示例#11
0
    def diff(self, r=None, warn=1, inner_eps=None):
        '''
        Evaluate the derivative of the profile function at a coordinate point.
        
        r can be any value or array. 
        
        The default y-grid is returned if r is None and inner_eps is 0.5 
        (the default).
        
        @keyword r: The coordinate point(s). If None, the default 
                    coordinate grid is used.
        
                    (default: None)
        @type r: array/float        
        @keyword warn: Warn when extrapolation occurs.
        
                       (default: 1)
        @type warn: bool
        @keyword inner_eps: The exponent of the Teps power law inner wind
                            extrapolation. If default, the inner_eps defined
                            upon initialisation is used.
        
                            (default: None)
        @type inner_eps: float
                
        @return: The derivative evaluated at r
        @rtype: array/float
        
        '''

        #-- First retrieve the original profile. If this is the first call from
        #   the __init__ method of Opacity(), this will be the standard grid.
        dydx = super(Temperature, self).diff(r, warn=warn)

        #-- No inner power law requested, just pass on the original
        if not self.inner:
            return dydx

        #-- Return self.dydr since r was given as None, if the eps is correct
        if inner_eps is None: inner_eps = self.inner_eps
        if r is None and inner_eps == self.inner_eps:
            return self.y

        #-- r can still be None. Apparently different inner_eps requested.
        #   So calc the profile anew with the inner wind law. Need r defined.
        if r is None:
            r = self.r

        #-- Replace the extrapolated values in the inner wind with the new power
        #   law. Make sure r is an array for this.
        rarr = Data.arrayify(r)
        dy_fac = Teps(rarr[rarr<self.r0],T0=self.T0,r0=self.r0,\
                      epsilon=inner_eps-1)
        dydx[rarr < self.r0] = -dy_fac * inner_eps / self.r0

        return dydx if isinstance(r, collections.Iterable) else dydx[0]
示例#12
0
 def eval(self,x=None,warn=1):
     
     '''
     Evaluate the profile function at a coordinate point.
     
     x can be any value or array. If func is an interpolation object, it is
     in principle limited by the x-range of the interpolator. It is advised 
     not to extend much beyond the given x-range.
     
     The default y-grid is returned if x is None.a
   
     @keyword x: The coordinate point(s). If None, the default 
                 coordinate grid is used.
     
                 (default: None)
     @type x: array/float
     @keyword warn: Warn when extrapolation occurs.
     
                    (default: 1)
     @type warn: bool
             
     @return: The profile evaluated at x
     @rtype: array/float
     
     '''
     
     #-- Run the boundary check for interpolators
     if self.interp_func and warn:
         #-- Select the actual x array (for the cases that x is None)
         xarr = self.x if x is None else x
         
         #-- Are all requested values in range of the original grid?
         if np.any((xarr>self.xin[-1])|(xarr<self.xin[0])):
             m = 'Warning! There were values outside of interpolation '+\
                 'range in module {}.'.format(sys.modules[self.__module__])
             vals = Data.arrayify(xarr)
             sel = vals[(vals>self.xin[-1])|(vals<self.xin[0])]
             m += '\n {}'.format(str(sel))
             print(m)
     
     #-- Return self.y since x was given as None
     if x is None:
         return self.y
     
     #-- call the interpolator or the function
     return self.func(x,*self._args,**self._kwargs)
示例#13
0
    def eval(self, x=None, warn=1):
        '''
        Evaluate the profile function at a coordinate point.
        
        x can be any value or array. If func is an interpolation object, it is
        in principle limited by the x-range of the interpolator. It is advised 
        not to extend much beyond the given x-range.
        
        The default y-grid is returned if x is None.a
      
        @keyword x: The coordinate point(s). If None, the default 
                    coordinate grid is used.
        
                    (default: None)
        @type x: array/float
        @keyword warn: Warn when extrapolation occurs.
        
                       (default: 1)
        @type warn: bool
                
        @return: The profile evaluated at x
        @rtype: array/float
        
        '''

        #-- Run the boundary check for interpolators
        if self.interp_func and warn:
            #-- Select the actual x array (for the cases that x is None)
            xarr = self.x if x is None else x

            #-- Are all requested values in range of the original grid?
            if np.any((xarr > self.xin[-1]) | (xarr < self.xin[0])):
                m = 'Warning! There were values outside of interpolation '+\
                    'range in module {}.'.format(sys.modules[self.__module__])
                vals = Data.arrayify(xarr)
                sel = vals[(vals > self.xin[-1]) | (vals < self.xin[0])]
                m += '\n {}'.format(str(sel))
                print(m)

        #-- Return self.y since x was given as None
        if x is None:
            return self.y

        #-- call the interpolator or the function
        return self.func(x, *self._args, **self._kwargs)
 def get(self,ptype,prop,index=None):
 
     '''
     Return a property for a given type of property possibly for a given 
     index. 
     
     In case a single value is requested via index, the property value is
     extracted from the array.
     
     @param ptype: The type of property. 'coll_trans', 'trans' or 'level'.
     @type ptype: str
     @param prop: The property itself. eg 'energy' for level, or 'lup' for 
                  trans, or 'rates' for coll_trans.
     @type prop: str
     
     @keyword index: The index. In case of default, all are returned. Can be
                     any array-like object that includes indices
                     
                     (default: None)
     @type index: int/array
     
     @return: The property sorted by property type index, or a single element
     @rtype: float/int/array
     
     '''
     
     #-- Return all if no index specified, otherwise set an iterable.
     if index is None:
         return self[ptype][prop]
         
     #-- Prefer explicit selection on indexing. Using indexing instead of 
     #   np.in1d to maintain the original shape of index. Assumes indexing in
     #   files goes 1 -> i_max. This is normally the case. Much faster. 
     #selection = self[ptype][prop][np.in1d(self[ptype]['index'],index)]
     selection = self[ptype][prop][Data.arrayify(index)-1]
     
     #-- If a non-iterable object was passed as index, return just one value
     #   if only one value was indeed found. Otherwise, just return as is.
     if selection.shape != (1,) or isinstance(index,collections.Iterable):
         return selection
     else:
         return selection[0]
示例#15
0
    def get(self, ptype, prop, index=None):
        '''
        Return a property for a given type of property possibly for a given 
        index. 
        
        In case a single value is requested via index, the property value is
        extracted from the array.
        
        @param ptype: The type of property. 'coll_trans', 'trans' or 'level'.
        @type ptype: str
        @param prop: The property itself. eg 'energy' for level, or 'lup' for 
                     trans, or 'rates' for coll_trans.
        @type prop: str
        
        @keyword index: The index. In case of default, all are returned. Can be
                        any array-like object that includes indices
                        
                        (default: None)
        @type index: int/array
        
        @return: The property sorted by property type index, or a single element
        @rtype: float/int/array
        
        '''

        #-- Return all if no index specified, otherwise set an iterable.
        if index is None:
            return self[ptype][prop]

        #-- Prefer explicit selection on indexing. Using indexing instead of
        #   np.in1d to maintain the original shape of index. Assumes indexing in
        #   files goes 1 -> i_max. This is normally the case. Much faster.
        #selection = self[ptype][prop][np.in1d(self[ptype]['index'],index)]
        selection = self[ptype][prop][Data.arrayify(index) - 1]

        #-- If a non-iterable object was passed as index, return just one value
        #   if only one value was indeed found. Otherwise, just return as is.
        if selection.shape != (1, ) or isinstance(index, collections.Iterable):
            return selection
        else:
            return selection[0]
示例#16
0
   def __convolveSphinx(self,star):
       
       '''
       Check if sphinx output has already been convolved (pacs db) and do so 
       if not.
       
       @param star: The parameter set
       @type star: Star()
       
       '''     
       
       #- check for which filenames the convolution has already been done
       finished_conv_filenames = self.checkStarDb(star)
       finished_conv_filenames = [this_f 
                                  for this_f in finished_conv_filenames 
                                  if this_f in [os.path.split(f)[1] 
                                                for f in self.data_filenames]]
       
       #- if after db check pacs id is undefined, then there is no pacs model,
       #- and the convolution will be done anyway
       if self.redo_convolution and star['LAST_PACS_MODEL']:    
           for filename in finished_conv_filenames:
               ori = os.path.join(cc.path.gout,'stars',self.star_name,\
                                  'PACS_results',star['LAST_PACS_MODEL'],\
                                  '_'.join(['sphinx',filename]))
               backup = os.path.join(cc.path.gout,'stars',self.star_name,\
                                     'PACS_results',star['LAST_PACS_MODEL'],\
                                     '_'.join(['backup','sphinx',filename]))
               subprocess.call(['mv %s %s'%(ori,backup)],shell=True)
           self.db[star['LAST_PACS_MODEL']]['filenames'] = []
           finished_conv_filenames = []
       filenames_to_do = [this_f 
                          for this_f in [os.path.split(f)[1] 
                                         for f in self.data_filenames]
                          if this_f not in finished_conv_filenames]     
       
       #-Get sphinx model output and merge, for all star models in star_grid
       if filenames_to_do:        
           #- if list is not empty, some filenames still need a convolution    
           print '* Reading Sphinx model and merging.'
           merged = star['LAST_GASTRONOOM_MODEL'] \
                       and self.mergeSphinx(star) \
                       or [[],[]]
           sphinx_wave = merged[0]
           sphinx_flux = merged[1]
           if not sphinx_wave: 
               print '* No Sphinx data found.'
               return
 
           #- convolve the model fluxes with a gaussian at central wavelength 
           #- from data_wave_list for every star, and appropriate sigma
           print '* Convolving Sphinx model, after correction for v_lsr.'
           if not self.data_delta_list:
               self.setDataResolution()
           for filename in filenames_to_do:
               i_file = [os.path.split(f)[1] 
                         for f in self.data_filenames].index(filename)
               if not star['LAST_PACS_MODEL']:
                   star['LAST_PACS_MODEL'] = \
                       'pacs_%.4i-%.2i-%.2ih%.2i-%.2i-%.2i'\
                       %(gmtime()[0],gmtime()[1],gmtime()[2],\
                         gmtime()[3],gmtime()[4],gmtime()[5])
                   self.db[star['LAST_PACS_MODEL']] = \
                       dict([('filenames',[]),\
                             ('trans_list',star.getTransList(dtype='PACS')),\
                             ('cooling_id',star['LAST_GASTRONOOM_MODEL'])])
                   DataIO.testFolderExistence(\
                       os.path.join(cc.path.gout,'stars',self.star_name,\
                                    'PACS_results',star['LAST_PACS_MODEL']))
               #-- Correct for the v_lsr of the central source
               sphinx_wave_corr = array(sphinx_wave)*(1./(1-self.vlsr/self.c))
               sph_conv = Data.doConvolution(\
                                       x_in=sphinx_wave_corr,\
                                       y_in=sphinx_flux,\
                                       x_out=self.data_wave_list[i_file],\
                                       widths=self.data_delta_list[i_file],\
                                       oversampling=self.oversampling)
               sph_fn = os.path.join(cc.path.gout,'stars',self.star_name,\
                                     'PACS_results',star['LAST_PACS_MODEL'],\
                                     '_'.join(['sphinx',filename])) 
               DataIO.writeCols(filename=sph_fn,\
                                cols=[self.data_wave_list[i_file],sph_conv])
               self.db[star['LAST_PACS_MODEL']]['filenames'].append(filename)
               self.db.addChangedKey(star['LAST_PACS_MODEL'])        
示例#17
0
    def __init__(self,x,func=interp_file,dfunc=None,order=3,*args,\
                 **kwargs):
    
        '''
        Create an instance of the Profiler() class. Requires a coordinate grid 
        and a function object for the profile. A function for the derivative is
        optional. The functions can also be given as an interpolation object.
        
        The optional args and kwargs give the additional arguments for the 
        two function, which are ignored in case func is an interpolation object.
        
        The default coordinate grid is evaluated for both the function and the
        derivative. They are saved in self.y and self.dydx. Alternatively, new
        evaluations can be attained through eval and diff.
        
        Note that if func is an interpolator object, the original input x and y
        grids can be passed as additional keywords xin and yin, which would then
        be arrays. Otherwise, the x and the interpolator(x) are set as xin and 
        yin. xin and yin are ignored if func is a function, even if it returns
        an interpolator (in which case the original grids are known)
        
        @param x: The default coordinate points, minimum three points. In the 
                  case of an interpolation function, this is the default grid
                  returned by the instance. The original x/y of the 
                  interpolated profile are saved as xori/yori in the object.
        @type x: array
        
        @keyword func: The function that describes the profile with respect to 
                       x. Can be given as an interp1d object. Default is a read
                       function that interpolates data and returns the 
                       interpolator object. If interpolation object, x and 
                       eval(x) are assumed to be the original grids, unless
                       xin and yin are given as keywords with arrays as values
                       for the original grids.
                       
                       (default: interp_file)
        @type func: function/interp1d object
        @keyword dfunc: Function that describes the derivative of the profile 
                        with respect to x. Can be given as an interpolation 
                        object. If None, a generic central difference is taken & 
                        interpolated with a spline of which the order can be 
                        chosen.
        
                        (default: None)
        @type dfunc: function/interpolation object
        @keyword order: Order of the spline interpolation of the derivative. 
                        Default is cubic. Not used for the interpolation if func
                        returns an interpolation object. Use read_order in that
                        case.
                        
                        (default: 3)
        @type order: int
        
        @keyword args: Additional parameters passed to the functions when eval
                       or diff are called. 
                       
                       (default: [])
        @type args: tuple
        @keyword kwargs: Additional keywords passed to the functions when eval
                         or diff are called. 
                       
                         (default: {})
        @type kwargs: dict
        
        '''
        
        #-- Check len of coordinate input. Cannot be less than three for the 
        #   derivative.
        if len(x) < 3:
            raise ValueError('Coordinate grid must have more than 2 elements.')
        
        #-- If the function is given as a string, retrieve it from the local 
        #   child module, or from the Profiler module (as parent). If the latter
        #   case then check if the function comes from one of Profiler's 
        #   attributes, such as the loaded DataIO module.
        #   Can also simply be a constant value, so try making a float first.
        if isinstance(func,str):
            try:
                #-- Check if a constant was given, rather than a function
                kwargs['c'] = float(func)
                func = constant

            except ValueError:
                #-- Note that self.module refers to the child, not Profiler
                if hasattr(sys.modules[self.__module__],func):
                    func = getattr(sys.modules[self.__module__],func)

                #-- Recursively find the function of loaded modules in Profiler
                #   or a function of the Profiler module itself if no '.'         
                else:
                    
                    func = DataIO.read(func=func,module=sys.modules[__name__],\
                                       return_func=1)
        
        #-- set functional args, remember spline order. args/kwargs for 
        #   func and dfunc are saved separately. They are removed if either are
        #   interpolation objects. They are always accessible, the _** variables
        #   are passed to the evaluation.
        self.args = args
        self.kwargs = kwargs
        self._args = self.args
        self._dargs = self.args
        self._dkwargs = self.kwargs
        self._kwargs = self.kwargs
        self.order = order
        
        #-- Grab default xin and yin keys in case they are included, and remove
        #   from the arguments dictionary. None if not available. 
        xin = self.kwargs.pop('xin',None)
        yin = self.kwargs.pop('yin',None)
        
        #-- By default no interpolation, so leave this off.
        self.interp_func = 0
        self.interp_dfunc = 0
        
        #-- Defaults for xori/yori, not used in case of normal functions
        self.xin = np.empty(0)
        self.yin = np.empty(0)
        
        #-- Evaluate the default grid with function. Set x as None first so it
        #   can actually evaluate. Set x once derivative has been evaluated. 
        self.x = None
        if not (isinstance(func,interp1d) or isinstance(func,UnivariateSpline)):
            #-- Evaluate the function, and check what is returned: array or 
            #   interpolation object
            y = func(x,*args,**kwargs)
            
            #-- Interpolation object: so set that as this instance's func. In 
            #   this case, the variable x passed to the class is the default x
            #   grid of this instance. The original x/y-grid is saved as xi, yi
            if isinstance(y,tuple):
                self.func = y[2]
                self.xin = y[0]
                self.yin = y[1]
                self._args = []
                self._kwargs = {}
                self.interp_func = 1
                self.y = self.func(x)
            else: 
                self.func = func
                self.y = y
                
        #-- func is an interpolation object, so just run the normal evaluation.
        #   Set _args/_kwargs to empty, so none are ever passed to the interpol
        else:
            self.func = func
            self._args = []
            self._kwargs = {}
            self.interp_func = 1
            self.y = self.func(x)
            self.yin = yin if not yin is None else self.y
            self.xin = xin if not xin is None else x
                                                    
        #-- Set the derivative function, resorting to default if needed
        if not dfunc is None:
            self.dfunc = dfunc
        elif self.func == constant:
            self.dfunc = zero
        else: 
            #-- Extend array slightly to allow odeint to succeed.
            #   Need better fix for this.
            #x0 = x[0]-(x[1]-x[0])#*0.5
            #xn = x[-1]+(x[-1]-x[-2])#*0.5
            #x_ext = np.hstack([[x0],x,[xn]])
            
            #-- Evaluate the function, and set up an interpolator for 
            #   central difference. The interpolator will extrapolate 
            #   beyond the given x range. This is necessary for odeint to work.
            #   Usually x-range is not exceeded much. 
            self.dfunc = spline1d(x=x,y=op.diff_central(self.y,x),\
                                  k=self.order)
        
        if (isinstance(self.dfunc,interp1d) \
                or isinstance(self.dfunc,UnivariateSpline)):
            self._dargs = []
            self._dkwargs = {}
            self.interp_dfunc = 1
        
        #-- Evaluate the derivative with the default grid
        self.dydx = self.dfunc(x,*self._dargs,**self._dkwargs)
        
        #-- Now set x.
        self.x = Data.arrayify(x)
示例#18
0
    def __init__(self,x,y,func,*args,**kwargs):
    
        '''
        Create an instance of the Profiler2D() class. Requires 2 coordinate 
        arrays and a function object for profile.
       
        The function can also be given as an interpolation object.
        
        The optional args and kwargs give the additional arguments for the 
        function, which are ignored in case func is an interpolation object.
        
        The default coordinate grids are both evaluated for the function. 
        They are saved in self.z, as an array of dimensions (x.size,y.size). 
        Alternatively, new evaluations can be attained through eval and diff.
        
        @param x: The default coordinates of the primary independent variable. 
                  Minimum three points.
        @type x: array
        @param y: The default coordinates of the secondary independent variable. 
                  Minimum three points.
        @type y: array
        @param func: The function that describes the profile with respect to x 
                     and y. Can be given as a 2D interpolation object.
        @type func: function/interpolation object
        
        @keyword args: Additional parameters passed to the functions when eval
                       or diff are called. 
                       
                       (default: [])
        @type args: tuple
        @keyword kwargs: Additional keywords passed to the functions when eval
                         or diff are called. 
                       
                         (default: {})
        @type kwargs: dict
        
        '''

        #-- If the function is given as a string, retrieve it from the local 
        #   child module, or from the Profiler module (as parent). If the latter
        #   check if the function comes from one of Profiler's attributes, such
        #   as the loaded DataIO module.
        if isinstance(func,str):
            try:
                #-- Note that self.module refers to the child, not Profiler
                func = getattr(sys.modules[self.__module__],func)
            except AttributeError:
                #-- Recursively find the function of loaded modules in Profiler
                #   or a function of the Profiler module itself if no '.' 
                func = DataIO.read(sys.modules[__name__],return_func=1)
                
        #-- set functional args, remember spline order. args/kwargs for 
        #   func are saved separately. They are removed if either are
        #   interpolation objects. They are always accessible, the _** variables
        #   are passed to the evaluation.
        self.args = args
        self.kwargs = kwargs
        self._args = args
        self._kwargs = kwargs
        self.func = func

        if isinstance(self.func,interp2d) \
                or isinstance(self.func,BivariateSpline):
            self.interp_func = 1
            self._args = []
            self._kwargs = {}
        else:
            self.interp_func = 0
        
        #-- Evaluate the default grid with function. Set x as None first so it
        #   can actually evaluate.
        self.x = None
        self.y = None
        self.z = self.func(x,y,*self._args,**self._kwargs)
        
        #-- Now set x and y. Make sure they are arrays.
        self.x = Data.arrayify(x)
        self.y = Data.arrayify(y) 
示例#19
0
   def __convolveSphinx(self,star):
       
       '''
       Check if sphinx output has already been convolved (pacs db) and do so 
       if not.
       
       @param star: The parameter set
       @type star: Star()
       
       '''     
       
       #- check for which filenames the convolution has already been done
       finished_conv_filenames = self.checkStarDb(star)
       finished_conv_filenames = [this_f 
                                  for this_f in finished_conv_filenames 
                                  if this_f in [os.path.split(f)[1] 
                                                for f in self.data_filenames]]
       
       #- if after db check pacs id is undefined, then there is no pacs model,
       #- and the convolution will be done anyway
       if self.redo_convolution and star['LAST_PACS_MODEL']:    
           for filename in finished_conv_filenames:
               ori = os.path.join(cc.path.gout,'stars',self.star_name,\
                                  'PACS_results',star['LAST_PACS_MODEL'],\
                                  '_'.join(['sphinx',filename]))
               backup = os.path.join(cc.path.gout,'stars',self.star_name,\
                                     'PACS_results',star['LAST_PACS_MODEL'],\
                                     '_'.join(['backup','sphinx',filename]))
               subprocess.call(['mv %s %s'%(ori,backup)],shell=True)
           self.db[star['LAST_PACS_MODEL']]['filenames'] = []
           finished_conv_filenames = []
       filenames_to_do = [this_f 
                          for this_f in [os.path.split(f)[1] 
                                         for f in self.data_filenames]
                          if this_f not in finished_conv_filenames]     
       
       #-Get sphinx model output and merge, for all star models in star_grid
       if filenames_to_do:        
           #- if list is not empty, some filenames still need a convolution    
           print '* Reading Sphinx model and merging.'
           merged = star['LAST_GASTRONOOM_MODEL'] \
                       and self.mergeSphinx(star) \
                       or [[],[]]
           sphinx_wave = merged[0]
           sphinx_flux = merged[1]
           if not sphinx_wave: 
               print '* No Sphinx data found.'
               return
 
           #- convolve the model fluxes with a gaussian at central wavelength 
           #- from data_wave_list for every star, and appropriate sigma
           print '* Convolving Sphinx model, after correction for v_lsr.'
           if not self.data_delta_list:
               self.setDataResolution()
           for filename in filenames_to_do:
               i_file = [os.path.split(f)[1] 
                         for f in self.data_filenames].index(filename)
               if not star['LAST_PACS_MODEL']:
                   star['LAST_PACS_MODEL'] = \
                       'pacs_%.4i-%.2i-%.2ih%.2i-%.2i-%.2i'\
                       %(gmtime()[0],gmtime()[1],gmtime()[2],\
                         gmtime()[3],gmtime()[4],gmtime()[5])
                   self.db[star['LAST_PACS_MODEL']] = \
                       dict([('filenames',[]),\
                             ('trans_list',star.getTransList(dtype='PACS')),\
                             ('cooling_id',star['LAST_GASTRONOOM_MODEL'])])
                   DataIO.testFolderExistence(\
                       os.path.join(cc.path.gout,'stars',self.star_name,\
                                    'PACS_results',star['LAST_PACS_MODEL']))
               #-- Correct for the v_lsr of the central source
               sphinx_wave_corr = array(sphinx_wave)*(1./(1-self.vlsr/self.c))
               sph_conv = Data.doConvolution(\
                                       x_in=sphinx_wave_corr,\
                                       y_in=sphinx_flux,\
                                       x_out=self.data_wave_list[i_file],\
                                       widths=self.data_delta_list[i_file],\
                                       oversampling=self.oversampling)
               sph_fn = os.path.join(cc.path.gout,'stars',self.star_name,\
                                     'PACS_results',star['LAST_PACS_MODEL'],\
                                     '_'.join(['sphinx',filename])) 
               DataIO.writeCols(filename=sph_fn,\
                                cols=[self.data_wave_list[i_file],sph_conv])
               self.db[star['LAST_PACS_MODEL']]['filenames'].append(filename)
               self.db.addChangedKey(star['LAST_PACS_MODEL'])        
示例#20
0
    def __init__(self,x,func=interp_file,dfunc=None,order=3,*args,\
                 **kwargs):
        '''
        Create an instance of the Profiler() class. Requires a coordinate grid 
        and a function object for the profile. A function for the derivative is
        optional. The functions can also be given as an interpolation object.
        
        The optional args and kwargs give the additional arguments for the 
        two function, which are ignored in case func is an interpolation object.
        
        The default coordinate grid is evaluated for both the function and the
        derivative. They are saved in self.y and self.dydx. Alternatively, new
        evaluations can be attained through eval and diff.
        
        Note that if func is an interpolator object, the original input x and y
        grids can be passed as additional keywords xin and yin, which would then
        be arrays. Otherwise, the x and the interpolator(x) are set as xin and 
        yin. xin and yin are ignored if func is a function, even if it returns
        an interpolator (in which case the original grids are known)
        
        @param x: The default coordinate points, minimum three points. In the 
                  case of an interpolation function, this is the default grid
                  returned by the instance. The original x/y of the 
                  interpolated profile are saved as xori/yori in the object.
        @type x: array
        
        @keyword func: The function that describes the profile with respect to 
                       x. Can be given as an interp1d object. Default is a read
                       function that interpolates data and returns the 
                       interpolator object. If interpolation object, x and 
                       eval(x) are assumed to be the original grids, unless
                       xin and yin are given as keywords with arrays as values
                       for the original grids.
                       
                       (default: interp_file)
        @type func: function/interp1d object
        @keyword dfunc: Function that describes the derivative of the profile 
                        with respect to x. Can be given as an interpolation 
                        object. If None, a generic central difference is taken & 
                        interpolated with a spline of which the order can be 
                        chosen.
        
                        (default: None)
        @type dfunc: function/interpolation object
        @keyword order: Order of the spline interpolation of the derivative. 
                        Default is cubic. Not used for the interpolation if func
                        returns an interpolation object. Use read_order in that
                        case.
                        
                        (default: 3)
        @type order: int
        
        @keyword args: Additional parameters passed to the functions when eval
                       or diff are called. 
                       
                       (default: [])
        @type args: tuple
        @keyword kwargs: Additional keywords passed to the functions when eval
                         or diff are called. 
                       
                         (default: {})
        @type kwargs: dict
        
        '''

        #-- Check len of coordinate input. Cannot be less than three for the
        #   derivative.
        if len(x) < 3:
            raise ValueError('Coordinate grid must have more than 2 elements.')

        #-- If the function is given as a string, retrieve it from the local
        #   child module, or from the Profiler module (as parent). If the latter
        #   case then check if the function comes from one of Profiler's
        #   attributes, such as the loaded DataIO module.
        #   Can also simply be a constant value, so try making a float first.
        if isinstance(func, str):
            try:
                #-- Check if a constant was given, rather than a function
                kwargs['c'] = float(func)
                func = constant

            except ValueError:
                #-- Note that self.module refers to the child, not Profiler
                if hasattr(sys.modules[self.__module__], func):
                    func = getattr(sys.modules[self.__module__], func)

                #-- Recursively find the function of loaded modules in Profiler
                #   or a function of the Profiler module itself if no '.'
                else:

                    func = DataIO.read(func=func,module=sys.modules[__name__],\
                                       return_func=1)

        #-- set functional args, remember spline order. args/kwargs for
        #   func and dfunc are saved separately. They are removed if either are
        #   interpolation objects. They are always accessible, the _** variables
        #   are passed to the evaluation.
        self.args = args
        self.kwargs = kwargs
        self._args = self.args
        self._dargs = self.args
        self._dkwargs = self.kwargs
        self._kwargs = self.kwargs
        self.order = order

        #-- Grab default xin and yin keys in case they are included, and remove
        #   from the arguments dictionary. None if not available.
        xin = self.kwargs.pop('xin', None)
        yin = self.kwargs.pop('yin', None)

        #-- By default no interpolation, so leave this off.
        self.interp_func = 0
        self.interp_dfunc = 0

        #-- Defaults for xori/yori, not used in case of normal functions
        self.xin = np.empty(0)
        self.yin = np.empty(0)

        #-- Evaluate the default grid with function. Set x as None first so it
        #   can actually evaluate. Set x once derivative has been evaluated.
        self.x = None
        if not (isinstance(func, interp1d)
                or isinstance(func, UnivariateSpline)):
            #-- Evaluate the function, and check what is returned: array or
            #   interpolation object
            y = func(x, *args, **kwargs)

            #-- Interpolation object: so set that as this instance's func. In
            #   this case, the variable x passed to the class is the default x
            #   grid of this instance. The original x/y-grid is saved as xi, yi
            if isinstance(y, tuple):
                self.func = y[2]
                self.xin = y[0]
                self.yin = y[1]
                self._args = []
                self._kwargs = {}
                self.interp_func = 1
                self.y = self.func(x)
            else:
                self.func = func
                self.y = y

        #-- func is an interpolation object, so just run the normal evaluation.
        #   Set _args/_kwargs to empty, so none are ever passed to the interpol
        else:
            self.func = func
            self._args = []
            self._kwargs = {}
            self.interp_func = 1
            self.y = self.func(x)
            self.yin = yin if not yin is None else self.y
            self.xin = xin if not xin is None else x

        #-- Set the derivative function, resorting to default if needed
        if not dfunc is None:
            self.dfunc = dfunc
        elif self.func == constant:
            self.dfunc = zero
        else:
            #-- Extend array slightly to allow odeint to succeed.
            #   Need better fix for this.
            #x0 = x[0]-(x[1]-x[0])#*0.5
            #xn = x[-1]+(x[-1]-x[-2])#*0.5
            #x_ext = np.hstack([[x0],x,[xn]])

            #-- Evaluate the function, and set up an interpolator for
            #   central difference. The interpolator will extrapolate
            #   beyond the given x range. This is necessary for odeint to work.
            #   Usually x-range is not exceeded much.
            self.dfunc = spline1d(x=x,y=op.diff_central(self.y,x),\
                                  k=self.order)

        if (isinstance(self.dfunc,interp1d) \
                or isinstance(self.dfunc,UnivariateSpline)):
            self._dargs = []
            self._dkwargs = {}
            self.interp_dfunc = 1

        #-- Evaluate the derivative with the default grid
        self.dydx = self.dfunc(x, *self._dargs, **self._dkwargs)

        #-- Now set x.
        self.x = Data.arrayify(x)
示例#21
0
 def doDataStats(self,method='clipping'):
     
     '''
     Calculate mean, std, rms for the data files.
     
     They are saved in self.data_stats.
     
     @keyword method: Std/Mean/RMS determination method. Can be 'clipping'
                      or 'preset'. The former 1-sigma clips based on 
                      mean/std/... of full spectrum, then takes mean/std/...
                      of clipped spectrum. Latter takes preset values from
                      Data.dat.
                      
                      (default: 'clipping')
     @type method: string
     
     '''
     
     method = method.lower()
     if method not in ['preset','clipping']: method = 'clipping'
     self.data_stats = dict()
     if self.instrument:
         if not self.data_info: self.setDataInfo()
         for filename,data_wave,data_flux,band in \
                     zip(self.instrument.data_filenames,\
                         self.instrument.data_wave_list,\
                         self.instrument.data_flux_list,\
                         self.instrument.data_ordernames):
             these_stats = dict()
             iband = self.data_info['bands'].index(band)
             these_stats['sigma'] = self.data_info['sigmas'][iband]
             if method == 'preset':
                 w_std_min = self.data_info['w_std_min'][iband]
                 w_std_max = self.data_info['w_std_max'][iband]
                 if w_std_min < data_wave[0] or w_std_max > data_wave[-1]:
                     method = 'clipping'
                 test_mean = Data.getMean(wave=data_wave,flux=data_flux,\
                                          wmin=w_std_min,wmax=w_std_max)
                 if test_mean is None:
                     method = 'clipping'
             if method == 'clipping':
                 totmean = Data.getMean(wave=data_wave,flux=data_flux)
                 totstd = Data.getStd(wave=data_wave,flux=data_flux)
                 limits = (-totstd,totstd)
                 these_stats['mean'] = Data.getMean(flux=data_flux,\
                                                    limits=limits)
                 these_stats['std'] = Data.getStd(flux=data_flux,\
                                                  limits=limits)
                 these_stats['rms'] = Data.getRMS(flux=data_flux-\
                                                       these_stats['mean'],\
                                                  limits=limits)                    
             else:
                 these_stats['mean'] = Data.getMean(wave=data_wave,\
                                                    flux=data_flux,\
                                                    wmin=w_std_min,\
                                                    wmax=w_std_max) 
                 these_stats['std'] = Data.getStd(wave=data_wave,\
                                                  flux=data_flux,\
                                                  wmin=w_std_min,\
                                                  wmax=w_std_max)
                 these_stats['rms'] = Data.getRMS(wave=data_wave,\
                                                  flux=data_flux-\
                                                       these_stats['mean'],\
                                                  wmin=w_std_min,\
                                                  wmax=w_std_max)
             print '* Data statistics for %s using "%s" method:'\
                   %(filename,method)
             if method == 'preset':
                 print '* Taken between %.2f and %.2f micron.'\
                       %(w_std_min,w_std_max)
             print 'mean = ',these_stats['mean'],' Jy'
             print 'std = ',these_stats['std'],' Jy'      
             print 'RMS = ',these_stats['rms'],' Jy'      
             self.data_stats[filename] = these_stats
         print '***********************************'
示例#22
0
def prepInput(star,path,repl_str=''):
    
    '''
    Prepare inputfiles for LIME from a GASTRoNOoM and MCMax model. 
    
    Input is taken from the model ouput and written into files. The output
    folder can be chosen. The model_id tag can be replaced with an arbitrary
    string.
    
    Input is converted to SI units, except opacities, which are in cm2/g.
    
    @param star: The model object including the GASTRoNOoM and MCMax model ids.
    @type star: Star()
    @param path: The target folder for the files.
    @type path: str
    
    @keyword repl_str: Replacement string for the model_id tag.
    
                       (default: '')
    @type repl_str: str
    
    '''
    
    #-- First opacities and t_dust, which are not part of the GASTRoNOoM output
    mcmid = star['LAST_MCMAX_MODEL']
    fnopac = os.path.join(path,'opac_%s.dat'%(repl_str and repl_str or mcmid))
    DataIO.writeCols(fnopac,star.getWeightedKappas())
    
    #-- Write dust temperature to a file.
    fntd = os.path.join(path,'td_%s.dat'%(repl_str and repl_str or mcmid))
    rad = star.getDustRad(unit='m')
    td = star.getDustTemperature()
    DataIO.writeCols(fntd,[rad,td])
    
    #-- Finally the gas properties
    if not repl_str: repl_str = star['LAST_GASTRONOOM_MODEL']
    
    #-- Radius for nh2 and vel
    rad = star.getGasRad(unit='m',ftype='fgr_all')
    if rad.size > 10000:
        icutoff = np.argmin(abs(rad-1e14))
        rad = Data.reduceArray(rad,20,1e14,'remove')
    else: 
        icutoff = None
    
    #-- h2 number density
    nh2 = star.getGasNumberDensity(ftype='fgr_all')
    nh2 = nh2*10**6
    if not icutoff is None: 
        nh2 = Data.reduceArray(nh2,20,nh2[icutoff],'remove')
    fnnh2 = os.path.join(path,'nh2_%s.dat'%repl_str)
    DataIO.writeCols(fnnh2,[rad,nh2])
    
    #-- Velocity profile
    vel = star.getGasVelocity(ftype='fgr_all')
    vel = vel*10**-2
    if not icutoff is None: 
        vel = Data.reduceArray(vel,20,vel[icutoff],'remove')
    fnvel = os.path.join(path,'vg_%s.dat'%repl_str)
    DataIO.writeCols(fnvel,[rad,vel])
    
    #-- CO abundance
    rad = star.getGasRad(ftype='1',mstr='12C16O',unit='m')
    nh2 = star.getGasNumberDensity(ftype='1',mstr='12C16O')
    nco = star.getGasNumberDensity(ftype='1',mstr='12C16O',molecule=1)
    aco = nco/nh2
    fnaco = os.path.join(path,'aco_%s.dat'%repl_str)
    DataIO.writeCols(fnaco,[rad,aco])

    
示例#23
0
    def __init__(self, x, y, func, *args, **kwargs):
        '''
        Create an instance of the Profiler2D() class. Requires 2 coordinate 
        arrays and a function object for profile.
       
        The function can also be given as an interpolation object.
        
        The optional args and kwargs give the additional arguments for the 
        function, which are ignored in case func is an interpolation object.
        
        The default coordinate grids are both evaluated for the function. 
        They are saved in self.z, as an array of dimensions (x.size,y.size). 
        Alternatively, new evaluations can be attained through eval and diff.
        
        @param x: The default coordinates of the primary independent variable. 
                  Minimum three points.
        @type x: array
        @param y: The default coordinates of the secondary independent variable. 
                  Minimum three points.
        @type y: array
        @param func: The function that describes the profile with respect to x 
                     and y. Can be given as a 2D interpolation object.
        @type func: function/interpolation object
        
        @keyword args: Additional parameters passed to the functions when eval
                       or diff are called. 
                       
                       (default: [])
        @type args: tuple
        @keyword kwargs: Additional keywords passed to the functions when eval
                         or diff are called. 
                       
                         (default: {})
        @type kwargs: dict
        
        '''

        #-- If the function is given as a string, retrieve it from the local
        #   child module, or from the Profiler module (as parent). If the latter
        #   check if the function comes from one of Profiler's attributes, such
        #   as the loaded DataIO module.
        if isinstance(func, str):
            try:
                #-- Note that self.module refers to the child, not Profiler
                func = getattr(sys.modules[self.__module__], func)
            except AttributeError:
                #-- Recursively find the function of loaded modules in Profiler
                #   or a function of the Profiler module itself if no '.'
                func = DataIO.read(sys.modules[__name__], return_func=1)

        #-- set functional args, remember spline order. args/kwargs for
        #   func are saved separately. They are removed if either are
        #   interpolation objects. They are always accessible, the _** variables
        #   are passed to the evaluation.
        self.args = args
        self.kwargs = kwargs
        self._args = args
        self._kwargs = kwargs
        self.func = func

        if isinstance(self.func,interp2d) \
                or isinstance(self.func,BivariateSpline):
            self.interp_func = 1
            self._args = []
            self._kwargs = {}
        else:
            self.interp_func = 0

        #-- Evaluate the default grid with function. Set x as None first so it
        #   can actually evaluate.
        self.x = None
        self.y = None
        self.z = self.func(x, y, *self._args, **self._kwargs)

        #-- Now set x and y. Make sure they are arrays.
        self.x = Data.arrayify(x)
        self.y = Data.arrayify(y)