예제 #1
0
def pix2virt(pos, origin=1):
    ddef_o = 1
    off = ddef_o - origin
    pos = np.atleast_2d(pos) + off
    nx, ny = dist.pvex(pos[:, 0], pos[:, 1])
    res = np.stack((nx, ny), axis=1)
    return res - off
예제 #2
0
def test_distortions_pc1():
    p_x1 = [16.20132521, 110.97939823, 1000.22549019, 1962.80728145]
    p_y1 = [1197.39342201, 901.47856688, 207.58843519, 33.71359561]
    x0 = [1, 100, 1000, 1990]
    y0 = [1200, 900, 200, 5]

    x1, y1 = pvex(x0, y0)

    assert numpy.allclose(x1, p_x1)
    assert numpy.allclose(y1, p_y1)
예제 #3
0
def test_distortions_pc1():
    p_x1 = [16.20132521,   110.97939823,  1000.22549019,  1962.80728145]
    p_y1 = [1197.39342201,   901.47856688,   207.58843519,    33.71359561]
    x0 = [1, 100, 1000, 1990]
    y0 = [1200, 900, 200, 5]

    x1, y1 = pvex(x0, y0)

    assert numpy.allclose(x1, p_x1)
    assert numpy.allclose(y1, p_y1)
예제 #4
0
def test_distortions_pc2():
    """Inverse transformation, not very precise"""

    e_x1 = [-14.95369787, 88.60095332, 999.76814675, 2019.84941119]
    e_y1 = [1202.73558767, 898.46492016, 192.1974284, -26.51887593]

    x0 = [1, 100, 1000, 1990]
    y0 = [1200, 900, 200, 5]
    # x0 = [0.992795185,   100.002590,   1000.00025,   1989.91083]
    # y0 = [1200.00123542, 900.00034883, 200.0082549, 5.09416157]

    p_x0, p_y0 = pvex(e_x1, e_y1)

    assert numpy.allclose(x0, p_x0, rtol=2e-2)
    assert numpy.allclose(y0, p_y0, rtol=2e-2)
예제 #5
0
def test_distortions_pc2():
    """Inverse transformation, not very precise"""

    e_x1 = [-14.95369787,    88.60095332,   999.76814675,  2019.84941119]
    e_y1 = [1202.73558767,   898.46492016,   192.1974284,    -26.51887593]

    x0 = [1, 100, 1000, 1990]
    y0 = [1200, 900, 200, 5]
    # x0 = [0.992795185,   100.002590,   1000.00025,   1989.91083]
    # y0 = [1200.00123542, 900.00034883, 200.0082549, 5.09416157]

    p_x0, p_y0 = pvex(e_x1, e_y1)

    assert numpy.allclose(x0, p_x0, rtol=2e-2)
    assert numpy.allclose(y0, p_y0, rtol=2e-2)
예제 #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 _char_bar_peak(arr_deriv, ypix, bstart, bend, th, sign=1):

    # extract a region to average
    # wy = 3
    # wx = 10
    # Fit the peak with these points
    # wfit = 3

    logger = logging.getLogger(__name__)

    yvpix = numpy.clip(ypix, 0, 2047)

    # Refine at different positions along the slit
    newrefine = []
    wx = 5
    wy = 1
    step = 2 * wy + 1
    # visibility
    #
    intv1 = [0, 2047]
    intv2 = [yvpix - 18, yvpix + 18]
    logger.debug('overlaping interval %s', intv2)

    bar_overlap = overlap(intv1, intv2)
    logger.debug('bar overlaping %.1f', bar_overlap)
    offs = []
    if bar_overlap < 10:
        maxval = 18
    else:
        maxval = 12
    offs2 = range(-step, -maxval, -step)
    offs.extend(reversed(offs2))
    offs.extend(range(0, maxval, step))

    cut = sign * arr_deriv[yvpix, bstart:bend]

    idxs = find_peaks_indexes(cut, window_width=3, threshold=th, fpeak=1)
    logger.debug('found %d peaks over threshold %f', len(idxs), th)

    if len(idxs) == 0:
        logger.debug('no peaks, exit')
        return 0, 0, 0, 0, 0, 1

    # Characterize: use the peak that has the greatest value in the derivative?
    pix_m = cut[idxs].argmax()
    centerx = bstart + idxs[pix_m]
    logger.debug('select the peak with maximum derivative')

    centery = yvpix
    logger.debug('centery is %7.2f at position %7.2f', centery + 1,
                 centerx + 1)
    # Refine at the computed center
    xl, fwhm_x, st = refine_bar_centroid(arr_deriv, centerx, centery, wx, wy,
                                         th, sign)
    logger.debug('measured values %7.2f (FWHM %7.2f)', xl, fwhm_x)

    if st != 0:
        logger.debug('faillure refining bar centroid, go to next bar')
        # Exiting now, can't refine the centroid
        return centery, centery, xl, xl, fwhm_x, st

    # This is basically to build a list of centers that dont overlap
    for off in offs:
        if 0 <= centery + off <= 2047:
            logger.debug('looping, off %d, measuring at %7.2f', off,
                         centery + off + 1)
            res = refine_bar_centroid(arr_deriv, centerx, centery + off, wx,
                                      wy, th, sign)
            logger.debug('looping, measured values %7.2f (FWHM %7.2f)', res[0],
                         res[1])
            newrefine.append(res)
        else:
            logger.debug('looping, off %d, skipping position %7.2f', off,
                         centery + off + 1)

    # this goes in FITS pix coordinates, adding 1
    # filter values with status != 0
    valid_mt = [r[2] == 0 for r in newrefine]
    xcoords_mt = [r[0] + 1 for r in newrefine]
    ycoords_mt = [centery + off + 1 for off in offs]

    ycoords_m = list(itertools.compress(ycoords_mt, valid_mt))
    xcoords_m = list(itertools.compress(xcoords_mt, valid_mt))

    if len(xcoords_m) == 0:
        logger.debug('no valid values to refine')
        return centery, centery, xl, xl, fwhm_x, 3

    logger.debug('transform values from real to virtual')
    xcoords_t, ycoords_t = dist.pvex(xcoords_m, ycoords_m)
    logger.debug('real xcoords are: %s:', xcoords_m)
    logger.debug('real ycoords are: %s:', ycoords_m)
    logger.debug('virtual xcoords are: %s:', xcoords_t)
    logger.debug('virtual ycoords are: %s:', ycoords_t)
    avg_xl_virt = numpy.mean(xcoords_t)
    logger.debug('reference real xcoord is: %s:', xl)
    logger.debug('average virtual xcoord is: %s:', avg_xl_virt)

    centerx_virt, centery_virt = dist.pvex(centerx + 1, centery + 1)

    return centery, centery_virt, xl, avg_xl_virt, fwhm_x, 0
