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