def calc_phase_resids(self): """Return timing model residuals in pulse phase.""" # Read any delta_pulse_numbers that are in the TOAs table. # These are for PHASE statements, -padd flags, as well as user-inserted phase jumps # Check for the column, and if not there then create it as zeros try: delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"]) except: self.toas.table["delta_pulse_number"] = np.zeros( len(self.toas.get_mjds())) delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"]) # Track on pulse numbers, if requested if self.track_mode == "use_pulse_numbers": pulse_num = self.toas.get_pulse_numbers() if pulse_num is None: raise ValueError( "Pulse numbers missing from TOAs but track_mode requires them" ) # Compute model phase. For pulse numbers tracking # we need absolute phases, since TZRMJD serves as the pulse # number reference. modelphase = (self.model.phase(self.toas, abs_phase=True) + delta_pulse_numbers) # First assign each TOA to the correct relative pulse number, including # and delta_pulse_numbers (from PHASE lines or adding phase jumps in GUI) residualphase = modelphase - Phase(pulse_num, np.zeros_like(pulse_num)) # This converts from a Phase object to a np.float128 full = residualphase.int + residualphase.frac # If not tracking then do the usual nearest pulse number calculation else: # Compute model phase modelphase = self.model.phase(self.toas) + delta_pulse_numbers # Here it subtracts the first phase, so making the first TOA be the # reference. Not sure this is a good idea. if self.subtract_mean: modelphase -= Phase(modelphase.int[0], modelphase.frac[0]) # Here we discard the integer portion of the residual and replace it with 0 # This is effectively selecting the nearst pulse to compute the residual to. residualphase = Phase(np.zeros_like(modelphase.frac), modelphase.frac) # This converts from a Phase object to a np.float128 full = residualphase.int + residualphase.frac # If we are using pulse numbers, do we really want to subtract any kind of mean? if not self.subtract_mean: return full if not self.use_weighted_mean: mean = full.mean() else: # Errs for weighted sum. Units don't matter since they will # cancel out in the weighted sum. if np.any(self.toas.get_errors() == 0): raise ValueError( "Some TOA errors are zero - cannot calculate residuals") w = 1.0 / (self.toas.get_errors().value**2) mean, err = weighted_mean(full, w) return full - mean
def rms_weighted(self): """Compute weighted RMS of the residals in time.""" if np.any(self.toas.get_errors() == 0): raise ValueError( "Some TOA errors are zero - cannot calculate weighted RMS of residuals" ) w = 1.0 / (self.toas.get_errors().to(u.s) ** 2) wmean, werr, wsdev = weighted_mean(self.time_resids, w, sdev=True) return wsdev.to(u.us)
def rms_weighted(self): """Compute weighted RMS of the residals in time.""" if np.any(self.data_error == 0): raise ValueError( "Some data errors are zero - cannot calculate weighted RMS of residuals" ) w = 1.0 / (self.data_error**2) wmean, werr, wsdev = weighted_mean(self.resids, w, sdev=True) return wsdev
def rms_weighted(self): """Compute weighted RMS of the residals in time.""" if np.any(self._combined_data_error == 0): raise ValueError( "Some data errors are zero - cannot calculate weighted RMS of residuals" ) wrms = {} for rs in self.residual_objs.values(): w = 1.0 / (rs.get_data_error() ** 2) wmean, werr, wsdev = weighted_mean(rs.resids, w, sdev=True) wrms[rs.residual_type] = wsdev return wrms
def rms_weighted(self): """Compute weighted RMS of the residals in time.""" # Use scaled errors, if the noise model is not presented, it will # return the raw errors scaled_errors = self.get_data_error() if np.any(scaled_errors.value == 0): raise ValueError( "Some TOA errors are zero - cannot calculate weighted RMS of residuals" ) w = 1.0 / (scaled_errors.to(u.s) ** 2) wmean, werr, wsdev = weighted_mean(self.time_resids, w, sdev=True) return wsdev.to(u.us)