def dedisperse(self, DM=None, interp=0, doppler=0): """ dedisperse(DM=self.bestdm, interp=0, doppler=0): Rotate (internally) the profiles so that they are de-dispersed at a dispersion measure of DM. Use FFT-based interpolation if 'interp' is non-zero (NOTE: It is off by default!). Doppler shift subband frequencies if doppler is non-zero. (NOTE: It is also off by default.) """ if DM is None: DM = self.bestdm # Note: Since TEMPO Doppler corrects observing frequencies, for # TOAs, at least, we need to de-disperse using topocentric # observing frequencies. if doppler: freqs = psr_utils.doppler(self.subfreqs, self.avgvoverc) else: freqs = self.subfreqs self.subdelays = psr_utils.delay_from_DM(DM, freqs) self.hifreqdelay = self.subdelays[-1] self.subdelays = self.subdelays - self.hifreqdelay delaybins = self.subdelays * self.binspersec - self.subdelays_bins if interp: new_subdelays_bins = delaybins for ii in range(self.npart): for jj in range(self.nsub): tmp_prof = self.profs[ii, jj, :] self.profs[ii, jj] = psr_utils.fft_rotate( tmp_prof, delaybins[jj]) # Note: Since the rotation process slightly changes the values of the # profs, we need to re-calculate the average profile value self.avgprof = (self.profs / self.proflen).sum() else: new_subdelays_bins = Num.floor(delaybins + 0.5) for ii in range(self.nsub): rotbins = int(new_subdelays_bins[ii]) % self.proflen if rotbins: # i.e. if not zero subdata = self.profs[:, ii, :] self.profs[:, ii] = Num.concatenate( (subdata[:, rotbins:], subdata[:, :rotbins]), 1) self.subdelays_bins += new_subdelays_bins self.sumprof = self.profs.sum(0).sum(0) if Num.fabs((self.sumprof / self.proflen).sum() - self.avgprof) > 1.0: print("self.avgprof is not the correct value!") self.currdm = DM
def time_vs_phase(self, p=None, pd=None, pdd=None, interp=0): """ time_vs_phase(p=*bestp*, pd=*bestpd*, pdd=*bestpdd*): Return the 2D time vs. phase profiles shifted so that the given period and period derivative are applied. Use FFT-based interpolation if 'interp' is non-zero. (NOTE: It is off by default as in prepfold!). """ # Cast to single precision and back to double precision to # emulate prepfold_plot.c, where parttimes is of type "float" # but values are upcast to "double" during computations. # (surprisingly, it affects the resulting profile occasionally.) parttimes = self.start_secs.astype('float32').astype('float64') # Get delays f_diff, fd_diff, fdd_diff = self.freq_offsets(p, pd, pdd) #print "DEBUG: in myprepfold.py -- parttimes", parttimes delays = psr_utils.delay_from_foffsets(f_diff, fd_diff, fdd_diff, parttimes) # Convert from delays in phase to delays in bins bin_delays = Num.fmod(delays * self.proflen, self.proflen) - self.pdelays_bins # Rotate subintegrations # subints = self.combine_profs(self.npart, 1)[:,0,:] # Slower than sum by ~9x subints = Num.sum(self.profs, axis=1).squeeze() if interp: new_pdelays_bins = bin_delays for ii in range(self.npart): tmp_prof = subints[ii, :] # Negative sign in num bins to shift because we calculated delays # Assuming +ve is shift-to-right, psr_utils.rotate assumes +ve # is shift-to-left subints[ii, :] = psr_utils.fft_rotate(tmp_prof, -new_pdelays_bins[ii]) else: new_pdelays_bins = Num.floor(bin_delays + 0.5) indices = Num.outer(Num.arange(self.proflen), Num.ones(self.npart)) indices = Num.mod(indices - new_pdelays_bins, self.proflen).T indices += Num.outer(Num.arange(self.npart)*self.proflen, \ Num.ones(self.proflen)) subints = subints.flatten('C')[indices.astype('i8')] return subints
def adjust_period(self, p=None, pd=None, pdd=None, interp=0): """ adjust_period(p=*bestp*, pd=*bestpd*, pdd=*bestpdd*): Rotate (internally) the profiles so that they are adjusted to the given period and period derivatives. By default, use the 'best' values as determined by prepfold's seaqrch. This should orient all of the profiles so that they are almost identical to what you see in a prepfold plot which used searching. Use FFT-based interpolation if 'interp' is non-zero. (NOTE: It is off by default, as in prepfold!) """ if self.fold_pow == 1.0: bestp = self.bary_p1 bestpd = self.bary_p2 bestpdd = self.bary_p3 else: bestp = self.topo_p1 bestpd = self.topo_p2 bestpdd = self.topo_p3 if p is None: p = bestp if pd is None: pd = bestpd if pdd is None: pdd = bestpdd # Cast to single precision and back to double precision to # emulate prepfold_plot.c, where parttimes is of type "float" # but values are upcast to "double" during computations. # (surprisingly, it affects the resulting profile occasionally.) parttimes = self.start_secs.astype('float32').astype('float64') # Get delays f_diff, fd_diff, fdd_diff = self.freq_offsets(p, pd, pdd) delays = psr_utils.delay_from_foffsets(f_diff, fd_diff, fdd_diff, parttimes) # Convert from delays in phase to delays in bins bin_delays = Num.fmod(delays * self.proflen, self.proflen) - self.pdelays_bins if interp: new_pdelays_bins = bin_delays else: new_pdelays_bins = Num.floor(bin_delays + 0.5) # Rotate subintegrations for ii in range(self.nsub): for jj in range(self.npart): tmp_prof = self.profs[jj, ii, :] # Negative sign in num bins to shift because we calculated delays # Assuming +ve is shift-to-right, psr_utils.rotate assumes +ve # is shift-to-left if interp: self.profs[jj, ii] = psr_utils.fft_rotate( tmp_prof, -new_pdelays_bins[jj]) else: self.profs[jj,ii] = psr_utils.rotate(tmp_prof, \ -new_pdelays_bins[jj]) self.pdelays_bins += new_pdelays_bins if interp: # Note: Since the rotation process slightly changes the values of the # profs, we need to re-calculate the average profile value self.avgprof = (self.profs / self.proflen).sum() self.sumprof = self.profs.sum(0).sum(0) if Num.fabs((self.sumprof / self.proflen).sum() - self.avgprof) > 1.0: print("self.avgprof is not the correct value!") # Save current p, pd, pdd self.curr_p1, self.curr_p2, self.curr_p3 = p, pd, pdd
# Resample the template profile to have the correct number of bins (if required) if not len(template) == numbins: oldlen = len(template) template = sinc_interp.periodic_interp(template, numbins)[::oldlen] else: if gaussfitfile is not None: template = psr_utils.read_gaussfitfile(gaussfitfile, numbins) else: template = psr_utils.gaussian_profile(numbins, 0.0, gaussianwidth) # Normalize it template -= min(template) template /= max(template) # Rotate it so that it becomes a "true" template according to FFTFIT shift, eshift, snr, esnr, b, errb, ngood = measure_phase( template, template) template = psr_utils.fft_rotate(template, shift) # Determine the off-pulse bins if bkgd_vals is not None: Pgplot.plotxy(template, labx="Phase bins") Pgplot.plotxy(template[bkgd_vals], Num.arange(numbins)[bkgd_vals], line=None, symbol=2, color='red') Pgplot.closeplot() offpulse_inds = bkgd_vals onpulse_inds = set(Num.arange(numbins)) - set(bkgd_vals) else: offpulse_inds = Num.compress(template <= bkgd_cutoff, Num.arange(numbins))