Пример #1
0
def compute_fw_at_frac_max_1d_simple(Y, xc, X=None, f=0.5):
    """Compute the full width at fraction f of the maximum"""

    yy = np.asarray(Y)

    if yy.ndim != 1:
        raise ValueError('array must be 1-d')

    if yy.size == 0:
        raise ValueError('array is empty')

    if X is None:
        xx = np.arange(yy.shape[0])
    else:
        xx = X

    xpix = coor_to_pix_1d(xc - xx[0])

    try:
        peak = yy[xpix]
    except IndexError:
        raise ValueError('peak is out of array')

    fwhm_x, _codex, _msgx = compute_fwhm_1d(xx, yy - f * peak, xc, xpix)
    return peak, fwhm_x
Пример #2
0
def _locate_bar_gen(icut, epos, transform1, transform2):
    """Generic function for the fine position of the CSU"""

    epos_pix = coor_to_pix_1d(epos)

    # transform ->
    epos_pix_s = transform1(epos_pix)
    icut2 = transform2(icut)
    #

    try:
        res = position_half_h(icut2, epos_pix_s)

        xint_s, next_peak_s, wpos1_s, wpos2_s, background_level, half_height = res
        #

        xint = transform1(xint_s)

        #
        epos_f = xint
        error = 0
    except ValueError:
        error = 2
        epos_f = epos

    return epos_pix, epos_f, error
Пример #3
0
def _locate_bar_gen(icut, epos, transform1, transform2):
    """Generic function for the fine position of the CSU"""

    epos_pix = coor_to_pix_1d(epos)

    # transform ->
    epos_pix_s = transform1(epos_pix)
    icut2 = transform2(icut)
    #

    try:
        res = position_half_h(icut2, epos_pix_s)

        xint_s, next_peak_s, wpos1_s, wpos2_s, background_level, half_height = res
        #

        xint = transform1(xint_s)

        #
        epos_f = xint
        error = 0
    except ValueError:
        error = 2
        epos_f = epos

    return epos_pix, epos_f, error
Пример #4
0
def compute_fwhm_2d_simple(img, xc, yc):

    X = np.arange(0, img.shape[1], 1.0)
    Y = np.arange(0, img.shape[0], 1.0)

    xpix = coor_to_pix_1d(xc - X[0])
    ypix = coor_to_pix_1d(yc - Y[0])

    peak = img[ypix, xpix]

    res11 = img[ypix, :]
    res22 = img[:, xpix]

    fwhm_x, _codex, _msgx = compute_fwhm_1d(X, res11 - 0.5 * peak, xc, xpix)
    fwhm_y, _codey, _msgy = compute_fwhm_1d(Y, res22 - 0.5 * peak, yc, ypix)

    return peak, fwhm_x, fwhm_y
Пример #5
0
def compute_fwhm_2d_spline(img, xc, yc):

    Y = np.arange(0.0, img.shape[1], 1.0)
    X = np.arange(0.0, img.shape[0], 1.0)

    xpix = coor_to_pix_1d(xc)
    ypix = coor_to_pix_1d(yc)
    # The image is already cropped

    bb = itpl.RectBivariateSpline(X, Y, img)
    # We assume that the peak is in the center...
    peak = bb(xc, yc)[0, 0]

    U = X
    V = bb.ev(U, [yc for _ in U]) - 0.5 * peak
    fwhm_x, _codex, _msgx = compute_fwhm_1d(U, V, yc, ypix)

    U = Y
    V = bb.ev([xc for _ in U], U) - 0.5 * peak
    fwhm_y, _codey, _msgy = compute_fwhm_1d(U, V, xc, xpix)

    return peak, fwhm_x, fwhm_y
Пример #6
0
    def compute_slits(self, hdulist, csu_conf):

        self.logger.debug('finding borders of slits')
        self.logger.debug('not strictly necessary...')
        data = hdulist[0].data
        self.logger.debug('dtype of data %s', data.dtype)

        self.logger.debug('median filter (3x3)')
        image_base = ndi.filters.median_filter(data, size=3)

        # Cast as original type for skimage
        self.logger.debug('casting image to unit16 (for skimage)')
        iuint16 = np.iinfo(np.uint16)
        image = np.clip(image_base, iuint16.min, iuint16.max).astype(np.uint16)

        self.logger.debug('compute Sobel filter')
        # FIXME: compute sob and sob_v is redundant
        sob = filt.sobel(image)
        self.save_intermediate_array(sob, 'sobel_image.fits')
        sob_v = filt.sobel_v(image)
        self.save_intermediate_array(sob_v, 'sobel_v_image.fits')

        # Compute detector coordinates of bars
        all_coords_virt = np.empty((110, 2))
        all_coords_real = np.empty((110, 2))

        # Origin of coordinates is 1
        for bar in csu_conf.bars.values():
            all_coords_virt[bar.idx - 1] = bar.xpos, bar.y0

        # Origin of coordinates is 1 for this function
        _x, _y = dist.exvp(all_coords_virt[:, 0], all_coords_virt[:, 1])
        all_coords_real[:, 0] = _x
        all_coords_real[:, 1] = _y

        # FIXME: hardcoded value
        h = 16
        slit_h_virt = 16.242
        slit_h_tol = 3
        slits_bb = {}

        mask1 = np.zeros_like(hdulist[0].data)

        for idx in range(EMIR_NBARS):
            lbarid = idx + 1
            rbarid = lbarid + EMIR_NBARS
            ref_x_l_v, ref_y_l_v = all_coords_virt[lbarid - 1]
            ref_x_r_v, ref_y_r_v = all_coords_virt[rbarid - 1]

            ref_x_l_d, ref_y_l_d = all_coords_real[lbarid - 1]
            ref_x_r_d, ref_y_r_d = all_coords_real[rbarid - 1]

            width_v = ref_x_r_v - ref_x_l_v
            # width_d = ref_x_r_d - ref_x_l_d

            if (ref_y_l_d >= 2047 + h) or (ref_y_l_d <= 1 - h):
                # print('reference y position is outlimits, skipping')
                continue

            if width_v < 5:
                # print('width is less than 5 pixels, skipping')
                continue

            plot = False
            regionw = 12
            px1 = coor_to_pix_1d(ref_x_l_d) - 1
            px2 = coor_to_pix_1d(ref_x_r_d) - 1
            prow = coor_to_pix_1d(ref_y_l_d) - 1

            comp_l, comp_r = calc0(image, sob_v, prow, px1, px2, regionw, h=h,
                                   plot=plot, lbarid=lbarid, rbarid=rbarid,
                                   plot2=False)
            if np.any(np.isnan([comp_l, comp_r])):
                self.logger.warning("converting NaN value, border of=%d", idx + 1)
                self.logger.warning("skipping bar=%d", idx + 1)
                continue
            elif comp_l > comp_r:
                # Not refining
                self.logger.warning("computed left border of=%d greater than right border", idx + 1)
                comp2_l, comp2_r = px1, px2
            else:
                region2 = 5
                px21 = coor_to_pix_1d(comp_l)
                px22 = coor_to_pix_1d(comp_r)

                comp2_l, comp2_r = calc0(image, sob_v, prow, px21, px22, region2,
                                         refine=True,
                                         plot=plot, lbarid=lbarid, rbarid=rbarid,
                                         plot2=False)

                if np.any(np.isnan([comp2_l, comp2_r])):
                    self.logger.warning("converting NaN value, border of=%d", idx + 1)
                    comp2_l, comp2_r = comp_l, comp_r
                elif comp2_l > comp2_r:
                    # Not refining
                    self.logger.warning("computed left border of=%d greater than right border", idx + 1)
                    comp2_l, comp2_r = comp_l, comp_r

            # print('slit', lbarid, '-', rbarid, comp_l, comp_r)
            # print('pos1', comp_l, comp_r)
            # print('pos2', comp2_l, comp2_r)

            xpos1_virt, _ = dist.pvex(comp2_l + 1, ref_y_l_d)
            xpos2_virt, _ = dist.pvex(comp2_r + 1, ref_y_r_d)

            y1_virt = ref_y_l_v - slit_h_virt - slit_h_tol
            y2_virt = ref_y_r_v + slit_h_virt + slit_h_tol
            _, y1 = dist.exvp(xpos1_virt + 1, y1_virt)
            _, y2 = dist.exvp(xpos2_virt + 1, y2_virt)
            # print(comp2_l, comp2_r, y1 - 1, y2 - 1)
            cbb = BoundingBox.from_coordinates(comp2_l, comp2_r, y1 - 1, y2 - 1)
            slits_bb[lbarid] = cbb
            mask1[cbb.slice] = lbarid

        self.save_intermediate_array(mask1, 'mask_slit_computed.fits')
        return slits_bb
