def test_get_lnoverlaps():
    """
    Confirms that star-component overlaps get smaller as stars get further
    away.

    First generates a component `sphere_comp`. Then generates three stars.
    The first one is identical to `sphere_comp` in mean and covmatrix.
    The other two share the same covmatrix yet are separated in X.
    We check that the overlap integral is smaller for the more separated
    stars.
    """
    dim = 6
    mean = np.zeros(dim)
    covmatrix = np.identity(dim)
    age = 1e-10
    sphere_comp = SphereComponent(attributes={
        'mean': mean,
        'covmatrix': covmatrix,
        'age': age,
    })

    dx_offsets = [0., 1., 10.]

    star_comps = []
    for dx_offset in dx_offsets:
        star = SphereComponent(
            attributes={
                'mean':
                sphere_comp.get_mean() +
                np.array([dx_offset, 0., 0., 0., 0., 0.]),
                'covmatrix':
                sphere_comp.get_covmatrix(),
                'age':
                sphere_comp.get_age(),
            })
        star_comps.append(star)

    nstars = len(star_comps)
    dummy_table = Table(data=np.arange(nstars).reshape(nstars, 1),
                        names=['name'])
    tabletool.append_cart_cols_to_table(dummy_table)

    for star_comp, row in zip(star_comps, dummy_table):
        tabletool.insert_data_into_row(
            row,
            star_comp.get_mean(),
            star_comp.get_covmatrix(),
            cartesian=True,
        )
    dummy_data = tabletool.build_data_dict_from_table(dummy_table)
    ln_overlaps = likelihood.get_lnoverlaps(sphere_comp, data=dummy_data)

    # Checks that ln_overlaps is descending
    assert np.allclose(ln_overlaps, sorted(ln_overlaps)[::-1])
def test_stationary_component():
    """
    Integrated test which fits a single component to a synthetic association.

    Runtime on my mac (single thread) is ~ 20 mins. Check logs/compfitter.log
    and temp_plots/*.png for progress.

    Takes about 10 mins single thread with C implementation of overlap
    or ~40 mins with python implementation of overlap
    """
    # log_filename = 'logs/compfitter_stationary.log'
    # synth_data_savefile = 'temp_data/compfitter_stationary_synthdata.fits'

    short_burnin_step = 200

    true_comp_mean = np.zeros(6)
    true_comp_dx = 2.
    true_comp_dv = 2.
    true_comp_covmatrix = np.identity(6)
    true_comp_covmatrix[:3,:3] *= true_comp_dx**2
    true_comp_covmatrix[3:,3:] *= true_comp_dv**2
    true_comp_age = 1e-10
    true_comp = SphereComponent(attributes={
        'mean':true_comp_mean,
        'covmatrix':true_comp_covmatrix,
        'age':true_comp_age,
    })
    nstars = 100
    measurement_error = 1e-10

    best_comp, chain, lnprob = run_fit_helper(
            true_comp=true_comp, starcounts=nstars,
            measurement_error=measurement_error,
            run_name='stationary',
            burnin_step=short_burnin_step,
            trace_orbit_func=dummy_trace_orbit_func,
    )
    np.save('temp_data/{}_compfitter_stationary_' \
            'true_and_best_comp.npy'.format(PY_VERS),
            [true_comp, best_comp],)


    assert np.allclose(true_comp.get_mean(), best_comp.get_mean(),
                       atol=1.0)
    assert np.allclose(true_comp.get_age(), best_comp.get_age(),
                       atol=1.0)
    assert np.allclose(true_comp.get_covmatrix(),
                       best_comp.get_covmatrix(),
                       atol=2.0)
def test_get_lnoverlaps():
    """
    Confirms that star-component overlaps get smaller as stars get further
    away.

    First generates a component `sphere_comp`. Then generates three stars.
    The first one is identical to `sphere_comp` in mean and covmatrix.
    The other two share the same covmatrix yet are separated in X.
    We check that the overlap integral is smaller for the more separated
    stars.
    """
    dim = 6
    mean = np.zeros(dim)
    covmatrix = np.identity(dim)
    age = 1e-10
    sphere_comp = SphereComponent(attributes={
        'mean':mean,
        'covmatrix':covmatrix,
        'age':age,
    })

    dx_offsets = [0., 1., 10.]

    star_comps = []
    for dx_offset in dx_offsets:
        star = SphereComponent(attributes={
            'mean':sphere_comp.get_mean()+np.array([dx_offset,0.,0.,0.,0.,0.]),
            'covmatrix':sphere_comp.get_covmatrix(),
            'age':sphere_comp.get_age(),
        })
        star_comps.append(star)

    nstars = len(star_comps)
    dummy_table = Table(data=np.arange(nstars).reshape(nstars,1),
                        names=['name'])
    tabletool.append_cart_cols_to_table(dummy_table)

    for star_comp, row in zip(star_comps, dummy_table):
        tabletool.insert_data_into_row(row,
                                       star_comp.get_mean(),
                                       star_comp.get_covmatrix(),
                                       cartesian=True,
                                       )
    dummy_data = tabletool.build_data_dict_from_table(dummy_table)
    ln_overlaps = likelihood.get_lnoverlaps(sphere_comp, data=dummy_data)

    # Checks that ln_overlaps is descending
    assert np.allclose(ln_overlaps, sorted(ln_overlaps)[::-1])
