def __init__(self, log):

        MainWindow.__init__(self, log, name='HOPS - Reduction', position=2)

        fits_name = find_fits_files(self.log.get_param('observation_files'))[0]
        fits = get_fits_data(fits_name)

        y_scale = (self.root.winfo_screenheight() - 500) / self.root.winfo_screenheight()

        self.progress_figure = self.FitsWindow(figsize=(0.5, y_scale, 10, 10, len(fits[0].data[0])/len(fits[0].data)))
        self.progress_figure.load_fits(fits[0], input_name=os.path.split(fits_name)[1])
        self.progress_bias = self.Progressbar(task="Creating master bias")
        self.progress_dark = self.Progressbar(task="Creating master dark")
        self.progress_flat = self.Progressbar(task="Creating master flat")
        self.progress_science = self.Progressbar(task="Reducing data and calculating statistics")
        self.progress_science_loop = self.CheckButton(text='Show all frames', initial=0)

        self.setup_window([
            [[self.progress_figure, 0, 2]],
            [[self.progress_bias, 0, 2]],
            [[self.progress_dark, 0, 2]],
            [[self.progress_flat, 0, 2]],
            [[self.progress_science, 0], [self.progress_science_loop, 1]],
            [[self.Button(text='STOP REDUCTION & RETURN TO MAIN MENU', command=self.trigger_exit), 0, 2]],
            []
        ])

        self.set_close_button_function(self.trigger_exit)
    def get_bias(self):

        if self.exit or len(self.bias_files) == 0:
            self.after(self.get_master_bias)

        else:

            if self.bias_counter == 0:
                self.progress_bias.initiate(10 * len(self.bias_files))

            fits = get_fits_data(self.bias_files[self.bias_counter])

            self.bias_frames.append(np.ones_like(fits[0].data) * fits[0].data)

            self.progress_bias.update()
            self.bias_counter += 1

            if self.bias_counter >= len(self.bias_files):
                self.after(self.get_master_bias)
            else:
                self.after(self.get_bias)
    def get_dark(self):

        if self.exit or len(self.dark_files) == 0:
            self.after(self.get_master_dark)

        else:

            if self.dark_counter == 0:
                self.progress_dark.initiate(10 * len(self.dark_files))

            fits = get_fits_data(self.dark_files[self.dark_counter])

            dark_frame = np.ones_like(fits[0].data) * fits[0].data
            self.dark_frames.append((dark_frame - self.master_bias) / fits[0].header[self.log.get_param('exposure_time_key')])

            self.progress_dark.update()
            self.dark_counter += 1

            if self.dark_counter >= len(self.dark_files):
                self.after(self.get_master_dark)
            else:
                self.after(self.get_dark)
    def update_observation_files(self, *event):

        check = find_fits_files(self.observation_files.get())
        self.science_files = len(check)

        if self.science_files == 0:

            self.observation_files_test.set(
                '{0} files found\nyou cannot proceed'.format(len(check)))
            self.science_header = []
            header_list = ['  Keywords:      Values:', '  ']

        else:
            self.observation_files_test.set('{0} files found - OK'.format(
                len(check)))
            self.science_header = []
            header_list = ['  Keywords:      Values:', '  ']

            self.science_header = get_fits_data(check[0])[0].header

            for ii in self.science_header:

                if ii != '':
                    header_list.append('  {0}{1}{2}'.format(
                        str(ii[:10]), ' ' * (15 - len(str(ii[:10]))),
                        str(self.science_header[ii])))

        self.header_list.update_list(header_list)

        self.update_exposure_time_key()
        self.update_observation_date_key()
        self.update_observation_time_key()
        self.update_ra_dec()
        self.choose_target()
        self.update_observing_info()
        self.update_save_button()
