Ejemplo n.º 1
0
def template_prof(input_profs, sum=True):
    """
    Phase aligns and sums (if sum=True) multiple input profiles from different observations
    to create a single high S/N template profile.
    input_profs - np.asarray((prof1,prof2,...)) of input profiles to be combined.
        prof1 is the profile to which the others are aligned
    """
    Nprof = np.shape(input_profs)[0]
    bins = input_profs[0].size
    aligned_profs = np.empty(np.shape(input_profs))
    for i in range(Nprof):
        offset = psr_utils.measure_phase_corr(input_profs[i], input_profs[0])
        #print 'Phase offset '+str(i)+' = '+str(offset)
        bin_offset = -offset * bins
        aligned_profs[i] = psr_utils.fft_rotate(input_profs[i], bin_offset)
    if sum is False:
        return aligned_profs
    else:
        template_prof = aligned_profs.sum(0)
        for i in range(Nprof):
            offset = psr_utils.measure_phase_corr(input_profs[i],
                                                  template_prof)
            bin_offset = -offset * bins
            aligned_profs[i] = psr_utils.fft_rotate(input_profs[i], bin_offset)
        template_prof = aligned_profs.sum(0)
        return template_prof
Ejemplo n.º 2
0
def template_2d(input_profs, sum=True):
    """
    Phase aligns and sums multiple input 2D profiles from different observations
    to create a single high S/N template profile, while keeping full frequency
    resolution.
    input_profs - np.asarray((prof1,prof2,...)) of input profiles to be combined.
        prof1 is the profile to which the others are aligned
    """
    Nprof = np.shape(input_profs)[0]
    bins = input_profs[0].shape[1]
    channels = input_profs[0].shape[0]
    aligned_profs = np.empty(np.shape(input_profs))
    for i in range(Nprof):
        #offset=psr_utils.measure_phase_corr(input_profs[i].sum(0),input_profs[0].sum(0))
        offset = psr_utils.measure_phase_corr(
            np.nanmean(input_profs[i], axis=0),
            np.nanmean(input_profs[0], axis=0))
        #print 'Phase offset '+str(i)+' = '+str(offset)
        bin_offset = -offset * bins
        print bin_offset  ################
        for jj in np.arange(channels):
            aligned_profs[i][jj] = psr_utils.fft_rotate(
                input_profs[i][jj], bin_offset)
    if sum is False:
        return aligned_profs
    else:
        #template_prof=aligned_profs.sum(0)
        template_prof = np.nanmean(aligned_profs, axis=0)
        for i in range(Nprof):
            #offset=psr_utils.measure_phase_corr(input_profs[i].sum(0),template_prof.sum(0))
            offset = psr_utils.measure_phase_corr(
                np.nanmean(input_profs[i], axis=0),
                np.nanmean(template_prof, axis=0))
            bin_offset = -offset * bins
            for jj in np.arange(channels):
                aligned_profs[i][jj] = psr_utils.fft_rotate(
                    input_profs[i][jj], bin_offset)
        #template_prof=aligned_profs.sum(0)
        template_prof = np.nanmean(aligned_profs, axis=0)
        return template_prof
Ejemplo n.º 3
0
def prof_align(prof, template_prof, return_more=False):

    # Get amplitudes and phases from FFTing the input data profile
    t_prof_fft, t_prof_amp, t_prof_phase = cprof(template_prof)
    
    # Now run fftfit to match the profiles and out the shifts and scales
    shift,eshift,snr,esnr,b,errb,ngood = fftfit(prof,t_prof_amp,t_prof_phase)
    prof_rot = pu.fft_rotate(prof, shift)
    
    if(return_more):
      return shift, eshift, snr, esnr, b, errb, prof_rot
    else:
      return prof_rot
