Example #1
0
    def integrate_to_bins(self, new_bin_edges, theta_unit='a'):
        """
        Uses integrate_gp to rebin the existing G_p.  Note that the new G_p
        does not have the new bin widths divided out so it follows
        Sum{G_p,i} = 1, not integral(G_p(theta) d theta) = 1

        Parameters
        ----------
        new_bin_edges: array
            The values of theta defining the bin edges that you want to
            integrate to.  The theta values are in units theta_unit
        theta_unit : string (optional)
            The unit in which new_bin_edges are given.  The options are
            'a', 'arcsec', 'arcseconds'; 'd', 'deg', 'degrees'; 'r',
            'rad', 'radians'.  Default is 'arcseconds'

        Returns
        -------
        new_gp : array
            Gp integrated over the new bins
        """

        #Convert the thetas to degrees
        new_bin_edges = misc.put_thetas_in_degrees(new_bin_edges, theta_unit)

        #Integrate Gp over each bin
        n_new_bins = len(new_bin_edges)-1
        binned = np.zeros(n_new_bins)
        for i in range(n_new_bins):
            binned[i] = self.integrate_gp(new_bin_edges[i], new_bin_edges[i+1])

        return binned
Example #2
0
    def integrate_powerlaw(self, A, beta, lowlim, highlim, param_unit='d',
                           theta_unit='d'):
        """
        A funtion that integrates the power law A * theta^-beta over a
        range of thetas

        Parameters
        ----------
        A : float
            The amplitude of the power law for theta in units param_unit
        beta : float
            The power in the power law
        lowlim : float
            The lower limit of the theta range to integrate over
        highlim : float
            The upper limit of the theta range to integrate over
        param_unit : string (optional)
            The units of theta for which A was calculated.  The options
            are 'a', 'arcsec', 'arcseconds'; 'd', 'deg', 'degrees'; 'r',
            'rad', 'radians'.  Default is 'd'
        theta_unit : string (optional)
            The units of lowlim and highlim.  The options are 'a',
            'arcsec', 'arcseconds'; 'd', 'deg', 'degrees'; 'r',
            'rad', 'radians'.  Default is 'd'

        Returns
        -------
        integral : float
            The integral of the power law over the specified range
        """
        
        #Do the integral of a power law A*theta^-beta from lowlim to highlim
        A = np.float(A)
        beta=np.float(beta)
        
        #Make sure the A is for theta in degrees
        A = self.convert_A_to_degrees(A, beta, param_unit)

        #Convert the limits to degrees
        lowlim, highlim = misc.put_thetas_in_degrees([lowlim, highlim],
                                                     unit=theta_unit)

        #First define the function to be integrated
        def powerlaw(theta):
            return A * theta ** (-beta)

        #Do the integral
        pl_int, pl_int_err= intg.quad(powerlaw, lowlim, highlim)

        return pl_int
    def _make_theta_bins(self, min_theta, max_theta, nbins,
                         unit='arcseconds'):
        """
        Internally sets the edges and centers of the angular bins

        Parameters
        ----------
        min_theta : float
                 The minimum of the theta bin edges
                 
        max_theta : float
                 The maximum of the theta bin edges
                 
        nbins : float
              The number of theta bins
              
        unit : string (optional)
             The unit that min and max theta are in.  Default is 'arcseconds'
        """
        
        #Make sure the min and max are in degrees
        min_theta, max_theta = misc.put_thetas_in_degrees([min_theta, max_theta],
                                                           unit)

        #Record things in degrees
        self._min_theta = min_theta
        self._max_theta = max_theta
        self._nbins = nbins

        #Make the bins
        if self._logbins:
            if min_theta<=0:
                print ("make_theta_bins says: you've asked for log theta bins "
                       "and a min of theta<=0 which makes logs unhappy.  "
                       "Changed to 1e-4")
                min_theta=0.0001
            edges = np.logspace(np.log10(min_theta), np.log10(max_theta), nbins+1)
            lcenters=misc.centers(np.log10(edges))
            centers=10.**lcenters
        else:
            edges=np.linspace(min_theta, max_theta, nbins+1)
            centers=misc.centers(edges)

        #Record the bins and return
        self._theta_bins=edges
        self._thetas=centers
        return
    def set_new_bins(self, min_theta, max_theta, nbins, unit='a'):
        """
        Redo the range and number of bins.

        Parameters
        ----------
        min_theta : float
                 The minimum of the theta bin edges
                 
        max_theta : float
                 The maximum of the theta bin edges
                 
        nbins : float
              The number of theta bins
              
        unit : string (optional)
             The unit that min and max theta are in.  Default is 'arcseconds'
        """
        #Set new params and rerun if different

        #First, convert to degrees if we need to
        min_theta, max_theta = misc.put_thetas_in_degrees([min_theta, max_theta],
                                                           unit)

        #Are they different?
        min_different = self._min_theta != min_theta
        max_different = self._max_theta != max_theta
        n_different = self._nbins != nbins

        #If so, record and rerun bins
        if min_different or max_different or n_different:
            self._min_theta = min_theta
            self._max_theta = max_theta
            self._nbins = nbins
            self._make_theta_bins(min_theta, max_theta, nbins, unit='d')
            
        return
