Ejemplo n.º 1
0
def calc_fwhm(img, region, fexpand=3, axis=0):
    """Compute the FWHM in the direction given by axis"""

    # We compute know the FWHM of the slit
    # Given the computed position of the slit
    # Expand 'fexpand' pixels around
    # and cut an slice in the median filtered image

    xpregion = expand_region(region, fexpand, fexpand)
    cslit = img[xpregion]

    # Collapse it
    pslit = cslit.mean(axis=axis)

    # Estimate the background as a flat line
    # starting in pslit[0] and ending in pslit[-1]
    x2 = len(pslit)
    y1, y2 = pslit[0], pslit[-1]
    mslope = (y2 - y1) / x2
    # background estimation
    backstim = mslope * numpy.arange(x2) + y1

    # We subtract background
    qslit = pslit - backstim
    # and find the pixel of the maximum
    pidx = numpy.argmax(qslit)
    peak, fwhm = fmod.compute_fwhm_1d_simple(qslit, pidx)
    return fwhm
Ejemplo n.º 2
0
def calc_fwhm(img, region, fexpand=3, axis=0):
    """Compute the FWHM in the direction given by axis"""

    # We compute know the FWHM of the slit
    # Given the computed position of the slit
    # Expand 'fexpand' pixels around
    # and cut an slice in the median filtered image

    xpregion = expand_region(region, fexpand, fexpand)
    cslit = img[xpregion]

    # Collapse it
    pslit = cslit.mean(axis=axis)

    # Estimate the background as a flat line
    # starting in pslit[0] and ending in pslit[-1]
    x2 = len(pslit)
    y1, y2 = pslit[0], pslit[-1]
    mslope = (y2-y1) / x2
    # background estimation
    backstim = mslope*numpy.arange(x2) + y1

    # We subtract background
    qslit = pslit-backstim
    # and find the pixel of the maximum
    pidx = numpy.argmax(qslit)
    peak, fwhm = fmod.compute_fwhm_1d_simple(qslit, pidx)
    return fwhm
Ejemplo n.º 3
0
    def calc_fwhm_of_line(self, row, peak_int, lwidth=20):
        """
        Compute FWHM of lines in spectra
        """
        import numina.array.fwhm as fmod

        # FIXME: this could wrap around the image
        qslit = row[peak_int - lwidth:peak_int + lwidth]
        return fmod.compute_fwhm_1d_simple(qslit, lwidth)
Ejemplo n.º 4
0
    def run_on_image(self, rssdata, tracemap, current_vph):
        """Extract spectra, find peaks and compute FWHM."""

        # Extract the polynomials
        # FIXME: a little hackish
        valid_traces = get_valid_traces(tracemap)
        pols = [t.polynomial for t in tracemap.contents]
        vph_t = vph_thr['default']
        this_val = vph_t.get(current_vph)
        if this_val:
            flux_limit = this_val.get('flux_limit', 200000)
        else:
            flux_limit = 40000

        nwinwidth = 5
        times_sigma = 50.0
        lwidth = 20
        fpeaks = {}
        # FIXME: We are using here only one in 10 fibers
        for fibid in valid_traces[::10]:
            # sampling every 10 fibers...
            idx = fibid - 1
            row = rssdata[idx, :]

            the_pol = pols[idx]

            # FIXME: using here a different peak routine than in arc
            # find peaks
            threshold = numpy.median(row) + times_sigma * sigmaG(row)

            ipeaks_int1 = find_peaks_indexes(row, nwinwidth, threshold)
            # filter by flux
            self.logger.info('Filtering peaks over %5.0f', flux_limit)
            ipeaks_vals = row[ipeaks_int1]
            mask = ipeaks_vals < flux_limit
            ipeaks_int = ipeaks_int1[mask]
            self.logger.debug('LEN (ipeaks_int): %s', len(ipeaks_int))
            self.logger.debug('ipeaks_int: %s', ipeaks_int)
            ipeaks_float = refine_peaks(row, ipeaks_int, nwinwidth)[0]

            # self.pintarGrafica(refine_peaks(row, ipeaks_int, nwinwidth)[0] - refinePeaks_spectrum(row, ipeaks_int, nwinwidth))

            fpeaks[idx] = []
            for peak, peak_f in zip(ipeaks_int, ipeaks_float):
                try:
                    sl = numina.array.utils.slice_create(peak, lwidth)
                    rel_peak = peak - sl.start
                    qslit = row[sl]
                    peak_val, fwhm = fmod.compute_fwhm_1d_simple(qslit, rel_peak)
                    peak_on_trace = the_pol(peak)
                    fpeaks[idx].append((peak_f, peak_on_trace, fwhm))
                except ValueError as error:
                    self.logger.warning('Error %s computing FWHM in fiber %d', error, idx + 1)
                except IndexError as error:
                    self.logger.warning('Error %s computing FWHM in fiber %d', error, idx + 1)
            self.logger.debug('found %d peaks in fiber %d', len(fpeaks[idx]), idx)
        return fpeaks
