示例#1
0
 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
示例#2
0
    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
示例#3
0
    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
示例#4
0
        # 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))