Beispiel #1
0
    def adjust_fold_frequency(self, phasebins, profs=None, shiftsubs=False):
        """
        adjust_fold_frequency(phasebins, profs=None, shiftsubs=False):
            Linearly shift the intervals by phasebins over the course of
                the observation in order to change the apparent folding
                frequency.  Return a 2D array containing the de-dispersed
                profiles as a function of time (i.e. shape = (npart, proflen)),
				and the reduced chi^2 of the resulting summed profile.
                If profs is not None, then use profs instead of self.profs.
				If shiftsubs is not False, then actually correct the subbands
				instead of a 2D projection of them.
        """
        if not self.__dict__.has_key('subdelays'):
            print "Dedispersing first..."
            self.dedisperse()
        if shiftsubs:
            print "Shifting all the subbands..."
            if profs is None:
                profs = self.profs
            for ii in range(self.npart):
                bins_to_shift = int(round(float(ii) / self.npart * phasebins))
                for jj in range(self.nsub):
                    profs[ii, jj] = psr_utils.rotate(profs[ii, jj],
                                                     bins_to_shift)
            redchi = self.calc_redchi2(prof=profs.sum(0).sum(0))
        else:
            print "Shifting just the projected intervals (not individual subbands)..."
            if profs is None:
                profs = self.profs.sum(1)
            for ii in range(self.npart):
                bins_to_shift = int(round(float(ii) / self.npart * phasebins))
                profs[ii] = psr_utils.rotate(profs[ii], bins_to_shift)
            redchi = self.calc_redchi2(prof=profs.sum(0))
        print "New reduced-chi^2 =", redchi
        return profs, redchi
Beispiel #2
0
 def estimate_offsignal_redchi2(self, numtrials=20):
     """
     estimate_offsignal_redchi2():
         Estimate the reduced-chi^2 off of the signal based on randomly shifting
             and summing all of the component profiles.
     """
     redchi2s = []
     for count in range(numtrials):
         prof = Num.zeros(self.proflen, dtype='d')
         for ii in range(self.npart):
             for jj in range(self.nsub):
                 tmpprof = copy.copy(self.profs[ii][jj])
                 prof += psr_utils.rotate(tmpprof, random.randrange(0,self.proflen))
         redchi2s.append(self.calc_redchi2(prof=prof))
     return Num.mean(redchi2s)
Beispiel #3
0
 def plot_chi2_vs_DM(self, loDM, hiDM, N=100, interp=0, device='/xwin'):
     """
     plot_chi2_vs_DM(self, loDM, hiDM, N=100, interp=0, device='/xwin'):
         Plot (and return) an array showing the reduced-chi^2 versus
             DM (N DMs spanning loDM-hiDM).  Use sinc_interpolation
             if 'interp' is non-zero.
     """
     # Sum the profiles in time
     sumprofs = self.profs.sum(0)
     if not interp:
         profs = sumprofs
     else:
         profs = Num.zeros(Num.shape(sumprofs), dtype='d')
     DMs = psr_utils.span(loDM, hiDM, N)
     chis = Num.zeros(N, dtype='f')
     subdelays_bins = self.subdelays_bins.copy()
     for ii, DM in enumerate(DMs):
         subdelays = psr_utils.delay_from_DM(DM, self.barysubfreqs)
         hifreqdelay = subdelays[-1]
         subdelays = subdelays - hifreqdelay
         delaybins = subdelays * self.binspersec - subdelays_bins
         if interp:
             interp_factor = 16
             for jj in range(self.nsub):
                 profs[jj] = psr_utils.interp_rotate(sumprofs[jj],
                                                     delaybins[jj],
                                                     zoomfact=interp_factor)
             # Note: Since the interpolation process slightly changes the values of the
             # profs, we need to re-calculate the average profile value
             avgprof = (profs / self.proflen).sum()
         else:
             new_subdelays_bins = Num.floor(delaybins + 0.5)
             for jj in range(self.nsub):
                 profs[jj] = psr_utils.rotate(profs[jj],
                                              int(new_subdelays_bins[jj]))
             subdelays_bins += new_subdelays_bins
             avgprof = self.avgprof
         sumprof = profs.sum(0)
         chis[ii] = self.calc_redchi2(prof=sumprof, avg=avgprof)
     # Now plot it
     Pgplot.plotxy(chis,
                   DMs,
                   labx="DM",
                   laby=r"Reduced-\gx\u2\d",
                   device=device)
     return (chis, DMs)