Example #5
0
    def integrate_gp_times_powerlaw(self, A, beta, lowlim, highlim,
                                    theta_unit='d', param_unit='d'):
        """
        Integrates G_p * A * theta^-beta over a range in thetas.  Useful
        for calculating the integral constraint.

        Parameters
        ----------
        A : float
            The amplitude of the power law for theta in units param_unit
        beta : float
            The power in the power law
        lowlim : float
            The lower limit of the theta range to integrate over
        highlim : float
            The upper limit of the theta range to integrate over
        param_unit : string (optional)
            The units of theta for which A was calculated.  The options
            are 'a', 'arcsec', 'arcseconds'; 'd', 'deg', 'degrees'; 'r',
            'rad', 'radians'.  Default is 'd'
        theta_unit : string (optional)
            The units of lowlim and highlim.  The options are 'a',
            'arcsec', 'arcseconds'; 'd', 'deg', 'degrees'; 'r', 'rad',
            'radians'.  Default is 'd'

        Returns
        -------
        integral : float
            The integral of G_p * A * theta^-beta
        """
        #Compute the integral of G_p * A * theta^-beta from lowlim to
        #highlim.  A and beta are for the unit specified 

        #Pull the theta properties
        centers, edges = self._theta_bins.get_bins(unit='d')
        
        #Get basic info and convert everything for theta in degrees
        nbins_gp = len(self._Gp)
        lowlim, highlim = misc.put_thetas_in_degrees([lowlim, highlim],
                                                     unit=theta_unit)
        A = self.convert_A_to_degrees(A, beta, param_unit)

        #If it's completely outside the G_p range, we assume that G_p is 0
        #and return 0
        if (lowlim >= edges[-1]) or (highlim <= edges[0]):
            return 0
    
        #Figure out which bins are all the way inside [lowlim, highlim]
        above_lowlim = edges >= lowlim
        min_edge_inside_val = edges[above_lowlim][0]
        min_edge_inside_index = np.arange(nbins_gp+1)[above_lowlim][0]
    
        below_highlim = edges <= highlim
        max_edge_inside_val = edges[below_highlim][-1]
        max_edge_inside_index = np.arange(nbins_gp+1)[below_highlim][-1]

        #Make sure that the limits aren't above or below the limits where G_p is defined
        if lowlim < edges[0]:
            min_edge_inside_val = edges[0]
            lowlim = edges[0]
            min_edge_inside_index = 0
        if highlim > edges[-1]:
            max_edge_inside_val = edges[-1]
            highlim = edges[-1]
            max_edge_inside_index = nbins_gp
        
        #Initialize the holder for the result
        result=0
    
        #Start by integrating the two partial bins if we didn't happen upon
        #an integration limit that corresponds exactly to an edge
        if min_edge_inside_val != lowlim:
            this_gp_val = self._Gp[min_edge_inside_index-1]
            w_int = self.integrate_powerlaw(A, beta, lowlim, min_edge_inside_val)
            result += this_gp_val * w_int
        
        if max_edge_inside_val != highlim:
            this_gp_val = self._Gp[max_edge_inside_index]
            w_int = self.integrate_powerlaw(A, beta, max_edge_inside_val, highlim)
            result += this_gp_val * w_int        

        #Now loop through the bins that are inside
        nbins_inside = max_edge_inside_index - min_edge_inside_index
        for i in np.arange(nbins_inside):
            this_index = min_edge_inside_index + i
            this_gp_val = self._Gp[this_index]
            w_int = self.integrate_powerlaw(A, beta, edges[this_index], edges[this_index+1])
            result += this_gp_val * w_int

        return result