def check_high_t(T=6000, metal=0.0, vsini=10): filenames = [f for f in os.listdir("./") if f.endswith("smoothed.fits") and f.startswith("H")] corrdir = "Cross_correlations/" logg = 4.5 HelperFunctions.ensure_dir("Figures/") for rootfile in sorted(filenames): corrfile = "{0:s}{1:s}.{2:d}kps_{3:.1f}K{4:+.1f}{5:+.1f}".format(corrdir, rootfile.split(".fits")[0], vsini, T, logg, metal) print corrfile try: vel, corr = np.loadtxt(corrfile, unpack=True) except IOError: continue plt.plot(vel, corr, 'k-') plt.xlabel("Velocity") plt.ylabel("CCF") plt.title(rootfile.split(".fits")[0]) plt.show()
spt_full = data.SpectralType().split()[0] spt = spt_full[0] + re.search(r'\d*\.?\d*', spt_full[1:]).group() d = {'Object': object, 'plx': plx, 'SpT': spt, 'exptime': header['exptime']} return d if __name__ == '__main__': scale = True early, late = parse_input(sys.argv[1:]) # Add each late file to all of the early-type files HelperFunctions.ensure_dir('GeneratedObservations') for late_file in late: for early_file in early: outfilename = 'GeneratedObservations/{}_{}.fits'.format(early_file.split('/')[-1].split( '.fits')[0], late_file.split('/')[-1].split('.fits')[0]) if scale: outfilename = outfilename.replace('.fits', '_scalex10.fits') if outfilename.split('/')[-1] in os.listdir('GeneratedObservations/'): print "File already generated. Skipping {}".format(outfilename) continue total, early_dict, late_dict = combine(early_file, late_file, increase_scale=scale) # Prepare for output column_list = [] for order in total:
def check_all(): filenames = [f for f in os.listdir("./") if f.endswith("smoothed.fits") and f.startswith("H")] corrdir = "Cross_correlations/" vsini_values = [1, 10, 20, 30, 40] Temperatures = [3300, 3500, 3700, 3900, 4200, 4500, 5000, 5500] Temperatures = range(3000, 6800, 100) metals = [-0.5, 0.0, 0.5] logg = 4.5 HelperFunctions.ensure_dir("Figures/") for rootfile in sorted(filenames): Tvals = [] Zvals = [] rotvals = [] significance = [] corrval = [] for T in Temperatures: for metal in metals: for vsini in vsini_values: corrfile = "{0:s}{1:s}.{2:d}kps_{3:.1f}K{4:+.1f}{5:+.1f}".format(corrdir, rootfile.split(".fits")[0], vsini, T, logg, metal) print corrfile try: vel, corr = np.loadtxt(corrfile, unpack=True) except IOError: continue # Check the significance of the highest peak within +/- 500 km/s left = np.searchsorted(vel, -500) right = np.searchsorted(vel, 500) idx = np.argmax(corr[left:right]) + left v = vel[idx] goodindices = np.where(np.abs(vel - v) > vsini)[0] std = np.std(corr[goodindices]) mean = np.mean(corr[goodindices]) mean = np.median(corr) mad = HelperFunctions.mad(corr) std = 1.4826 * mad sigma = (corr[idx] - mean) / std """ # Plot if > 3 sigma peak if sigma > 4: fig = plt.figure(10) ax = fig.add_subplot(111) ax.plot(vel, corr, 'k-', lw=2) ax.set_xlabel("Velocity (km/s)") ax.set_ylabel("CCF") ax.set_title(r'{0:s}: $T_s$={1:d}K & [Fe/H]={2:.1f}'.format(rootfile, T, metal)) ax.grid(True) fig.savefig(u"Figures/{0:s}.pdf".format(corrfile.split("/")[-1])) plt.close(fig) """ Tvals.append(T) Zvals.append(metal) rotvals.append(vsini) significance.append(sigma) corrval.append(corr[idx] - np.median(corr)) # Now, make a plot of the significance as a function of Temperature and metallicity for each vsini Tvals = np.array(Tvals) Zvals = np.array(Zvals) rotvals = np.array(rotvals) significance = np.array(significance) corrval = np.array(corrval) fig = plt.figure(1) ax = fig.add_subplot(111, projection='3d') ax.set_title("Significance Summary for %s" % (rootfile.split(".fits")[0].replace("_", " "))) for i, rot in enumerate(vsini_values): goodindices = np.where(abs(rotvals - rot) < 1e-5)[0] ax.set_xlabel("Temperature (K)") ax.set_ylabel("[Fe/H]") ax.set_zlabel("Significance") ax.plot(Tvals[goodindices], Zvals[goodindices], significance[goodindices], 'o', label="%i km/s" % rot) #ax.plot(Tvals[goodindices], Zvals[goodindices], corrval[goodindices], 'o', label="{0:d} km/s".format(rot)) leg = ax.legend(loc='best', fancybox=True) leg.get_frame().set_alpha(0.5) fig.savefig("Figures/Summary_{0:s}.pdf".format(rootfile.split(".fits")[0])) idx = np.argmax(significance) #ax.plot(Tvals[idx], Zvals[idx], significance[idx], 'x', markersize=25, label="Most Significant") print os.getcwd() plt.show()
import numpy as np import DataStructures import HelperFunctions from PlotBlackbodies import Planck import Normalized_Xcorr currentdir = os.getcwd() + "/" homedir = os.environ["HOME"] outfiledir = currentdir + "Cross_correlations/" modeldir = homedir + "/School/Research/Models/Sorted/Stellar/Vband/" minvel = -1000 # Minimum velocity to output, in km/s maxvel = 1000 HelperFunctions.ensure_dir(outfiledir) model_list = [modeldir + "lte30-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte31-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte32-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte33-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte34-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte35-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte36-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte37-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte38-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte39-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte40-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte42-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte43-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted", modeldir + "lte44-4.00-0.0.AGS.Cond.PHOENIX-ACES-2009.HighRes.7.sorted",
matplotlib.use("tkagg") import matplotlib.pyplot as plt import numpy as np import HelperFunctions if __name__ == "__main__": filenames = [f for f in os.listdir("./") if f.endswith("smoothed.fits") and f.startswith("H")] corrdir = "Cross_correlations/" vsini_values = [1, 10, 20, 30, 40] Temperatures = [3300, 3500, 3700, 3900, 4200, 4500, 5000, 5500] Temperatures = range(3000, 6800, 100) metals = [-0.5, 0.0, 0.5] logg = 4.5 HelperFunctions.ensure_dir("Figures/") for rootfile in sorted(filenames): Tvals = [] Zvals = [] rotvals = [] significance = [] for T in Temperatures: for metal in metals: for vsini in vsini_values: corrfile = "{0:s}{1:s}.{2:d}kps_{3:.1f}K{4:+.1f}{5:+.1f}".format(corrdir, rootfile.split(".fits")[0], vsini, T, logg, metal)
plt.show() # Get instrument name from the header header = fits.getheader(fname) observatory = header["OBSERVAT"] if "ctio" in observatory.lower(): instrument = "CHIRON" star = header["OBJECT"].replace(" ", "") else: instrument = header["INSTRUME"] if "ts23" in instrument.lower(): instrument = "TS23" star = header["OBJECT"].replace(" ", "") elif "hrs" in instrument.lower(): instrument = "HRS" star = header["OBJECT"].split()[0].replace("_", "") else: raise ValueError("Unknown instrument: %s" % instrument) outfilename = "%s/%s/%s/%s.txt" % (outdir, instrument, star, star) print outfilename HelperFunctions.ensure_dir(outfilename) np.savetxt(outfilename, np.transpose((output.x * 10.0, output.y))) # for i, order in enumerate(orders): # outfilename = "%s/%s/%s/order%i.txt" %(outdir, instrument, star, i+1) # np.savetxt(outfilename, np.transpose((order.x*10.0, order.y/order.cont)))
tellurics = False trimsize = 1 windowsize = 101 MS = SpectralTypeRelations.MainSequence() PMS = SpectralTypeRelations.PreMainSequence() vel_list = range(-400, 400, 50) outdir = "Sensitivity/" for arg in sys.argv[1:]: if "-e" in arg: extensions = False if "-t" in arg: tellurics = True #telluric lines modeled but not removed else: fileList.append(arg) HelperFunctions.ensure_dir(outdir) outfile = open(outdir + "logfile.dat", "w") outfile.write("Sensitivity Analysis:\n*****************************\n\n") outfile.write( "Filename\t\t\tPrimary Temperature\tSecondary Temperature\tMass (Msun)\tMass Ratio\tVelocity\tPeak Correct?\tSignificance\n") for fname in fileList: if extensions: orders_original = HelperFunctions.ReadFits(fname, extensions=extensions, x="wavelength", y="flux", errors="error") if tellurics: model_orders = HelperFunctions.ReadFits(fname, extensions=extensions, x="wavelength", y="model") for i, order in enumerate(orders_original): orders_original[i].cont = FindContinuum.Continuum(order.x, order.y, lowreject=2, highreject=2) orders_original[i].y /= model_orders[i].y
def slow_companion_search(fileList, primary_vsini, badregions=[], interp_regions=[], extensions=True, resolution=None, trimsize=1, reject_outliers=True, vsini_values=(10, 20, 30, 40), Tvalues=range(3000, 6900, 100), metal_values=(-0.5, 0.0, +0.5), logg_values=(4.5,), modeldir=StellarModel.modeldir, hdf5_file=StellarModel.HDF5_FILE, vbary_correct=True, observatory="CTIO", addmode="ML", output_mode='text', output_file='CCF.hdf5', obstype='real', min_x=None, max_x=None, debug=False, makeplots=False): """ This function runs a companion search, but makes a new model for each file. That is necessary because it subtracts the 'smoothed' model from the model spectrum before correlating :param fileList: The list of fits data files :param primary_vsini: A list of the same length as fileList, which contains the vsini for each star (in km/s) :param badregions: A list of wavelength regions to ignore in the CCF (contaminated by tellurics, etc) :param interp_regions: A list of wavelength regions to interpolate over in the data. Generally, badregions should be on the edge of the orders or contain the whole order, and interp_regions should contain a small wavelength range. :param resolution: The detector resolution in lam/dlam. The default is now to use a pre-broadened grid; do not give a value for resolution unless the grid is un-broadened! :param trimsize: The number of pixels to cut from both sides of each order. This is because the order edges are usually pretty noisy. :param reject_outliers: Whether or not to detect and smooth over outliers in the data. :param vsini_values: A list of vsini values (in km/s) to apply to each model spectrum before correlation. :param Tvalues: A list of model temperatures (in K) to correlate the data against. :param metal_values: A list of [Fe/H] values to correlate the model against :param logg_values: A list of log(g) values (in cgs units) to correlate the model against :param modeldir: The model directory. This is no longer used by default! :param hdf5_file: The path to the hdf5 file containing the pre-broadened model grid. :param vbary_correct: Correct for the heliocentric motion of the Earth around the Sun? :param observatory: The name of the observatory, in a way that IRAF's rvcorrect will understand. Only needed if vbary_correct = True :param addmode: The way to add the CCFs for each order. Options are: 1: 'simple': Do a simple average 2: 'weighted': Do a weighted average: $C = \sum_i{w_i C_i^2}$ where $w_i$ is the line depth of the each pixel 3: 'simple-weighted': Same as weighted, but without squaring the CCFs: $C = \sum_i{w_i C_i}$ 4: 'T-weighted': Do a weighted average: $C = \sum_i{w_i C_i}$ where $w_i$ is how fast each pixel changes with temperature 5: 'dc': $C = \sum_i{C_i^2}$ (basically, weighting by the CCF itself) 6: 'ml': The maximum likelihood estimate. See Zucker 2003, MNRAS, 342, 1291 7: 'all': does simple, dc, and ml all at once. :param output_mode: How to output. Valid options are: 1: text, which is just ascii data with a filename convention. This is the default option 2: hdf5, which ouputs a single hdf5 file with all the metadata necessary to classify the output :param output_file: An HDF5 file to output to. Only used if output_mode = 'hdf5' :param obstype: Is this a synthetic binary star or real observation? (default is real) :param min_x: The minimum wavelength to use in the model. If not given, the whole model will be used :param max_x: The maximum wavelength to use in the model. If not given, the whole model will be used :param debug: Flag to print a bunch of information to screen, and save some intermediate data files :param makeplots: A 'higher level' of debug. Will make a plot of the data and model orders for each model. """ # Make sure the temperature, metal, and logg are all at least 1d arrays. Tvalues = np.atleast_1d(Tvalues) metal_values = np.atleast_1d(metal_values) logg_values = np.atleast_1d(logg_values) model_list = StellarModel.GetModelList(type='hdf5', hdf5_file=hdf5_file, temperature=Tvalues, metal=metal_values, logg=logg_values) if addmode.lower() == 't-weighted': modeldict, processed, sensitivity = StellarModel.MakeModelDicts(model_list, type='hdf5', hdf5_file=hdf5_file, vsini_values=vsini_values, vac2air=True, logspace=True, get_T_sens=True) else: modeldict, processed = StellarModel.MakeModelDicts(model_list, type='hdf5', hdf5_file=hdf5_file, vsini_values=vsini_values, vac2air=True, logspace=True) sensitivity = None get_weights = True if addmode.lower() == "weighted" or addmode.lower() == 'simple-weighted' else False orderweights = None MS = SpectralTypeRelations.MainSequence() # Do the cross-correlation datadict = defaultdict(list) temperature_dict = defaultdict(float) vbary_dict = defaultdict(float) alpha = 0.0 for temp in sorted(modeldict.keys()): for gravity in sorted(modeldict[temp].keys()): for metallicity in sorted(modeldict[temp][gravity].keys()): for vsini_sec in vsini_values: if debug: logging.info('T: {}, logg: {}, [Fe/H]: {}, vsini: {}'.format(temp, gravity, metallicity, vsini_sec)) # broaden the model model = modeldict[temp][gravity][metallicity][alpha][vsini_sec].copy() l_idx = 0 if min_x is None else np.searchsorted(model.x, min_x) r_idx = model.size() if max_x is None else np.searchsorted(model.x, max_x) model = Broaden.RotBroad(model[l_idx:r_idx], vsini_sec * u.km.to(u.cm), linear=True) if resolution is not None: model = FittingUtilities.ReduceResolutionFFT(model, resolution) # Interpolate the temperature weights, if addmode='T-weighted' if addmode.lower() == 't-weighted': x = modeldict[temp][gravity][metallicity][alpha][vsini_sec].x y = sensitivity[temp][gravity][metallicity][alpha][vsini_sec] temperature_weights = spline(x, y) for i, (fname, vsini_prim) in enumerate(zip(fileList, primary_vsini)): if vbary_correct: if fname in vbary_dict: vbary = vbary_dict[fname] else: vbary = HelCorr_IRAF(fits.getheader(fname), observatory=observatory) vbary_dict[fname] = vbary process_data = False if fname in datadict else True if process_data: orders = Process_Data(fname, badregions, interp_regions=interp_regions, logspacing=True, extensions=extensions, trimsize=trimsize, vsini=vsini_prim, reject_outliers=reject_outliers) header = fits.getheader(fname) try: spt = StarData.GetData(header['object']).spectype if spt == 'Unknown': temperature_dict[fname] = np.nan # Unknown logging.warning('Spectral type retrieval from simbad failed! Entering NaN for primary temperature!') else: match = re.search('[0-9]', spt) if match is None: spt = spt[0] + "5" else: spt = spt[:match.start() + 1] temperature_dict[fname] = MS.Interpolate(MS.Temperature, spt) except AttributeError: temperature_dict[fname] = np.nan # Unknown logging.warning('Spectral type retrieval from simbad failed! Entering NaN for primary temperature!') datadict[fname] = orders else: orders = datadict[fname] # Now, process the model model_orders = process_model(model.copy(), orders, vsini_primary=vsini_prim, maxvel=1000.0, debug=debug, oversample=1, logspace=False) # Get order weights if addmode='T-weighted' if addmode.lower() == 't-weighted': get_weights = False orderweights = [np.sum(temperature_weights(o.x)) for o in orders] addmode = 'simple-weighted' if debug and makeplots: fig = plt.figure('T={} vsini={}'.format(temp, vsini_sec)) for o, m in zip(orders, model_orders): d_scale = np.std(o.y/o.cont) m_scale = np.std(m.y/m.cont) plt.plot(o.x, (o.y/o.cont-1.0)/d_scale, 'k-', alpha=0.4) plt.plot(m.x, (m.y/m.cont-1.0)/m_scale, 'r-', alpha=0.6) plt.show(block=False) # Make sure the output directory exists output_dir = "Cross_correlations/" outfilebase = fname.split(".fits")[0] if "/" in fname: dirs = fname.split("/") outfilebase = dirs[-1].split(".fits")[0] if obstype.lower() == 'synthetic': output_dir = "" for directory in dirs[:-1]: output_dir = output_dir + directory + "/" output_dir = output_dir + "Cross_correlations/" HelperFunctions.ensure_dir(output_dir) # Save the model and data orders, if debug=True if debug: # Save the individual spectral inputs and CCF orders (unweighted) output_dir2 = output_dir.replace("Cross_correlations", "CCF_inputs") HelperFunctions.ensure_dir(output_dir2) HelperFunctions.ensure_dir("%sCross_correlations/" % (output_dir2)) for i, (o, m) in enumerate(zip(orders, model_orders)): outfilename = "{0:s}{1:s}.{2:.0f}kps_{3:.1f}K{4:+.1f}{5:+.1f}.data.order{6:d}".format( output_dir2, outfilebase, vsini_sec, temp, gravity, metallicity, i + 1) o.output(outfilename) outfilename = "{0:s}{1:s}.{2:.0f}kps_{3:.1f}K{4:+.1f}{5:+.1f}.model.order{6:d}".format( output_dir2, outfilebase, vsini_sec, temp, gravity, metallicity, i + 1) m.output(outfilename) corr = Correlate.Correlate(orders, model_orders, addmode=addmode, outputdir=output_dir, get_weights=get_weights, prim_teff=temperature_dict[fname], orderweights=orderweights, debug=debug) if debug: corr, ccf_orders = corr # Barycentric correction if vbary_correct: corr.x += vbary # Output the ccf if obstype.lower() == 'synthetic': pars = {'outdir': output_dir, 'outbase': outfilebase, 'addmode': addmode, 'vsini_prim': vsini_prim, 'vsini': vsini_sec, 'T': temp, 'logg': gravity, '[Fe/H]': metallicity} save_synthetic_ccf(corr, params=pars, mode=output_mode) else: pars = {'outdir': output_dir, 'fname': fname, 'addmode': addmode, 'vsini_prim': vsini_prim, 'vsini': vsini_sec, 'T': temp, 'logg': gravity, '[Fe/H]': metallicity} pars['vbary'] = vbary if vbary_correct else np.nan save_ccf(corr, params=pars, mode=output_mode, hdf_outfilename=output_file) # Save the individual orders, if debug=True if debug: for i, c in enumerate(ccf_orders): print "Saving CCF inputs for order {}".format(i + 1) outfilename = "{0:s}Cross_correlations/{1:s}.{2:.0f}kps_{3:.1f}K{4:+.1f}{5:+.1f}.order{6:d}".format( output_dir2, outfilebase, vsini_sec, temp, gravity, metallicity, i + 1) c.output(outfilename) # Delete the model. We don't need it anymore and it just takes up ram. modeldict[temp][gravity][metallicity][alpha][vsini_sec] = [] return
def CompanionSearch(fileList, badregions=[], interp_regions=[], extensions=True, resolution=60000, trimsize=1, vsini_values=(10, 20, 30, 40), Tvalues=range(3000, 6900, 100), metal_values=(-0.5, 0.0, +0.5), logg_values=(4.5,), modeldir=StellarModel.modeldir, hdf5_file=StellarModel.HDF5_FILE, vbary_correct=True, observatory="CTIO", addmode="ML", debug=False): model_list = StellarModel.GetModelList(type='hdf5', hdf5_file=hdf5_file, temperature=Tvalues, metal=metal_values, logg=logg_values) modeldict, processed = StellarModel.MakeModelDicts(model_list, type='hdf5', hdf5_file=hdf5_file, vsini_values=vsini_values, vac2air=True) get_weights = True if addmode.lower() == "weighted" else False orderweights = None MS = SpectralTypeRelations.MainSequence() # Do the cross-correlation datadict = defaultdict(list) temperature_dict = defaultdict(float) vbary_dict = defaultdict(float) alpha=0.0 for temp in sorted(modeldict.keys()): for gravity in sorted(modeldict[temp].keys()): for metallicity in sorted(modeldict[temp][gravity].keys()): for vsini in vsini_values: for fname in fileList: if vbary_correct: if fname in vbary_dict: vbary = vbary_dict[fname] else: vbary = HelCorr_IRAF(fits.getheader(fname), observatory=observatory) vbary_dict[fname] = vbary process_data = False if fname in datadict else True if process_data: orders = Process_Data(fname, badregions, interp_regions=interp_regions, extensions=extensions, trimsize=trimsize) header = fits.getheader(fname) spt = StarData.GetData(header['object']).spectype match = re.search('[0-9]', spt) if match is None: spt = spt[0] + "5" else: spt = spt[:match.start() + 1] temperature_dict[fname] = MS.Interpolate(MS.Temperature, spt) else: orders = datadict[fname] output_dir = "Cross_correlations/" outfilebase = fname.split(".fits")[0] if "/" in fname: dirs = fname.split("/") output_dir = "" outfilebase = dirs[-1].split(".fits")[0] for directory in dirs[:-1]: output_dir = output_dir + directory + "/" output_dir = output_dir + "Cross_correlations/" HelperFunctions.ensure_dir(output_dir) model = modeldict[temp][gravity][metallicity][alpha][vsini] pflag = not processed[temp][gravity][metallicity][alpha][vsini] # if pflag: # orderweights = None retdict = Correlate.GetCCF(orders, model, resolution=resolution, vsini=vsini, rebin_data=process_data, process_model=pflag, debug=debug, outputdir=output_dir.split("Cross_corr")[0], addmode=addmode, orderweights=orderweights, get_weights=get_weights, prim_teff=temperature_dict[fname]) corr = retdict["CCF"] if pflag: processed[temp][gravity][metallicity][alpha][vsini] = True modeldict[temp][gravity][metallicity][alpha][vsini] = retdict["model"] # orderweights = retdict['weights'] if process_data: datadict[fname] = retdict['data'] outfilename = "{0:s}{1:s}.{2:.0f}kps_{3:.1f}K{4:+.1f}{5:+.1f}".format(output_dir, outfilebase, vsini, temp, gravity, metallicity) print "Outputting to ", outfilename, "\n" if vbary_correct: corr.x += vbary np.savetxt(outfilename, np.transpose((corr.x, corr.y)), fmt="%.10g") if debug: # Save the individual spectral inputs and CCF orders (unweighted) output_dir2 = output_dir.replace("Cross_correlations", "CCF_inputs") HelperFunctions.ensure_dir(output_dir2) HelperFunctions.ensure_dir("%sCross_correlations/" % (output_dir2)) for i, (o, m, c) in enumerate( zip(retdict['data'], retdict['model'], retdict['CCF_orders'])): print "Saving CCF inputs for order {}".format(i + 1) outfilename = "{0:s}Cross_correlations/{1:s}.{2:.0f}kps_{3:.1f}K{4:+.1f}{5:+.1f}.order{6:d}".format( output_dir2, outfilebase, vsini, temp, gravity, metallicity, i + 1) c.output(outfilename) outfilename = "{0:s}{1:s}.{2:.0f}kps_{3:.1f}K{4:+.1f}{5:+.1f}.data.order{6:d}".format( output_dir2, outfilebase, vsini, temp, gravity, metallicity, i + 1) o.output(outfilename) outfilename = "{0:s}{1:s}.{2:.0f}kps_{3:.1f}K{4:+.1f}{5:+.1f}.model.order{6:d}".format( output_dir2, outfilebase, vsini, temp, gravity, metallicity, i + 1) m.output(outfilename) # Delete the model. We don't need it anymore and it just takes up ram. modeldict[temp][gravity][metallicity][vsini] = [] return
def Fit(arguments, mg=None): # Define some constants c = constants.c good_orders = range(41) good_orders.pop(33) # Set up default values, and then read in command line arguments T_min = 9000 T_max = 9250 metal_min = -0.8 metal_max = 0.2 logg_min = 3.0 logg_max = 5.0 alpha_min = 0.0 alpha_max = 0.4 modeldir = "models/" rv = 0.0 * u.km / u.s vsini = 200.0 * u.km / u.s R = 80000.0 output_dir = "{:s}/Dropbox/School/Research/AstarStuff/Parameters/".format(os.environ['HOME']) texfile = "Parameters.tex" # Put in output_dir after command-line arguments are parsed file_list = [] debug = False N_iter = 100 for arg in arguments: if "-temp" in arg.lower(): r = arg.partition("=")[-1] values = r.partition(",") T_min = float(values[0]) T_max = float(values[-1]) elif "-metal" in arg.lower(): r = arg.partition("=")[-1] values = r.partition(",") metal_min = float(values[0]) metal_max = float(values[-1]) elif "-logg" in arg.lower(): r = arg.partition("=")[-1] values = r.partition(",") logg_min = float(values[0]) logg_max = float(values[-1]) elif "-alpha" in arg.lower(): r = arg.partition("=")[-1] values = r.partition(",") alpha_min = float(values[0]) alpha_max = float(values[-1]) elif "-model" in arg.lower(): modeldir = arg.partition("=")[-1] if "," in modeldir: #More than one directory is given modeldir = modeldir.split(",") for m in modeldir: if not m.endswith("/"): m += "/" elif not modeldir.endswith("/"): modeldir += "/" elif "-rv" in arg.lower(): rv = float(arg.partition("=")[-1]) * u.km / u.s elif "-vsini" in arg.lower(): vsini = float(arg.partition("=")[-1]) * u.km / u.s elif "-resolution" in arg.lower(): R = float(arg.partition("=")[-1]) elif "-outdir" in arg.lower(): output_dir = arg.partition("=")[-1] if not output_dir.endswith("/"): output_dir += "/" elif "-texfile" in arg.lower(): texfile = arg.partition("=")[-1] elif "-debug" in arg.lower(): debug = True print "Debug mode ON" elif "-iteration" in arg.lower(): N_iter = int(arg.partition("=")[-1]) else: file_list.append(arg) texfile = "{:s}{:s}".format(output_dir, texfile) # Make sure files were give if len(file_list) == 0: sys.exit("Must give at least one file!") # Make guess values for each of the values from the bounds temperature = (T_min + T_max) / 2.0 logg = (logg_min + logg_max) / 2.0 metal = (metal_min + metal_max) / 2.0 alpha = (alpha_min + alpha_max) / 2.0 #Make an instance of the model getter if mg is None: mg = StellarModel.KuruczGetter(modeldir, T_min=T_min, T_max=T_max, logg_min=logg_min, logg_max=logg_max, metal_min=metal_min, metal_max=metal_max, alpha_min=alpha_min, alpha_max=alpha_max, wavemin=350.0) # Make the appropriate lmfit model fitter = HelperFunctions.ListModel(LM_Model, independent_vars=['x'], model_getter=mg) #Set default values fitter.set_param_hint("rv", value=rv.value, min=-50, max=50) fitter.set_param_hint('vsini', value=vsini.value, vary=True, min=0.0, max=500.0) fitter.set_param_hint('temperature', value=temperature, min=T_min, max=T_max, vary=True) fitter.set_param_hint('logg', value=logg, min=logg_min, max=logg_max, vary=True) fitter.set_param_hint('metal', value=metal, min=metal_min, max=metal_max, vary=True) fitter.set_param_hint('alpha', value=0.0, min=alpha_min, max=alpha_max, vary=mg.alpha_varies) """ Here is the main loop over files! """ for filename in file_list: # Make output directories header = fits.getheader(filename) date = header['date-obs'].split("T")[0] star = header['object'] stardir = "{:s}{:s}/".format(output_dir, star.replace(" ", "_")) HelperFunctions.ensure_dir(stardir) datedir = "{:s}{:s}/".format(stardir, date) HelperFunctions.ensure_dir(datedir) chain_filename = "{:s}chain.dat".format(datedir) # Read the data print "Fitting parameters for {}".format(filename) all_orders = HelperFunctions.ReadExtensionFits(filename) orders = [o[1] for o in enumerate(all_orders) if o[0] in good_orders] # Perform the fit optdict = {"epsfcn": 1e-2} params = fitter.make_params() fitparams = {"rv": np.zeros(N_iter), "vsini": np.zeros(N_iter), "temperature": np.zeros(N_iter), "logg": np.zeros(N_iter), "metal": np.zeros(N_iter), "alpha": np.zeros(N_iter)} orders_original = [o.copy() for o in orders] chainfile = open(chain_filename, "a") vbary = GenericSearch.HelCorr(header, observatory="CTIO") for n in range(N_iter): print "Fitting iteration {:d}/{:d}".format(n + 1, N_iter) orders = [] for order in orders_original: o = order.copy() o.y += np.random.normal(loc=0, scale=o.err) orders.append(o.copy()) # Make a fast interpolator instance if not the first loop #if n > 0: # fast_interpolator = mg.make_vsini_interpolator() # result = fitter.fit(orders, fit_kws=optdict, params=params, first_interpolator=fast_interpolator) #else: # result = fitter.fit(orders, fit_kws=optdict, params=params) result = fitter.fit(orders, fit_kws=optdict, params=params) result.best_values['rv'] += vbary if debug: print "\n********** Best values ************" for key in fitparams.keys(): fitparams[key][n] = result.best_values[key] chainfile.write("{:g}\t".format(result.best_values[key])) if debug: print key, ': ', result.best_values[key] print "\n\n" chainfile.write("\n") chainfile.close() # Save the fitted parameters texlog = open(texfile, "a") texlog.write("{:s} & {:s}".format(star, date)) print "\n\nBest-fit parameters:\n=================================" if mg.alpha_varies: keys = ['rv', 'temperature', 'metal', 'vsini', 'logg', 'alpha'] else: keys = ['rv', 'temperature', 'metal', 'vsini', 'logg'] for key in keys: low, med, up = np.percentile(fitparams[key], [16, 50, 84]) up_err = up - med low_err = med - low # Get significant digits dist = max(-int(floor(np.log10(up_err))), -int(floor(np.log10(low_err)))) med = round(med, dist) up_err = round(up_err, dist + 1) low_err = round(low_err, dist + 1) print "{:s} = {:g} + {:g} / - {:g}".format(key, med, up_err, low_err) texlog.write(" & $%g^{+ %g}_{- %g}$" % (med, up_err, low_err)) if not mg.alpha_varies: texlog.write(" & $0.0^{+0.0}_{-0.0}$") texlog.write(" \\\\ \n") # Save a corner plot of the fitted results chain = np.vstack([fitparams[key] for key in fitparams.keys()]).T fig, axes = plt.subplots(len(fitparams), len(fitparams), figsize=(10, 10)) labeldict = {'rv': '$ \\rm rv$ $ \\rm (km \\cdot s^{-1}$)', 'vsini': '$ \\rm v \sin{i}$ $ \\rm (km s^{-1}$)', 'temperature': '$ \\rm T_{\\rm eff}$ $\\rm (K)$', 'logg': '$\log{g}$', 'metal': '$\\rm [Fe/H]$', 'alpha': '$\\rm [\\alpha/Fe]$'} names = [labeldict[key] for key in fitparams.keys()] try: triangle.corner(chain, labels=names, fig=fig) plt.savefig("{:s}corner_plot.pdf".format(datedir)) except AttributeError: print "Could not save the corner plot!" print "Done with file {:s}\n\n\n".format(filename)