"""Gather the analysis's numbers into the declared results the claims name, each value at the
precision its uncertainty supports.

python collect.py <results dir>

Reads the registered analysis (results/*.json), the same analysis without the events whose SAP
flux moved the opposite way (results/corrected/*.json), the development set (results/dev/), the
sign check, the audit, and the exploratory analyses. R1 to R10 and R13 come from the corrected
analysis; R0 keeps the registered one's primary numbers.
"""
import json
import os
import sys
from math import log10

out = sys.argv[1]
cor = os.path.join(out, 'corrected')
dev = os.path.join(out, 'dev')


def load(d, name):
    p = os.path.join(d, name + '.json')
    return json.load(open(p)) if os.path.exists(p) else None


def r(x, nd=2):
    return None if x is None else round(float(x), nd)


def rate_block(t, nd=2):
    """The numbers of one comparison with the Kepler rate."""
    return {
        'stars': t['stars'], 'light_curves': t['light_curves'], 'star_years': r(t['star_years'], 0),
        'observed': t['observed'], 'expected_kepler': r(t['expected_vasilyev'], 1),
        'expected_earlier': r(t['expected_earlier'], 2),
        'ratio': r(t['ratio'], nd), 'ratio_low': r(t['ratio_ci95'][0], nd), 'ratio_high': r(t['ratio_ci95'][1], nd),
        'p_at_most_observed_if_kepler': r(t['p_at_most_observed_if_vasilyev'], 4),
        'log10_p_at_least_observed_if_earlier': r(log10(max(t['p_at_least_observed_if_earlier'], 1e-300)), 1),
    }


def sensitivity(t):
    return {'observed': t['observed'], 'expected_kepler': r(t['expected_vasilyev'], 1), 'ratio': r(t['ratio']),
            'ratio_low': r(t['ratio_ci95'][0]), 'ratio_high': r(t['ratio_ci95'][1])}


def write(name, obj):
    with open(os.path.join(out, name + '.json'), 'w') as fh:
        json.dump(obj, fh, indent=1, sort_keys=True)


def main():
    write('R0', rate_block(load(out, 'primary')))
    p = load(cor, 'primary')
    block = rate_block(p)
    f34 = p['vasilyev_f34']
    block['kepler_rate_per_year'] = r(f34, 5)
    block['earlier_years_per_superflare'] = 2500
    block['rate_per_year'] = r(p['rate_above_1e34_per_year'], 4)
    block['rate_low'] = r(p['rate_above_1e34_ci95'][0], 4)
    block['rate_high'] = r(p['rate_above_1e34_ci95'][1], 4)
    block['years_per_superflare'] = r(p['years_per_superflare'], 0)
    block['years_low'] = r(1 / p['rate_above_1e34_ci95'][1], 0)
    block['years_high'] = r(1 / p['rate_above_1e34_ci95'][0], 0)
    write('R1', block)
    write('R2', rate_block(load(cor, 'sunlike')))
    write('R3', {'low': rate_block(load(cor, 'low_activity')), 'high': rate_block(load(cor, 'high_activity')),
                 'median_index_nm': r(load(cor, 'sample')['activity_median_nm'], 4)})
    write('R4', {'bright': rate_block(load(cor, 'tmag_0_8.5')), 'middle': rate_block(load(cor, 'tmag_8.5_9.5')),
                 'faint': rate_block(load(cor, 'tmag_9.5_10.5'))})
    write('R5', {'above_e34_5': rate_block(load(cor, 'above_10^34.5')), 'above_e35': rate_block(load(cor, 'above_10^35'))})
    b = load(cor, 'background_subtracted')
    s = load(out, 'sap_sign')
    flares_before = s['flares_checked'] - s['flares_opposite_sign']
    dips_before = s['dips_checked'] - s['dips_opposite_sign']
    write('R6', {'dips': b['dips'], 'dips_before_eclipser_rule': dips_before,
                 'flares_before_eclipser_rule': flares_before,
                 'ratio_less_every_dip_before_rule': r((p['observed'] - dips_before) / p['expected_vasilyev'])})
    d = load(cor, 'durations')
    write('R7', {'light_curves': d['light_curves'], 'short': sensitivity(d['short'] | {'observed': p['observed']}),
                 'long': sensitivity(d['long'] | {'observed': p['observed']})})
    t = load(cor, 'flare_temperature')
    write('R8', {f't{k}': sensitivity(v) for k, v in t.items()})
    write('R9', rate_block(load(cor, 'localized')))
    write('R10', rate_block(load(cor, 'strict_single')))
    sm = load(cor, 'sample')
    sel = load(out, 'selection')
    write('R11', {'stars_selected': sel['main_stars'], 'light_curves_selected': sel['main_light_curves'],
                  'stars_fast_rotators': sm['stars_tess_fast_rotators'], 'stars_eclipsers': sm['stars_eclipsers'],
                  'stars_used': sm['stars_used'], 'light_curves_used': sm['light_curves_used'],
                  'star_years': r(sm['star_years'], 0), 'median_noise_ppm': r(sm['median_sigma_ppm'], -1),
                  'selection_reproduced': sel['sample_stars']['identical'] and sel['sample_lcs']['identical']})
    a = load(out, 'audit_all')
    write('R12', {'light_curves': a['light_curves'], 'light_curves_agree': a['light_curves_agree'],
                  'fields_compared': a['fields_compared'], 'fields_mismatched': a['fields_mismatched'],
                  'all_but_fits_agree': a['all_but_fits_agree'], 'fit_differences_on_vetted': a['fit_differences_on_vetted'],
                  'max_fit_relative_difference': float(f"{a['max_fit_relative_difference']:.1g}"),
                  'fits_within_one_percent': a['fits_within_one_percent']})
    write('R13', rate_block(load(dev, 'primary')))
    w = load(out, 'width_check')
    write('R15', w)
    write('R17', {'flares_opposite_sign': s['counted_flares_opposite_sign'], 'dips_opposite_sign': s['dips_opposite_sign'],
                  'injection_light_curves': s['injection_light_curves'],
                  'injections_recovered_above_1e34': s['injections_recovered_above_1e34'],
                  'injections_changed_by_sign': s['injections_changed_by_sign']})
    c = load(out, 'cadence')
    sig = lambda x: float(f'{x:.3g}')  # noqa: E731
    shape = lambda v: {'factor_low_bin': r(v['factor_low_bin']), 'factor_high_bin': r(v['factor_high_bin'])}  # noqa: E731
    fig, rates, fit = c['figure'], c['rates'], c['calibration']
    write('R18', {name: shape(c[name]) for name in ('two_point', 'short', 'base', 'long', 'base_steeper')} | {
        'energy_bins': fit['bins'], 'fit_rms': r(fit['rms'], 3), 'fit_difference_max': r(fit['max_difference'], 3),
        'beta': r(c['beta']), 'beta_steeper': r(c['beta_steeper']),
        'applied_exceeds_figure_from_log_e': r(fig['applied_exceeds_from_log_e']),
        'log_e_near_1e35': r(fig['log_e_near_1e35']), 'applied_r_near_1e35': r(fig['applied_r_near_1e35']),
        'figure_max_r_near_1e35': r(fig['figure_max_r_near_1e35']),
        'figure_rate_low_bin': sig(rates['figure_low_bin']), 'figure_rate_high_bin': sig(rates['figure_high_bin']),
        'table_rate_low_bin': rates['table_low_bin'], 'table_rate_high_bin': rates['table_high_bin']})


if __name__ == '__main__':
    main()
