Example #1
0
    def test_fit(self):
        # Test the method Class1.method1
        # See http://docs.python.org/library/unittest.html#test-cases for further
        # information
        #print "run gaussian fit"
        #print gaussian
        fit, popt, perr = nonLinFit(gaussian, self.x_data, self.y_data, p_guess=self.p_guess, verbose=False)
        diff = max(fit) - (self.p[1]+self.p[0])
        self.assertTrue(abs(diff) < 0.0001)
        for i in range(len(self.p)):
            self.assertAlmostEqual(self.p[i],popt[i])
        
        
        #print "run gauss + polynomial fit"
        fitPoly, poptPoly, perr = nonLinFit(gaussPlusPoly, self.x_data, self.y_data_poly, p_guess=self.p_poly_guess, verbose=False) 

        for i in range(len(self.p)):
            self.assertAlmostEqual(self.p_poly[i],poptPoly[i])

        
        coeff = self.fitter.fit()
        self.assertTrue(coeff[0] == 1.)
        
        error = self.fitter.calcLinFitError(self.x_data)
        self.assertTrue(numpy.mean(error) == 0.)    
        line = self.fitter.straightLine(self.x_data)
        self.assertTrue(numpy.all(line - self.x_data) == 0.)    
        
        del coeff
        del error
        del fitPoly
        del popt
        del poptPoly
        del fit
        del line
Example #2
0
def get_psf_fit(data, minX=0, leftY=0, verbose=False, makeplot=False):
    """
    
    fits a pinhole (point source) continuum spectrum by a Gaussian for each row (x axis).
    
    :Parameters:

    data: MiriMeasuredModel (or similar 2-D DataModel)
        The 2-D data product from which spectra will be extracted.
        
    :Returns:
    
    * x values per row
    * fit function (vs x) per row
    * all Gaussian fit parameters per row
    * all errors of Gaussian fit parameters per row
    
    """

    # Make sure the given data is a 2-D JWST data product.
    if isinstance(data, MiriMeasuredModel):
        if np.ndim(data.data) != 2:
            strg = "lrs_extract_spec - 2 dimensional data expected "
            strg += "(%d given)." % np.ndim(data.data)
            raise TypeError(strg)
    else:
        raise TypeError("lrs_extract_spec - " + \
                        "Given data product is not a MiriMeasuredModel")
    if np.ndim(data.err) != 2:
        raise TypeError("lrs_extract_spec - " + \
                        "Given data product does not contain any data!")

    sig = data.data
    sigErr = data.err
    all_x = []
    all_p = []
    all_fit = []
    all_perr = []
    for i in range(sig.shape[0]):
        si = sig[i, :]
        simax = np.max(si)
        stdevSi = np.std(si)
        if simax <= 0 or stdevSi == 0:
            if verbose:
                print("signal is below or equal zero in row ", i)
            continue
        if simax / stdevSi < 1. or simax < np.mean(sigErr):
            if verbose:
                print("signal too low in row ", i)
            continue
        maxind = np.where(si == simax)[0][0]
        p_guess = (0, simax, maxind, 2)
        try:
            fit, p, perr = nonLinFit(gaussian,
                                     np.arange(sig.shape[1]),
                                     si,
                                     y_sigma=sigErr[i, :],
                                     p_guess=p_guess,
                                     plotting=makeplot,
                                     verbose=verbose)
            p[2] = p[2] + leftY
            all_p.append(p)
            all_fit.append(fit)
            all_perr.append(perr)
            all_x.append(i + minX)
        except:
            print("fit ", i, " did not work")

    return all_x, all_fit, all_p, all_perr