Ejemplo n.º 5
0
    def run_on_image(self, img, tracemap, flux_limit=40000, valid_traces=None, times_sigma=50):
        """Extract spectra, find peaks and compute FWHM."""

        rssdata = img[0].data

        if valid_traces:
            valid_traces_s = set(valid_traces) # use set for fast membership
            valid_apers = [aper for aper in tracemap.contents if aper.valid and aper.fibid in valid_traces_s]
        else:
            valid_apers = [aper for aper in tracemap.contents if aper.valid]

        nwinwidth = 5
        lwidth = 20
        fpeaks = {}

        for aper in valid_apers:
            fibid = aper.fibid
            idx = fibid - 1
            row = rssdata[idx, :]

            the_pol = aper.polynomial

            # FIXME: using here a different peak routine than in arc
            # find peaks
            threshold = numpy.median(row) + times_sigma * sigmaG(row)
            self.logger.debug('values for threshold: median: %f, scale: %f, sigma: %f',
                              numpy.median(row), times_sigma, sigmaG(row))
            self.logger.debug('threshold is: %f', threshold)
            ipeaks_int1 = find_peaks_indexes(row, nwinwidth, threshold)
            # filter by flux
            self.logger.info('Filtering peaks over %5.0f', flux_limit)
            ipeaks_vals = row[ipeaks_int1]
            mask = ipeaks_vals < flux_limit
            ipeaks_int = ipeaks_int1[mask]
            self.logger.debug('LEN (ipeaks_int): %s', len(ipeaks_int))
            self.logger.debug('ipeaks_int: %s', ipeaks_int)
            ipeaks_float = refine_peaks(row, ipeaks_int, nwinwidth)[0]

            # self.pintarGrafica(refine_peaks(row, ipeaks_int, nwinwidth)[0] - refinePeaks_spectrum(row, ipeaks_int, nwinwidth))

            fpeaks[fibid] = []
            for peak, peak_f in zip(ipeaks_int, ipeaks_float):
                try:
                    sl = numina.array.utils.slice_create(peak, lwidth)
                    rel_peak = peak - sl.start
                    qslit = row[sl]
                    peak_val, fwhm = fmod.compute_fwhm_1d_simple(qslit, rel_peak)
                    peak_on_trace = the_pol(peak)
                    fpeaks[fibid].append((peak_f, peak_on_trace, fwhm))
                except ValueError as error:
                    self.logger.warning('Error %s computing FWHM in fiber %d', error, fibid)
                except IndexError as error:
                    self.logger.warning('Error %s computing FWHM in fiber %d', error, fibid)
            self.logger.debug('found %d peaks in fiber %d', len(fpeaks[fibid]), fibid)
        return fpeaks
Ejemplo n.º 6
0
def refine_bar_centroid(arr_deriv, centerx, centery, wx, wy, threshold, sign):
    # Refine values
    logger = logging.getLogger('emir.recipes.bardetect')

    logger.debug('collapsing a %d x %d region', 2 * wx + 1, 2 * wy + 1)
    #
    slicey = slice_create(centery, wy, start=1, stop=2047)
    slicex = slice_create(centerx, wx, start=1, stop=2047)
    region = arr_deriv[slicey, slicex]

    if region.size == 0:
        logger.debug('region to collapse is empty')
        return 0, 0, 1

    collapsed = sign * region.mean(axis=0)

    # Fine tunning
    idxs_t = find_peaks_indexes(collapsed, window_width=3, threshold=threshold)
    # Use only the peak nearest the original peak
    if len(idxs_t) == 0:
        logger.debug('no peaks after fine-tunning')
        return 0, 0, 2

    dist_t = numpy.abs(idxs_t - wx)
    only_this = dist_t.argmin()
    idxs_p = numpy.atleast_1d(idxs_t[only_this])
    x_t, y_t = refine_peaks(collapsed, idxs_p, window_width=3)

    if len(x_t) == 0:
        logger.debug('no peaks to refine after fitting')
        return 0, 0, 2

    if x_t[0] >= collapsed.shape[0]:
        logger.debug('wrong position %d when refining', x_t[0])
        return 0, 0, 2

    _, fwhm_x = fmod.compute_fwhm_1d_simple(collapsed, x_t[0])

    xl = centerx - wx + x_t[0]
    return xl, fwhm_x, 0
Ejemplo n.º 7
0
def refine_bar_centroid(arr_deriv, centerx, centery, wx, wy, threshold, sign):
    # Refine values
    logger = logging.getLogger('emir.recipes.bardetect')

    logger.debug('collapsing a %d x %d region', 2 * wx + 1 , 2 * wy + 1)
    #
    slicey = slice_create(centery, wy, start=1, stop=2047)
    slicex = slice_create(centerx, wx, start=1, stop=2047)
    region = arr_deriv[slicey, slicex]

    if region.size == 0:
        logger.debug('region to collapse is empty')
        return 0, 0, 1

    collapsed = sign * region.mean(axis=0)

    # Fine tunning
    idxs_t = find_peaks_indexes(collapsed, window_width=3, threshold=threshold)
    # Use only the peak nearest the original peak
    if len(idxs_t) == 0:
        logger.debug('no peaks after fine-tunning')
        return 0, 0, 2

    dist_t = numpy.abs(idxs_t - wx)
    only_this = dist_t.argmin()
    idxs_p = numpy.atleast_1d(idxs_t[only_this])
    x_t, y_t = refine_peaks(collapsed, idxs_p, window_width=3)

    if len(x_t) == 0:
        logger.debug('no peaks to refine after fitting')
        return 0, 0, 2

    if x_t[0] >= collapsed.shape[0]:
        logger.debug('wrong position %d when refining', x_t[0])
        return 0, 0, 2

    _, fwhm_x = fmod.compute_fwhm_1d_simple(collapsed, x_t[0])

    xl = centerx - wx + x_t[0]
    return xl, fwhm_x, 0