Beispiel #4
0
    def shift_channels(self, bins, padval=0):
        """Shift each channel to the left by the corresponding 
            value in bins, an array.

            Inputs:
                bins: An array containing the number of bins
                    to shift each channel by.
                padval: Value to use when shifting near the edge
                    of a channel. This can be a numeric value,
                    'median', 'mean', or 'rotate'. 
                    
                    The values 'median' and 'mean' refer to the 
                    median and mean of the channel. The value 
                    'rotate' takes values from one end of the 
                    channel and shifts them to the other.

            Outputs:
                None

            *** Shifting happens in-place ***
        """
        assert self.numchans == len(bins)
        for ii in range(self.numchans):
            chan = self.get_chan(ii)
            # Use 'chan[:]' so update happens in-place
            # this way the change effects self.data
            chan[:] = psr_utils.rotate(chan, bins[ii])
            if padval != 'rotate':
                # Get padding value
                if padval == 'mean':
                    pad = np.mean(chan)
                elif padval == 'median':
                    pad = np.median(chan)
                else:
                    pad = padval

                # Replace rotated values with padval
                if bins[ii] > 0:
                    chan[-bins[ii]:] = pad
                elif bins[ii] < 0:
                    chan[:-bins[ii]] = pad
Beispiel #5
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
Beispiel #6
0
    sumprof *= Num.sqrt(current_pfd.DOF_corr()) / offpulse.std()
    print("\nSummed profile approx SNR = %.3f" % sum(sumprof))
    if SEFD:
        avg_S /= len(pfdfilenms)
        if pulsebins is None:
            SNR = sumprof.sum()  # integrate everything
        else:
            SNR = sumprof[pulsebins].sum()
        S = SEFD * SNR / Num.sqrt(2.0 * BW * Tpostrfi / numbins) / numbins
        print("     Approx sum profile flux density = %.3f mJy" % S)
        print("    Avg of individual flux densities = %.3f mJy" % avg_S)
        print("     Total (RFI cleaned) integration = %.0f s (%.2f hrs)" % \
              (Tpostrfi, Tpostrfi/3600.0))

    # Rotate the summed profile so that the max value is at the phase ~ 0.25 mark
    sumprof = psr_utils.rotate(sumprof, -len(sumprof) / 4)
    Pgplot.plotxy(sumprof,
                  Num.arange(numbins),
                  labx="Pulse Phase",
                  laby="Relative Flux")
    Pgplot.closeplot()

    print("\n Writing profile to '%s'..." % (outfilenm), end=' ')

    outfile = open(outfilenm, "w")
    for ii, val in enumerate(sumprof):
        outfile.write("%04d  %20.15g\n" % (ii, val))
    outfile.close()

    print("Done\n")
Beispiel #7
0
def calc_features_from_pfd(pfd_filepath):

    pfd_data = prepfold.pfd(str(pfd_filepath))

    if pfd_filepath.parent.name == 'positive':
        label = 1
    elif pfd_filepath.parent.name == 'negative':
        label = 0
    else:
        label = -1
        # return (label, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        #     np.empty(shape=(0,)), np.empty(shape=(0,0)),
        #     np.empty(shape=(0,0)), np.empty(shape=(0,)))

    pfd_data.dedisperse()

    #### As done in: prepfold.pfd.plot_sumprofs
    profile = pfd_data.sumprof
    profile = normalise_1d(profile)
    ####

    profiles_sum_axis0 = pfd_data.profs.sum(0)

    #### As done in: prepfold.pfd.plot_chi2_vs_DM
    loDM = 0
    hiDM = pfd_data.numdms
    N = pfd_data.numdms
    profs = profiles_sum_axis0.copy()  # = pfd_data.profs.sum(0)
    DMs = psr_utils.span(loDM, hiDM, N)
    chis = np.zeros(N, dtype='f')
    subdelays_bins = pfd_data.subdelays_bins.copy()
    for ii, DM in enumerate(DMs):
        subdelays = psr_utils.delay_from_DM(DM, pfd_data.barysubfreqs)
        hifreqdelay = subdelays[-1]
        subdelays = subdelays - hifreqdelay
        delaybins = subdelays * pfd_data.binspersec - subdelays_bins
        new_subdelays_bins = np.floor(delaybins + 0.5)
        for jj in range(pfd_data.nsub):
            profs[jj] = psr_utils.rotate(profs[jj],
                                         int(new_subdelays_bins[jj]))
        subdelays_bins += new_subdelays_bins
        sumprof = profs.sum(0)
        chis[ii] = pfd_data.calc_redchi2(prof=sumprof, avg=pfd_data.avgprof)
    ####

    # best_dm = pfd_data.bestdm
    # crop_radius = 100
    # best_dm_index = np.searchsorted(DMs, best_dm)  # Not accurate, but close.
    # bloated_chis = np.insert(chis, N, np.full(crop_radius, chis[-1]))
    # bloated_chis = np.insert(bloated_chis, 0, np.full(crop_radius, chis[0]))
    # cropped_chis = bloated_chis[ best_dm_index : best_dm_index+2*crop_radius ]
    # chis = cropped_chis

    #### As done in: prepfold.pfd.plot_intervals
    intervals = pfd_data.profs.sum(1)
    intervals = normalise_2d_rowwise(intervals)
    ####

    #### As done in: prepfold.pfd.plot_subbands
    subbands = profiles_sum_axis0.copy()  # = pfd_data.profs.sum(0)
    subbands = normalise_2d_rowwise(subbands)
    ####

    return label, profile, intervals, subbands, chis