def test_stationary_component():
    """
    Integrated test which fits a single component to a synthetic association.

    Runtime on my mac (single thread) is ~ 20 mins. Check logs/compfitter.log
    and temp_plots/*.png for progress.

    Takes about 10 mins single thread with C implementation of overlap
    or ~40 mins with python implementation of overlap
    """
    # log_filename = 'logs/compfitter_stationary.log'
    # synth_data_savefile = 'temp_data/compfitter_stationary_synthdata.fits'

    short_burnin_step = 200

    true_comp_mean = np.zeros(6)
    true_comp_dx = 2.
    true_comp_dv = 2.
    true_comp_covmatrix = np.identity(6)
    true_comp_covmatrix[:3, :3] *= true_comp_dx**2
    true_comp_covmatrix[3:, 3:] *= true_comp_dv**2
    true_comp_age = 1e-10
    true_comp = SphereComponent(
        attributes={
            'mean': true_comp_mean,
            'covmatrix': true_comp_covmatrix,
            'age': true_comp_age,
        })
    nstars = 100
    measurement_error = 1e-10

    best_comp, chain, lnprob = run_fit_helper(
        true_comp=true_comp,
        starcounts=nstars,
        measurement_error=measurement_error,
        run_name='stationary',
        burnin_step=short_burnin_step,
        trace_orbit_func=dummy_trace_orbit_func,
    )
    np.save('temp_data/{}_compfitter_stationary_' \
            'true_and_best_comp.npy'.format(PY_VERS),
            [true_comp, best_comp],)

    assert np.allclose(true_comp.get_mean(), best_comp.get_mean(), atol=1.0)
    assert np.allclose(true_comp.get_age(), best_comp.get_age(), atol=1.0)
    assert np.allclose(true_comp.get_covmatrix(),
                       best_comp.get_covmatrix(),
                       atol=2.0)
def test_lcc_like():
    """
    Takes about 40 mins
    """
    mean_now = np.array([50., -100., 25., 1.1, -7.76, 2.25])

    age = 10.
    mean = trace_cartesian_orbit(mean_now, times=-age)
    dx = 5.
    dv = 2.
    covmatrix = np.identity(6)
    covmatrix[:3,:3] *= dx**2
    covmatrix[3:,3:] *= dv**2

    true_comp = SphereComponent(attributes={
        'mean':mean,
        'covmatrix':covmatrix,
        'age':age,
    })

    nstars = 100
    tiny_measurement_error = 1e-10
    short_burnin_step = 200

    best_comp, chain, lnprob = run_fit_helper(
            true_comp=true_comp, starcounts=nstars,
            measurement_error=tiny_measurement_error,
            burnin_step=short_burnin_step,
            run_name='lcc_like',
    )

    np.save('temp_data/{}_compfitter_lcc_like_'\
            'true_and_best_comp.npy'.format(PY_VERS),
            [true_comp, best_comp],)

    assert np.allclose(true_comp.get_mean(), best_comp.get_mean(),
                       atol=3.0)
    assert np.allclose(true_comp.get_age(), best_comp.get_age(),
                       atol=1.0)
    assert np.allclose(true_comp.get_covmatrix(),
                       best_comp.get_covmatrix(),
                       atol=5.0)
def test_lcc_like():
    """
    Takes about 40 mins
    """
    mean_now = np.array([50., -100., 25., 1.1, -7.76, 2.25])

    age = 10.
    mean = trace_cartesian_orbit(mean_now, times=-age)
    dx = 5.
    dv = 2.
    covmatrix = np.identity(6)
    covmatrix[:3, :3] *= dx**2
    covmatrix[3:, 3:] *= dv**2

    true_comp = SphereComponent(attributes={
        'mean': mean,
        'covmatrix': covmatrix,
        'age': age,
    })

    nstars = 100
    tiny_measurement_error = 1e-10
    short_burnin_step = 200

    best_comp, chain, lnprob = run_fit_helper(
        true_comp=true_comp,
        starcounts=nstars,
        measurement_error=tiny_measurement_error,
        burnin_step=short_burnin_step,
        run_name='lcc_like',
    )

    np.save('temp_data/{}_compfitter_lcc_like_'\
            'true_and_best_comp.npy'.format(PY_VERS),
            [true_comp, best_comp],)

    assert np.allclose(true_comp.get_mean(), best_comp.get_mean(), atol=3.0)
    assert np.allclose(true_comp.get_age(), best_comp.get_age(), atol=1.0)
    assert np.allclose(true_comp.get_covmatrix(),
                       best_comp.get_covmatrix(),
                       atol=5.0)
                       comp_now=True,
                       comp_then=True,
                       comp_orbit=True,
                       alpha=0.3)

        sub_ax.set_xlabel('{} [{}]'.format(labels[dim1], units[dim1]))
        sub_ax.set_ylabel('{} [{}]'.format(labels[dim2], units[dim2]))
        sub_ax.set_xlim(lims[dim1])
        # print('x set fine: {}'.format(lims))
        sub_ax.set_ylim(lims[dim2])
        # print('y set fine {}'.format(lims))

    # Put in some annotation
    first_ax = ax[0, 0]
    first_ax.text(0.8,
                  0.9,
                  '{:>5.1f} Myr  '.format(best_comp.get_age()),
                  horizontalalignment='right',
                  transform=first_ax.transAxes)
    first_ax.text(0.8,
                  0.8,
                  '{:>6} steps'.format(step_ix),
                  horizontalalignment='right',
                  transform=first_ax.transAxes)

    plt.savefig('../plots/explanation_movie/{:04}_explanation.png'.\
        format(
            plot_ix,
            # labels[dim1],
            # labels[dim2]
        ))