def optimize_Cheb(self, *args): ''' Keeping the current Theta parameters fixed and assuming white noise, optimize the Chebyshev parameters ''' # self.fix_c0 = True if index == (len(DataSpectrum.wls) - 1) else False #Fix the last c0 # This is necessary if we want to update just a single order. if self.chebyshevSpectrum.fix_c0 & len(self.dataSpectrum.wls) > 1: p0 = np.zeros((self.npoly - 1)) else: self.chebyshevSpectrum.fix_c0 = False p0 = np.zeros((self.npoly)) def fprob(p): self.chebyshevSpectrum.update(p) lnp = self.evaluate() print(self.order, p, lnp) if lnp == -np.inf: return 1e99 else: return -lnp from scipy.optimize import fmin result = fmin(fprob, p0, maxiter=10000, maxfun=10000) print(self.order, result) # Due to a JSON bug, np.int64 type objects will get read twice, # and cause this routine to fail. Therefore we have to be careful # to convert these to ints. phi = PhiParam(spectrum_id=int(self.spectrum_id), order=int(self.order), fix_c0=self.chebyshevSpectrum.fix_c0, cheb=result) phi.save()
def optimize_Cheb(self, *args): ''' Keeping the current Theta parameters fixed and assuming white noise, optimize the Chebyshev parameters ''' if self.chebyshevSpectrum.fix_c0: p0 = np.zeros((self.npoly - 1)) self.fix_c0 = True else: p0 = np.zeros((self.npoly)) self.fix_c0 = False def fprob(p): self.chebyshevSpectrum.update(p) lnp = self.evaluate() print(self.order, p, lnp) if lnp == -np.inf: return 1e99 else: return -lnp from scipy.optimize import fmin result = fmin(fprob, p0, maxiter=10000, maxfun=10000) print(self.order, result) # Due to a JSON bug, np.int64 type objects will get read twice, # and cause this routine to fail. Therefore we have to be careful # to convert these to ints. phi = PhiParam(spectrum_id=int(self.spectrum_id), order=int(self.order), fix_c0=self.chebyshevSpectrum.fix_c0, cheb=result) phi.save()
def setup_class(self): self.phiparam = PhiParam(spectrum_id=0, order=22, fix_c0=True, cheb=np.zeros((4, )), sigAmp=1.0, logAmp=-5.0, l=20., regions=np.ones((4, 3)))
def initialize(self, key): super().initialize(key) # for now, just use white noise self.data_mat = self.sigma_mat.copy() self.data_mat_last = self.data_mat.copy() #Set up p0 and the independent sampler fname = Starfish.specfmt.format(self.spectrum_id, self.order) + "phi.json" phi = PhiParam.load(fname) self.p0 = phi.cheb cov = np.diag(Starfish.config["cheb_jump"]**2 * np.ones(len(self.p0))) def lnfunc(p): # turn this into pars self.update_Phi(p) lnp = self.evaluate() self.logger.debug("Evaluated Phi parameters: {} {}".format(p, lnp)) return lnp def rejectfn(): self.logger.debug("Calling Phi revertfn.") self.revert_Phi() self.sampler = StateSampler(lnfunc, self.p0, cov, query_lnprob=self.get_lnprob, rejectfn=rejectfn, debug=True)
def initialize(self, key): # Run through the standard initialization super().initialize(key) # for now, start with white noise self.data_mat = self.sigma_mat.copy() self.data_mat_last = self.data_mat.copy() #Set up p0 and the independent sampler fname = Starfish.specfmt.format(self.spectrum_id, self.order) + "phi.json" phi = PhiParam.load(fname) # Set the regions to None, since we don't want to include them even if they # are there phi.regions = None #Loading file that was previously output # Convert PhiParam object to an array self.p0 = phi.toarray() jump = Starfish.config["Phi_jump"] cheb_len = (self.npoly - 1) if self.chebyshevSpectrum.fix_c0 else self.npoly cov_arr = np.concatenate((Starfish.config["cheb_jump"]**2 * np.ones((cheb_len,)), np.array([jump["sigAmp"], jump["logAmp"], jump["l"]])**2 )) cov = np.diag(cov_arr) def lnfunc(p): # Convert p array into a PhiParam object ind = self.npoly if self.chebyshevSpectrum.fix_c0: ind -= 1 cheb = p[0:ind] sigAmp = p[ind] ind+=1 logAmp = p[ind] ind+=1 l = p[ind] par = PhiParam(self.spectrum_id, self.order, self.chebyshevSpectrum.fix_c0, cheb, sigAmp, logAmp, l) self.update_Phi(par) # sigAmp must be positive (this is effectively a prior) # See https://github.com/iancze/Starfish/issues/26 if not (0.0 < sigAmp): self.lnprob_last = self.lnprob lnp = -np.inf self.logger.debug("sigAmp was negative, returning -np.inf") self.lnprob = lnp # Same behavior as self.evaluate() else: lnp = self.evaluate() self.logger.debug("Evaluated Phi parameters: {} {}".format(par, lnp)) return lnp def rejectfn(): self.logger.debug("Calling Phi revertfn.") self.revert_Phi() self.sampler = StateSampler(lnfunc, self.p0, cov, query_lnprob=self.get_lnprob, rejectfn=rejectfn, debug=True)
def lnfunc(p): # Convert p array into a PhiParam object ind = self.npoly #if self.chebyshevSpectrum.fix_c0: # ind -= 1 ind=0 #cheb = p[0:ind] cheb = [0, 0, 0] sigAmp = p[ind] ind+=1 logAmp = p[ind] ind+=1 l = p[ind] par = PhiParam(self.spectrum_id, self.order, self.chebyshevSpectrum.fix_c0, cheb, sigAmp, logAmp, l) self.update_Phi(par) # sigAmp must be positive (this is effectively a prior) # See https://github.com/iancze/Starfish/issues/26 if not (0.0 < sigAmp): self.lnprob_last = self.lnprob lnp = -np.inf self.logger.debug("sigAmp was negative, returning -np.inf") self.lnprob = lnp # Same behavior as self.evaluate() else: lnp = self.evaluate() self.logger.debug("Evaluated Phi parameters: {} {}".format(par, lnp)) return lnp
def lnprob_all(p): pars1 = ThetaParam(grid=p[0:2], vz=p[2], vsini=p[3], logOmega=p[4]) model.update_Theta(pars1) # hard code npoly=3 (for fixc0 = True with npoly=4) pars2 = PhiParam(0, 0, True, p[5:8], p[8], p[9], p[10]) model.update_Phi(pars2) draw = model.draw_save() return draw
class TestPhiParam: def setup_class(self): self.phiparam = PhiParam(spectrum_id=0, order=22, fix_c0=True, cheb=np.zeros((4,)), sigAmp=1.0, logAmp=-5.0, l=20., regions=np.ones((4, 3))) def test_save(self): self.phiparam.save(fname="phi_test.json") def test_load(self): load = PhiParam.load(Starfish.specfmt.format(0, 22) + "phi_test.json") print(load.spectrum_id) print(load.order) print(load.fix_c0) print(load.cheb) print(load.sigAmp) print(load.logAmp) print(load.l) print(load.regions)
def test_load(self): load = PhiParam.load(Starfish.specfmt.format(0, 22) + "phi_test.json") print(load.spectrum_id) print(load.order) print(load.fix_c0) print(load.cheb) print(load.sigAmp) print(load.logAmp) print(load.l) print(load.regions)
def lnlike(p): try: pars1 = ThetaParam(grid=p[0:2], vz=p[2], vsini=p[3], logOmega=p[4]) model.update_Theta(pars1) # hard code npoly=3 (for fixc0 = True with chebyshev polynomials turned off) pars2 = PhiParam(0, 0, True, [0.0, 0.0, 0.0], p[5], p[6], p[7]) model.update_Phi(pars2) lnp = model.evaluate() return lnp except C.ModelError: model.logger.debug("ModelError in stellar parameters, sending back -np.inf {}".format(p)) return -np.inf
class TestPhiParam: def setup_class(self): self.phiparam = PhiParam(spectrum_id=0, order=22, fix_c0=True, cheb=np.zeros((4, )), sigAmp=1.0, logAmp=-5.0, l=20., regions=np.ones((4, 3))) def test_save(self): self.phiparam.save(fname="phi_test.json") def test_load(self): load = PhiParam.load(Starfish.specfmt.format(0, 22) + "phi_test.json") print(load.spectrum_id) print(load.order) print(load.fix_c0) print(load.cheb) print(load.sigAmp) print(load.logAmp) print(load.l) print(load.regions)
def lnfunc(p): # Convert p array into a PhiParam object ind = self.npoly if self.chebyshevSpectrum.fix_c0: ind -= 1 cheb = p[0:ind] sigAmp = p[ind] ind+=1 logAmp = p[ind] ind+=1 l = p[ind] phi = PhiParam(self.spectrum_id, self.order, self.chebyshevSpectrum.fix_c0, cheb, sigAmp, logAmp, l) self.update_Phi(phi) lnp = self.evaluate() self.logger.debug("Evaluated Phi parameters: {} {}".format(phi, lnp)) return lnp
def initialize(self, key): # Run through the standard initialization super().initialize(key) # for now, start with white noise self.data_mat = self.sigma_mat.copy() self.data_mat_last = self.data_mat.copy() #Set up p0 and the independent sampler fname = Starfish.specfmt.format(self.spectrum_id, self.order) + "phi.json" phi = PhiParam.load(fname) # print("Phi.regions", phi.regions) # import sys # sys.exit() # Get the regions matrix region_func = make_k_func_region(phi) max_r = 4.0 * np.max(phi.regions, axis=0)[2] self.region_mat = get_dense_C(self.wl, k_func=region_func, max_r=max_r) print(self.region_mat) # Then set phi to None phi.regions = None #Loading file that was previously output # Convert PhiParam object to an array self.p0 = phi.toarray() jump = Starfish.config["Phi_jump"] cheb_len = (self.npoly - 1) if self.chebyshevSpectrum.fix_c0 else self.npoly cov_arr = np.concatenate( (Starfish.config["cheb_jump"]**2 * np.ones((cheb_len, )), np.array([jump["sigAmp"], jump["logAmp"], jump["l"]])**2)) cov = np.diag(cov_arr) def lnfunc(p): # Convert p array into a PhiParam object ind = self.npoly if self.chebyshevSpectrum.fix_c0: ind -= 1 cheb = p[0:ind] sigAmp = p[ind] ind += 1 logAmp = p[ind] ind += 1 l = p[ind] phi = PhiParam(self.spectrum_id, self.order, self.chebyshevSpectrum.fix_c0, cheb, sigAmp, logAmp, l) self.update_Phi(phi) lnp = self.evaluate() self.logger.debug("Evaluated Phi parameters: {} {}".format( phi, lnp)) return lnp def rejectfn(): self.logger.debug("Calling Phi revertfn.") self.revert_Phi() self.sampler = StateSampler(lnfunc, self.p0, cov, query_lnprob=self.get_lnprob, rejectfn=rejectfn, debug=True)
except: print("Don't you want to use a user defined prior??") raise # Insert the prior here def lnprob(p): lp = lnprior(p) if not np.isfinite(lp): return -np.inf return lp + lnlike(p) import emcee start = Starfish.config["Theta"] fname = Starfish.specfmt.format(model.spectrum_id, model.order) + "phi.json" phi0 = PhiParam.load(fname) ndim, nwalkers = 8, 40 p0 = np.array(start["grid"] + [start["vz"], start["vsini"], start["logOmega"]] + [phi0.sigAmp, phi0.logAmp, phi0.l]) p0_std = [5, 0.02, 0.5, 0.5, 0.01, 0.01, 0.001, 0.5] if args.resume: p0_ball = np.load("emcee_chain.npy")[:,-1,:] else: p0_ball = emcee.utils.sample_ball(p0, p0_std, size=nwalkers) n_threads = multiprocessing.cpu_count() sampler = emcee.EnsembleSampler(nwalkers, ndim, lnprob, threads=n_threads)
def initialize(self, key): # Run through the standard initialization super().initialize(key) # for now, start with white noise self.data_mat = self.sigma_mat.copy() self.data_mat_last = self.data_mat.copy() #Set up p0 and the independent sampler fname = Starfish.specfmt.format(self.spectrum_id, self.order) + "phi.json" phi = PhiParam.load(fname) # print("Phi.regions", phi.regions) # import sys # sys.exit() # Get the regions matrix region_func = make_k_func_region(phi) max_r = 4.0 * np.max(phi.regions, axis=0)[2] self.region_mat = get_dense_C(self.wl, k_func=region_func, max_r=max_r) print(self.region_mat) # Then set phi to None phi.regions = None #Loading file that was previously output # Convert PhiParam object to an array self.p0 = phi.toarray() jump = Starfish.config["Phi_jump"] cheb_len = (self.npoly - 1) if self.chebyshevSpectrum.fix_c0 else self.npoly cov_arr = np.concatenate((Starfish.config["cheb_jump"]**2 * np.ones((cheb_len,)), np.array([jump["sigAmp"], jump["logAmp"], jump["l"]])**2 )) cov = np.diag(cov_arr) def lnfunc(p): # Convert p array into a PhiParam object ind = self.npoly if self.chebyshevSpectrum.fix_c0: ind -= 1 cheb = p[0:ind] sigAmp = p[ind] ind+=1 logAmp = p[ind] ind+=1 l = p[ind] phi = PhiParam(self.spectrum_id, self.order, self.chebyshevSpectrum.fix_c0, cheb, sigAmp, logAmp, l) self.update_Phi(phi) lnp = self.evaluate() self.logger.debug("Evaluated Phi parameters: {} {}".format(phi, lnp)) return lnp def rejectfn(): self.logger.debug("Calling Phi revertfn.") self.revert_Phi() self.sampler = StateSampler(lnfunc, self.p0, cov, query_lnprob=self.get_lnprob, rejectfn=rejectfn, debug=True)
fname = Starfish.specfmt.format(spectrum_id, order) + "regions.json" f = open(fname, "r") read = json.load(f) # read is a dictionary f.close() mus = np.array(read["mus"]) assert spectrum_id == read["spectrum_id"], "Spectrum/Order mismatch" assert order == read["order"], "Spectrum/Order mismatch" # Load the guesses for the global parameters from the .json # If the file exists, optionally initiliaze to the chebyshev values fname = Starfish.specfmt.format(spectrum_id, order) + "phi.json" try: phi = PhiParam.load(fname) except FileNotFoundError: print("No order parameter file found (e.g. sX_oXXphi.json), please run `star.py --initPhi` first.") raise # Puposely set phi.regions to none for this exercise, since we don't care about existing regions, and likely we want to overwrite them. phi.regions = None def optimize_region_residual(wl, residuals, sigma, mu): ''' Determine the optimal parameters for the line kernels by fitting a Gaussian directly to the residuals. ''' # Using sigma0, truncate the wavelength vector and residulas to include # only those portions that fall in the range [mu - sigma, mu + sigma] ind = (wl > mu - args.sigma0) & (wl < mu + args.sigma0) wl = wl[ind]
if args.initPhi: # Figure out how many models and orders we have i_last = len(Starfish.data["orders"]) - 1 for spec_id in range(len(Starfish.data["files"])): for i, order in enumerate(Starfish.data["orders"]): fix_c0 = True if i==i_last else False if fix_c0: cheb = np.zeros((Starfish.config["cheb_degree"] - 1,)) else: cheb = np.zeros((Starfish.config["cheb_degree"],)) # For each order, create a Phi with these values # Automatically reads all of the Phi parameters from config.yaml phi = PhiParam(spectrum_id=spec_id, order=int(order), fix_c0=fix_c0, cheb=cheb) # Write to CWD using predetermined format string phi.save() if args.optimize == "Cheb": model = parallel_linear.OptimizeTheta(debug=True) # Now that the different processes have been forked, initialize them pconns, cconns, ps = parallel_linear.initialize(model) # Initialize to the basics pars = ThetaParam.from_dict(Starfish.config["Theta"]) #Distribute the calculation to each process for ((spectrum_id, order_id), pconn) in pconns.items():
def initialize(self, key): ''' Initialize to the correct chunk of data (echelle order). :param key: (spectrum_id, order_key) :param type: (int, int) This method should only be called after all subprocess have been forked. ''' self.id = key spectrum_id, self.order_key = self.id # Make sure these are ints self.spectrum_id = int(spectrum_id) self.instrument = Instruments[self.spectrum_id] self.dataSpectrum = DataSpectra[self.spectrum_id] self.wl = self.dataSpectrum.wls[self.order_key] self.fl = self.dataSpectrum.fls[self.order_key] self.sigma = self.dataSpectrum.sigmas[self.order_key] self.ndata = len(self.wl) self.mask = self.dataSpectrum.masks[self.order_key] self.order = int(self.dataSpectrum.orders[self.order_key]) self.logger = logging.getLogger("{} {}".format(self.__class__.__name__, self.order)) if self.debug: self.logger.setLevel(logging.DEBUG) else: self.logger.setLevel(logging.INFO) self.logger.info("Initializing model on Spectrum {}, order {}.".format(self.spectrum_id, self.order_key)) self.npoly = Starfish.config["cheb_degree"] self.chebyshevSpectrum = ChebyshevSpectrum(self.dataSpectrum, self.order_key, npoly=self.npoly) # If the file exists, optionally initiliaze to the chebyshev values fname = Starfish.specfmt.format(self.spectrum_id, self.order) + "phi.json" if os.path.exists(fname): self.logger.debug("Loading stored Chebyshev parameters.") phi = PhiParam.load(fname) self.chebyshevSpectrum.update(phi.cheb) self.resid_deque = deque(maxlen=500) #Deque that stores the last residual spectra, for averaging self.counter = 0 self.emulator = Emulator.open() self.emulator.determine_chunk_log(self.wl) self.pca = self.emulator.pca self.wl_FFT = self.pca.wl # The raw eigenspectra and mean flux components self.EIGENSPECTRA = np.vstack((self.pca.flux_mean[np.newaxis,:], self.pca.flux_std[np.newaxis,:], self.pca.eigenspectra)) self.ss = np.fft.rfftfreq(self.pca.npix, d=self.emulator.dv) self.ss[0] = 0.01 # junk so we don't get a divide by zero error # Holders to store the convolved and resampled eigenspectra self.eigenspectra = np.empty((self.pca.m, self.ndata)) self.flux_mean = np.empty((self.ndata,)) self.flux_std = np.empty((self.ndata,)) self.sigma_mat = self.sigma**2 * np.eye(self.ndata) self.mus, self.C_GP, self.data_mat = None, None, None self.lnprior = 0.0 # Modified and set by NuisanceSampler.lnprob # self.nregions = 0 # self.exceptions = [] # Update the outdir based upon id self.noutdir = Starfish.routdir + "{}/{}/".format(self.spectrum_id, self.order)
if args.initPhi: # Figure out how many models and orders we have i_last = len(Starfish.data["orders"]) - 1 for spec_id in range(len(Starfish.data["files"])): for i, order in enumerate(Starfish.data["orders"]): fix_c0 = True if i == i_last else False if fix_c0: cheb = np.zeros((Starfish.config["cheb_degree"] - 1, )) else: cheb = np.zeros((Starfish.config["cheb_degree"], )) # For each order, create a Phi with these values # Automatically reads all of the Phi parameters from config.yaml phi = PhiParam(spectrum_id=spec_id, order=int(order), fix_c0=fix_c0, cheb=cheb) # Write to CWD using predetermined format string phi.save() if args.optimize == "Cheb": model = parallel.OptimizeCheb(debug=True) # Now that the different processes have been forked, initialize them pconns, cconns, ps = parallel.initialize(model) # Initialize to the basics pars = ThetaParam.from_dict(Starfish.config["Theta"]) #Distribute the calculation to each process
def setup_class(self): self.phiparam = PhiParam(spectrum_id=0, order=22, fix_c0=True, cheb=np.zeros((4,)), sigAmp=1.0, logAmp=-5.0, l=20., regions=np.ones((4, 3)))
def initialize(self, key): ''' Initialize to the correct chunk of data (echelle order). :param key: (spectrum_id, order_key) :param type: (int, int) This method should only be called after all subprocess have been forked. ''' self.id = key spectrum_id, self.order_key = self.id # Make sure these are ints self.spectrum_id = int(spectrum_id) self.instrument = Instruments[self.spectrum_id] self.dataSpectrum = DataSpectra[self.spectrum_id] self.wl = self.dataSpectrum.wls[self.order_key] self.fl = self.dataSpectrum.fls[self.order_key] self.sigma = self.dataSpectrum.sigmas[self.order_key] self.ndata = len(self.wl) self.mask = self.dataSpectrum.masks[self.order_key] self.order = int(self.dataSpectrum.orders[self.order_key]) self.logger = logging.getLogger("{} {}".format(self.__class__.__name__, self.order)) if self.debug: self.logger.setLevel(logging.DEBUG) else: self.logger.setLevel(logging.INFO) self.logger.info("Initializing model on Spectrum {}, order {}.".format(self.spectrum_id, self.order_key)) self.npoly = Starfish.config["cheb_degree"] self.chebyshevSpectrum = ChebyshevSpectrum(self.dataSpectrum, self.order_key, npoly=self.npoly) # If the file exists, optionally initiliaze to the chebyshev values fname = Starfish.specfmt.format(self.spectrum_id, self.order) + "phi.json" if os.path.exists(fname): self.logger.debug("Loading stored Chebyshev parameters.") phi = PhiParam.load(fname) self.chebyshevSpectrum.update(phi.cheb) #self.resid_deque = deque(maxlen=500) #Deque that stores the last residual spectra, for averaging self.counter = 0 self.emulator = Emulator.open() self.emulator.determine_chunk_log(self.wl) self.pca = self.emulator.pca self.wl_FFT = self.pca.wl # The raw eigenspectra and mean flux components self.EIGENSPECTRA = np.vstack((self.pca.flux_mean[np.newaxis,:], self.pca.flux_std[np.newaxis,:], self.pca.eigenspectra)) self.ss = np.fft.rfftfreq(self.pca.npix, d=self.emulator.dv) self.ss[0] = 0.01 # junk so we don't get a divide by zero error # Holders to store the convolved and resampled eigenspectra self.eigenspectra = np.empty((self.pca.m, self.ndata)) self.flux_mean = np.empty((self.ndata,)) self.flux_std = np.empty((self.ndata,)) self.flux_scalar = None self.sigma_mat = self.sigma**2 * np.eye(self.ndata) self.mus, self.C_GP, self.data_mat = None, None, None self.Omega = None self.lnprior = 0.0 # Modified and set by NuisanceSampler.lnprob # self.nregions = 0 # self.exceptions = [] # Update the outdir based upon id self.noutdir = Starfish.routdir + "{}/{}/".format(self.spectrum_id, self.order)
from Starfish import utils # Determine all of the orders we will be fitting spectra = Starfish.data["files"] orders = Starfish.data["orders"] for spectrum_id in range(len(spectra)): for order in orders: npoly = Starfish.config["cheb_degree"] if order == orders[-1]: # Use cheb degree - 1 for the last order npoly -= 1 fname_phi = Starfish.specfmt.format(spectrum_id, order) + "phi.json" phi = PhiParam.load(fname_phi) fname_mc = args.rundir + "/" + Starfish.specfmt.format( spectrum_id, order) + "/mc.hdf5" flatchain = utils.h5read(fname_mc) pars = flatchain[-1, :] phi.cheb = pars[:npoly] phi.sigAmp = float(pars[npoly]) phi.logAmp = float(pars[npoly + 1]) phi.l = float(pars[npoly + 2]) phi.save()