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
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)
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)
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
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
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
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