Example #1
0
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)
Example #2
0
    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