Ejemplo n.º 4
0
def baseline_search(prof_2d, nchan, off_pulse_size, subfreqs, LOFAR=True):
    nbin = prof_2d.shape[1]
    binspersec = nbin / 0.0016627
    tmp_fp = np.empty(np.shape(prof_2d))
    mask = np.zeros(np.shape(prof_2d), dtype=bool)
    mask[:, :off_pulse_size] = 1
    binstep = 3
    binshift_range = np.arange(0, nbin, binstep)
    if LOFAR is False:
        dmstep = 0.002  ## WSRT
        dm_range = np.arange(0, 0.05, dmstep)  ## WSRT
    else:
        dmstep = 0.0005  ## LOFAR
        dm_range = np.arange(0, 0.01, dmstep)  ## LOFAR
    fit = np.empty((binshift_range.size, dm_range.size))
    for binshift in binshift_range:
        for dm in dm_range:
            subdelays = psr_utils.delay_from_DM(dm, subfreqs)
            hifreqdelay = subdelays[-1]
            subdelays = subdelays - hifreqdelay
            delaybins = subdelays * binspersec + binshift
            for jj in range(nchan):
                tmp_prof = prof_2d[jj, :].copy()
                tmp_fp[jj] = psr_utils.fft_rotate(tmp_prof, delaybins[jj])
            fit[binshift / binstep,
                int(dm / dmstep)] = np.nanmean(tmp_fp[mask])
    best = np.unravel_index(fit.argmin(), fit.shape)
    Bin = best[0] * binstep
    DM = best[1] * dmstep
    subdelays = psr_utils.delay_from_DM(DM, subfreqs)
    hifreqdelay = subdelays[-1]
    subdelays = subdelays - hifreqdelay
    delaybins = subdelays * binspersec + Bin
    for jj in range(nchan):
        tmp_prof = prof_2d[jj, :].copy()
        tmp_fp[jj] = psr_utils.fft_rotate(tmp_prof, delaybins[jj])
    base_perchan = np.nanmean(tmp_fp[:, :off_pulse_size], axis=1)
    return base_perchan, DM
Ejemplo n.º 5
0
 def dedisperse(self, DM=None, interp=0, doppler=1):
     """
     dedisperse(DM=self.bestdm, interp=0, doppler=1):
         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 *ON* by default. This default behaviour is
                     different with respect to PRESTO's prepfold.py)
     """
     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)
         #print "DEBUG: in myprepfold.py -- DM, new_subdelays_bins:", DM, new_subdelays_bins
         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
Ejemplo n.º 6
0
 def dedisperse(self, DM=None, interp=0, doppler=1):
     """
     dedisperse(DM=self.bestdm, interp=0, doppler=1):
         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 *ON* by default. This default behaviour is
                     different with respect to PRESTO's prepfold.py)
     """
     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)
         #print "DEBUG: in myprepfold.py -- DM, new_subdelays_bins:", DM, new_subdelays_bins
         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
Ejemplo n.º 8
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
Ejemplo n.º 9
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!).

            Dedisperses the datacube, if necessary.
            Other than running self.dedisperse(), the datacube
                is not modified.
        """
        # 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)

        # Rotate subintegrations
        subints = self.combine_profs(self.npart, 1)[:,0,:]
        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
            if interp:
                subints[ii,:] = psr_utils.fft_rotate(tmp_prof, -bin_delays[ii])
            else:
                subints[ii,:] = psr_utils.rotate(tmp_prof, -Num.floor(bin_delays[ii]+0.5))
        return subints
Ejemplo n.º 10
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.astype(int)
        else:
            new_pdelays_bins = Num.floor(bin_delays+0.5).astype(int)

        # 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
Ejemplo n.º 11
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))
Ejemplo n.º 12
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
Ejemplo n.º 13
0
     template = psr_utils.read_profile(templatefilenm)
     # 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))
     onpulse_inds = Num.compress(template>bkgd_cutoff, Num.arange(numbins))
     Pgplot.plotxy(template)
     Pgplot.plotxy([bkgd_cutoff, bkgd_cutoff], [0.0, numbins], color='red')
     Pgplot.closeplot()