def initialize(self, key): ''' Initialize the OrderModel to the correct chunk of data (echelle order). :param key: (spectrum_id, order_id) :param type: (int, int) This should only be called after all subprocess have been forked. ''' self.id = key self.spectrum_id, self.order_id = self.id self.logger.info("Initializing model on Spectrum {}, order {}.".format( self.spectrum_id, self.order_id)) self.instrument = Instruments[self.spectrum_id] self.DataSpectrum = DataSpectra[self.spectrum_id] self.wl = self.DataSpectrum.wls[self.order_id] self.fl = self.DataSpectrum.fls[self.order_id] self.sigma = self.DataSpectrum.sigmas[self.order_id] self.npoints = len(self.wl) self.mask = self.DataSpectrum.masks[self.order_id] self.order = self.DataSpectrum.orders[self.order_id] 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.npoly = config["cheb_degree"] self.ChebyshevSpectrum = ChebyshevSpectrum(self.DataSpectrum, self.order_id, npoly=self.npoly) self.resid_deque = deque( maxlen=500 ) #Deque that stores the last residual spectra, for averaging self.counter = 0 self.Emulator = Emulator.open( config["PCA_path"]) # Returns mu and var vectors self.Emulator.determine_chunk_log( self.wl) # Truncates the grid to this wl format, power of 2 pg = self.Emulator.PCAGrid self.wl_FFT = pg.wl self.ncomp = pg.ncomp self.PCOMPS = np.vstack((pg.flux_mean[np.newaxis, :], pg.flux_std[np.newaxis, :], pg.pcomps)) self.min_v = self.Emulator.min_v self.ss = np.fft.rfftfreq(len(self.wl_FFT), d=self.min_v) self.ss[0] = 0.01 # junk so we don't get a divide by zero error self.pcomps = np.empty((self.ncomp, self.npoints)) self.flux_mean = np.empty((self.npoints, )) self.flux_std = np.empty((self.npoints, )) self.mus, self.vars = None, None self.C_GP = None self.data_mat = None self.sigma_matrix = self.sigma**2 * np.eye(self.npoints) self.prior = 0.0 # Modified and set by NuisanceSampler.lnprob self.nregions = 0 self.exceptions = [] #TODO: perturb #if args.perturb: #perturb(stellar_Starting, config["stellar_jump"], factor=args.perturb) cheb_MH_cov = float(config["cheb_jump"])**2 * np.ones((self.npoly, )) cheb_tuple = ("logc0", ) # add in new coefficients for i in range(1, self.npoly): cheb_tuple += ("c{}".format(i), ) # set starting position to 0 cheb_Starting = {k: 0.0 for k in cheb_tuple} # Design cov starting cov_Starting = config['cov_params'] cov_tuple = C.dictkeys_to_cov_global_tuple(cov_Starting) cov_MH_cov = np.array( [float(config["cov_jump"][key]) for key in cov_tuple])**2 nuisance_MH_cov = np.diag(np.concatenate((cheb_MH_cov, cov_MH_cov))) nuisance_starting = { "cheb": cheb_Starting, "cov": cov_Starting, "regions": {} } # Because this initialization is happening on the subprocess, I think # the random state should be fine. # Update the outdir based upon id self.noutdir = outdir + "{}/{}/".format(self.spectrum_id, self.order) # Create the nuisance parameter sampler to run independently self.sampler = NuisanceSampler(OrderModel=self, starting_param_dict=nuisance_starting, cov=nuisance_MH_cov, debug=True, outdir=self.noutdir, order=self.order) self.p0 = self.sampler.p0 # Udpate the nuisance parameters to the starting values so that we at # least have a self.data_mat self.logger.info( "Updating nuisance parameter data products to starting values.") self.update_nuisance(nuisance_starting) self.lnprob = None
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)
sigma_mat = sigma**2 * np.eye(ndata) mus, C_GP, data_mat = None, None, None # For each star # In the config file, list the astroseismic parameters as the starting grid parameters # Read this into a ThetaParam object grid = np.array(Starfish.config["Theta"]["grid"]) # Now update the parameters for the emulator # If pars are outside the grid, Emulator will raise C.ModelError emulator.params = grid mus, C_GP = emulator.matrix npoly = Starfish.config["cheb_degree"] chebyshevSpectrum = ChebyshevSpectrum(dataSpec, 0, npoly=npoly) chebyshevSpectrum.update(np.array(Starfish.config["chebs"])) def lnprob(p): vz, vsini, logOmega = p[:3] cheb = p[3:] chebyshevSpectrum.update(cheb) # Local, shifted copy of wavelengths wl_FFT = wl_FFT_orig * np.sqrt((C.c_kms + vz) / (C.c_kms - vz)) # Holders to store the convolved and resampled eigenspectra eigenspectra = np.empty((pca.m, ndata)) flux_mean = np.empty((ndata, ))