def fit(self, selected, iters=1): """ Run a fit using the specified fitter """ # Select all the TOAs if none are explicitly set if not any(selected): selected = ~selected """JUMP check, TODO: put in fitter?""" if "PhaseJump" in self.prefit_model.components: # if attempted fit (selected) # A) contains only jumps, don't do the fit and return an error # B) excludes a jump, turn that jump off # C) partially contains a jump, redefine that jump only with the overlap fit_jumps = [] for param in self.prefit_model.params: if getattr(self.prefit_model, param).frozen == False and param.startswith("JUMP"): fit_jumps.append(int(param[4:])) numjumps = self.prefit_model.components[ "PhaseJump"].get_number_of_jumps() if numjumps == 0: log.warn( "There are no jumps (maskParameter objects) in PhaseJump. Please delete the PhaseJump object and try again. " ) return None # boolean array to determine if all selected toas are jumped jumps = [ True if "jump" in dict.keys() and dict["jump"] in fit_jumps else False for dict in self.all_toas.table["flags"][selected] ] # check if par file jumps in PhaseJump object if not any(jumps): # for every jump, set appropriate flag for TOAs it jumps for jump_par in self.prefit_model.components[ "PhaseJump"].get_jump_param_objects(): # find TOAs jump applies to mask = jump_par.select_toa_mask(self.all_toas) # apply to dictionaries for future use for dict in self.all_toas.table["flags"][mask]: dict["jump"] = jump_par.index jumps = [ True if "jump" in dict.keys() and dict["jump"] in fit_jumps else False for dict in self.all_toas.table["flags"][selected] ] if all(jumps): log.warn( "toas being fit must not all be jumped. Remove or uncheck at least one jump in the selected toas before fitting." ) return None # numerical array of selected jump flags sel_jump_nums = [ dict["jump"] if "jump" in dict.keys() else np.nan for dict in self.all_toas.table["flags"][selected] ] # numerical array of all jump flags full_jump_nums = [ dict["jump"] if "jump" in dict.keys() else np.nan for dict in self.all_toas.table["flags"] ] for num in range(1, numjumps + 1): num = int(num) if num not in sel_jump_nums: getattr(self.prefit_model, "JUMP" + str(num)).frozen = True continue jump_select = [num == jump_num for jump_num in full_jump_nums] overlap = [a and b for a, b in zip(jump_select, selected)] # remove the jump flags for that num for dict in self.all_toas.table["flags"]: if "jump" in dict.keys() and dict["jump"] == num: del dict["jump"] # re-add the jump using overlap as 'selected' for dict in self.all_toas.table["flags"][overlap]: dict["jump"] = num if self.fitted: self.prefit_model = self.postfit_model self.prefit_resids = self.postfit_resids if self.fitter == Fitters.POWELL: fitter = pint.fitter.PowellFitter(self.selected_toas, self.prefit_model) elif self.fitter == Fitters.WLS: fitter = pint.fitter.WLSFitter(self.selected_toas, self.prefit_model) elif self.fitter == Fitters.GLS: fitter = pint.fitter.GLSFitter(self.selected_toas, self.prefit_model) chi2 = self.prefit_resids.chi2 wrms = np.sqrt(chi2 / self.selected_toas.ntoas) print("Pre-Fit Chi2:\t\t%.8g us^2" % chi2) print("Pre-Fit Weighted RMS:\t%.8g us" % wrms) fitter.fit_toas(maxiter=1) self.postfit_model = fitter.model self.postfit_resids = Residuals(self.all_toas, self.postfit_model) self.fitted = True self.write_fit_summary() # TODO: delta_pulse_numbers need some work. They serve both for PHASE and -padd functions from the TOAs # as well as for phase jumps added manually in the GUI. They really should not be zeroed out here because # that will wipe out preexisting values self.fulltoas.table["delta_pulse_numbers"] = np.zeros( self.fulltoas.ntoas) self.selected_toas.table["delta_pulse_number"] = np.zeros( self.selected_toas.ntoas) # plot the prefit without jumps pm_no_jumps = copy.deepcopy(self.postfit_model) for param in pm_no_jumps.params: if param.startswith("JUMP"): getattr(pm_no_jumps, param).value = 0.0 getattr(pm_no_jumps, param).frozen = True self.prefit_resids_no_jumps = Residuals(self.selected_toas, pm_no_jumps) f = copy.deepcopy(fitter) no_jumps = [ False if "jump" in dict.keys() else True for dict in f.toas.table["flags"] ] f.toas.select(no_jumps) selectedMJDs = self.selected_toas.get_mjds() if all(no_jumps): q = list(self.all_toas.get_mjds()) index = q.index([ i for i in self.all_toas.get_mjds() if i > selectedMJDs.min() ][0]) rs_mean = (Residuals( self.all_toas, f.model).phase_resids[index:index + len(selectedMJDs)].mean()) else: rs_mean = self.prefit_resids_no_jumps.phase_resids[no_jumps].mean() # determines how far on either side fake toas go # TODO: hard limit on how far fake toas can go --> can get clkcorr # errors if go before GBT existed, etc. minMJD, maxMJD = selectedMJDs.min(), selectedMJDs.max() spanMJDs = maxMJD - minMJD if spanMJDs < 30 * u.d: redge = ledge = 4 npoints = 400 elif spanMJDs < 90 * u.d: redge = ledge = 2 npoints = 300 elif spanMJDs < 200 * u.d: redge = ledge = 1 npoints = 300 elif spanMJDs < 400 * u.d: redge = ledge = 0.5 npoints = 200 else: redge = ledge = 0.2 npoints = 150 # Check to see if too recent nowish = (Time.now().mjd - 40) * u.d if maxMJD + spanMJDs * redge > nowish: redge = (nowish - maxMJD) / spanMJDs if redge < 0.0: redge = 0.0 f_toas, rs, mrands = random_models( f, rs_mean=rs_mean, redge_multiplier=redge, ledge_multiplier=ledge, npoints=npoints, iter=10, ) self.random_resids = rs self.fake_toas = f_toas
def fit(self, selected, iters=1): """ Run a fit using the specified fitter """ # Select all the TOAs if none are explicitly set if not any(selected): selected = ~selected """JUMP check, TODO: put in fitter?""" if "PhaseJump" in self.prefit_model.components: # if attempted fit (selected) # A) contains only jumps, don't do the fit and return an error # B) excludes a jump, turn that jump off # C) partially contains a jump, redefine that jump only with the overlap fit_jumps = [] for param in self.prefit_model.params: if getattr(self.prefit_model, param).frozen == False and param.startswith("JUMP"): fit_jumps.append(int(param[4:])) jumps = [ True if "jump" in dict.keys() and dict["jump"] in fit_jumps else False for dict in self.selected_toas.table["flags"] ] if all(jumps): log.warn( "toas being fit must not all be jumped. Remove or uncheck at least one jump in the selected toas before fitting." ) return None sel_jump_nums = [ dict["jump"] if "jump" in dict.keys() else np.nan for dict in self.selected_toas.table["flags"] ] full_jump_nums = [ dict["jump"] if "jump" in dict.keys() else np.nan for dict in self.all_toas.table["flags"] ] for num in range(1, int(np.nanmax(full_jump_nums) + 1)): num = int(num) if num not in sel_jump_nums: getattr(self.prefit_model, "JUMP" + str(num)).frozen = True continue jump_select = [num == jump_num for jump_num in full_jump_nums] overlap = [a and b for a, b in zip(jump_select, selected)] # remove the jump flags for that num for dict in self.all_toas.table["flags"]: if "jump" in dict.keys() and dict["jump"] == num: del dict["jump"] # re-add the jump using overlap as 'selected' for dict in self.all_toas.table["flags"][overlap]: dict["jump"] = num if self.fitted: self.prefit_model = self.postfit_model self.prefit_resids = self.postfit_resids if self.fitter == Fitters.POWELL: fitter = pint.fitter.PowellFitter(self.selected_toas, self.prefit_model) elif self.fitter == Fitters.WLS: fitter = pint.fitter.WLSFitter(self.selected_toas, self.prefit_model) elif self.fitter == Fitters.GLS: fitter = pint.fitter.GLSFitter(self.selected_toas, self.prefit_model) chi2 = self.prefit_resids.chi2 wrms = np.sqrt(chi2 / self.selected_toas.ntoas) print("Pre-Fit Chi2:\t\t%.8g us^2" % chi2) print("Pre-Fit Weighted RMS:\t%.8g us" % wrms) fitter.fit_toas(maxiter=1) self.postfit_model = fitter.model self.postfit_resids = Residuals(self.all_toas, self.postfit_model, set_pulse_nums=True) self.fitted = True self.write_fit_summary() # TODO: set pulse nums above not working to reset delta pulse nums, have to force it here # self.fulltoas.table['delta_pulse_numbers'] = np.zeros(self.fulltoas.ntoas) self.selected_toas.table["delta_pulse_number"] = np.zeros( self.selected_toas.ntoas) # plot the prefit without jumps pm_no_jumps = copy.deepcopy(self.postfit_model) for param in pm_no_jumps.params: if param.startswith("JUMP"): getattr(pm_no_jumps, param).value = 0.0 getattr(pm_no_jumps, param).frozen = True self.prefit_resids_no_jumps = Residuals(self.all_toas, pm_no_jumps, set_pulse_nums=True) f = copy.deepcopy(fitter) no_jumps = [ False if "jump" in dict.keys() else True for dict in f.toas.table["flags"] ] f.toas.select(no_jumps) selectedMJDs = self.selected_toas.get_mjds() if all(no_jumps): q = list(self.all_toas.get_mjds()) index = q.index([ i for i in self.all_toas.get_mjds() if i > selectedMJDs.min() ][0]) rs_mean = (Residuals( self.all_toas, f.model, set_pulse_nums=True).phase_resids[index:index + len(selectedMJDs)].mean()) else: rs_mean = self.prefit_resids_no_jumps.phase_resids[no_jumps].mean() # determines how far on either side fake toas go # TODO: hard limit on how far fake toas can go --> can get clkcorr # errors if go before GBT existed, etc. minMJD, maxMJD = selectedMJDs.min(), selectedMJDs.max() spanMJDs = maxMJD - minMJD if spanMJDs < 30 * u.d: redge = ledge = 4 npoints = 400 elif spanMJDs < 90 * u.d: redge = ledge = 2 npoints = 300 elif spanMJDs < 200 * u.d: redge = ledge = 1 npoints = 300 elif spanMJDs < 400 * u.d: redge = ledge = 0.5 npoints = 200 else: redge = ledge = 0.2 npoints = 150 # Check to see if too recent nowish = (Time.now().mjd - 40) * u.d if maxMJD + spanMJDs * redge > nowish: redge = (nowish - maxMJD) / spanMJDs if redge < 0.0: redge = 0.0 f_toas, rs = random_models( f, rs_mean=rs_mean, redge_multiplier=redge, ledge_multiplier=ledge, npoints=npoints, iter=10, ) self.random_resids = rs self.fake_toas = f_toas