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