예제 #8
0
def _char_bar_peak(arr_deriv,
                   ypix,
                   bstart,
                   bend,
                   th,
                   center_of_bar=None,
                   wx=10,
                   wy=15,
                   wfit=3,
                   sign=1):

    # extract a region to average
    # wy = 3
    # wx = 10
    # Fit the peak with these points
    # wfit = 3

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

    cut = sign * arr_deriv[ypix, bstart:bend]

    idxs = find_peaks_indexes(cut, window_width=3, threshold=th, fpeak=1)
    logger.debug('found %d peaks over threshold %f', len(idxs), th)

    if len(idxs) == 0:
        logger.debug('no peaks, exit')
        return 0, 0, 0, 0, 0, 1

    # Characterize: use the peak that has the greatest value in the derivative?
    pix_m = cut[idxs].argmax()
    centerx = bstart + idxs[pix_m]
    logger.debug('select the peak with maximum derivative')
    # This function should return the center of 'barid'
    # when its position is 'x'
    # without information, the best guess is 'ypix'
    if center_of_bar is None:
        logger.debug('using reference value for center of bar')
        centery = ypix
    else:
        centery = center_of_bar(centerx)

    logger.debug('centery is %7.2f at position %7.2f', centery + 1,
                 centerx + 1)

    # Refine at the computed center
    xl, fwhm_x, st = refine_bar_centroid(arr_deriv, centerx, centery, wx, wy,
                                         th, sign)
    logger.debug('measured values %7.2f (FWHM %7.2f)', xl, fwhm_x)

    if st != 0:
        logger.debug('faillure refining bar centroid, go to next bar')
        # Exiting now, can't refine the centroid
        return centery, centery, xl, xl, fwhm_x, st

    # Refine at different positions along the slit
    newrefine = []
    wx = 5
    wy = 1
    step = 2 * wy + 1
    offs = []
    maxval = 18
    offs2 = range(-step, -maxval, -step)
    offs.extend(reversed(offs2))
    offs.extend(range(0, maxval, step))
    # This is basically to build a list of centers that dont overlap

    for off in offs:
        logger.debug('looping, off %d, measuring at %7.2f', off,
                     centery + off + 1)
        res = refine_bar_centroid(arr_deriv, centerx, centery + off, wx, wy,
                                  th, sign)
        logger.debug('looping, measured values %7.2f (FWHM %7.2f)', res[0],
                     res[1])
        newrefine.append(res)

    # this goes in FITS pix coordinates, adding 1
    # filter values with status != 0
    valid_mt = [r[2] == 0 for r in newrefine]
    xcoords_mt = [r[0] + 1 for r in newrefine]
    ycoords_mt = [centery + off + 1 for off in offs]

    ycoords_m = list(itertools.compress(ycoords_mt, valid_mt))
    xcoords_m = list(itertools.compress(xcoords_mt, valid_mt))

    if len(xcoords_m) == 0:
        logger.debug('no valid values to refine')
        return centery, centery, xl, xl, fwhm_x, 3

    logger.debug('transform values from real to virtual')
    xcoords_t, ycoords_t = dist.pvex(xcoords_m, ycoords_m)
    logger.debug('real xcoords are: %s:', xcoords_m)
    logger.debug('real ycoords are: %s:', ycoords_m)
    logger.debug('virtual xcoords are: %s:', xcoords_t)
    logger.debug('virtual ycoords are: %s:', ycoords_t)
    avg_xl_virt = numpy.mean(xcoords_t)
    logger.debug('reference real xcoord is: %s:', xl)
    logger.debug('average virtual xcoord is: %s:', avg_xl_virt)

    centerx_virt, centery_virt = dist.pvex(centerx + 1, centery + 1)

    return centery, centery_virt, xl, avg_xl_virt, fwhm_x, 0