Example #3
0
def lrs_extract_spec_with_fit(data,
                              minX=0,
                              leftY=0,
                              verbose=False,
                              makeplot=False):
    """
    
    Extracts spectra from the data by summing along the spatial-x axis considering NaNs.
    The row extension to sum over is determined by a Gaussian fit +- 3*FWHM

    :Parameters:

    data: MiriMeasuredModel (or similar 2-D DataModel)
        The 2-D data product from which spectra will be extracted.
        
    :Returns:
    
    Spectrum1d: dataproduct with
        * spec: 1d array 
            The extracted spectrum
        * err: 1d array
            The propagated error 

    :Raises:
    
    TypeError
        if wrong input type
    
    """

    # Make sure the given data is a 2-D JWST data product.
    if isinstance(data, MiriMeasuredModel):
        if np.ndim(data.data) != 2:
            strg = "lrs_extract_spec - 2 dimensional data expected "
            strg += "(%d given)." % np.ndim(data.data)
            raise TypeError(strg)
    else:
        raise TypeError("lrs_extract_spec - " + \
                        "Given data product is not a MiriMeasuredModel")
    if np.ndim(data.err) != 2:
        raise TypeError("lrs_extract_spec - " + \
                        "Given data product does not contain any data!")

    sig = data.data
    sigErr = data.err
    col = []
    xpixel = []
    fwhm = []
    for i in range(sig.shape[0]):
        si = sig[i, :]
        simax = np.max(si)
        stdevSi = np.std(si)
        if simax <= 0 or stdevSi == 0:
            continue
        if simax < 0.03 and simax / stdevSi < 1.:
            continue
        maxind = np.where(si == simax)[0][0]
        p_guess = (0, simax, maxind, 2)
        try:
            fit, p, perr = nonLinFit(gaussian,
                                     np.arange(sig.shape[1]),
                                     si,
                                     y_sigma=sigErr[i, :],
                                     p_guess=p_guess,
                                     plotting=False,
                                     verbose=verbose)
            col.append(p[2] + leftY)
            xpixel.append(i + minX)
            fwhm.append(p[3])
        except:
            print("fit ", i, " did not work")

    col = np.asarray(col)
    xpixel = np.asarray(xpixel)
    fwhm = np.asarray(fwhm)
    if makeplot:
        mplt.plot_xy(xpixel, col, title="fit result position of peak")
    stdevCol = np.std(col)
    meanCol = np.mean(col)
    if verbose:
        print("mean column ", meanCol)
        print("stddev column ", stdevCol)
    colInd = np.where(
        np.logical_and(col < meanCol + _sigma_clip * stdevCol,
                       col > meanCol - _sigma_clip * stdevCol))[0]

    newXpixel = xpixel[colInd]
    newCol = col[colInd]
    newFwhm = fwhm[colInd]
    coeff = np.polyfit(newXpixel, newCol, 1)
    line = coeff[0] * newXpixel + coeff[1]
    fwhmCoeff = np.polyfit(newXpixel, newFwhm, 1)
    lineFwhm = fwhmCoeff[0] * newXpixel + fwhmCoeff[1]
    if verbose:
        print("no of useful pixels ", len(newXpixel))
    if makeplot:
        fig = pyplot.figure(facecolor="0.98")
        fit = fig.add_subplot(211)
        fit.plot(newXpixel, newCol, 'ro', np.sort(newXpixel), line)
        fit.set_title("fitted determined columns")
        fw = fig.add_subplot(212)
        fw.plot(newXpixel, lineFwhm)
        fw.set_title("FWHM")
        pyplot.show()

    #extract the spectra along col +- 3 * FHWM
    spec = np.ndarray(sig.shape[0])
    err = np.ndarray(sig.shape[0])
    for i in range(sig.shape[0]):
        column = coeff[0] * (i + minX) + coeff[1] - leftY
        fw = fwhmCoeff[0] * (i + minX) + fwhmCoeff[1]
        si = sig[i, int(column - 3. * fw):int(column + 3. * fw)]
        er = sigErr[i, int(column - 3. * fw):int(column + 3. * fw)]
        spec[i] = np.nansum(si)
        err[i] = np.sqrt(np.nansum(np.square(er)))

    if np.ndim(data.dq) > 1:
        dq = data.dq
        # Crunch the DQ array into 1-D by taking the maximum
        #         qual = np.max(dq, 1)
        qual = dq.max(0)
        data.dq = qual
    else:
        qual = None

    data.data = spec
    data.err = err
    #spectrum = Spectrum1D(spec, error = err, quality = qual )
    return data, newXpixel, line