Ejemplo n.º 8
0
def rim(data, xinit, yinit,
        recenter_half_box=5,
        recenter_nloop=10,
        recenter_maxdist=10.0, buff=3, width=5, niter=10, rplot=8):

    fine_recentering = False
    sigma0 = 1.0
    rad = 3 * sigma0 * FWHM_G
    box = recenter_half_box
    recenter_half_box = (box, box)
    plot_half_box = (3*box, 3*box)

    print('C initial', xinit, yinit)
    x0, y0, _1, _2, _3 = centering_centroid(data, xinit, yinit,
                                            box=recenter_half_box,
                                            maxdist=recenter_maxdist,
                                            nloop=recenter_nloop
                                            )
    print('C final', x0, y0)

    if fine_recentering:
        print('Fine recentering')
        print('C initial', x0, y0)
        x1, y1, _back, _status, _msg = centering_centroid(
            data,
            x0,
            y0,
            box=(1, 1),
            maxdist=2*math.sqrt(2),
            nloop=1
            )
        print('C final', x1, y1)

    sl = image_box2d(x0, y0, data.shape, plot_half_box)
    part = data[sl]

    xx0 = x0 - sl[1].start
    yy0 = y0 - sl[0].start

    Y, X = np.mgrid[sl]

    # Photometry
    D = np.sqrt((X-x0)**2 + (Y-y0)**2)
    m = D < rplot
    r1 = D[m]

    fitter = fitting.LevMarLSQFitter()
    model = models.Gaussian1D(amplitude=1.0, mean=0, stddev=1.0)
    model.mean.fixed = True  # Mean is always 0.0

    irad = rad
    for i in range(niter):
        rs1 = rad + buff
        rs2 = rs1 + width

        bckestim = AnnulusBackgroundEstimator(r1=rs1, r2=rs2)
        bck = bckestim(part, xx0, yy0)
        part_s = part - bck

        ca = CircularAperture([(xx0, yy0)], rad)
        m = aperture_photometry(part_s, ca)
        flux_aper = m['aperture_sum'][0]

        f1 = part_s[m]
        g1d_f = fitter(model, r1, f1, weights=(r1+1e-12)**-1)

        rpeak = g1d_f.amplitude.value
        # sometimes the fit is negative
        rsigma = abs(g1d_f.stddev.value)

        rfwhm = rsigma * FWHM_G

        dpeak, dfwhm, smsg = compute_fwhm_enclosed_direct(part_s, xx0, yy0)

        rad = 3 * dfwhm
        if abs(rad-irad) < 1e-3:
            # reached convergence
            print('convergence in iter %d' % (i+1))
            break
        else:
            irad = rad
    else:
        print('no convergence in photometric radius determination')

    print('P, aper rad', rad, 'flux_aper', flux_aper[0])
    print('P, annulus background:', bck, 'radii', rs1, rs2)
    eamp, efwhm, epeak, emsg = compute_fwhm_enclosed_grow(
        part_s, xx0, yy0, maxrad=rs1
        )
    print('Enclosed fit, peak:', epeak, 'fwhm', efwhm)
    print('Radial fit, peak:', rpeak, 'fwhm', rfwhm)
    print('Direct enclosed, peak:', dpeak, 'dfwhm', dfwhm)

    lpeak, fwhm_x, fwhm_y = compute_fwhm_1d_simple(part_s, xx0, yy0)
    print('Simple, peak:', lpeak, 'fwhm x', fwhm_x, 'fwhm y', fwhm_y)

    # Fit in a smaller box
    fit2d_rad = int(math.ceil(0.5 * rad))

    fit2d_half_box = (fit2d_rad, fit2d_rad)
    sl1 = image_box2d(x0, y0, data.shape, fit2d_half_box)
    part1 = data[sl1]
    Y1, X1 = np.mgrid[sl1]
    g2d = models.Gaussian2D(amplitude=rpeak, x_mean=x0, y_mean=y0,
                            x_stddev=1.0, y_stddev=1.0)
    g2d_f = fitter(g2d, X1, Y1, part1 - bck)
    print('Gauss2D fit')
    print(g2d_f)

    moments_half_box = fit2d_half_box
    Mxx, Myy, Mxy, e, pa = moments(data, x0, y0, moments_half_box)

    print(Mxx, Myy, Mxy, e, pa)