<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Simulate/fit/analyze in batch mode
Generate observed binary properties
Step1:  Use a StarCatalog to organize data
Step2:  Fit models
Here is a snippet to fit all the models (using the convenient .iter_models() API); this could easily be adapted into a cluster script (e.g., using schwimmbad) to run thousands of fits.
Step3:  Analyze samples
A StarCatalog could probably have some convenience methods for some of this stuff, but this for now.
<ASSISTANT_TASK:>
Python Code:
import numpy as np
from isochrones import get_ichrone
bands = ['J', 'H', 'K', 'G', 'BP', 'RP']
mist = get_ichrone('mist', bands=bands)
from itertools import product
primary_masses = [0.8, 1.0]
mass_ratios = [0.5, 0.9]
feh_grid = [-0.25, 0.0]
age = 9.7
distance = 500
AV = 0.
m1, m2, feh, name = zip(*[(m, q*m, f, f'{m:.2f}_{q*m:0.2f}_{f:0.2f}') 
                          for m, q, f 
                          in product(primary_masses, mass_ratios, feh_grid)])
df = mist.generate_binary(m1, m2, age, feh, distance=distance, AV=AV, accurate=True)
# add uncertainties for each band
uncs = {'J': 0.02, 'H': 0.02, 'K':0.02, 'G': 0.002, 'BP': 0.002, 'RP':0.002}
for b in bands:
    df[f'{b}_mag_unc'] = uncs[b]
    
# Add parallax & uncertainty
df['parallax'] = 1000/distance
df['parallax_unc'] = 0.02
df.index = name
Explanation: Simulate/fit/analyze in batch mode
Generate observed binary properties
End of explanation
from isochrones.catalog import StarCatalog
from isochrones.priors import FlatPrior
catalog = StarCatalog(df, bands=bands, props=['parallax'])
catalog.set_prior(AV=FlatPrior((0, 0.0001)), age=FlatPrior((8.5, 10)))
Explanation: Use a StarCatalog to organize data
End of explanation
from multiprocessing import Pool
def fit_model(mod):
    print(mod.mnest_basename)
    mod.fit(verbose=True)
    return mod.derived_samples
pool = Pool(processes=8)  # e.g.
samples = pool.map(fit_model, catalog.iter_models(N=2))
Explanation: Fit models
Here is a snippet to fit all the models (using the convenient .iter_models() API); this could easily be adapted into a cluster script (e.g., using schwimmbad) to run thousands of fits.
End of explanation
cols = ['mass_0', 'mass_1', 'age', 'feh', 'AV']
qs = [0.05, 0.16, 0.5, 0.84, 0.95]
for name, samps in zip(catalog.df.index, samples):
    print(name)
    print(samps[cols].quantile(qs))
from corner import corner
corner(samples[-1][['mass_0', 'mass_1', 'age', 'feh', 'distance']]);
corner(samples[-1][['J_mag', 'K_mag', 'G_mag', 'BP_mag', 'RP_mag']]);
Explanation: Analyze samples
A StarCatalog could probably have some convenience methods for some of this stuff, but this for now.
End of explanation
<END_TASK>