Beispiel #5
0
    def load_fits(self, input, input_name=None, input_options=None, draw=True):
        if isinstance(input, str):
            fits = get_fits_data(input)
            input_name = os.path.split(input)[1]
        elif isinstance(input, pf.ImageHDU) or isinstance(
                input, pf.PrimaryHDU) or isinstance(input, pf.CompImageHDU):
            fits = [input]
        else:
            raise RuntimeError('Invalid input ', type(input))

        if input_name:
            if len(input_name) > 50:
                split = [
                    input_name[i:i + 50]
                    for i in range(0, len(input_name), 50)
                ]
                input_name = '\n'.join(split)

        self.fits_name.set(input_name)

        self.data = fits[0].data

        try:
            self.mean = fits[0].header[self.window.log.mean_key]
            self.std = fits[0].header[self.window.log.std_key]
        except:
            self.mean = np.median(fits[0].data)
            self.std = plc.mad(fits[0].data) * 1.5

        self.black_entry['from_'] = np.sqrt(max(0, np.min(self.data)))
        self.black_entry['to'] = np.sqrt(np.max(self.data))

        self.white_entry['from_'] = np.sqrt(max(0, np.min(self.data)))
        self.white_entry['to'] = np.sqrt(np.max(self.data))

        self.ax.cla()
        if not self.show_axes:
            self.ax.axis('off')
        self.ax.tick_params(axis='y', rotation=90)

        self.vmin.set(
            max(1, int(self.mean + self.window.log.frame_low_std * self.std)))
        self.vmax.set(
            max(1,
                int(self.mean + self.window.log.frame_upper_std * self.std)))
        self.gamma.set(0)

        if input_options:
            if input_options[0] != 'auto':
                self.vmin.set(input_options[0])
            if input_options[1] != 'auto':
                self.vmax.set(input_options[1])
            self.gamma.set(input_options[2])
            self.flip.set(input_options[3])
            self.mirror.set(input_options[4])
            self.white_sky.set(input_options[5])

        self.sqrt_vmin.set(np.sqrt(self.vmin.get()))
        self.sqrt_vmax.set(np.sqrt(self.vmax.get()))

        self.image = self.ax.imshow(self.data**(10**-self.gamma.get()),
                                    origin='lower',
                                    extent=(0, len(self.data[0]), 0,
                                            len(self.data)),
                                    cmap=Greys,
                                    vmin=self.vmin.get(),
                                    vmax=self.vmax.get())
        if self.white_sky.get():
            self.image.set_cmap(Greys)
        else:
            self.image.set_cmap(Greys_r)

        if self.flip.get():
            self.ax.set_ylim(len(self.data) + 5, 0)
        else:
            self.ax.set_ylim(0, len(self.data) + 5)

        if self.mirror.get():
            self.ax.set_xlim(len(self.data[0]) + 5, 0)
        else:
            self.ax.set_xlim(0, len(self.data[0]) + 5)

        if draw:
            self.draw()