예제 #9
0
def _char_bar_peak(arr_deriv, ypix, bstart, bend, th, sign=1):

    # extract a region to average
    # wy = 3
    # wx = 10
    # Fit the peak with these points
    # wfit = 3

    logger = logging.getLogger(__name__)

    yvpix = numpy.clip(ypix, 0, 2047)

    # Refine at different positions along the slit
    newrefine = []
    wx = 5
    wy = 1
    step = 2 * wy + 1
    # visibility
    #
    intv1 = [0, 2047]
    intv2 = [yvpix - 18, yvpix + 18]
    logger.debug('overlaping interval %s', intv2)

    bar_overlap = overlap(intv1, intv2)
    logger.debug('bar overlaping %.1f', bar_overlap)
    offs = []
    if bar_overlap < 10:
        maxval = 18
    else:
        maxval = 12
    offs2 = range(-step, -maxval, -step)
    offs.extend(reversed(offs2))
    offs.extend(range(0, maxval, step))

    cut = sign * arr_deriv[yvpix, bstart:bend]

    idxs = find_peaks_indexes(cut, window_width=3, threshold=th, fpeak=1)
    logger.debug('found %d peaks over threshold %f', len(idxs), th)

    if len(idxs) == 0:
        logger.debug('no peaks, exit')
        return 0, 0, 0, 0, 0, 1

    # Characterize: use the peak that has the greatest value in the derivative?
    pix_m = cut[idxs].argmax()
    centerx = bstart + idxs[pix_m]
    logger.debug('select the peak with maximum derivative')

    centery = yvpix
    logger.debug('centery is %7.2f at position %7.2f', centery+1,  centerx+1)
    # Refine at the computed center
    xl, fwhm_x, st = refine_bar_centroid(arr_deriv, centerx, centery, wx, wy, th, sign)
    logger.debug('measured values %7.2f (FWHM %7.2f)', xl, fwhm_x)

    if st != 0:
        logger.debug('faillure refining bar centroid, go to next bar')
        # Exiting now, can't refine the centroid
        return centery, centery, xl, xl, fwhm_x, st

    # This is basically to build a list of centers that dont overlap
    for off in offs:
        if 0 <= centery + off <= 2047:
            logger.debug('looping, off %d, measuring at %7.2f', off, centery + off + 1)
            res = refine_bar_centroid(arr_deriv, centerx, centery + off, wx, wy, th, sign)
            logger.debug('looping, measured values %7.2f (FWHM %7.2f)', res[0], res[1])
            newrefine.append(res)
        else:
            logger.debug('looping, off %d, skipping position %7.2f', off, centery + off + 1)

    # this goes in FITS pix coordinates, adding 1
    # filter values with status != 0
    valid_mt = [r[2] == 0 for r in newrefine]
    xcoords_mt = [r[0] + 1 for r in newrefine]
    ycoords_mt = [centery + off + 1 for off in offs]

    ycoords_m = list(itertools.compress(ycoords_mt, valid_mt))
    xcoords_m = list(itertools.compress(xcoords_mt, valid_mt))

    if len(xcoords_m) == 0:
        logger.debug('no valid values to refine')
        return centery, centery, xl, xl, fwhm_x, 3

    logger.debug('transform values from real to virtual')
    xcoords_t, ycoords_t = dist.pvex(xcoords_m, ycoords_m)
    logger.debug('real xcoords are: %s:', xcoords_m)
    logger.debug('real ycoords are: %s:', ycoords_m)
    logger.debug('virtual xcoords are: %s:', xcoords_t)
    logger.debug('virtual ycoords are: %s:', ycoords_t)
    avg_xl_virt = numpy.mean(xcoords_t)
    logger.debug('reference real xcoord is: %s:', xl)
    logger.debug('average virtual xcoord is: %s:', avg_xl_virt)

    centerx_virt, centery_virt = dist.pvex(centerx + 1, centery + 1)

    return centery, centery_virt, xl, avg_xl_virt, fwhm_x, 0