Пример #7
0
    def run(self, rinput):
        self.logger.info('starting processing for bars detection')

        flow = self.init_filters(rinput)

        hdulist = basic_processing_with_combination(rinput, flow=flow)

        hdr = hdulist[0].header
        self.set_base_headers(hdr)

        try:
            rotang = hdr['ROTANG']
            tsutc1 = hdr['TSUTC1']
            dtub, dtur = datamodel.get_dtur_from_header(hdr)
            csupos = datamodel.get_csup_from_header(hdr)
            csusens = datamodel.get_cs_from_header(hdr)

        except KeyError as error:
            self.logger.error(error)
            raise numina.exceptions.RecipeError(error)

        self.logger.debug('finding bars')
        # Processed array
        arr = hdulist[0].data

        # Median filter of processed array (two times)
        mfilter_size = rinput.median_filter_size

        self.logger.debug('median filtering X, %d columns', mfilter_size)
        arr_median = median_filter(arr, size=(1, mfilter_size))
        self.logger.debug('median filtering X, %d rows', mfilter_size)
        arr_median = median_filter(arr_median, size=(mfilter_size, 1))

        # Median filter of processed array (two times) in the other direction
        # for Y coordinates
        self.logger.debug('median filtering Y, %d rows', mfilter_size)
        arr_median_alt = median_filter(arr, size=(mfilter_size, 1))
        self.logger.debug('median filtering Y, %d columns', mfilter_size)
        arr_median_alt = median_filter(arr_median_alt, size=(1, mfilter_size))

        xfac = dtur[0] / EMIR_PIXSCALE
        yfac = -dtur[1] / EMIR_PIXSCALE

        vec = [yfac, xfac]
        self.logger.debug('DTU shift is %s', vec)

        # and the table of approx positions of the slits
        barstab = rinput.bars_nominal_positions
        # Currently, we only use fields 0 and 2
        # of the nominal positions file

        # Number or rows used
        # These other parameters cab be tuned also
        bstart = 1
        bend = 2047
        self.logger.debug('ignoring columns outside %d - %d',bstart, bend-1)

        # extract a region to average
        wy = (rinput.average_box_row_size // 2)
        wx = (rinput.average_box_col_size // 2)
        self.logger.debug('extraction window is %d rows, %d cols',2*wy+1, 2*wx+1)
        # Fit the peak with these points
        wfit = 2 * (rinput.fit_peak_npoints // 2) + 1
        self.logger.debug('fit with %d points', wfit)

        # Minimum threshold
        threshold = 5 * EMIR_RON
        # Savitsky and Golay (1964) filter to compute the X derivative
        # scipy >= xx has a savgol_filter function
        # for compatibility we do it manually

        allpos = {}
        ypos3_kernel = None
        slits = numpy.zeros((EMIR_NBARS, 8), dtype='float')

        self.logger.info('start finding bars')
        for ks in [3, 5, 7, 9]:
            self.logger.debug('kernel size is %d', ks)
            # S and G kernel for derivative
            kw = ks * (ks*ks-1) / 12.0
            coeffs_are = -numpy.arange((1-ks)//2, (ks-1)//2 + 1) / kw
            if ks == 3:
                ypos3_kernel = coeffs_are
            self.logger.debug('kernel weights are %s', coeffs_are)

            self.logger.debug('derive image in X direction')
            arr_deriv = convolve1d(arr_median, coeffs_are, axis=-1)
            # Axis 0 is
            #
            self.logger.debug('derive image in Y direction (with kernel=3)')
            arr_deriv_alt = convolve1d(arr_median_alt, ypos3_kernel, axis=0)

            positions = []
            for coords in barstab:
                lbarid = int(coords[0])
                rbarid = lbarid + EMIR_NBARS
                ref_y_coor = coords[1] + vec[1]
                poly_coeffs = coords[2:]
                prow = coor_to_pix_1d(ref_y_coor) - 1
                fits_row = prow + 1 # FITS pixel index

                # A function that returns the center of the bar
                # given its X position
                def center_of_bar(x):
                    # Pixel values are 0-based
                    return polyval(x+1-vec[0], poly_coeffs) + vec[1] - 1

                self.logger.debug('looking for bars with ids %d - %d', lbarid, rbarid)
                self.logger.debug('reference y position is Y %7.2f', ref_y_coor)

                # if ref_y_coor is outlimits, skip this bar
                # ref_y_coor is in FITS format
                if (ref_y_coor >= 2047) or (ref_y_coor <= 1):
                    self.logger.debug('reference y position is outlimits, skipping')
                    positions.append([lbarid, fits_row, fits_row, 1, 0, 3])
                    positions.append([rbarid, fits_row, fits_row, 1, 0, 3])
                    continue

                # Left bar
                self.logger.debug('measure left border (%d)', lbarid)

                centery, xpos, fwhm, st = char_bar_peak_l(arr_deriv, prow, bstart, bend, threshold,
                                                          center_of_bar, wx=wx, wy=wy, wfit=wfit)
                xpos1 = xpos
                positions.append([lbarid, centery+1, fits_row, xpos+1, fwhm, st])

                # Right bar
                self.logger.debug('measure rigth border (%d)', rbarid)
                centery, xpos, fwhm, st = char_bar_peak_r(arr_deriv, prow, bstart, bend, threshold,
                                                          center_of_bar, wx=wx, wy=wy, wfit=wfit)
                positions.append([rbarid, centery+1, fits_row, xpos+1, fwhm, st])
                xpos2 = xpos
                #
                if st == 0:
                    self.logger.debug('measure top-bottom borders')
                    try:
                        y1, y2, statusy = char_bar_height(arr_deriv_alt, xpos1, xpos2, centery, threshold,
                                                          wh=35, wfit=wfit)
                    except Exception as error:
                        self.logger.warning('Error computing height: %s', error)
                        statusy = 44

                    if statusy in [0, 40]:
                        # Main border is detected
                        positions[-1][1] = y2 + 1
                        positions[-2][1] = y2 + 1
                    else:
                        # Update status
                        positions[-1][-1] = 4
                        positions[-2][-1] = 4
                else:
                    self.logger.debug('slit is not complete')
                    y1, y2 = 0, 0

                # Update positions

                self.logger.debug('bar %d centroid-y %9.4f, row %d x-pos %9.4f, FWHM %6.3f, status %d', *positions[-2])
                self.logger.debug('bar %d centroid-y %9.4f, row %d x-pos %9.4f, FWHM %6.3f, status %d', *positions[-1])

                if ks == 5:
                    slits[lbarid - 1] = [xpos1, y2, xpos2, y2, xpos2, y1, xpos1, y1]
                    # FITS coordinates
                    slits[lbarid - 1] += 1.0
                    self.logger.debug('inserting bars %d-%d into "slits"', lbarid, rbarid)

            allpos[ks] = numpy.asarray(positions, dtype='float') # GCS doesn't like lists of lists

        self.logger.debug('end finding bars')
        result = self.create_result(frame=hdulist,
                                    slits=slits,
                                    positions9=allpos[9],
                                    positions7=allpos[7],
                                    positions5=allpos[5],
                                    positions3=allpos[3],
                                    DTU=dtub,
                                    ROTANG=rotang,
                                    TSUTC1=tsutc1,
                                    csupos=csupos,
                                    csusens=csusens,
                                    )
        return result
Пример #8
0
    def run(self, rinput):

        logger = logging.getLogger('numina.recipes.emir')

        logger.info('starting processing for bars detection')

        flow = self.init_filters(rinput)

        hdulist = basic_processing_with_combination(rinput, flow=flow)

        hdr = hdulist[0].header
        self.set_base_headers(hdr)

        try:
            rotang = hdr['ROTANG']
            dtub, dtur = datamodel.get_dtur_from_header(hdr)
            csupos = datamodel.get_csup_from_header(hdr)
            csusens = datamodel.get_cs_from_header(hdr)

        except KeyError as error:
            logger.error(error)
            raise numina.exceptions.RecipeError(error)

        logger.debug('finding bars')

        arr = hdulist[0].data

        # Median filter
        logger.debug('median filtering')
        mfilter_size = rinput.median_filter_size

        arr_median = median_filter(arr, size=mfilter_size)

        # Image is mapped between 0 and 1
        # for the full range [0: 2**16]
        logger.debug('image scaling to 0-1')
        arr_grey = normalize_raw(arr_median)

        # Find borders
        logger.debug('find borders')
        canny_sigma = rinput.canny_sigma
        # These threshols corespond roughly with
        # value x (2**16 - 1)
        high_threshold = rinput.canny_high_threshold
        low_threshold = rinput.canny_low_threshold

        edges = canny(arr_grey,
                      sigma=canny_sigma,
                      high_threshold=high_threshold,
                      low_threshold=low_threshold)

        # Number or rows used
        # These other parameters cab be tuned also
        total = 5
        maxdist = 1.0
        bstart = 100
        bend = 1900

        positions = []
        nt = total // 2

        xfac = dtur[0] / EMIR_PIXSCALE
        yfac = -dtur[1] / EMIR_PIXSCALE

        vec = [yfac, xfac]
        logger.debug('DTU shift is %s', vec)

        # Based on the 'edges image'
        # and the table of approx positions of the slits
        barstab = rinput.bars_nominal_positions

        # Currently, we only use fields 0 and 2
        # of the nominal positions file

        for coords in barstab:
            lbarid = int(coords[0])
            rbarid = lbarid + 55
            ref_y_coor = coords[2] + vec[1]
            prow = coor_to_pix_1d(ref_y_coor) - 1
            fits_row = prow + 1  # FITS pixel index

            logger.debug('looking for bars with ids %d - %d', lbarid, rbarid)
            logger.debug('reference y position is Y %7.2f', ref_y_coor)
            # Find the position of each bar

            bpos = find_position(edges, prow, bstart, bend, total)

            nbars_found = len(bpos)

            # If no bar is found, append and empty token
            if nbars_found == 0:
                logger.debug('bars %d, %d not found at row %d', lbarid, rbarid,
                             fits_row)
                thisres1 = (lbarid, fits_row, 0, 0, 1)
                thisres2 = (rbarid, fits_row, 0, 0, 1)

            elif nbars_found == 2:

                # Order values by increasing X
                centl, centr = sorted(bpos, key=lambda cen: cen[0])
                c1 = centl[0]
                c2 = centr[0]

                logger.debug('bars found  at row %d between %7.2f - %7.2f',
                             fits_row, c1, c2)
                # Compute FWHM of the collapsed profile

                cslit = arr_grey[prow - nt:prow + nt + 1, :]
                pslit = cslit.mean(axis=0)

                # Add 1 to return FITS coordinates
                epos, epos_f, error = locate_bar_l(pslit, c1)
                thisres1 = lbarid, fits_row, epos + 1, epos_f + 1, error

                epos, epos_f, error = locate_bar_r(pslit, c2)
                thisres2 = rbarid, fits_row, epos + 1, epos_f + 1, error

            elif nbars_found == 1:
                logger.warning(
                    'only 1 edge found  at row %d, not yet implemented',
                    fits_row)
                thisres1 = (lbarid, fits_row, 0, 0, 1)
                thisres2 = (rbarid, fits_row, 0, 0, 1)

            else:
                logger.warning(
                    '3 or more edges found  at row %d, not yet implemented',
                    fits_row)
                thisres1 = (lbarid, fits_row, 0, 0, 1)
                thisres2 = (rbarid, fits_row, 0, 0, 1)

            positions.append(thisres1)
            positions.append(thisres2)

        logger.debug('end finding bars')
        result = self.create_result(
            frame=hdulist,
            positions=positions,
            DTU=dtub,
            ROTANG=rotang,
            csupos=csupos,
            csusens=csusens,
            param_median_filter_size=rinput.median_filter_size,
            param_canny_high_threshold=rinput.canny_high_threshold,
            param_canny_low_threshold=rinput.canny_low_threshold)
        return result
Пример #9
0
    def run(self, rinput):

        logger = logging.getLogger('numina.recipes.emir')

        logger.info('starting processing for bars detection')

        flow = self.init_filters(rinput)

        hdulist = basic_processing_with_combination(rinput, flow=flow)

        hdr = hdulist[0].header
        self.set_base_headers(hdr)

        try:
            rotang = hdr['ROTANG']
            dtub, dtur = datamodel.get_dtur_from_header(hdr)
            csupos = datamodel.get_csup_from_header(hdr)
            csusens = datamodel.get_cs_from_header(hdr)

        except KeyError as error:
            logger.error(error)
            raise numina.exceptions.RecipeError(error)

        logger.debug('finding bars')

        arr = hdulist[0].data

        # Median filter
        logger.debug('median filtering')
        mfilter_size = rinput.median_filter_size

        arr_median = median_filter(arr, size=mfilter_size)

        # Image is mapped between 0 and 1
        # for the full range [0: 2**16]
        logger.debug('image scaling to 0-1')
        arr_grey = normalize_raw(arr_median)

        # Find borders
        logger.debug('find borders')
        canny_sigma = rinput.canny_sigma
        # These threshols corespond roughly with
        # value x (2**16 - 1)
        high_threshold = rinput.canny_high_threshold
        low_threshold = rinput.canny_low_threshold

        edges = canny(arr_grey, sigma=canny_sigma,
                      high_threshold=high_threshold,
                      low_threshold=low_threshold)

        # Number or rows used
        # These other parameters cab be tuned also
        total = 5
        maxdist = 1.0
        bstart = 100
        bend = 1900

        positions = []
        nt = total // 2

        xfac = dtur[0] / EMIR_PIXSCALE
        yfac = -dtur[1] / EMIR_PIXSCALE

        vec = [yfac, xfac]
        logger.debug('DTU shift is %s', vec)

        # Based on the 'edges image'
        # and the table of approx positions of the slits
        barstab = rinput.bars_nominal_positions

        # Currently, we only use fields 0 and 2
        # of the nominal positions file

        for coords in barstab:
            lbarid = int(coords[0])
            rbarid = lbarid + 55
            ref_y_coor = coords[2] + vec[1]
            prow = coor_to_pix_1d(ref_y_coor) - 1
            fits_row = prow + 1 # FITS pixel index

            logger.debug('looking for bars with ids %d - %d', lbarid, rbarid)
            logger.debug('reference y position is Y %7.2f', ref_y_coor)
            # Find the position of each bar

            bpos = find_position(edges, prow, bstart, bend, total)

            nbars_found = len(bpos)

            # If no bar is found, append and empty token
            if nbars_found == 0:
                logger.debug('bars %d, %d not found at row %d', lbarid, rbarid, fits_row)
                thisres1 = (lbarid, fits_row, 0, 0, 1)
                thisres2 = (rbarid, fits_row, 0, 0, 1)

            elif nbars_found == 2:

                # Order values by increasing X
                centl, centr = sorted(bpos, key=lambda cen: cen[0])
                c1 = centl[0]
                c2 = centr[0]

                logger.debug('bars found  at row %d between %7.2f - %7.2f', fits_row, c1, c2)
                # Compute FWHM of the collapsed profile

                cslit = arr_grey[prow-nt:prow+nt+1,:]
                pslit = cslit.mean(axis=0)

                # Add 1 to return FITS coordinates
                epos, epos_f, error = locate_bar_l(pslit, c1)
                thisres1 = lbarid, fits_row, epos + 1, epos_f + 1, error


                epos, epos_f, error = locate_bar_r(pslit, c2)
                thisres2 = rbarid, fits_row, epos + 1, epos_f + 1, error

            elif nbars_found == 1:
                logger.warning('only 1 edge found  at row %d, not yet implemented', fits_row)
                thisres1 = (lbarid, fits_row, 0, 0, 1)
                thisres2 = (rbarid, fits_row, 0, 0, 1)

            else:
                logger.warning('3 or more edges found  at row %d, not yet implemented', fits_row)
                thisres1 = (lbarid, fits_row, 0, 0, 1)
                thisres2 = (rbarid, fits_row, 0, 0, 1)

            positions.append(thisres1)
            positions.append(thisres2)

        logger.debug('end finding bars')
        result = self.create_result(frame=hdulist,
                                    positions=positions,
                                    DTU=dtub,
                                    ROTANG=rotang,
                                    csupos=csupos,
                                    csusens=csusens,
                                    param_median_filter_size=rinput.median_filter_size,
                                    param_canny_high_threshold=rinput.canny_high_threshold,
                                    param_canny_low_threshold=rinput.canny_low_threshold
                                    )
        return result
Пример #10
0
def find_bars(hdulist,
              bars_nominal_positions,
              csupos,
              dtur,
              average_box_row_size=7,
              average_box_col_size=21,
              fit_peak_npoints=3,
              median_filter_size=5,
              logger=None):

    logger.debug('filtering image')
    # Processed array
    arr_median = median_filtering(hdulist, median_filter_size)

    xfac = dtur[0] / EMIR_PIXSCALE
    yfac = -dtur[1] / EMIR_PIXSCALE

    vec = [yfac, xfac]
    logger.debug('DTU shift is %s', vec)

    # and the table of approx positions of the slits
    barstab = bars_nominal_positions
    # Currently, we only use fields 0 and 2
    # of the nominal positions file

    # Number or rows used
    # These other parameters cab be tuned also
    bstart = 1
    bend = 2047
    logger.debug('ignoring columns outside %d - %d', bstart, bend - 1)

    # extract a region to average
    # wy = (average_box_row_size // 2)
    # wx = (average_box_col_size // 2)
    # logger.debug('extraction window is %d rows, %d cols', 2 * wy + 1, 2 * wx + 1)
    # Fit the peak with these points
    # wfit = 2 * (fit_peak_npoints // 2) + 1
    # logger.debug('fit with %d points', wfit)

    # Minimum threshold
    threshold = 5 * EMIR_RON
    # Savitsky and Golay (1964) filter to compute the X derivative
    # scipy >= xx has a savgol_filter function
    # for compatibility we do it manually

    allpos = {}
    slits = numpy.zeros((EMIR_NBARS, 8), dtype='float')

    logger.info('find peaks in derivative image')
    for ks in [3, 5, 7, 9]:
        logger.debug('kernel size is %d', ks)
        # S and G kernel for derivative
        kw = ks * (ks * ks - 1) / 12.0
        coeffs_are = -numpy.arange((1 - ks) // 2, (ks - 1) // 2 + 1) / kw
        logger.debug('kernel weights are %s', coeffs_are)

        logger.debug('derive image in X direction')
        arr_deriv = convolve1d(arr_median, coeffs_are, axis=-1)
        # self.save_intermediate_array(arr_deriv, 'deriv_image_k%d.fits' % ks)
        # Axis 0 is
        #
        # logger.debug('derive image in Y direction (with kernel=3)')
        # arr_deriv_alt = convolve1d(arr_median_alt, ypos3_kernel, axis=0)

        positions = []
        logger.info('using bar parameters')
        for idx in range(EMIR_NBARS):
            params_l = barstab[idx]
            params_r = barstab[idx + EMIR_NBARS]
            lbarid = int(params_l[0])

            # CSUPOS for this bar
            rbarid = lbarid + EMIR_NBARS
            current_csupos_l = csupos[lbarid - 1]
            current_csupos_r = csupos[rbarid - 1]
            logger.debug('CSUPOS for bar %d is %f', lbarid, current_csupos_l)
            logger.debug('CSUPOS for bar %d is %f', rbarid, current_csupos_r)

            ref_y_coor_virt = params_l[1]  # Do I need to add vec[1]?
            ref_x_l_coor_virt = params_l[3] + current_csupos_l * params_l[2]
            ref_x_r_coor_virt = params_r[3] + current_csupos_r * params_r[2]
            # Transform to REAL..
            ref_x_l_coor, ref_y_l_coor = dist.exvp(ref_x_l_coor_virt,
                                                   ref_y_coor_virt)
            ref_x_r_coor, ref_y_r_coor = dist.exvp(ref_x_r_coor_virt,
                                                   ref_y_coor_virt)
            # FIXME: check if DTU has to be applied
            # ref_y_coor = ref_y_coor + vec[1]
            prow = coor_to_pix_1d(ref_y_l_coor) - 1
            fits_row = prow + 1  # FITS pixel index

            logger.debug('looking for bars with ids %d - %d', lbarid, rbarid)
            logger.debug('ref Y virtual position is %7.2f', ref_y_coor_virt)
            logger.debug('ref X virtual positions are %7.2f %7.2f',
                         ref_x_l_coor_virt, ref_x_r_coor_virt)
            logger.debug('ref X positions are %7.2f %7.2f', ref_x_l_coor,
                         ref_x_r_coor)
            logger.debug('ref Y positions are %7.2f %7.2f', ref_y_l_coor,
                         ref_y_r_coor)
            # if ref_y_coor is outlimits, skip this bar
            # ref_y_coor is in FITS format
            if (ref_y_l_coor >= 2047 + 16) or (ref_y_l_coor <= 1 - 16):
                logger.debug('reference y position is outlimits, skipping')
                positions.append(
                    [lbarid, fits_row, fits_row, fits_row, 1, 1, 0, 3])
                positions.append(
                    [rbarid, fits_row, fits_row, fits_row, 1, 1, 0, 3])
                continue

            # minimal width of the slit
            minwidth = 0.9
            if abs(ref_x_l_coor_virt - ref_x_r_coor_virt) < minwidth:
                # FIXME: if width < minwidth fit peak in image
                logger.debug('slit is less than %d virt pixels, skipping',
                             minwidth)
                positions.append(
                    [lbarid, fits_row, fits_row, fits_row, 1, 1, 0, 3])
                positions.append(
                    [rbarid, fits_row, fits_row, fits_row, 1, 1, 0, 3])
                continue

            # Left bar
            # Dont add +1 to virtual pixels
            logger.debug('measure left border (%d)', lbarid)
            regionw = 10
            bstart1 = coor_to_pix_1d(ref_x_l_coor - regionw)
            bend1 = coor_to_pix_1d(ref_x_l_coor + regionw) + 1
            centery, centery_virt, xpos1, xpos1_virt, fwhm, st = char_bar_peak_l(
                arr_deriv, prow, bstart1, bend1, threshold)

            insert1 = [
                lbarid, centery + 1, centery_virt, fits_row, xpos1 + 1,
                xpos1_virt, fwhm, st
            ]
            positions.append(insert1)

            # Right bar
            # Dont add +1 to virtual pixels
            logger.debug('measure rigth border (%d)', rbarid)
            bstart2 = coor_to_pix_1d(ref_x_r_coor - regionw)
            bend2 = coor_to_pix_1d(ref_x_r_coor + regionw) + 1
            centery, centery_virt, xpos2, xpos2_virt, fwhm, st = char_bar_peak_r(
                arr_deriv, prow, bstart2, bend2, threshold)
            # This centery/centery_virt should be equal to ref_y_coor_virt
            insert2 = [
                rbarid, centery + 1, centery_virt, fits_row, xpos2 + 1,
                xpos2_virt, fwhm, st
            ]
            positions.append(insert2)

            # FIXME: hardcoded value
            y1_virt = ref_y_coor_virt - 16.242
            y2_virt = ref_y_coor_virt + 16.242
            _, y1 = dist.exvp(xpos1_virt + 1, y1_virt + 1)
            _, y2 = dist.exvp(xpos2_virt + 1, y2_virt + 1)

            # Update positions

            msg = 'bar %d, centroid-y %9.4f centroid-y virt %9.4f, ' \
                  'row %d, x-pos %9.4f x-pos virt %9.4f, FWHM %6.3f, status %d'
            logger.debug(msg, *positions[-2])
            logger.debug(msg, *positions[-1])

            if ks == 5:
                slits[lbarid - 1] = numpy.array(
                    [xpos1, y2, xpos2, y2, xpos2, y1, xpos1, y1])
                # FITS coordinates
                slits[lbarid - 1] += 1.0
                logger.debug('inserting bars %d-%d into "slits"', lbarid,
                             rbarid)

        allpos[ks] = numpy.asarray(
            positions, dtype='float')  # GCS doesn't like lists of lists

    return allpos, slits
Пример #11
0
    def run(self, rinput):
        self.logger.info('starting processing for bars detection')

        flow = self.init_filters(rinput)

        hdulist = basic_processing_with_combination(rinput, flow=flow)

        hdr = hdulist[0].header
        self.set_base_headers(hdr)

        try:
            rotang = hdr['ROTANG']
            tsutc1 = hdr['TSUTC1']
            dtub, dtur = datamodel.get_dtur_from_header(hdr)
            csupos = datamodel.get_csup_from_header(hdr)
            csusens = datamodel.get_cs_from_header(hdr)

        except KeyError as error:
            self.logger.error(error)
            raise numina.exceptions.RecipeError(error)

        self.logger.debug('finding bars')
        # Processed array
        arr = hdulist[0].data

        # Median filter of processed array (two times)
        mfilter_size = rinput.median_filter_size

        self.logger.debug('median filtering X, %d columns', mfilter_size)
        arr_median = median_filter(arr, size=(1, mfilter_size))
        self.logger.debug('median filtering X, %d rows', mfilter_size)
        arr_median = median_filter(arr_median, size=(mfilter_size, 1))

        # Median filter of processed array (two times) in the other direction
        # for Y coordinates
        self.logger.debug('median filtering Y, %d rows', mfilter_size)
        arr_median_alt = median_filter(arr, size=(mfilter_size, 1))
        self.logger.debug('median filtering Y, %d columns', mfilter_size)
        arr_median_alt = median_filter(arr_median_alt, size=(1, mfilter_size))

        xfac = dtur[0] / EMIR_PIXSCALE
        yfac = -dtur[1] / EMIR_PIXSCALE

        vec = [yfac, xfac]
        self.logger.debug('DTU shift is %s', vec)

        # and the table of approx positions of the slits
        barstab = rinput.bars_nominal_positions
        # Currently, we only use fields 0 and 2
        # of the nominal positions file

        # Number or rows used
        # These other parameters cab be tuned also
        bstart = 1
        bend = 2047
        self.logger.debug('ignoring columns outside %d - %d', bstart, bend - 1)

        # extract a region to average
        wy = (rinput.average_box_row_size // 2)
        wx = (rinput.average_box_col_size // 2)
        self.logger.debug('extraction window is %d rows, %d cols', 2 * wy + 1,
                          2 * wx + 1)
        # Fit the peak with these points
        wfit = 2 * (rinput.fit_peak_npoints // 2) + 1
        self.logger.debug('fit with %d points', wfit)

        # Minimum threshold
        threshold = 5 * EMIR_RON
        # Savitsky and Golay (1964) filter to compute the X derivative
        # scipy >= xx has a savgol_filter function
        # for compatibility we do it manually

        allpos = {}
        ypos3_kernel = None
        slits = numpy.zeros((EMIR_NBARS, 8), dtype='float')

        self.logger.info('start finding bars')
        for ks in [3, 5, 7, 9]:
            self.logger.debug('kernel size is %d', ks)
            # S and G kernel for derivative
            kw = ks * (ks * ks - 1) / 12.0
            coeffs_are = -numpy.arange((1 - ks) // 2, (ks - 1) // 2 + 1) / kw
            if ks == 3:
                ypos3_kernel = coeffs_are
            self.logger.debug('kernel weights are %s', coeffs_are)

            self.logger.debug('derive image in X direction')
            arr_deriv = convolve1d(arr_median, coeffs_are, axis=-1)
            # Axis 0 is
            #
            self.logger.debug('derive image in Y direction (with kernel=3)')
            arr_deriv_alt = convolve1d(arr_median_alt, ypos3_kernel, axis=0)

            positions = []
            for coords in barstab:
                lbarid = int(coords[0])
                rbarid = lbarid + EMIR_NBARS
                ref_y_coor = coords[1] + vec[1]
                poly_coeffs = coords[2:]
                prow = coor_to_pix_1d(ref_y_coor) - 1
                fits_row = prow + 1  # FITS pixel index

                # A function that returns the center of the bar
                # given its X position
                def center_of_bar(x):
                    # Pixel values are 0-based
                    return polyval(x + 1 - vec[0], poly_coeffs) + vec[1] - 1

                self.logger.debug('looking for bars with ids %d - %d', lbarid,
                                  rbarid)
                self.logger.debug('reference y position is Y %7.2f',
                                  ref_y_coor)

                # if ref_y_coor is outlimits, skip this bar
                # ref_y_coor is in FITS format
                if (ref_y_coor >= 2047) or (ref_y_coor <= 1):
                    self.logger.debug(
                        'reference y position is outlimits, skipping')
                    positions.append([lbarid, fits_row, fits_row, 1, 0, 3])
                    positions.append([rbarid, fits_row, fits_row, 1, 0, 3])
                    continue

                # Left bar
                self.logger.debug('measure left border (%d)', lbarid)

                centery, xpos, fwhm, st = char_bar_peak_l(arr_deriv,
                                                          prow,
                                                          bstart,
                                                          bend,
                                                          threshold,
                                                          center_of_bar,
                                                          wx=wx,
                                                          wy=wy,
                                                          wfit=wfit)
                xpos1 = xpos
                positions.append(
                    [lbarid, centery + 1, fits_row, xpos + 1, fwhm, st])

                # Right bar
                self.logger.debug('measure rigth border (%d)', rbarid)
                centery, xpos, fwhm, st = char_bar_peak_r(arr_deriv,
                                                          prow,
                                                          bstart,
                                                          bend,
                                                          threshold,
                                                          center_of_bar,
                                                          wx=wx,
                                                          wy=wy,
                                                          wfit=wfit)
                positions.append(
                    [rbarid, centery + 1, fits_row, xpos + 1, fwhm, st])
                xpos2 = xpos
                #
                if st == 0:
                    self.logger.debug('measure top-bottom borders')
                    try:
                        y1, y2, statusy = char_bar_height(arr_deriv_alt,
                                                          xpos1,
                                                          xpos2,
                                                          centery,
                                                          threshold,
                                                          wh=35,
                                                          wfit=wfit)
                    except Exception as error:
                        self.logger.warning('Error computing height: %s',
                                            error)
                        statusy = 44

                    if statusy in [0, 40]:
                        # Main border is detected
                        positions[-1][1] = y2 + 1
                        positions[-2][1] = y2 + 1
                    else:
                        # Update status
                        positions[-1][-1] = 4
                        positions[-2][-1] = 4
                else:
                    self.logger.debug('slit is not complete')
                    y1, y2 = 0, 0

                # Update positions

                self.logger.debug(
                    'bar %d centroid-y %9.4f, row %d x-pos %9.4f, FWHM %6.3f, status %d',
                    *positions[-2])
                self.logger.debug(
                    'bar %d centroid-y %9.4f, row %d x-pos %9.4f, FWHM %6.3f, status %d',
                    *positions[-1])

                if ks == 5:
                    slits[lbarid -
                          1] = [xpos1, y2, xpos2, y2, xpos2, y1, xpos1, y1]
                    # FITS coordinates
                    slits[lbarid - 1] += 1.0
                    self.logger.debug('inserting bars %d-%d into "slits"',
                                      lbarid, rbarid)

            allpos[ks] = numpy.asarray(
                positions, dtype='float')  # GCS doesn't like lists of lists

        self.logger.debug('end finding bars')
        result = self.create_result(
            frame=hdulist,
            slits=slits,
            positions9=allpos[9],
            positions7=allpos[7],
            positions5=allpos[5],
            positions3=allpos[3],
            DTU=dtub,
            ROTANG=rotang,
            TSUTC1=tsutc1,
            csupos=csupos,
            csusens=csusens,
        )
        return result
Пример #12
0
def char_bar_height(arr_deriv_alt,
                    xpos1,
                    xpos2,
                    centery,
                    threshold,
                    wh=35,
                    wfit=3):

    logger = logging.getLogger('emir.recipes.bardetect')
    pcentery = coor_to_pix_1d(centery)
    slicey = slice_create(pcentery, wh, start=1, stop=2047)

    ref_pcentery = pcentery - slicey.start
    mm = arr_deriv_alt[slicey, xpos1:xpos2 + 1].mean(axis=-1)

    idxs_t = find_peaks_indexes(mm, window_width=3, threshold=threshold)
    idxs_u = find_peaks_indexes(-mm, window_width=3, threshold=threshold)
    # Peaks on the right

    status = 0
    npeaks_u = len(idxs_u)
    if npeaks_u == 0:
        # This is a problem, no peak on the right
        b2 = 0
        status = 4
        logger.debug('no bottom border found')
    else:
        # Filter over reference
        g_idxs_u = idxs_u[idxs_u >= ref_pcentery]
        if len(g_idxs_u) == 0:
            logger.debug('no peak over center')
            b2 = 0
            status = 4
        else:
            x_u, y_u = refine_peaks(-mm, g_idxs_u, window_width=wfit)
            # Select the peak with max derivative
            if len(x_u) == 0 or len(y_u) == 0:
                logger.warning("no 1st peak found after refine")
                b2 = 0
                status = 4
            else:
                idmax = y_u.argmax()
                b2 = x_u[idmax]
                b2val = y_u[idmax]
                logger.debug('main border in %f', slicey.start + b2)

    # peaks on the left
    npeaks_t = len(idxs_t)
    if npeaks_t == 0:
        # This is a problem, no peak on the left
        b1 = 0
        logger.debug('no top border found')
        status = 40 + status
    else:
        g_idxs_t = idxs_t[idxs_t <= ref_pcentery]
        if len(g_idxs_t) == 0:
            logger.debug('no peak under center')
            b1 = 0
            status = 40 + status
        else:
            x_t, y_t = refine_peaks(mm, g_idxs_t, window_width=wfit)
            # Select the peak with max derivative
            if len(x_t) == 0 or len(y_t) == 0:
                logger.warning("no 2nd peak found after refine")
                b1 = 0
                status = 40 + status
            else:
                idmax = y_t.argmax()
                b1 = x_t[idmax]
                b1val = y_t[idmax]
                logger.debug('second border in %f', slicey.start + b1)

    return slicey.start + b1, slicey.start + b2, status
Пример #13
0
def find_bars(hdulist, bars_nominal_positions, csupos, dtur,
              average_box_row_size=7, average_box_col_size=21, fit_peak_npoints=3,
              median_filter_size=5, logger=None):

    logger.debug('filtering image')
    # Processed array
    arr_median = median_filtering(hdulist, median_filter_size)

    xfac = dtur[0] / EMIR_PIXSCALE
    yfac = -dtur[1] / EMIR_PIXSCALE

    vec = [yfac, xfac]
    logger.debug('DTU shift is %s', vec)

    # and the table of approx positions of the slits
    barstab = bars_nominal_positions
    # Currently, we only use fields 0 and 2
    # of the nominal positions file

    # Number or rows used
    # These other parameters cab be tuned also
    bstart = 1
    bend = 2047
    logger.debug('ignoring columns outside %d - %d', bstart, bend - 1)

    # extract a region to average
    # wy = (average_box_row_size // 2)
    # wx = (average_box_col_size // 2)
    # logger.debug('extraction window is %d rows, %d cols', 2 * wy + 1, 2 * wx + 1)
    # Fit the peak with these points
    # wfit = 2 * (fit_peak_npoints // 2) + 1
    # logger.debug('fit with %d points', wfit)

    # Minimum threshold
    threshold = 5 * EMIR_RON
    # Savitsky and Golay (1964) filter to compute the X derivative
    # scipy >= xx has a savgol_filter function
    # for compatibility we do it manually

    allpos = {}
    slits = numpy.zeros((EMIR_NBARS, 8), dtype='float')

    logger.info('find peaks in derivative image')
    for ks in [3, 5, 7, 9]:
        logger.debug('kernel size is %d', ks)
        # S and G kernel for derivative
        kw = ks * (ks * ks - 1) / 12.0
        coeffs_are = -numpy.arange((1 - ks) // 2, (ks - 1) // 2 + 1) / kw
        logger.debug('kernel weights are %s', coeffs_are)

        logger.debug('derive image in X direction')
        arr_deriv = convolve1d(arr_median, coeffs_are, axis=-1)
        # self.save_intermediate_array(arr_deriv, 'deriv_image_k%d.fits' % ks)
        # Axis 0 is
        #
        # logger.debug('derive image in Y direction (with kernel=3)')
        # arr_deriv_alt = convolve1d(arr_median_alt, ypos3_kernel, axis=0)

        positions = []
        logger.info('using bar parameters')
        for idx in range(EMIR_NBARS):
            params_l = barstab[idx]
            params_r = barstab[idx + EMIR_NBARS]
            lbarid = int(params_l[0])

            # CSUPOS for this bar
            rbarid = lbarid + EMIR_NBARS
            current_csupos_l = csupos[lbarid - 1]
            current_csupos_r = csupos[rbarid - 1]
            logger.debug('CSUPOS for bar %d is %f', lbarid, current_csupos_l)
            logger.debug('CSUPOS for bar %d is %f', rbarid, current_csupos_r)

            ref_y_coor_virt = params_l[1]  # Do I need to add vec[1]?
            ref_x_l_coor_virt = params_l[3] + current_csupos_l * params_l[2]
            ref_x_r_coor_virt = params_r[3] + current_csupos_r * params_r[2]
            # Transform to REAL..
            ref_x_l_coor, ref_y_l_coor = dist.exvp(ref_x_l_coor_virt, ref_y_coor_virt)
            ref_x_r_coor, ref_y_r_coor = dist.exvp(ref_x_r_coor_virt, ref_y_coor_virt)
            # FIXME: check if DTU has to be applied
            # ref_y_coor = ref_y_coor + vec[1]
            prow = coor_to_pix_1d(ref_y_l_coor) - 1
            fits_row = prow + 1  # FITS pixel index

            logger.debug('looking for bars with ids %d - %d', lbarid, rbarid)
            logger.debug('ref Y virtual position is %7.2f', ref_y_coor_virt)
            logger.debug('ref X virtual positions are %7.2f %7.2f', ref_x_l_coor_virt, ref_x_r_coor_virt)
            logger.debug('ref X positions are %7.2f %7.2f', ref_x_l_coor, ref_x_r_coor)
            logger.debug('ref Y positions are %7.2f %7.2f', ref_y_l_coor, ref_y_r_coor)
            # if ref_y_coor is outlimits, skip this bar
            # ref_y_coor is in FITS format
            if (ref_y_l_coor >= 2047 + 16) or (ref_y_l_coor <= 1 - 16):
                logger.debug('reference y position is outlimits, skipping')
                positions.append([lbarid, fits_row, fits_row, fits_row, 1, 1, 0, 3])
                positions.append([rbarid, fits_row, fits_row, fits_row, 1, 1, 0, 3])
                continue

            # minimal width of the slit
            minwidth = 0.9
            if abs(ref_x_l_coor_virt - ref_x_r_coor_virt) < minwidth:
                # FIXME: if width < minwidth fit peak in image
                logger.debug('slit is less than %d virt pixels, skipping', minwidth)
                positions.append([lbarid, fits_row, fits_row, fits_row, 1, 1, 0, 3])
                positions.append([rbarid, fits_row, fits_row, fits_row, 1, 1, 0, 3])
                continue

            # Left bar
            # Dont add +1 to virtual pixels
            logger.debug('measure left border (%d)', lbarid)
            regionw = 10
            bstart1 = coor_to_pix_1d(ref_x_l_coor - regionw)
            bend1 = coor_to_pix_1d(ref_x_l_coor + regionw) + 1
            centery, centery_virt, xpos1, xpos1_virt, fwhm, st = char_bar_peak_l(arr_deriv,
                                                                                 prow, bstart1, bend1,
                                                                                 threshold)

            insert1 = [lbarid, centery + 1, centery_virt, fits_row, xpos1 + 1, xpos1_virt, fwhm, st]
            positions.append(insert1)

            # Right bar
            # Dont add +1 to virtual pixels
            logger.debug('measure rigth border (%d)', rbarid)
            bstart2 = coor_to_pix_1d(ref_x_r_coor - regionw)
            bend2 = coor_to_pix_1d(ref_x_r_coor + regionw) + 1
            centery, centery_virt, xpos2, xpos2_virt, fwhm, st = char_bar_peak_r(arr_deriv, prow, bstart2, bend2,
                                                                                 threshold)
            # This centery/centery_virt should be equal to ref_y_coor_virt
            insert2 = [rbarid, centery + 1, centery_virt, fits_row, xpos2 + 1, xpos2_virt, fwhm, st]
            positions.append(insert2)

            # FIXME: hardcoded value
            y1_virt = ref_y_coor_virt - 16.242
            y2_virt = ref_y_coor_virt + 16.242
            _, y1 = dist.exvp(xpos1_virt + 1, y1_virt + 1)
            _, y2 = dist.exvp(xpos2_virt + 1, y2_virt + 1)

            # Update positions

            msg = 'bar %d, centroid-y %9.4f centroid-y virt %9.4f, ' \
                  'row %d, x-pos %9.4f x-pos virt %9.4f, FWHM %6.3f, status %d'
            logger.debug(msg, *positions[-2])
            logger.debug(msg, *positions[-1])

            if ks == 5:
                slits[lbarid - 1] = numpy.array([xpos1, y2, xpos2, y2, xpos2, y1, xpos1, y1])
                # FITS coordinates
                slits[lbarid - 1] += 1.0
                logger.debug('inserting bars %d-%d into "slits"', lbarid, rbarid)

        allpos[ks] = numpy.asarray(positions, dtype='float')  # GCS doesn't like lists of lists

    return allpos, slits
Пример #14
0
def char_bar_height(arr_deriv_alt, xpos1, xpos2, centery, threshold, wh=35, wfit=3):

    logger = logging.getLogger('emir.recipes.bardetect')
    pcentery = coor_to_pix_1d(centery)
    slicey = slice_create(pcentery, wh, start=1, stop=2047)

    ref_pcentery = pcentery - slicey.start
    mm = arr_deriv_alt[slicey, xpos1:xpos2 + 1].mean(axis=-1)

    idxs_t = find_peaks_indexes(mm, window_width=3,threshold=threshold)
    idxs_u = find_peaks_indexes(-mm, window_width=3,threshold=threshold)
    # Peaks on the right

    status = 0
    npeaks_u = len(idxs_u)
    if npeaks_u == 0:
        # This is a problem, no peak on the right
        b2 = 0
        status = 4
        logger.debug('no bottom border found')
    else:
        # Filter over reference
        g_idxs_u = idxs_u[idxs_u >= ref_pcentery]
        if len(g_idxs_u) == 0:
            logger.debug('no peak over center')
            b2 = 0
            status = 4
        else:
            x_u, y_u = refine_peaks(-mm, g_idxs_u, window_width=wfit)
            # Select the peak with max derivative
            if len(x_u) == 0 or len(y_u) == 0:
                logger.warning("no 1st peak found after refine")
                b2 = 0
                status = 4
            else:
                idmax = y_u.argmax()
                b2 = x_u[idmax]
                b2val = y_u[idmax]
                logger.debug('main border in %f', slicey.start + b2)

    # peaks on the left
    npeaks_t = len(idxs_t)
    if npeaks_t == 0:
        # This is a problem, no peak on the left
        b1 = 0
        logger.debug('no top border found')
        status = 40 + status
    else:
        g_idxs_t = idxs_t[idxs_t <= ref_pcentery]
        if len(g_idxs_t) == 0:
            logger.debug('no peak under center')
            b1 = 0
            status = 40 + status
        else:
            x_t, y_t = refine_peaks(mm, g_idxs_t, window_width=wfit)
            # Select the peak with max derivative
            if len(x_t) == 0 or len(y_t) == 0:
                logger.warning("no 2nd peak found after refine")
                b1 = 0
                status = 40 + status
            else:
                idmax = y_t.argmax()
                b1 = x_t[idmax]
                b1val = y_t[idmax]
                logger.debug('second border in %f', slicey.start + b1)

    return slicey.start + b1, slicey.start + b2, status