def alignment(): print('Alignment...') if log.read_local_log('pipeline', 'alignment_complete'): if askyesno('Overwrite alignment', 'Alignment has been completed, do you want to run again?'): log.write_local_log('pipeline', False, 'alignment_complete') test_all_stars = True try: all_stars = plc.open_dict('all_stars.pickle') in_fov = all_stars['in_fov'] all_stars = all_stars['all_stars'] except: test_all_stars = False if log.read_local_log('alignment', 'star_psf_x') == 0 or not log.read_local_log( 'pipeline', 'alignment_complete'): test_all_stars = False # if all_stars exist and repeat not requested: exit if test_all_stars and log.read_local_log('pipeline', 'alignment_complete'): return 0 # continue to alignment # load parameters reduction_directory = log.read_local_log('pipeline', 'reduction_directory') mean_key = log.read_local_log('pipeline_keywords', 'mean_key') std_key = log.read_local_log('pipeline_keywords', 'std_key') align_x0_key = log.read_local_log('pipeline_keywords', 'align_x0_key') align_y0_key = log.read_local_log('pipeline_keywords', 'align_y0_key') align_u0_key = log.read_local_log('pipeline_keywords', 'align_u0_key') frame_low_std = log.read_local_log('windows', 'frame_low_std') frame_upper_std = log.read_local_log('windows', 'frame_upper_std') bin_fits = int(log.read_local_log('reduction', 'bin_fits')) burn_limit = int(log.read_local_log('alignment', 'burn_limit')) * bin_fits * bin_fits shift_tolerance_p = log.read_local_log('alignment', 'shift_tolerance_p') rotation_tolerance = log.read_local_log('alignment', 'rotation_tolerance') min_calibration_stars_number = int( log.read_local_log('alignment', 'min_calibration_stars_number')) star_std = log.read_local_log('alignment', 'star_std') science = find_fits_files(os.path.join(reduction_directory, '*')) def find_all_stars(): stars, psf = plc.find_all_stars(fits[1].data, mean=fits[1].header[mean_key], std=fits[1].header[std_key], std_limit=3, burn_limit=burn_limit, star_std=star_std, order_by_flux=False, progress_pack=(progress_bar, percent_label)) stars = np.array(stars) log.write_local_log('alignment', int(max(1, round(max(psf[0], psf[1])))), 'star_std') log.write_local_log('alignment', float(max(psf[0], psf[1])), 'star_psf') log.write_local_log('alignment', float(psf[0]), 'star_psf_x') log.write_local_log('alignment', float(psf[1]), 'star_psf_y') all_stars_dict = {'all_stars': stars} plc.save_dict(all_stars_dict, 'all_stars.pickle') def align(): star_std = log.read_local_log('alignment', 'star_std') psf = (log.read_local_log('alignment', 'star_psf_x'), log.read_local_log('alignment', 'star_psf_y')) all_stars_dict = plc.open_dict('all_stars.pickle') stars = np.array(all_stars_dict['all_stars']) fits = pf.open(science[0], memmap=False) frame_mean = fits[1].header[mean_key] frame_std = fits[1].header[std_key] shift_tolerance = int( max(len(fits[1].data), len(fits[1].data[0])) * (shift_tolerance_p / 100.0)) y_length, x_length = fits[1].data.shape circles_diameter = 0.02 * max(y_length, x_length) bright_stars = [] std_limit = 30 while len(bright_stars) < 100 and std_limit >= 5.0: bright_stars = [] for star in stars: if star[2] + star[3] < 2.0 * burn_limit / 3.0: if star[-1] > (2 * np.pi * (std_limit * frame_std) * psf[0] * psf[1]): alignment_log( star[-1], 2 * np.pi * (frame_mean + std_limit * frame_std) * psf[0] * psf[1]) bright_stars.append(star) std_limit -= 5 stars = sorted(bright_stars, key=lambda x: -x[-1] / (x[-2]**3)) x_ref_position = stars[0][0] y_ref_position = stars[0][1] del stars[0] # take the rest as calibration stars and calculate their polar coordinates relatively to the first calibration_stars_polar = [] for star in stars: r_position, u_position = plc.cartesian_to_polar( star[0], star[1], x_ref_position, y_ref_position) if r_position > 5 * star_std: calibration_stars_polar.append([r_position, u_position]) stars = sorted(stars, key=lambda x: -x[-1]) calibration_stars_polar_snr = [] for star in stars: r_position, u_position = plc.cartesian_to_polar( star[0], star[1], x_ref_position, y_ref_position) if r_position > 5 * star_std: calibration_stars_polar_snr.append([r_position, u_position]) if len(calibration_stars_polar) <= min_calibration_stars_number: check_num = len(calibration_stars_polar) - 0.5 check_num_snr = len(calibration_stars_polar) - 0.5 else: check_num = max(min_calibration_stars_number - 0.5, int(len(calibration_stars_polar)) / 10 - 0.5) check_num_snr = max(min_calibration_stars_number - 0.5, int(len(calibration_stars_polar)) / 20 - 0.5) x0, y0, u0, comparisons = x_ref_position, y_ref_position, 0, calibration_stars_polar x0, y0, u0, comparisons_snr = x_ref_position, y_ref_position, 0, calibration_stars_polar_snr fits.close() # set the looking window and angular step circle = mpatches.Circle((x0, y0), circles_diameter, ec='r', fill=False) ax.add_patch(circle) for ii in comparisons[:10]: circle = mpatches.Circle((x0 + ii[0] * np.cos(u0 + ii[1]), y0 + ii[0] * np.sin(u0 + ii[1])), circles_diameter, ec='w', fill=False) ax.add_patch(circle) # for each science_file percent = 0 skip_time = 0 lt0 = time.time() for counter, science_file in enumerate(science): if show_progress.exit: return None alignment_log('\n', science_file) label_2.configure(text='Running Alignment: {0}'.format( science_file.split(os.sep)[-1])) label_2.update() label_3.configure(text='') label_3.update() fits = pf.open(science_file, mode='update') ax.cla() ax.imshow(fits[1].data, origin='lower', cmap=cm.Greys_r, vmin=fits[1].header[mean_key] + frame_low_std * fits[1].header[std_key], vmax=fits[1].header[mean_key] + frame_upper_std * fits[1].header[std_key]) ax.axis('off') circle = mpatches.Circle((-100, -100), circles_diameter, ec='r', fill=False) ax.add_patch(circle) rotation_detected = False # super fast detection test alignment_log('Test no shift', x0, y0, u0) star = plc.find_single_star(fits[1].data, x0, y0, mean=fits[1].header[mean_key], std=fits[1].header[std_key], burn_limit=burn_limit, star_std=star_std) if star: tests = [] max_x = star[0] max_y = star[1] alignment_log(science_file) alignment_log('Testing star at: ', max_x, max_y, ', with rotation:', u0) test = 0 for comp in comparisons: check_x = int(max_x + comp[0] * np.cos(u0 + comp[1])) check_y = int(max_y + comp[0] * np.sin(u0 + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num: break tests.append([test, max_x, max_y]) alignment_log([test, max_x, max_y]) tests.sort() test, max_x, max_y = tests[-1] if test < check_num: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = u0 else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # super fast detection test if show_progress.exit: return None delta_skip_time = time.time() # look for reasonable field shift if not stars_detected: alignment_log('Testing small shift') label_3.configure(text='Testing small shift and rotation') label_3.update() stars = plc.find_all_stars(fits[1].data, x_low=x0 - shift_tolerance, x_upper=x0 + shift_tolerance, y_low=y0 - shift_tolerance, y_upper=y0 + shift_tolerance, x_centre=x0, y_centre=y0, mean=fits[1].header[mean_key], std=fits[1].header[std_key], burn_limit=burn_limit, star_std=star_std)[0] if show_progress.exit: return None if stars: tests = [] for star in stars: if show_progress.exit: return None max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() alignment_log(science_file) alignment_log('Testing star at: ', max_x, max_y, ',with rotation:', u0) test = 0 for comp in comparisons: check_x = int(max_x + comp[0] * np.cos(u0 + comp[1])) check_y = int(max_y + comp[0] * np.sin(u0 + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num: break tests.append([test, max_x, max_y]) alignment_log([test, max_x, max_y]) if test > check_num: break tests.sort() test, max_x, max_y = tests[-1] if test < check_num: tests = [] for star in stars: if show_progress.exit: return None max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() alignment_log(science_file) alignment_log('LOW-SNR Testing star at: ', max_x, max_y, ', with rotation:', u0) test = 0 for comp in comparisons_snr: check_x = int(max_x + comp[0] * np.cos(u0 + comp[1])) check_y = int(max_y + comp[0] * np.sin(u0 + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num_snr: break tests.append([test, max_x, max_y]) alignment_log([test, max_x, max_y]) if test > check_num_snr: break tests.sort() test, max_x, max_y = tests[-1] if test < min_calibration_stars_number - 0.5: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = u0 rotation_detected = True else: stars_detected = True x0 = max_x y0 = max_y u0 = u0 rotation_detected = True else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # look for reasonable field shift if show_progress.exit: return None # look for reasonable field rotation if not stars_detected: alignment_log('Testing small rotation') ustep = np.arcsin( float(star_std) / comparisons[int(len(comparisons) / 2)][0]) angles = np.append( np.arange(-rotation_tolerance, rotation_tolerance, ustep), np.arange(-rotation_tolerance, rotation_tolerance, ustep) + np.pi) if stars: tests = [] for star in stars: if show_progress.exit: return None test = 0 max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() for rotation in angles: alignment_log(science_file) alignment_log('Testing star at: ', max_x, max_y, ', with rotation: ', rotation) test = 0 for comp in comparisons: check_x = int(max_x + comp[0] * np.cos(rotation + comp[1])) check_y = int(max_y + comp[0] * np.sin(rotation + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num: break tests.append([test, max_x, max_y, rotation]) alignment_log([test, max_x, max_y, rotation]) if test > check_num: break if test > check_num: break tests.sort() test, max_x, max_y, rotation = tests[-1] if test < check_num: for star in stars: if show_progress.exit: return None test = 0 max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() for rotation in angles: alignment_log(science_file) alignment_log('LOW SNR Testing star at: ', max_x, max_y, ', with rotation: ', rotation) test = 0 for comp in comparisons_snr: check_x = int(max_x + comp[0] * np.cos(rotation + comp[1])) check_y = int(max_y + comp[0] * np.sin(rotation + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = ( fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num_snr: break tests.append([test, max_x, max_y, rotation]) alignment_log([test, max_x, max_y, rotation]) if test > check_num_snr: break if test > check_num_snr: break tests.sort() test, max_x, max_y, rotation = tests[-1] if test < check_num_snr: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = rotation rotation_detected = True else: stars_detected = True x0 = max_x y0 = max_y u0 = rotation rotation_detected = True else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # look for reasonable field rotation if not stars_detected: circle.set_center((-100, -100)) canvas.draw() show_progress.update() skip_frame = askyesno( 'Alignment', 'Stars not found close to their previous positions.\n' 'Do you want to skip this frame?', parent=show_progress.root) else: skip_frame = False if show_progress.exit: return None # look for large field shift if not stars_detected and not skip_frame: alignment_log('Testing large shift and rotation') label_3.configure(text='Testing large shift and rotation') label_3.update() canvas.draw() show_progress.update() stars = plc.find_all_stars(fits[1].data, mean=fits[1].header[mean_key], std=fits[1].header[std_key], burn_limit=burn_limit, star_std=star_std, order_by_flux=True)[0] if show_progress.exit: return None if stars: tests = [] for star in stars: if show_progress.exit: return None max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() alignment_log(science_file) alignment_log('LOW SNR Testing star at: ', max_x, max_y, ', with rotation: ', u0) test = 0 for comp in comparisons_snr: check_x = int(max_x + comp[0] * np.cos(u0 + comp[1])) check_y = int(max_y + comp[0] * np.sin(u0 + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num_snr: break tests.append([test, max_x, max_y]) alignment_log([test, max_x, max_y]) if test > check_num_snr: break tests.sort() test, max_x, max_y = tests[-1] if test < check_num_snr: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = u0 rotation_detected = True else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # look for large field shift # look for large field rotation if not stars_detected and not skip_frame: alignment_log('Test large rotation') ustep = np.arcsin( float(star_std) / comparisons[int(len(comparisons) / 2)][0]) angles = np.array([np.pi, 0]) for ff in range(1, int(np.pi / ustep) + 1): angles = np.append(angles, np.pi - ff * ustep) angles = np.append(angles, np.pi + ff * ustep) angles = np.append(angles, 0 - ff * ustep) angles = np.append(angles, 0 + ff * ustep) if stars: if show_progress.exit: return None tests = [] for rotation in angles: test = 0 for star in stars: max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() alignment_log(science_file) alignment_log('LOW SNR Testing star at: ', max_x, max_y, ', with rotation: ', rotation) test = 0 for comp in comparisons_snr: check_x = int(max_x + comp[0] * np.cos(rotation + comp[1])) check_y = int(max_y + comp[0] * np.sin(rotation + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 2 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num_snr: break tests.append([test, max_x, max_y, rotation]) alignment_log([test, max_x, max_y, rotation]) if test > check_num_snr: break if test > check_num_snr: break tests.sort() test, max_x, max_y, rotation = tests[-1] if test < check_num_snr: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = rotation rotation_detected = True else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # look for large field rotation skip_time += time.time() - delta_skip_time if show_progress.exit: return None if stars_detected: if rotation_detected: test_u0 = [] test_cos = [] test_sin = [] for ii in comparisons[:int(check_num + 0.5)]: star = plc.find_single_star( fits[1].data, x0 + ii[0] * np.cos(u0 + ii[1]), y0 + ii[0] * np.sin(u0 + ii[1]), mean=fits[1].header[mean_key], std=fits[1].header[std_key], burn_limit=burn_limit, star_std=star_std) if star: diff = plc.cartesian_to_polar( star[0], star[1], x0, y0)[1] - ii[1] if diff < 0: diff += 2 * np.pi test_u0.append(diff) test_cos.append(np.cos(diff)) test_sin.append(np.sin(diff)) if len(test_u0) > 0: test_u0 = np.mean(test_u0) test_cos = np.mean(test_cos) test_sin = np.mean(test_sin) u0 = np.arccos(test_cos) if test_sin < 0: u0 = np.pi + (np.pi - u0) fits[1].header.set(align_x0_key, x0) fits[1].header.set(align_y0_key, y0) fits[1].header.set(align_u0_key, u0) circle = mpatches.Circle((x0, y0), circles_diameter, ec='r', fill=False) ax.add_patch(circle) for ii in comparisons[:int(check_num + 0.5)]: circle = mpatches.Circle((x0 + ii[0] * np.cos(u0 + ii[1]), y0 + ii[0] * np.sin(u0 + ii[1])), circles_diameter, ec='w', fill=False) ax.add_patch(circle) canvas.draw() show_progress.update() else: fits[1].header.set(align_x0_key, False) fits[1].header.set(align_y0_key, False) fits[1].header.set(align_u0_key, False) fits.flush() fits.close() # counter new_percent = round(100 * (counter + 1) / float(len(science)), 1) if new_percent != percent: lt1 = time.time() rm_time = (100 - new_percent) * (lt1 - lt0 - skip_time) / new_percent hours = rm_time / 3600.0 minutes = (hours - int(hours)) * 60 seconds = (minutes - int(minutes)) * 60 progress_bar_2['value'] = new_percent percent_label_2.configure( text='{0} % ({1}h {2}m {3}s left)'.format( new_percent, int(hours), int(minutes), int(seconds))) percent = new_percent show_progress.update() if show_progress.exit: return None def check_visibility(): star_std = log.read_local_log('alignment', 'star_std') all_stars_dict = plc.open_dict('all_stars.pickle') stars = np.array(all_stars_dict['all_stars']) polar_coords = [] fits = pf.open(science[0]) for star in all_stars_dict['all_stars']: polar_coords.append( plc.cartesian_to_polar(star[0], star[1], fits[1].header[align_x0_key], fits[1].header[align_y0_key])) fits.close() in_fov = np.ones(len(polar_coords)) percent = 0 lt0 = time.time() for counter, science_file in enumerate(science): if show_progress.exit: return None in_fov_single = [] fits = pf.open(science_file) if fits[1].header[align_x0_key]: ref_x_position = fits[1].header[align_x0_key] ref_y_position = fits[1].header[align_y0_key] ref_u_position = fits[1].header[align_u0_key] for star in polar_coords: cartesian_x = ref_x_position + star[0] * np.cos( ref_u_position + star[1]) cartesian_y = ref_y_position + star[0] * np.sin( ref_u_position + star[1]) if (cartesian_x > 3 * star_std and cartesian_x < len(fits[1].data[0]) - 3 * star_std and cartesian_y > 3 * star_std and cartesian_y < len(fits[1].data) - 3 * star_std): in_fov_single.append(1) else: in_fov_single.append(0) in_fov *= in_fov_single fits.close() # counter new_percent = round(100 * (counter + 1) / float(len(science)), 1) if new_percent != percent: lt1 = time.time() rm_time = (100 - new_percent) * (lt1 - lt0) / new_percent hours = rm_time / 3600.0 minutes = (hours - int(hours)) * 60 seconds = (minutes - int(minutes)) * 60 progress_bar_3['value'] = new_percent percent_label_3.configure( text='{0} % ({1}h {2}m {3}s left)'.format( new_percent, int(hours), int(minutes), int(seconds))) percent = new_percent show_progress.update() all_stars_dict['in_fov'] = np.array(in_fov) visible_fov_x_min = np.min(stars[np.where(in_fov), 0]) - 3 * star_std visible_fov_x_max = np.max(stars[np.where(in_fov), 0]) + 3 * star_std visible_fov_y_min = np.min(stars[np.where(in_fov), 1]) - 3 * star_std visible_fov_y_max = np.max(stars[np.where(in_fov), 1]) + 3 * star_std log.write_local_log('alignment', float(visible_fov_x_min), 'min_x') log.write_local_log('alignment', float(visible_fov_y_min), 'min_y') log.write_local_log('alignment', float(visible_fov_x_max), 'max_x') log.write_local_log('alignment', float(visible_fov_y_max), 'max_y') plc.save_dict(all_stars_dict, 'all_stars.pickle') def run(): if not show_progress.exit: find_all_stars() if log.read_local_log('pipeline', 'alignment_complete'): if not show_progress.exit: check_visibility() else: if not show_progress.exit: align() if not show_progress.exit: check_visibility() if not show_progress.exit: log.write_local_log('pipeline', True, 'alignment_complete') show_progress.close() # progress window show_progress = ProgressWindow('HOPS - Alignment', 0, 0, 5) f = Figure() f.patch.set_facecolor('white') ax = f.add_subplot(111) f.subplots_adjust(left=0.01, right=0.99, top=0.99, bottom=0.01) ax.axis('off') canvas = show_progress.FigureCanvasTkAgg(f) canvas.get_tk_widget().pack() fits = pf.open(science[0], memmap=False) ax.imshow(fits[1].data, origin='lower', cmap=cm.Greys_r, vmin=fits[1].header[mean_key] + frame_low_std * fits[1].header[std_key], vmax=fits[1].header[mean_key] + frame_upper_std * fits[1].header[std_key]) fits.close() frame1 = show_progress.Frame() frame1.pack() label_1 = Label(frame1, text="Locating all stars in the FOV") progress_bar = ttk.Progressbar(frame1, orient=HORIZONTAL, length=300, maximum=100, mode='determinate', value=0) percent_label = Label(frame1, text='0.0 %') if log.read_local_log('pipeline', 'alignment_complete'): label_2 = Label(frame1, text='Running Alignment: --- Skipping ---') else: label_2 = Label(frame1, text='Running Alignment: ') progress_bar_2 = ttk.Progressbar(frame1, orient=HORIZONTAL, length=300, maximum=100, mode='determinate', value=0) percent_label_2 = Label(frame1, text='0.0 %') label_3 = Label(frame1, text=' ') label_4 = Label(frame1, text='Aligning all stars in the FOV') progress_bar_3 = ttk.Progressbar(frame1, orient=HORIZONTAL, length=300, maximum=100, mode='determinate', value=0) percent_label_3 = Label(frame1, text='0.0 %') setup_window( frame1, [[[label_1, 0, 2]], [[progress_bar, 0, 1, 1, (20, 0)], [percent_label, 1]], [[label_2, 0, 2]], [[label_3, 0, 2]], [[progress_bar_2, 0, 1, 1, (20, 0)], [percent_label_2, 1]], [[label_4, 0, 2]], [[progress_bar_3, 0, 1, 1, (20, 0)], [percent_label_3, 1]], []], main_font='Courier') canvas.draw() show_progress.after(200, run) show_progress.loop()
def check_visibility(): star_std = log.read_local_log('alignment', 'star_std') all_stars_dict = plc.open_dict('all_stars.pickle') stars = np.array(all_stars_dict['all_stars']) polar_coords = [] fits = pf.open(science[0]) for star in all_stars_dict['all_stars']: polar_coords.append( plc.cartesian_to_polar(star[0], star[1], fits[1].header[align_x0_key], fits[1].header[align_y0_key])) fits.close() in_fov = np.ones(len(polar_coords)) percent = 0 lt0 = time.time() for counter, science_file in enumerate(science): if show_progress.exit: return None in_fov_single = [] fits = pf.open(science_file) if fits[1].header[align_x0_key]: ref_x_position = fits[1].header[align_x0_key] ref_y_position = fits[1].header[align_y0_key] ref_u_position = fits[1].header[align_u0_key] for star in polar_coords: cartesian_x = ref_x_position + star[0] * np.cos( ref_u_position + star[1]) cartesian_y = ref_y_position + star[0] * np.sin( ref_u_position + star[1]) if (cartesian_x > 3 * star_std and cartesian_x < len(fits[1].data[0]) - 3 * star_std and cartesian_y > 3 * star_std and cartesian_y < len(fits[1].data) - 3 * star_std): in_fov_single.append(1) else: in_fov_single.append(0) in_fov *= in_fov_single fits.close() # counter new_percent = round(100 * (counter + 1) / float(len(science)), 1) if new_percent != percent: lt1 = time.time() rm_time = (100 - new_percent) * (lt1 - lt0) / new_percent hours = rm_time / 3600.0 minutes = (hours - int(hours)) * 60 seconds = (minutes - int(minutes)) * 60 progress_bar_3['value'] = new_percent percent_label_3.configure( text='{0} % ({1}h {2}m {3}s left)'.format( new_percent, int(hours), int(minutes), int(seconds))) percent = new_percent show_progress.update() all_stars_dict['in_fov'] = np.array(in_fov) visible_fov_x_min = np.min(stars[np.where(in_fov), 0]) - 3 * star_std visible_fov_x_max = np.max(stars[np.where(in_fov), 0]) + 3 * star_std visible_fov_y_min = np.min(stars[np.where(in_fov), 1]) - 3 * star_std visible_fov_y_max = np.max(stars[np.where(in_fov), 1]) + 3 * star_std log.write_local_log('alignment', float(visible_fov_x_min), 'min_x') log.write_local_log('alignment', float(visible_fov_y_min), 'min_y') log.write_local_log('alignment', float(visible_fov_x_max), 'max_x') log.write_local_log('alignment', float(visible_fov_y_max), 'max_y') plc.save_dict(all_stars_dict, 'all_stars.pickle')
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 align(): star_std = log.read_local_log('alignment', 'star_std') psf = (log.read_local_log('alignment', 'star_psf_x'), log.read_local_log('alignment', 'star_psf_y')) all_stars_dict = plc.open_dict('all_stars.pickle') stars = np.array(all_stars_dict['all_stars']) fits = pf.open(science[0], memmap=False) frame_mean = fits[1].header[mean_key] frame_std = fits[1].header[std_key] shift_tolerance = int( max(len(fits[1].data), len(fits[1].data[0])) * (shift_tolerance_p / 100.0)) y_length, x_length = fits[1].data.shape circles_diameter = 0.02 * max(y_length, x_length) bright_stars = [] std_limit = 30 while len(bright_stars) < 100 and std_limit >= 5.0: bright_stars = [] for star in stars: if star[2] + star[3] < 2.0 * burn_limit / 3.0: if star[-1] > (2 * np.pi * (std_limit * frame_std) * psf[0] * psf[1]): alignment_log( star[-1], 2 * np.pi * (frame_mean + std_limit * frame_std) * psf[0] * psf[1]) bright_stars.append(star) std_limit -= 5 stars = sorted(bright_stars, key=lambda x: -x[-1] / (x[-2]**3)) x_ref_position = stars[0][0] y_ref_position = stars[0][1] del stars[0] # take the rest as calibration stars and calculate their polar coordinates relatively to the first calibration_stars_polar = [] for star in stars: r_position, u_position = plc.cartesian_to_polar( star[0], star[1], x_ref_position, y_ref_position) if r_position > 5 * star_std: calibration_stars_polar.append([r_position, u_position]) stars = sorted(stars, key=lambda x: -x[-1]) calibration_stars_polar_snr = [] for star in stars: r_position, u_position = plc.cartesian_to_polar( star[0], star[1], x_ref_position, y_ref_position) if r_position > 5 * star_std: calibration_stars_polar_snr.append([r_position, u_position]) if len(calibration_stars_polar) <= min_calibration_stars_number: check_num = len(calibration_stars_polar) - 0.5 check_num_snr = len(calibration_stars_polar) - 0.5 else: check_num = max(min_calibration_stars_number - 0.5, int(len(calibration_stars_polar)) / 10 - 0.5) check_num_snr = max(min_calibration_stars_number - 0.5, int(len(calibration_stars_polar)) / 20 - 0.5) x0, y0, u0, comparisons = x_ref_position, y_ref_position, 0, calibration_stars_polar x0, y0, u0, comparisons_snr = x_ref_position, y_ref_position, 0, calibration_stars_polar_snr fits.close() # set the looking window and angular step circle = mpatches.Circle((x0, y0), circles_diameter, ec='r', fill=False) ax.add_patch(circle) for ii in comparisons[:10]: circle = mpatches.Circle((x0 + ii[0] * np.cos(u0 + ii[1]), y0 + ii[0] * np.sin(u0 + ii[1])), circles_diameter, ec='w', fill=False) ax.add_patch(circle) # for each science_file percent = 0 skip_time = 0 lt0 = time.time() for counter, science_file in enumerate(science): if show_progress.exit: return None alignment_log('\n', science_file) label_2.configure(text='Running Alignment: {0}'.format( science_file.split(os.sep)[-1])) label_2.update() label_3.configure(text='') label_3.update() fits = pf.open(science_file, mode='update') ax.cla() ax.imshow(fits[1].data, origin='lower', cmap=cm.Greys_r, vmin=fits[1].header[mean_key] + frame_low_std * fits[1].header[std_key], vmax=fits[1].header[mean_key] + frame_upper_std * fits[1].header[std_key]) ax.axis('off') circle = mpatches.Circle((-100, -100), circles_diameter, ec='r', fill=False) ax.add_patch(circle) rotation_detected = False # super fast detection test alignment_log('Test no shift', x0, y0, u0) star = plc.find_single_star(fits[1].data, x0, y0, mean=fits[1].header[mean_key], std=fits[1].header[std_key], burn_limit=burn_limit, star_std=star_std) if star: tests = [] max_x = star[0] max_y = star[1] alignment_log(science_file) alignment_log('Testing star at: ', max_x, max_y, ', with rotation:', u0) test = 0 for comp in comparisons: check_x = int(max_x + comp[0] * np.cos(u0 + comp[1])) check_y = int(max_y + comp[0] * np.sin(u0 + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num: break tests.append([test, max_x, max_y]) alignment_log([test, max_x, max_y]) tests.sort() test, max_x, max_y = tests[-1] if test < check_num: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = u0 else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # super fast detection test if show_progress.exit: return None delta_skip_time = time.time() # look for reasonable field shift if not stars_detected: alignment_log('Testing small shift') label_3.configure(text='Testing small shift and rotation') label_3.update() stars = plc.find_all_stars(fits[1].data, x_low=x0 - shift_tolerance, x_upper=x0 + shift_tolerance, y_low=y0 - shift_tolerance, y_upper=y0 + shift_tolerance, x_centre=x0, y_centre=y0, mean=fits[1].header[mean_key], std=fits[1].header[std_key], burn_limit=burn_limit, star_std=star_std)[0] if show_progress.exit: return None if stars: tests = [] for star in stars: if show_progress.exit: return None max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() alignment_log(science_file) alignment_log('Testing star at: ', max_x, max_y, ',with rotation:', u0) test = 0 for comp in comparisons: check_x = int(max_x + comp[0] * np.cos(u0 + comp[1])) check_y = int(max_y + comp[0] * np.sin(u0 + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num: break tests.append([test, max_x, max_y]) alignment_log([test, max_x, max_y]) if test > check_num: break tests.sort() test, max_x, max_y = tests[-1] if test < check_num: tests = [] for star in stars: if show_progress.exit: return None max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() alignment_log(science_file) alignment_log('LOW-SNR Testing star at: ', max_x, max_y, ', with rotation:', u0) test = 0 for comp in comparisons_snr: check_x = int(max_x + comp[0] * np.cos(u0 + comp[1])) check_y = int(max_y + comp[0] * np.sin(u0 + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num_snr: break tests.append([test, max_x, max_y]) alignment_log([test, max_x, max_y]) if test > check_num_snr: break tests.sort() test, max_x, max_y = tests[-1] if test < min_calibration_stars_number - 0.5: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = u0 rotation_detected = True else: stars_detected = True x0 = max_x y0 = max_y u0 = u0 rotation_detected = True else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # look for reasonable field shift if show_progress.exit: return None # look for reasonable field rotation if not stars_detected: alignment_log('Testing small rotation') ustep = np.arcsin( float(star_std) / comparisons[int(len(comparisons) / 2)][0]) angles = np.append( np.arange(-rotation_tolerance, rotation_tolerance, ustep), np.arange(-rotation_tolerance, rotation_tolerance, ustep) + np.pi) if stars: tests = [] for star in stars: if show_progress.exit: return None test = 0 max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() for rotation in angles: alignment_log(science_file) alignment_log('Testing star at: ', max_x, max_y, ', with rotation: ', rotation) test = 0 for comp in comparisons: check_x = int(max_x + comp[0] * np.cos(rotation + comp[1])) check_y = int(max_y + comp[0] * np.sin(rotation + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num: break tests.append([test, max_x, max_y, rotation]) alignment_log([test, max_x, max_y, rotation]) if test > check_num: break if test > check_num: break tests.sort() test, max_x, max_y, rotation = tests[-1] if test < check_num: for star in stars: if show_progress.exit: return None test = 0 max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() for rotation in angles: alignment_log(science_file) alignment_log('LOW SNR Testing star at: ', max_x, max_y, ', with rotation: ', rotation) test = 0 for comp in comparisons_snr: check_x = int(max_x + comp[0] * np.cos(rotation + comp[1])) check_y = int(max_y + comp[0] * np.sin(rotation + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = ( fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num_snr: break tests.append([test, max_x, max_y, rotation]) alignment_log([test, max_x, max_y, rotation]) if test > check_num_snr: break if test > check_num_snr: break tests.sort() test, max_x, max_y, rotation = tests[-1] if test < check_num_snr: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = rotation rotation_detected = True else: stars_detected = True x0 = max_x y0 = max_y u0 = rotation rotation_detected = True else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # look for reasonable field rotation if not stars_detected: circle.set_center((-100, -100)) canvas.draw() show_progress.update() skip_frame = askyesno( 'Alignment', 'Stars not found close to their previous positions.\n' 'Do you want to skip this frame?', parent=show_progress.root) else: skip_frame = False if show_progress.exit: return None # look for large field shift if not stars_detected and not skip_frame: alignment_log('Testing large shift and rotation') label_3.configure(text='Testing large shift and rotation') label_3.update() canvas.draw() show_progress.update() stars = plc.find_all_stars(fits[1].data, mean=fits[1].header[mean_key], std=fits[1].header[std_key], burn_limit=burn_limit, star_std=star_std, order_by_flux=True)[0] if show_progress.exit: return None if stars: tests = [] for star in stars: if show_progress.exit: return None max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() alignment_log(science_file) alignment_log('LOW SNR Testing star at: ', max_x, max_y, ', with rotation: ', u0) test = 0 for comp in comparisons_snr: check_x = int(max_x + comp[0] * np.cos(u0 + comp[1])) check_y = int(max_y + comp[0] * np.sin(u0 + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 3 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num_snr: break tests.append([test, max_x, max_y]) alignment_log([test, max_x, max_y]) if test > check_num_snr: break tests.sort() test, max_x, max_y = tests[-1] if test < check_num_snr: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = u0 rotation_detected = True else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # look for large field shift # look for large field rotation if not stars_detected and not skip_frame: alignment_log('Test large rotation') ustep = np.arcsin( float(star_std) / comparisons[int(len(comparisons) / 2)][0]) angles = np.array([np.pi, 0]) for ff in range(1, int(np.pi / ustep) + 1): angles = np.append(angles, np.pi - ff * ustep) angles = np.append(angles, np.pi + ff * ustep) angles = np.append(angles, 0 - ff * ustep) angles = np.append(angles, 0 + ff * ustep) if stars: if show_progress.exit: return None tests = [] for rotation in angles: test = 0 for star in stars: max_x = star[0] max_y = star[1] circle.set_center((max_x, max_y)) canvas.draw() show_progress.update() alignment_log(science_file) alignment_log('LOW SNR Testing star at: ', max_x, max_y, ', with rotation: ', rotation) test = 0 for comp in comparisons_snr: check_x = int(max_x + comp[0] * np.cos(rotation + comp[1])) check_y = int(max_y + comp[0] * np.sin(rotation + comp[1])) if 0 < check_x < x_length and 0 < check_y < y_length: check_sum = np.sum( fits[1].data[check_y - star_std:check_y + star_std + 1, check_x - star_std:check_x + star_std + 1]) check_lim = (fits[1].header[mean_key] + 2 * fits[1].header[std_key]) * ( (2 * star_std + 1)**2) if check_sum > check_lim: test += 1 else: test -= 1 alignment_log('Check ref. star at: ', check_x, check_y, ', Test: ', test) if abs(test) > check_num_snr: break tests.append([test, max_x, max_y, rotation]) alignment_log([test, max_x, max_y, rotation]) if test > check_num_snr: break if test > check_num_snr: break tests.sort() test, max_x, max_y, rotation = tests[-1] if test < check_num_snr: stars_detected = False else: stars_detected = True x0 = max_x y0 = max_y u0 = rotation rotation_detected = True else: stars_detected = False alignment_log(stars_detected, x0, y0, u0) # look for large field rotation skip_time += time.time() - delta_skip_time if show_progress.exit: return None if stars_detected: if rotation_detected: test_u0 = [] test_cos = [] test_sin = [] for ii in comparisons[:int(check_num + 0.5)]: star = plc.find_single_star( fits[1].data, x0 + ii[0] * np.cos(u0 + ii[1]), y0 + ii[0] * np.sin(u0 + ii[1]), mean=fits[1].header[mean_key], std=fits[1].header[std_key], burn_limit=burn_limit, star_std=star_std) if star: diff = plc.cartesian_to_polar( star[0], star[1], x0, y0)[1] - ii[1] if diff < 0: diff += 2 * np.pi test_u0.append(diff) test_cos.append(np.cos(diff)) test_sin.append(np.sin(diff)) if len(test_u0) > 0: test_u0 = np.mean(test_u0) test_cos = np.mean(test_cos) test_sin = np.mean(test_sin) u0 = np.arccos(test_cos) if test_sin < 0: u0 = np.pi + (np.pi - u0) fits[1].header.set(align_x0_key, x0) fits[1].header.set(align_y0_key, y0) fits[1].header.set(align_u0_key, u0) circle = mpatches.Circle((x0, y0), circles_diameter, ec='r', fill=False) ax.add_patch(circle) for ii in comparisons[:int(check_num + 0.5)]: circle = mpatches.Circle((x0 + ii[0] * np.cos(u0 + ii[1]), y0 + ii[0] * np.sin(u0 + ii[1])), circles_diameter, ec='w', fill=False) ax.add_patch(circle) canvas.draw() show_progress.update() else: fits[1].header.set(align_x0_key, False) fits[1].header.set(align_y0_key, False) fits[1].header.set(align_u0_key, False) fits.flush() fits.close() # counter new_percent = round(100 * (counter + 1) / float(len(science)), 1) if new_percent != percent: lt1 = time.time() rm_time = (100 - new_percent) * (lt1 - lt0 - skip_time) / new_percent hours = rm_time / 3600.0 minutes = (hours - int(hours)) * 60 seconds = (minutes - int(minutes)) * 60 progress_bar_2['value'] = new_percent percent_label_2.configure( text='{0} % ({1}h {2}m {3}s left)'.format( new_percent, int(hours), int(minutes), int(seconds))) percent = new_percent show_progress.update() if show_progress.exit: return None
def check_visibility(self): if self.exit: self.def_close() else: all_stars_dict = plc.open_dict('all_stars.pickle') stars = np.array(all_stars_dict['all_stars']) fits = plc.open_fits( os.path.join(self.log.reduction_directory, self.science_files[0])) polar_coords = [] for star in all_stars_dict['all_stars']: polar_coords.append( plc.cartesian_to_polar( star[0], star[1], self.all_frames[ self.science_files[0]][self.log.align_x0_key], self.all_frames[self.science_files[0]][ self.log.align_y0_key])) in_fov = np.ones(len(polar_coords)) for science_file in self.science_files: metadata = self.all_frames[science_file] if self.exit: self.def_close() ref_x_position = metadata[self.log.align_x0_key] ref_y_position = metadata[self.log.align_y0_key] ref_u_position = metadata[self.log.align_u0_key] star_std = metadata[self.log.psf_key] if ref_x_position: in_fov_single = [] for star in polar_coords: cartesian_x = ref_x_position + star[0] * np.cos( ref_u_position + star[1]) cartesian_y = ref_y_position + star[0] * np.sin( ref_u_position + star[1]) if (3 * star_std < cartesian_x < len(fits[1].data[0]) - 3 * star_std and 3 * star_std < cartesian_y < len(fits[1].data) - 3 * star_std): in_fov_single.append(1) else: in_fov_single.append(0) in_fov *= in_fov_single all_stars_dict['in_fov'] = np.array(in_fov) visible_fov_x_min = np.min(stars[np.where(in_fov), 0]) - 3 * star_std visible_fov_x_max = np.max(stars[np.where(in_fov), 0]) + 3 * star_std visible_fov_y_min = np.min(stars[np.where(in_fov), 1]) - 3 * star_std visible_fov_y_max = np.max(stars[np.where(in_fov), 1]) + 3 * star_std self.log.set_param('min_x', float(visible_fov_x_min)) self.log.set_param('min_y', float(visible_fov_y_min)) self.log.set_param('max_x', float(visible_fov_x_max)) self.log.set_param('max_y', float(visible_fov_y_max)) plc.save_dict(all_stars_dict, 'all_stars.pickle') self.log.set_param('alignment_complete', True) self.log.set_param('alignment_version', self.log.version) self.log.save_local_log() self.log.set_param('proceed', True) self.def_close()
def choose_calibartion_stars(self): if self.exit: self.after(self.align) else: all_stars_dict = plc.open_dict('all_stars.pickle') stars = np.array(all_stars_dict['all_stars']) fits = pf.open(os.path.join(self.log.reduction_directory, self.science_files[0]), memmap=False) metadata = self.all_frames[self.science_files[0]] frame_mean = metadata[self.log.mean_key] frame_std = metadata[self.log.std_key] frame_star_psf = metadata[self.log.psf_key] bright_stars = [] std_limit = 30 while len(bright_stars) < 100 and std_limit >= 5.0: bright_stars = [] for star in stars: if star[2] + star[3] < 2.0 * self.burn_limit / 3.0: if star[-1] > (2 * np.pi * (std_limit * frame_std) * frame_star_psf * frame_star_psf): self.alignment_log( star[0], star[1], star[-1], 2 * np.pi * (frame_mean + std_limit * frame_std) * (frame_star_psf**2)) bright_stars.append(star) std_limit -= 5 if len(bright_stars) < self.min_calibration_stars_number: bright_stars = [] std_limit = 30 while len(bright_stars) < 100 and std_limit >= 5.0: bright_stars = [] for star in stars: if star[-1] > (2 * np.pi * (std_limit * frame_std) * frame_star_psf * frame_star_psf): self.alignment_log( star[0], star[1], star[-1], 2 * np.pi * (frame_mean + std_limit * frame_std) * (frame_star_psf**2)) bright_stars.append(star) std_limit -= 5 stars = sorted(bright_stars, key=lambda x: -x[-1] / (x[-2]**3)) x_ref_position = stars[0][0] y_ref_position = stars[0][1] f_ref = stars[0][-1] del stars[0] # take the rest as calibration stars and calculate their polar coordinates relatively to the first calibration_stars_polar = [] for star in stars: r_position, u_position = plc.cartesian_to_polar( star[0], star[1], x_ref_position, y_ref_position) if r_position > 5 * frame_star_psf: calibration_stars_polar.append([r_position, u_position]) stars = sorted(stars, key=lambda x: -x[-1]) calibration_stars_polar_snr = [] for star in stars: r_position, u_position = plc.cartesian_to_polar( star[0], star[1], x_ref_position, y_ref_position) if r_position > 5 * frame_star_psf: calibration_stars_polar_snr.append( [r_position, u_position]) if len(calibration_stars_polar ) <= self.min_calibration_stars_number: self.check_num = len(calibration_stars_polar) - 0.5 self.check_num_snr = len(calibration_stars_polar) - 0.5 else: self.check_num = max(self.min_calibration_stars_number - 0.5, len(calibration_stars_polar) / 10.0 - 0.5) self.check_num_snr = max( self.min_calibration_stars_number - 0.5, len(calibration_stars_polar) / 20.0 - 0.5) self.x0 = x_ref_position self.y0 = y_ref_position self.u0 = 0 self.f0 = f_ref self.comparisons = calibration_stars_polar self.comparisons_snr = calibration_stars_polar_snr fits.close() ustep = np.arcsin( float(frame_star_psf) / self.comparisons[int(len(self.comparisons) / 2)][0]) self.small_angles = np.append( np.arange(-self.rotation_tolerance, self.rotation_tolerance, ustep), np.arange(-self.rotation_tolerance, self.rotation_tolerance, ustep) + np.pi) self.large_angles = np.array([np.pi, 0]) for ff in range(1, int(np.pi / ustep) + 1): self.large_angles = np.append(self.large_angles, np.pi - ff * ustep) self.large_angles = np.append(self.large_angles, np.pi + ff * ustep) self.large_angles = np.append(self.large_angles, 0 - ff * ustep) self.large_angles = np.append(self.large_angles, 0 + ff * ustep) # set the looking window and angular step self.progress_all_stars.set(' ') self.after(self.align)
def __init__(self, log): MainWindow.__init__(self, log, name='HOPS - Alignment', position=2) # set variables, create and place widgets self.bin_fits = self.log.get_param('bin_fits') self.burn_limit = int( 1.1 * self.log.get_param('burn_limit')) * self.bin_fits * self.bin_fits self.shift_tolerance_p = self.log.get_param('shift_tolerance_p') self.rotation_tolerance = self.log.get_param('rotation_tolerance') self.min_calibration_stars_number = int( self.log.get_param('min_calibration_stars_number')) self.all_frames = plc.open_dict(self.log.all_frames) self.science_files = [] for science_file in self.all_frames: if not self.all_frames[science_file][self.log.skip_key]: self.science_files.append([ self.all_frames[science_file][self.log.time_key], science_file ]) else: self.all_frames[science_file][self.log.align_x0_key] = False self.all_frames[science_file][self.log.align_y0_key] = False self.all_frames[science_file][self.log.align_u0_key] = False fits = pf.open(os.path.join(self.log.reduction_directory, science_file), mode='update') fits[1].header.set(self.log.align_x0_key, False) fits[1].header.set(self.log.align_y0_key, False) fits[1].header.set(self.log.align_u0_key, False) fits.flush() fits.close() self.science_files.sort() self.science_files = [ff[1] for ff in self.science_files] self.skip_time = 0 self.science_counter = 0 self.test_level = None self.redraw = None self.stars = None self.science_file = None self.fits = None self.std = None self.mean = None self.star_std = None self.int_psf = None self.stars_detected = None self.rotation_detected = None self.check_num = None self.check_num_snr = None self.x0 = None self.y0 = None self.u0 = None self.f0 = None self.comparisons = None self.comparisons_snr = None self.small_angles = None self.large_angles = None self.circle = None self.settings_to_check = None self.comparisons_to_check = None # common definitions for all images fits = plc.open_fits( os.path.join(self.log.reduction_directory, self.science_files[0])) self.shift_tolerance = int( max(len(fits[1].data), len(fits[1].data[0])) * (self.shift_tolerance_p / 100.0)) self.y_length, self.x_length = fits[1].data.shape self.circles_diameter = 0.02 * max(self.y_length, self.x_length) # progress window 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[1].data[0]) / len(fits[1].data))) self.progress_figure.load_fits(fits[1], input_name=self.science_files[0]) self.progress_all_stars = self.Label(text='') self.progress_alignment = self.Progressbar(task="Aligning frames") # self.progress_all_frames = self.Progressbar(task="Aligning all stars in all frames") self.setup_window([[[self.progress_figure, 0, 2]], [[self.progress_all_stars, 0, 2]], [[self.progress_alignment, 0, 2]], [[ self.Button( text='STOP ALIGNMENT & RETURN TO MAIN MENU', command=self.trigger_exit), 0, 2 ]], []]) self.set_close_button_function(self.trigger_exit)
def __init__(self, log): MainWindow.__init__(self, log, name='HOPS - Data & Target', position=2) # extra windows self.content_window = AddOnWindow(self, name='Files list', sizex=3, sizey=3, position=1) self.header_window = AddOnWindow(self, name='Header keywords list', sizex=3, sizey=3, position=7) self.target_window = AddOnWindow(self, name='Select Target') # set variables, create and place widgets # main window self.directory_test = self.Label( text=self.log.get_param('directory_short')) self.observation_files = self.Entry( value=self.log.get_param('observation_files'), instance=str, command=self.update_observation_files) self.observation_files_test = self.Label(text=' ') self.science_files = 0 self.science_header = [] self.show_files_button = self.Button(text='Show files', command=self.content_window.show) self.bias_files = self.Entry(value=self.log.get_param('bias_files'), instance=str, command=self.update_bias_files) self.bias_files_test = self.Label(text=' ') self.dark_files = self.Entry(value=self.log.get_param('dark_files'), instance=str, command=self.update_dark_files) self.dark_files_test = self.Label(text=' ') self.flat_files = self.Entry(value=self.log.get_param('flat_files'), instance=str, command=self.update_flat_files) self.flat_files_test = self.Label(text=' ') try: initial_bin = self.log.get_param('bin_fits') initial_bin = max(1, initial_bin) initial_bin = min(initial_bin, 4) except: print( 'WARNING the bin_fits parameter should be 1, 2, 3 or 4. Re-setting it to 1.' ) initial_bin = 1 self.bin_fits = self.DropDown(initial=initial_bin, options=[1, 2, 3, 4], instance=int) self.show_header_button = self.Button(text='Show header', command=self.header_window.show) self.exposure_time_key = self.Entry( value=self.log.get_param('exposure_time_key'), instance=str, command=self.update_exposure_time_key) self.exposure_time_key_test = self.Label(text=' ') self.observation_date_key = self.Entry( value=self.log.get_param('observation_date_key'), instance=str, command=self.update_observation_date_key) self.observation_date_key_test = self.Label(text=' ') self.observation_time_key = self.Entry( value=self.log.get_param('observation_time_key'), instance=str, command=self.update_observation_time_key) self.observation_time_key_test = self.Label(text=' ') self.time_stamp = self.DropDown( initial=self.log.get_param('time_stamp'), options=['exposure start', 'mid-exposure', 'exposure end']) self.select_target_button = self.Button( text='CHOOSE TARGET', command=self.update_ra_dec_options) self.target_ra_dec = self.Label( text=self.log.get_param('target_ra_dec')) self.target_name = self.Label(text=self.log.get_param('target_name')) self.target_ra_dec_test = self.Label(text='') self.observer = self.Entry(value=self.log.get_param('observer')) self.observatory = self.Entry(value=self.log.get_param('observatory')) self.telescope = self.Entry(value=self.log.get_param('telescope')) self.camera = self.Entry(value=self.log.get_param('camera')) filters = ['default'] + list(filter_map.keys()) if self.log.get_param('filter') not in filters: self.log.set_param('filter', 'default') self.filter = self.DropDown(initial=self.log.get_param('filter'), options=filters, command=self.check_filter) self.filter_test = self.Label(text=' ') self.save_and_return_button = self.Button( text='SAVE OPTIONS & RETURN TO MAIN MENU', command=self.save_and_return) self.save_and_proceed_button = self.Button( text='SAVE OPTIONS & PROCEED', command=self.save_and_proceed, bg='green', highlightbackground='green') self.setup_window([ [], [[ self.Button(text='CHOOSE DIRECTORY', command=self.update_directory), 1 ], [self.directory_test, 2, 2]], [[self.show_files_button, 2]], [[self.Label(text='Name identifier for observation files'), 1], [self.observation_files, 2], [self.observation_files_test, 3]], [[self.Label(text='Name identifier for bias files'), 1], [self.bias_files, 2], [self.bias_files_test, 3]], [[self.Label(text='Name identifier for dark files'), 1], [self.dark_files, 2], [self.dark_files_test, 3]], [ [self.Label(text='Name identifier for flat files'), 1], [self.flat_files, 2], [self.flat_files_test, 3], ], [[self.Label(text='Bin fits files (reduced only)'), 1], [self.bin_fits, 2]], [[self.show_header_button, 2]], [[self.Label(text='Exposure time header keyword'), 1], [self.exposure_time_key, 2], [self.exposure_time_key_test, 3]], [ [ self.Label( text= 'Observation date header keyword\n(no JD, HJD, BJD)'), 1 ], [self.observation_date_key, 2], [self.observation_date_key_test, 3], ], [[self.Label(text='Observation time header keyword'), 1], [self.observation_time_key, 2], [self.observation_time_key_test, 3]], [[ self.Label( text='Time-stamp\n(which time is saved in your fits files?)' ), 1 ], [self.time_stamp, 2]], [], [[self.select_target_button, 1], [self.target_ra_dec, 2], [self.target_ra_dec_test, 3]], [[self.target_name, 2]], [[self.Label(text='Observer'), 1], [self.observer, 2], [self.Label(text='OK'), 3]], [[self.Label(text='Observatory'), 1], [self.observatory, 2], [self.Label(text='OK'), 3]], [[self.Label(text='Telescope'), 1], [self.telescope, 2], [self.Label(text='OK'), 3]], [[self.Label(text='Camera'), 1], [self.camera, 2], [self.Label(text='OK'), 3]], [[self.Label(text='Filter'), 1], [self.filter, 2], [self.filter_test, 3]], [], [[ self.Button(text='RETURN TO MAIN MENU', command=self.close), 1, 6 ]], [[self.save_and_return_button, 1, 6]], [[self.save_and_proceed_button, 1, 6]], [] ], entries_wd=self.log.entries_width) # files window self.content_list = self.content_window.ListDisplay() self.content_window.setup_window([[[self.content_list, 0]]]) content_list = [' List of files in your directory:', ' '] xx = find_fits_files('*') for ii in xx: content_list.append(' {0}'.format(str(ii).split(os.sep)[-1])) self.content_list.update_list(content_list) # headers window self.header_list = self.header_window.ListDisplay() self.header_window.setup_window([[[self.header_list, 0]]]) self.stars = plc.open_dict( os.path.join(plc.databases.oec, 'stars_catalogue.pickle')) self.stars = { self.stars[ff]['simbad_id']: self.stars[ff]['planets'][0] for ff in self.stars } # target window self.target_ra_dec_choice = self.target_window.IntVar( self.log.get_param('target_ra_dec_choice')) self.target_ra_dec_choice_0 = self.target_window.Radiobutton( text='Use the RA/DEC found in the file\'s header:', variable=self.target_ra_dec_choice, value=0, command=self.update_ra_dec) self.target_ra_dec_choice_1 = self.target_window.Radiobutton( text='Provide the name of the target:', variable=self.target_ra_dec_choice, value=1, command=self.update_ra_dec) self.target_ra_dec_choice_2 = self.target_window.Radiobutton( text='Provide the RA/DEC of the target\n(hh:mm:ss +/-dd:mm:ss):', variable=self.target_ra_dec_choice, value=2, command=self.update_ra_dec) self.auto_target_ra_dec = self.target_window.Label( text=self.log.get_param('auto_target_ra_dec')) self.auto_target_ra_dec_check = self.target_window.Label(text='') self.simbad_target_name = self.target_window.Entry( value=self.log.get_param('simbad_target_name'), command=self.update_ra_dec) self.simbad_target_name_check = self.target_window.Label(text='') self.manual_target_ra_dec = self.target_window.Entry( value=self.log.get_param('manual_target_ra_dec'), command=self.update_ra_dec) self.target_ra_dec_2 = self.target_window.Label( text=self.log.get_param('target_ra_dec')) self.target_name_2 = self.target_window.Label( text=self.log.get_param('target_name')) self.target_window.setup_window([ [], [[ self.target_window.Label( text= 'How would you like to choose your target? Select one of the three options:' ), 0, 5 ]], [], [[self.target_ra_dec_choice_0, 1], [self.auto_target_ra_dec, 2, 2], [self.auto_target_ra_dec_check, 4]], [[self.target_ra_dec_choice_1, 1], [self.simbad_target_name, 2, 2], [self.simbad_target_name_check, 4]], [[self.target_ra_dec_choice_2, 1], [self.manual_target_ra_dec, 2, 2]], [], [[self.target_window.Label(text='Target RA/DEC: '), 0], [self.target_ra_dec_2, 1, 3]], [[self.target_window.Label(text='Target Name: '), 0], [self.target_name_2, 1, 3]], [], [[ self.target_window.Button(text=' Cancel ', command=self.target_window.hide), 2 ], [ self.target_window.Button(text=' Choose ', command=self.choose_target), 3 ]], [] ], entries_wd=self.log.entries_width) self.update_observation_files() self.update_bias_files() self.update_dark_files() self.update_flat_files()
def update_window(self): self.data_target_button.activate() if self.log.get_param('data_target_complete'): self.data_target_complete.set('Data: {0}\nTarget: {1} '.format( self.log.get_param('directory_short'), self.log.get_param('target_name'))) self.reduction_button.activate() trash = 0 if not os.path.isfile(self.log.all_frames): self.log.set_param('reduction_complete', False) else: all_frames = plc.open_dict(self.log.all_frames) for i in all_frames: if not os.path.isfile(os.path.join(self.log.reduction_directory, i)): self.log.set_param('reduction_complete', False) break if all_frames[i][self.log.skip_key]: trash += 1 if self.log.get_param('reduction_complete'): self.reduction_complete.set('Completed under v{0}'.format(self.log.get_param('reduction_version'))) self.inspection_button.activate() self.inspection_complete.set('Files discarded: {0}'.format(trash)) self.alignment_button.activate() all_frames = plc.open_dict(self.log.all_frames) for i in all_frames: if not all_frames[i][self.log.skip_key] and not all_frames[i][self.log.align_x0_key]: self.log.set_param('alignment_complete', False) plc.save_dict(all_frames, self.log.all_frames) if not os.path.isfile(self.log.all_stars): self.log.set_param('alignment_complete', False) if self.log.get_param('alignment_complete'): self.alignment_complete.set('Completed under v{0}'.format(self.log.get_param('alignment_version'))) self.photometry_button.activate() if len(glob.glob('{0}*'.format(self.log.photometry_directory_base))) == 0: self.log.set_param('photometry_complete', False) if self.log.get_param('photometry_complete'): self.photometry_complete.set('Completed under v{0}'.format(self.log.get_param('photometry_version'))) self.fitting_button.activate() if self.log.get_param('fitting_complete'): self.fitting_complete.set('Completed under v{0}'.format(self.log.get_param('fitting_version'))) else: self.photometry_complete.set('You need to complete this step to proceed') self.fitting_button.disable() self.fitting_complete.set('') else: self.alignment_complete.set('You need to complete this step to proceed') self.photometry_button.disable() self.photometry_complete.set('') self.fitting_button.disable() self.fitting_complete.set('') else: self.reduction_complete.set('You need to complete this step to proceed') self.inspection_button.disable() self.inspection_complete.set('') self.alignment_button.disable() self.alignment_complete.set('') self.photometry_button.disable() self.photometry_complete.set('') self.fitting_button.disable() self.fitting_complete.set('') else: self.data_target_complete.set('You need to complete this step to proceed.') self.reduction_button.disable() self.reduction_complete.set('') self.inspection_button.disable() self.inspection_complete.set('') self.alignment_button.disable() self.alignment_complete.set('') self.photometry_button.disable() self.photometry_complete.set('') self.fitting_button.disable() self.fitting_complete.set('')