Beispiel #6
0
    def __init__(self, log):

        MainWindow.__init__(self, log, name='HOPS - Inspection', position=2)

        # set variables, create and place widgets

        self.all_frames = plc.open_dict(self.log.all_frames)

        self.science_files = []
        for science_file in self.all_frames:
            self.science_files.append([
                self.all_frames[science_file][self.log.time_key], science_file
            ])

        self.science_files.sort()
        self.science_files = [ff[1] for ff in self.science_files]

        self.science_keys = []
        self.science = []
        self.time_array = []
        self.sky_mean_array = []
        self.sky_std_array = []
        self.psf_array = []
        self.skip_array = []

        for science_file in self.science_files:
            self.science_keys.append(science_file)
            self.science.append(
                os.path.join(self.log.reduction_directory, science_file))
            self.time_array.append(
                self.all_frames[science_file][self.log.time_key])
            self.sky_mean_array.append(
                self.all_frames[science_file][self.log.mean_key] /
                self.all_frames[science_file][self.log.get_param(
                    'exposure_time_key')])
            self.sky_std_array.append(
                self.all_frames[science_file][self.log.std_key] /
                self.all_frames[science_file][self.log.get_param(
                    'exposure_time_key')])
            self.psf_array.append(
                self.all_frames[science_file][self.log.psf_key] * 2.355 / 2)
            self.skip_array.append(
                self.all_frames[science_file][self.log.skip_key])

        self.time_array = (np.array(self.time_array) -
                           np.min(self.time_array)) * 24
        self.sky_mean_array = np.array(self.sky_mean_array)
        self.psf_array = np.array(self.psf_array)
        self.skip_array = np.array(self.skip_array)

        # main window

        y_scale = (self.root.winfo_screenheight() -
                   375) / self.root.winfo_screenheight()

        data = get_fits_data(self.science[0])[0].data

        self.fits_figure = self.FitsWindow(figsize=(0.5, y_scale, 20, 20,
                                                    len(data[0]) / len(data)),
                                           show_controls=True)
        self.fits_to_plot = np.argmin(self.time_array)
        self.fits_figure.load_fits(self.science[self.fits_to_plot])

        self.sky_threshold = self.Entry(
            value=self.log.get_param('sky_threshold'),
            instance=float,
            command=self.apply_thresholds)
        self.psf_threshold = self.Entry(
            value=self.log.get_param('psf_threshold'),
            instance=float,
            command=self.apply_thresholds)

        self.inspection_figure = self.FigureWindow(figsize=(0.5, 0.5, 10, 6,
                                                            1.1),
                                                   show_nav=True)
        self.inspection_figure_ax1 = self.inspection_figure.figure.add_subplot(
            211)
        self.inspection_figure_ax2 = self.inspection_figure.figure.add_subplot(
            212)
        self.inspection_figure.figure.subplots_adjust(left=0.15,
                                                      right=0.99,
                                                      bottom=0.1,
                                                      top=0.99)
        self.inspection_figure.figure.canvas.callbacks.connect(
            'button_press_event', self.update_window)
        self.arrow1 = 0
        self.arrow2 = 0

        self.inspection_figure_ax1.plot(self.time_array,
                                        self.sky_mean_array,
                                        'ko',
                                        ms=3)
        self.inspection_figure_ax2.plot(self.time_array,
                                        self.psf_array,
                                        'ko',
                                        ms=3)

        self.inspection_figure_ax1.set_xlim(
            np.min(self.time_array) - 0.1,
            np.max(self.time_array) + 0.1)
        self.inspection_figure_ax2.set_xlim(
            np.min(self.time_array) - 0.1,
            np.max(self.time_array) + 0.1)

        self.yspil = self.inspection_figure.figure.get_size_inches(
        )[1] * self.inspection_figure.figure.dpi * 0.55
        box1 = self.inspection_figure_ax1.get_window_extent()
        self.ax1_width = box1.width
        self.ax1_height = box1.height
        box2 = self.inspection_figure_ax2.get_window_extent()
        self.ax2_width = box2.width
        self.ax2_height = box2.height

        self.dbclick = False
        self.dbclick_xy = (0, 0)

        self.replot()

        self.setup_window([
            [[self.fits_figure, 0, 1, 10], [self.inspection_figure, 1, 4]], [],
            [[
                self.Label(
                    text='On the time-sky or PSF-sky graph above'
                    '\n'
                    'double-click on a point to see the frame on the left panel.'
                    '\n'
                    'To mark this point as faulty, use the right double-click.'
                    '\n'
                    'To undo, use the right double-click again.'), 1, 4
            ]], [],
            [[self.Label(text='Sky Threshold'), 1], [self.sky_threshold, 2],
             [self.Label(text='PSF Threshold'), 3], [self.psf_threshold,
                                                     4]], [],
            [[
                self.Button(text='RETURN TO MAIN MENU', command=self.close), 1,
                4
            ]],
            [[
                self.Button(text='SAVE OPTIONS & RETURN TO MAIN MENU',
                            command=self.save_and_return), 1, 4
            ]],
            [[
                self.Button(text='SAVE OPTIONS & PROCEED',
                            command=self.save_and_proceed,
                            bg='green',
                            highlightbackground='green'), 1, 4
            ]], []
        ])

        self.replot()
    def reduce_science(self):

        # correct each observation_files file

        if self.exit:
            self.after(self.save)

        else:
            xx = time.time()

            if self.science_counter == 0:
                self.progress_science.initiate(len(self.science_files))

            science_file = self.science_files[self.science_counter]

            # correct it with master bias_files, master dark_files and master flat_files

            fits = get_fits_data(science_file)

            exp_time = fits[0].header[self.log.get_param('exposure_time_key')]
            data_frame = np.ones_like(fits[0].data) * fits[0].data
            data_frame = (data_frame - self.master_bias - exp_time * self.master_dark) / self.master_flat
            data_frame[np.where(np.isnan(data_frame))] = 0

            if self.log.get_param('bin_fits') > 1:
                data_frame = plc.bin_frame(data_frame, self.log.get_param('bin_fits'))

            try:
                distribution = plc.one_d_distribution(data_frame.flatten()[::int(200000.0/self.log.bin_to)],
                                                      gaussian_fit=True, mad_filter=5.0)
                mean = distribution[2]
                std = distribution[3]
            except:
                mean = np.median(data_frame)
                std = plc.mad(data_frame) * 1.5

            with warnings.catch_warnings():
                warnings.filterwarnings("ignore")
                psf = plc.fast_psf_find(data_frame, mean, std, 0.95 * self.log.get_param('burn_limit'))
            if np.isnan(psf):
                psf = self.psf + 10
                skip = True
            else:
                self.psf = psf
                skip = False

            if self.log.get_param('observation_date_key') == self.log.get_param('observation_time_key'):
                observation_time = ' '.join(fits[0].header[self.log.get_param('observation_date_key')].split('T'))
            else:
                observation_time = ' '.join([fits[0].header[self.log.get_param('observation_date_key')].split('T')[0],
                                             fits[0].header[self.log.get_param('observation_time_key')]])

            observation_time = plc.UTC(observation_time)
            if self.log.get_param('time_stamp') == 'exposure start':
                julian_date = observation_time.jd
            elif self.log.get_param('time_stamp') == 'mid-exposure':
                julian_date = observation_time.jd - 0.5 * exp_time / 60.0 / 60.0 / 24.0
            elif self.log.get_param('time_stamp') == 'exposure end':
                julian_date = observation_time.jd - exp_time / 60.0 / 60.0 / 24.0
            else:
                raise RuntimeError('Not acceptable time stamp.')

            fits[0].header.set(self.log.mean_key, mean)
            fits[0].header.set(self.log.std_key, std)
            fits[0].header.set(self.log.psf_key, psf)
            fits[0].header.set(self.log.time_key, julian_date)

            # write the new fits file
            # important to keep it like this for windows!

            time_in_file = observation_time.utc.isoformat()
            time_in_file = time_in_file.split('.')[0]
            time_in_file = time_in_file.replace('-', '_').replace(':', '_').replace('T', '_')

            new_name = '{0}{1}_{2}'.format(self.log.reduction_prefix, time_in_file, science_file.split(os.sep)[-1])

            hdu = pf.ImageHDU(header=fits[0].header, data=np.array(data_frame, dtype=np.float32))

            plc.save_fits(pf.HDUList([pf.PrimaryHDU(), hdu]), os.path.join(self.log.reduction_directory, new_name))

            self.all_frames[new_name] = {self.log.mean_key: mean, self.log.std_key: std, self.log.psf_key: psf,
                                    self.log.time_key: julian_date,
                                    self.log.get_param('exposure_time_key'): fits[0].header[self.log.get_param('exposure_time_key')],
                                    self.log.skip_key: skip,
                                    self.log.align_x0_key: False,
                                    self.log.align_y0_key: False,
                                    self.log.align_u0_key: False}

            if self.progress_science_loop.get() or self.science_counter == 0:
                self.progress_figure.load_fits(hdu, new_name)

            # counter

            self.progress_science.update()
            self.science_counter += 1

            if self.science_counter >= len(self.science_files):
                self.after(self.save)
            else:
                self.after(self.reduce_science)