def test_compute_trend(): numpy.random.seed(12812818) xx = numpy.arange(100) yy = 700 + 3.2 * (xx / 100.0) yy = numpy.random.normal(loc=yy, scale=2.0) trend = detrend(yy) maxt = trend.max() mint = trend.min() expected = [704.812599, 698.595538331] numpy.testing.assert_array_almost_equal([maxt, mint], expected)
def calibrate_wl(self, rss, lines_catalog, poldeg, tracemap, nlines, threshold=0.27, min_distance=30): wv_master = lines_catalog[:, 0] ntriplets_master, ratios_master_sorted, triplets_master_sorted_list = \ gen_triplets_master(wv_master) nwinwidth = 5 error_contador = 0 missing_fib = 0 data_wlcalib = WavelengthCalibration(instrument='MEGARA') data_wlcalib.total_fibers = tracemap.total_fibers for trace in tracemap.contents: fibid = trace.fibid idx = trace.fibid - 1 if trace.valid: row = rss[idx] trend = detrend(row) fibdata_detrend = row - trend # A fix for LR-V Jun 2016 test images # that only have lines there row = fibdata_detrend self.logger.info('Starting row %d, fibid %d', idx, fibid) # find peaks (initial search providing integer numbers) ipeaks_int = peak_local_max(row, threshold_rel=threshold, min_distance=min_distance)[:, 0] self.logger.debug('ipeaks_int.........: %s', ipeaks_int) # Filter by flux, selecting a maximum number of brightest # lines in each region region_size = (len(row)-1)/(len(nlines)) ipeaks_int_filtered = numpy.array([], dtype=int) for iregion, nlines_in_region in enumerate(nlines): if nlines_in_region > 0: imin = int(iregion * region_size) imax = int((iregion + 1) * region_size) if iregion > 0: imin += 1 ipeaks_int_region = ipeaks_int[numpy.logical_and( ipeaks_int >= imin, ipeaks_int <= imax )] if len(ipeaks_int_region) > 0: peak_fluxes = row[ipeaks_int_region] spos = peak_fluxes.argsort() ipeaks_tmp = ipeaks_int_region[ spos[-nlines_in_region:] ] ipeaks_tmp.sort() # in-place sort self.logger.debug('ipeaks_in_region...: %s', ipeaks_tmp) ipeaks_int_filtered=numpy.concatenate( (ipeaks_int_filtered, ipeaks_tmp) ) self.logger.debug('ipeaks_int_filtered: %s', ipeaks_int_filtered) ipeaks_float = refine_peaks(row, ipeaks_int_filtered, nwinwidth)[0] # if idx==299: if False: import matplotlib.pyplot as plt plt.title('fibid %d' % fibid) plt.plot(row) plt.plot(ipeaks_int, row[ipeaks_int], 'ro', alpha=.9, ms=7, label="ipeaks_int") plt.plot(ipeaks_int_filtered, row[ipeaks_int_filtered], 'ro', alpha=.9, ms=7, label="ipeaks_int_filtered") plt.legend() plt.show() # FIXME: xchannel ??? # This comes from Nico's code, so probably pixels # will start in 1 naxis1 = row.shape[0] crpix1 = 1.0 xchannel = numpy.arange(1, naxis1 + 1) finterp_channel = interp1d(range(xchannel.size), xchannel, kind='linear', bounds_error=False, fill_value=0.0) xpeaks_refined = finterp_channel(ipeaks_float) wv_range_catalog = lines_catalog[-1][0] - lines_catalog[0][0] delta_wv = 0.05 * wv_range_catalog wv_ini_search = int(lines_catalog[0][0] - delta_wv) wv_end_search = int(lines_catalog[-1][0] + delta_wv) try: self.logger.info('wv_ini_search %s', wv_ini_search) self.logger.info('wv_end_search %s', wv_end_search) list_of_wvfeatures = arccalibration_direct( wv_master, ntriplets_master, ratios_master_sorted, triplets_master_sorted_list, xpeaks_refined, naxis1, crpix1=crpix1, wv_ini_search=wv_ini_search, wv_end_search=wv_end_search, error_xpos_arc=2.3, # initially: 2.0 times_sigma_r=3.0, frac_triplets_for_sum=0.50, times_sigma_theil_sen=10.0, poly_degree_wfit=poldeg, times_sigma_polfilt=10.0, times_sigma_cook=10.0, times_sigma_inclusion=5.0 ) self.logger.info('Solution for row %d completed', idx) self.logger.info('Fitting solution for row %d', idx) solution_wv = fit_list_of_wvfeatures( list_of_wvfeatures, naxis1_arc=naxis1, crpix1=crpix1, poly_degree_wfit=poldeg, weighted=False, debugplot=0, plot_title=None ) self.logger.info('linear crval1, cdelt1: %f %f', solution_wv.cr_linear.crval, solution_wv.cr_linear.cdelt) self.logger.info('fitted coefficients %s', solution_wv.coeff) trace_pol = trace.polynomial # Update feature with measurements of Y coord in original image # Peak and FWHM in RSS for feature in solution_wv.features: # Compute Y feature.ypos = trace_pol(feature.xpos) # FIXME: check here FITS vs PYTHON coordinates, etc peak_int = int(feature.xpos) try: peak, fwhm = self.calc_fwhm_of_line(row, peak_int, lwidth=20) except Exception as error: self.logger.error("%s", error) self.logger.error('error in feature %s', feature) # workaround peak = row[peak_int] fwhm = 0.0 # I would call this peak instead... feature.peak = peak feature.fwhm = fwhm # if True: # plt.title('fibid %d' % fibid) # plt.plot(row) # plt.plot(ipeaks_int, row[ipeaks_int],'ro', alpha=.9, ms=7, label="ipeaks_int") # # # plt.plot(ipeaks_int2, row[ipeaks_int2],'gs', alpha=.5 , ms=10) # plt.legend() # plt.show() new = FiberSolutionArcCalibration(fibid, solution_wv) data_wlcalib.contents.append(new) except (ValueError, TypeError, IndexError) as error: self.logger.error("%s", error) self.logger.error('error in row %d, fibid %d', idx, fibid) traceback.print_exc() data_wlcalib.error_fitting.append(fibid) if False: import matplotlib.pyplot as plt plt.title('fibid %d' % fibid) rrow = row[::-1] rpeaks = 4096-ipeaks_int_filtered[::-1] plt.plot(rrow) plt.plot(rpeaks, rrow[rpeaks], 'ro', alpha=.9, ms=7, label="ipeaks_int_filtered") # # plt.plot(ipeaks_int2, row[ipeaks_int2],'gs', alpha=.5 , ms=10) plt.legend() plt.show() error_contador += 1 else: self.logger.info('skipping row %d, fibid %d, not extracted', idx, fibid) missing_fib += 1 data_wlcalib.missing_fibers.append(fibid) self.logger.info('Errors in fitting: %s', error_contador) self.logger.info('Missing fibers: %s', missing_fib) self.logger.info('Generating fwhm_image...') image = self.generate_fwhm_image(data_wlcalib.contents) fwhm_image = fits.PrimaryHDU(image) fwhm_hdulist = fits.HDUList([fwhm_image]) self.logger.info('End arc calibration') return data_wlcalib, fwhm_hdulist