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