def plot_current(self): if self.exit: self.after(self.save) else: if self.stars_detected: if self.rotation_detected: test_u0 = [] test_cos = [] test_sin = [] for ii in self.comparisons[:int(self.check_num + 0.5)]: check_x = self.x0 + ii[0] * np.cos(self.u0 + ii[1]) check_y = self.y0 + ii[0] * np.sin(self.u0 + ii[1]) star = plc.find_single_star(self.fits[1].data, check_x, check_y, mean=self.mean, std=self.std, burn_limit=self.burn_limit, star_std=self.star_std) if star: diff = plc.cartesian_to_polar( star[0], star[1], self.x0, self.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_cos = np.median(test_cos) test_sin = np.median(test_sin) self.u0 = np.arccos(test_cos) if test_sin < 0: self.u0 = np.pi + (np.pi - self.u0) self.fits[1].header.set(self.log.align_x0_key, self.x0) self.fits[1].header.set(self.log.align_y0_key, self.y0) self.fits[1].header.set(self.log.align_u0_key, self.u0) self.circle.set_center((self.x0, self.y0)) for ii in self.comparisons[:int(self.check_num + 0.5)]: circle = mpatches.Circle( (self.x0 + ii[0] * np.cos(self.u0 + ii[1]), self.y0 + ii[0] * np.sin(self.u0 + ii[1])), self.circles_diameter, ec='w', fill=False) self.progress_figure.ax.add_patch(circle) else: self.fits[1].header.set(self.log.align_x0_key, False) self.fits[1].header.set(self.log.align_y0_key, False) self.fits[1].header.set(self.log.align_u0_key, False) self.all_frames[self.science_file][ self.log.align_x0_key] = self.fits[1].header[ self.log.align_x0_key] self.all_frames[self.science_file][ self.log.align_y0_key] = self.fits[1].header[ self.log.align_y0_key] self.all_frames[self.science_file][ self.log.align_u0_key] = self.fits[1].header[ self.log.align_u0_key] if not self.fits[1].header[self.log.align_x0_key]: self.all_frames[self.science_file][self.log.skip_key] = True self.fits.flush() self.fits.close() self.progress_figure.draw() if self.skip_time == 0: self.progress_alignment.update() else: self.progress_alignment.update(skip=time.time() - self.skip_time) self.skip_time = 0 self.science_counter += 1 if self.science_counter >= len(self.science_files): self.progress_all_stars.set( 'Aligning all stars in all frames...') self.after(self.save) else: self.after(self.align)
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 detect_stars(self): if self.exit: self.after(self.plot_current) else: if self.test_level == 1: self.stars = plc.find_single_star(self.fits[1].data, self.x0, self.y0, mean=self.mean, std=self.std, burn_limit=self.burn_limit, star_std=self.star_std) if self.stars: self.stars.append(2 * np.pi * self.stars[2] * self.stars[4] * self.stars[5]) self.stars = [self.stars] elif self.test_level == 2: self.skip_time = time.time() self.stars = plc.find_all_stars( self.fits[1].data, x_low=self.x0 - self.shift_tolerance, x_upper=self.x0 + self.shift_tolerance, y_low=self.y0 - self.shift_tolerance, y_upper=self.y0 + self.shift_tolerance, x_centre=self.x0, y_centre=self.y0, mean=self.mean, std=self.std, burn_limit=self.burn_limit, star_std=self.star_std, verbose=True, order_by_distance_and_flux=self.f0)[0] self.progress_all_stars.set(' ') elif self.test_level == 4: if self.askyesno( 'HOPS - Alignment', 'Stars not found close to their previous positions.\n' 'Do you want to skip this frame?'): self.after(self.plot_current) self.stars = plc.find_all_stars(self.fits[1].data, mean=self.mean, std=self.std, burn_limit=self.burn_limit, star_std=self.star_std, order_by_flux=self.f0, verbose=True)[0] self.progress_all_stars.set(' ') if self.stars: self.settings_to_check = [] if self.test_level == 1: self.settings_to_check.append([ self.stars[0][0], self.stars[0][1], self.u0, self.stars[0] ]) self.setting_checking = 0 self.comparisons_to_check = self.comparisons elif self.test_level == 2: for star in self.stars: self.settings_to_check.append( [star[0], star[1], self.u0, star]) self.comparisons_to_check = self.comparisons_snr elif self.test_level == 3: for star in self.stars: for rotation in self.small_angles: self.settings_to_check.append( [star[0], star[1], rotation, star]) elif self.test_level == 4: for star in self.stars: self.settings_to_check.append( [star[0], star[1], self.u0, star]) elif self.test_level == 5: for star in self.stars: for rotation in self.large_angles: self.settings_to_check.append( [star[0], star[1], rotation, star]) self.setting_checking = 0 self.after(self.check_star) else: if self.test_level == 1: self.test_level = 2 self.progress_figure.draw() self.progress_all_stars.set('Analysing frame...') self.progress_alignment.show_message( 'Testing small shift...') self.after(self.detect_stars) elif self.test_level == 2: self.test_level = 3 self.progress_alignment.show_message( 'Testing small shift & rotation...') self.after(self.detect_stars) elif self.test_level == 3: self.test_level = 4 self.progress_all_stars.set('Analysing frame...') self.progress_alignment.show_message( 'Testing large shift...') self.after(self.detect_stars) elif self.test_level == 4: self.test_level = 5 self.progress_alignment.show_message( 'Testing large shift & rotation...') self.after(self.detect_stars) else: self.after(self.plot_current)