====== Isochrone Fitting and Optimization Script ====== This Python script is designed for fitting isochrones to color-magnitude diagrams (CMDs) utilizing photometry data and bolometric correction tables. It supports multiple methods for fitting, can accept various filters, and allows for the generation of plots to visualize the fitting process. The script relies on external libraries for loading isochrone data and performing the optimization process. It saves the results in a Pickle file format, including the best fit results and processed photometry data. This can be used in astrophysical research to model stellar populations based on observational data. from fidanka.isofit.fit import optimize, MC_optimize from isochrones import load_ISO_CMDs, interCMDatMag, interp_isochrone_age import pickle as pkl import os import shutil from tqdm import tqdm import re PHOT_ROOT = "../../photometry/HUGS/ngc2808" ISO_ROOT = "../../outputs.denseAlpha.fixedLowmass" def order_best_fit_result(optimizationResults): comparison = {'A': list(), 'E': list()} for pop, popD in optimizationResults.items(): for Y, YD in popD.items(): for a, aD in YD.items(): comparison[pop].append((aD['opt']['fun'], aD['opt']['x'], pop, Y, a)) comparison[pop] = sorted(comparison[pop], key=lambda x: x[0]) return comparison if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Fit an isochrones to a CMD") method = parser.add_mutually_exclusive_group(required=True) method.add_argument("--meth1", help="Use HUGS Method 1", action='store_true') method.add_argument("--meth2", help="Use HUGS Method 2", action='store_true') method.add_argument("--meth3", help="Use HUGS Method 3", action='store_true') parser.add_argument("--fLines", help="Fiducial piclke file", default="Fiducial.pkl") parser.add_argument("--filter1", help="Magnitude filter", default="F606W") parser.add_argument("--filter2", help="Second Color Filter", default="F814W") parser.add_argument("--rFilterOrder", action="store_true", help="flip which filter in the color is the magnitude axis") parser.add_argument("--verbosePlotting", action="store_true", help="Write out a lot of plots") parser.add_argument("-o", "--output", type=str, default="OptResult.pkl", help="Where to save Pickle File") parser.add_argument("--bTabs", type=str, help="Root paths to the bolometric correction tables") args = parser.parse_args() if args.rFilterOrder: f3 = args.filter2 else: f3 = args.filter1 f1 = args.filter1 f2 = args.filter2 assert os.path.exists(args.bTabs), "Bolometric Correction Table Path does not exist" bolFilenames = list(filter(lambda x: re.search("feh[mp]\d+", x), os.listdir(args.bTabs))) bolPaths = list(map(lambda x: os.path.join(args.bTabs, x), bolFilenames)) with open(os.path.join(PHOT_ROOT, "photometry.pkl"), 'rb') as f: photometry = pkl.load(f) if args.meth1: methID = 1 elif args.meth2: methID = 2 elif args.meth3: methID = 3 else: raise RuntimeError("Something Horrid has gone wrong! You should re-evalute the choices which lead you here...") cleanedPhot = photometry[methID] with open(args.fLines, 'rb') as f: fiducialSequences = pkl.load(f) fiducialSequences[0].name = "A" fiducialSequences[1].name = "E" fiducialLookup = dict() print(fiducialSequences) for i, fid in enumerate(fiducialSequences): fiducialLookup[fid.name] = i ISOs, FeHs = load_ISO_CMDs(ISO_ROOT) results = dict() popFid = None for population, popISO in tqdm(ISOs.items(), total=len(ISOs), leave=False): results[population] = dict() assert population in fiducialLookup.keys() if population == "A": popFid = fiducialSequences[fiducialLookup['A']] if population == "E": popFid = fiducialSequences[fiducialLookup['E']] for Y, YISO in tqdm(popISO.items(), total=len(popISO), leave=False): results[population][Y] = dict() for a, alphaISO in tqdm(YISO.items(), total=len(YISO), leave=False): FeH = FeHs[population][Y][a] print(f"Working on {population} {Y} {a} {FeH}") if os.path.exists(f"testFigures/{population}_{Y}_{a}"): shutil.rmtree(f"testFigures/{population}_{Y}_{a}") os.mkdir(f"testFigures/{population}_{Y}_{a}") results[population][Y][a] = optimize( popFid.mean, alphaISO, (f1, f2, f3), bolPaths, FeH, figDir=f"{population}_{Y}_{a}",) orderedOptimizationResults = order_best_fit_result(results) with open(args.output, 'wb') as f: pkl.dump({'bf': orderedOptimizationResults, 'r': results, 'phot': cleanedPhot}, f)