Example #1
0
    def subband(self, nsub, subdm=None, padval=0):
        """Reduce the number of channels to 'nsub' by subbanding.
            The channels within a subband are combined using the
            DM 'subdm'. 'padval' is passed to the call to
            'Spectra.shift_channels'.

            Inputs:
                nsub: Number of subbands. Must be a factor of 
                    the number of channels.
                subdm: The DM with which to combine channels within
                    each subband (Default: don't shift channels 
                    within each subband)
                padval: The padding value to use when shifting
                    channels during dedispersion. See documentation
                    of Spectra.shift_channels. (Default: 0)

            Outputs:
                None

            *** Subbanding happens in-place ***
        """
        assert (self.numchans % nsub) == 0
        assert (subdm is None) or (subdm >= 0)
        nchan_per_sub = self.numchans // nsub
        sub_hifreqs = self.freqs[np.arange(nsub) * nchan_per_sub]
        sub_lofreqs = self.freqs[(1 + np.arange(nsub)) * nchan_per_sub - 1]
        sub_ctrfreqs = 0.5 * (sub_hifreqs + sub_lofreqs)

        if subdm is not None:
            # Compute delays
            ref_delays = psr_utils.delay_from_DM(subdm - self.dm, sub_ctrfreqs)
            delays = psr_utils.delay_from_DM(subdm - self.dm, self.freqs)
            rel_delays = delays - ref_delays.repeat(
                nchan_per_sub)  # Relative delay
            rel_bindelays = np.round(rel_delays / self.dt).astype('int')
            # Shift channels
            self.shift_channels(rel_bindelays, padval)

        # Subband
        self.data = np.array([np.sum(sub, axis=0) for sub in \
                                np.vsplit(self.data, nsub)])
        self.freqs = sub_ctrfreqs
        self.numchans = nsub
Example #2
0
        def getDMcurve(
                M):  # return the normalized DM curve downsampled to M points
            feature = '%s:%s' % ('DMbins', M)
            if M == 0:
                return np.array([])
            if not feature in self.extracted_feature:
                ddm = (self.dms.max() - self.dms.min()) / 2.
                loDM, hiDM = (self.bestdm - ddm, self.bestdm + ddm)
                loDM = max((0, loDM))  #make sure cut off at 0 DM
                hiDM = max((ddm, hiDM))  #make sure cut off at 0 DM
                N = 100
                interp = False
                sumprofs = self.profs.sum(0)
                if not interp:
                    profs = sumprofs
                else:
                    profs = np.zeros(np.shape(sumprofs), dtype='d')
                DMs = psr_utils.span(loDM, hiDM, N)
                chis = np.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 = np.floor(delaybins + 0.5)
                        for jj in range(self.nsub):
                            #profs[jj] = psr_utils.rotate(profs[jj], new_subdelays_bins[jj])
                            delay_bins = int(new_subdelays_bins[jj] %
                                             len(profs[jj]))
                            if not delay_bins == 0:
                                profs[jj] = np.concatenate(
                                    (profs[jj][delay_bins:],
                                     profs[jj][:delay_bins]))

                        subdelays_bins += new_subdelays_bins
                        avgprof = self.avgprof
                    sumprof = profs.sum(0)
                    chis[ii] = self.calc_redchi2(prof=sumprof, avg=avgprof)
                DMcurve = normalize(downsample(chis, M))
                self.extracted_feature[feature] = DMcurve
            return self.extracted_feature[feature]
Example #3
0
    def dedisperse(self, dm=0, padval=0):
        """Shift channels according to the delays predicted by
            the given DM.
            
            Inputs:
                dm: The DM (in pc/cm^3) to use.
                padval: The padding value to use when shifting
                    channels during dedispersion. See documentation
                    of Spectra.shift_channels. (Default: 0)

            Outputs:
                None

            *** Dedispersion happens in place ***
        """
        assert dm >= 0
        ref_delay = psr_utils.delay_from_DM(dm - self.dm, np.max(self.freqs))
        delays = psr_utils.delay_from_DM(dm - self.dm, self.freqs)
        rel_delays = delays - ref_delay  # Relative delay
        rel_bindelays = np.round(rel_delays / self.dt).astype('int')
        # Shift channels
        self.shift_channels(rel_bindelays, padval)

        self.dm = dm
Example #4
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)
Example #5
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
Example #6
0
def get_phasedelays(dm, freqs, period):
    """Return phase delays corresponding to a particular DM.

        Inputs:
            dm: DM (in pc cm-3)
            freqs: The list of frequencies (in MHz)
            period: The profiles period (in seconds)

        Outputs:
            phasedelays: The corresponding phase delays.
    """
    # Prepare delays
    timedelays = psr_utils.delay_from_DM(dm, freqs)
    # Reference all delays to highest frequency channel, which remains
    # unchanged
    # TODO: Do we really want to refer to high freq?
    timedelays -= timedelays[np.argmax(freqs)]
    phasedelays = timedelays/period
    return phasedelays
Example #7
0
def make_spd_from_file(spdcand, rawdatafile, \
                       txtfile, maskfile, \
                       min_rank, group_rank, \
                       plot, just_waterfall, \
                       integrate_ts, integrate_spec, disp_pulse, \
                       loc_pulse, nsub, \
                       maxnumcands, \
                       basename, \
                       mask=False, bandpass_corr=True, barytime=True, \
                       man_params=None):
    
    """
    Makes spd files from output files of rratrap. 
    Inputs:
        spdcand: spcand parameters instance (read in spcand.params)
        rawdatafile: psrfits file instance
        txtfile: rratrap output file (groups.txt file)
        maskfile: rfifind mask file. need this file if you want to remove the bandpass 
                  or use rfifind mask information.
        min_rank: plot all groups with rank more than this. min 1, max 6
        group_rank: plot groups ranked whatever you specify
        plot: do you want to produce the plots as well? 
        just_waterfall: Do you just want to make the waterfall plots.
        integrate_ts: Do you want to display the dedispersed time series in the plot?
        integrate_spec: Do you want to display the pulse spectrum in the plot?
        disp_pulse: Do you want to see the inset dispersed pulse in the plot?
        loc_pulse: Fraction of the window length where the pulse is located.(eg. 0.25 = 1/4th of the way in.
                                                                             0.5 = middle of the plot)
        maxnumcands: What is the maximum number of candidates you would like to generate?
        basename: output basename of the file. Appended with _DM_TIME(s)_RANK.spd 
    Optional arguments:
        mask: Do you want to mask out rfi contaminated channels?
        bandpass_corr: Do you want to remove the bandpass?
        barytime: Is the given time(s) barycentric?
        man_params: Do you want to specify the parameters for waterfalling 
                    manually? If yes, I suggest using the function make_spd_from_man_params().
                    (I suggest giving it the rratrap output file)    
    Outputs:
       Binary npz file containing the necessary arrays and header information to generate the spd plots.
    """
    numcands=0 # counter for max number of candidates
    loop_must_break = False # dont break the loop unless num of cands >100.
    files = spio.get_textfile(options.txtfile)
    if group_rank:
        groups=[group_rank-1]
    else:
        groups = [i for i in range(6) if(i>=min_rank)][::-1]
     
    for group in groups:
        rank = group+1
        if files[group] != "Number of rank %i groups: 0 "%rank:
            values = spio.split_parameters(rank, txtfile)
            lis = np.where(files == '\tRank:             %i.000000'%rank)[0]
            for ii in range(len(values)):
                #### Arrays for Plotting DM vs SNR
                dm_list, time_list, dm_arr, sigma_arr, width_arr = spio.read_RRATrap_info(txtfile, lis[ii], rank)


                # Array for Plotting Dedispersed waterfall plot - zerodm - OFF
                spdcand.read_from_file(values[ii], rawdatafile.tsamp, rawdatafile.specinfo.N, \
                                       rawdatafile.frequencies[0], rawdatafile.frequencies[-1], \
                                       rawdatafile, loc_pulse=loc_pulse, dedisp = True, \
                                       scaleindep = None, zerodm = None, mask = mask, \
                                       barytime=barytime, \
                                       nsub = nsub, bandpass_corr = bandpass_corr)

                #make an array to store header information for the spd files
                temp_filename = basename+"_DM%.1f_%.1fs_rank_%i"%(spdcand.subdm, \
                                                   spdcand.topo_start_time, rank)
                
                print_debug("Running waterfaller with Zero-DM OFF...")
                
                # Add additional information to the header information array
                data, Data_dedisp_nozerodm = waterfall_array(rawdatafile, spdcand.start, \
                                             spdcand.duration, spdcand.dm, spdcand.nbins, spdcand.nsub, \
                                             spdcand.subdm, spdcand.zerodm, spdcand.downsamp, \
                                             spdcand.scaleindep, spdcand.width_bins, \
                                             spdcand.mask, maskfile, spdcand.bandpass_corr)

                text_array = np.array([args[0], rawdatafile.specinfo.telescope, \
                                       rawdatafile.specinfo.ra_str, rawdatafile.specinfo.dec_str, \
                                       rawdatafile.specinfo.start_MJD[0], \
                                       rank, spdcand.nsub, spdcand.nbins, spdcand.subdm, \
                                       spdcand.sigma, spdcand.sample_number, spdcand.duration, \
                                       spdcand.width_bins, spdcand.pulse_width, rawdatafile.tsamp,\
                                       rawdatafile.specinfo.T, spdcand.topo_start_time, data.starttime, \
                                       data.dt,data.numspectra, data.freqs.min(), data.freqs.max()])

                #### Array for plotting Dedispersed waterfall plot zerodm - ON
                print_debug("Running Waterfaller with Zero-DM ON...")
                zerodm=True
                data, Data_dedisp_zerodm = waterfall_array(rawdatafile, spdcand.start, \
                                           spdcand.duration, spdcand.dm, spdcand.nbins, spdcand.nsub, \
                                           spdcand.subdm, zerodm, spdcand.downsamp, \
                                           spdcand.scaleindep, spdcand.width_bins, \
                                           spdcand.mask, maskfile, spdcand.bandpass_corr)
                ####Sweeped without zerodm
                spdcand.read_from_file(values[ii], rawdatafile.tsamp, rawdatafile.specinfo.N, \
                                      rawdatafile.frequencies[0], rawdatafile.frequencies[-1], \
                                      rawdatafile, loc_pulse=loc_pulse, dedisp = None, \
                                      scaleindep = None, zerodm = None, mask = mask, \
                                      barytime=barytime, \
                                      nsub = nsub, bandpass_corr = bandpass_corr)
                data, Data_nozerodm = waterfall_array(rawdatafile, spdcand.start, \
                                           spdcand.duration, spdcand.dm, spdcand.nbins, spdcand.nsub, \
                                           spdcand.subdm, spdcand.zerodm, spdcand.downsamp, \
                                           spdcand.scaleindep, spdcand.width_bins, \
                                           spdcand.mask, maskfile, spdcand.bandpass_corr)
                text_array = np.append(text_array, spdcand.sweep_duration)
                text_array = np.append(text_array, data.starttime)
                text_array = np.append(text_array, spdcand.bary_start_time)
                text_array = np.append(text_array, man_params)
                # Array to Construct the sweep
                if spdcand.sweep_dm is not None:
                    ddm = spdcand.sweep_dm-data.dm
                    delays = psr_utils.delay_from_DM(ddm, data.freqs)
                    delays -= delays.min()
                    delays_nozerodm = delays
                    freqs_nozerodm = data.freqs
                # Sweeped with zerodm-on 
                zerodm = True
                #downsamp_temp = 1
                data, Data_zerodm = waterfall_array(rawdatafile, spdcand.start, \
                                           spdcand.duration, spdcand.dm, spdcand.nbins, spdcand.nsub, \
                                           spdcand.subdm, zerodm, spdcand.downsamp, \
                                           spdcand.scaleindep, spdcand.width_bins, \
                                           spdcand.mask, maskfile, spdcand.bandpass_corr)
                # Saving the arrays into the .spd file.
                with open(temp_filename+".spd", 'wb') as f:
                    np.savez_compressed(f, \
                                        Data_dedisp_nozerodm = Data_dedisp_nozerodm.astype(np.float16),\
                                        Data_dedisp_zerodm = Data_dedisp_zerodm.astype(np.float16),\
                                        Data_nozerodm = Data_nozerodm.astype(np.float16),\
                                        delays_nozerodm = delays_nozerodm, \
                                        freqs_nozerodm = freqs_nozerodm,\
                                        Data_zerodm = Data_zerodm.astype(np.float16), \
                                        dm_arr= list(map(np.float16, dm_arr)),\
                                        sigma_arr = list(map(np.float16, sigma_arr)), \
                                        width_arr =list(map(np.uint8, width_arr)),\
                                        dm_list= list(map(np.float16, dm_list)), \
                                        time_list = list(map(np.float16, time_list)), \
                                        text_array = text_array)
                #### Arrays for Plotting DM vs Time is in plot_spd.plot(...)
                if plot:
                    print_debug("Now plotting...")
                    plot_spd.plot(temp_filename+".spd", args[1:], \
                                  spec_width=1.5, loc_pulse=loc_pulse, \
                                  xwin=False, outfile=basename, \
                                  just_waterfall=just_waterfall, \
                                  integrate_spec=integrate_spec, \
                                  integrate_ts=integrate_ts, \
                                  disp_pulse=disp_pulse, tar = None)
                    print_debug("Finished plot %i " %ii+strftime("%Y-%m-%d %H:%M:%S"))
                numcands+= 1
                print_debug('Finished sp_candidate : %i'%numcands)
                if numcands >= maxnumcands:    # Max number of candidates to plot 100.
                    loop_must_break = True
                    break
            if loop_must_break:
                break

        print_debug("Finished group %i... "%rank+strftime("%Y-%m-%d %H:%M:%S"))
    print_debug("Finished running waterfaller... "+strftime("%Y-%m-%d %H:%M:%S"))
Example #8
0
def make_spd_from_man_params(spdcand, rawdatafile, \
                             txtfile, maskfile, \
                             plot, just_waterfall, \
                             subdm, dm, sweep_dm, \
                             sigma, \
                             start_time, duration, \
                             width_bins, nbins, downsamp, \
                             nsub, \
                             scaleindep, \
                             spec_width, loc_pulse, \
                             integrate_ts, integrate_spec, disp_pulse, \
                             basename, \
                             mask, bandpass_corr, barytime, man_params):            
    """
    Makes spd files from output files of rratrap. 
    Inputs:
        spdcand: spcand parameters instance (read in spcand.params)
        rawdatafile: psrfits file instance
        txtfile: rratrap output file (groups.txt file)
        maskfile: rfifind mask file. need this file if you want to remove the bandpass 
                  or use rfifind mask information.
        plot: do you want to produce the plots as well? 
        just_waterfall: Do you just want to make the waterfall plots.
        subdm: DM to use when subbanding.
        dm: DM to use when dedispersing data for plot. 
        sweep_dm: Show the frequency sweep using this DM.
        sigma: signal-to-noise of the pulse
        start_time: start time of the data to be read in for waterfalling.
        duration: duration of data to be waterfalled.
        width_bins: Smooth each channel/subband with a boxcar width_bins wide.
        nbins: Number of time bins to plot. This option overrides
                the duration argument. 
        downsamp: Factor to downsample in time by. Default: Don't downsample.
        nsub: Number of subbands to use. Must be a factor of number of channels.
        scaleindep:Do you want to scale each subband independently?(Type: Boolean)
        spec_width: Twice this number times the pulse_width around the pulse to consider for the spectrum
        loc_pulse: Fraction of the window length where the pulse is located.(eg. 0.25 = 1/4th of the way in.
                                                                             0.5 = middle of the plot)
        integrate_ts: Do you want to display the dedispersed time series in the plot?
        integrate_spec: Do you want to display the pulse spectrum in the plot?
        disp_pulse: Do you want to see the inset dispersed pulse in the plot?
        basename: output basename of the file. Appended with _DM_TIME(s)_RANK.spd 
        mask: Do you want to mask out rfi contaminated channels?
        bandpass_corr: Do you want to remove the bandpass?
        barytime: Is the given time(s) barycentric?
        man_params: Do you want to specify the parameters for waterfalling 
                    manually? If yes, I suggest using the function make_spd_from_man_params().
                    (I suggest giving it the rratrap output file)    
    Outputs:
       Binary npz file containing the necessary arrays and header information to generate the spd plots.
    """
    rank = None
    if not nsub:
        nsub = rawdatafile.nchan

    # Array for Plotting Dedispersed waterfall plot - zerodm - OFF
    spdcand.manual_params(subdm, dm, sweep_dm, sigma, start_time, \
                         width_bins, downsamp, duration, nbins, nsub, rawdatafile.tsamp, \
                         rawdatafile.specinfo.N, \
                         rawdatafile.frequencies[0], rawdatafile.frequencies[-1], rawdatafile, \
                         loc_pulse=loc_pulse, dedisp=True, scaleindep=False, zerodm=False, \
                         mask=mask, barytime=barytime, bandpass_corr=bandpass_corr)
    #make an array to store header information for the spd files
    temp_filename = basename+"_DM%.1f_%.1fs"%(spdcand.subdm, spdcand.topo_start_time)
           
    print_debug("Running waterfaller with Zero-DM OFF...")
    data, Data_dedisp_nozerodm = waterfall_array(rawdatafile, spdcand.start, \
                                 spdcand.duration, spdcand.dm, spdcand.nbins, spdcand.nsub, \
                                 spdcand.subdm, spdcand.zerodm, spdcand.downsamp, \
                                 spdcand.scaleindep, spdcand.width_bins, \
                                 spdcand.mask, maskfile, spdcand.bandpass_corr)
    # Add additional information to the header information array
    text_array = np.array([args[0], rawdatafile.specinfo.telescope, \
                           rawdatafile.specinfo.ra_str, rawdatafile.specinfo.dec_str, \
                           rawdatafile.specinfo.start_MJD[0], rank, \
                           spdcand.nsub, spdcand.nbins, \
                           spdcand.subdm, spdcand.sigma, spdcand.sample_number, \
                           spdcand.duration, spdcand.width_bins, spdcand.pulse_width, \
                           rawdatafile.tsamp, rawdatafile.specinfo.T, spdcand.topo_start_time, \
                           data.starttime, data.dt,data.numspectra, data.freqs.min(), \
                           data.freqs.max()])

    #### Array for plotting Dedispersed waterfall plot zerodm - ON
    print_debug("Running Waterfaller with Zero-DM ON...")
    zerodm=True
    data, Data_dedisp_zerodm = waterfall_array(rawdatafile, spdcand.start, \
                                 spdcand.duration, spdcand.dm, spdcand.nbins, spdcand.nsub, \
                                 spdcand.subdm, zerodm, spdcand.downsamp, \
                                 spdcand.scaleindep, spdcand.width_bins, \
                                 spdcand.mask, maskfile, spdcand.bandpass_corr)
    ####Sweeped without zerodm
    spdcand.manual_params(subdm, dm, sweep_dm, sigma, start_time, \
                          width_bins, downsamp, duration, nbins, nsub, rawdatafile.tsamp, \
                          rawdatafile.specinfo.N, \
                          rawdatafile.frequencies[0], rawdatafile.frequencies[-1], rawdatafile, \
                          loc_pulse=loc_pulse, dedisp=None, scaleindep=None, zerodm=None, mask=mask, \
                          barytime=barytime, bandpass_corr=bandpass_corr)
    data, Data_nozerodm = waterfall_array(rawdatafile, spdcand.start, \
                                 spdcand.duration, spdcand.dm, spdcand.nbins, spdcand.nsub, \
                                 spdcand.subdm, spdcand.zerodm, spdcand.downsamp, \
                                 spdcand.scaleindep, spdcand.width_bins, \
                                 spdcand.mask, maskfile, spdcand.bandpass_corr)
    text_array = np.append(text_array, spdcand.sweep_duration)
    text_array = np.append(text_array, data.starttime)
    text_array = np.append(text_array, spdcand.bary_start_time)
    text_array = np.append(text_array, man_params)
    # Array to Construct the sweep
    if spdcand.sweep_dm is not None:
        ddm = spdcand.sweep_dm-data.dm
        delays = psr_utils.delay_from_DM(ddm, data.freqs)
        delays -= delays.min()
        delays_nozerodm = delays
        freqs_nozerodm = data.freqs
    # Sweeped with zerodm-on 
    zerodm = True
    #downsamp_temp = 1
    data, Data_zerodm = waterfall_array(rawdatafile, spdcand.start, \
                                 spdcand.duration, spdcand.dm, spdcand.nbins, spdcand.nsub, \
                                 spdcand.subdm, zerodm, spdcand.downsamp, \
                                 spdcand.scaleindep, spdcand.width_bins, \
                                 spdcand.mask, maskfile, spdcand.bandpass_corr)
    with open(temp_filename+".spd", 'wb') as f:
        np.savez_compressed(f, \
                            Data_dedisp_nozerodm = Data_dedisp_nozerodm.astype(np.float16),\
                            Data_dedisp_zerodm = Data_dedisp_zerodm.astype(np.float16),\
                            Data_nozerodm = Data_nozerodm.astype(np.float16),\
                            delays_nozerodm = delays_nozerodm, \
                            freqs_nozerodm = freqs_nozerodm,\
                            Data_zerodm = Data_zerodm.astype(np.float16), \
                            text_array = text_array)
    #### Arrays for Plotting DM vs Time is in plot_spd.plot(...)
    if plot:
        print_debug("Now plotting...")
        plot_spd.plot(temp_filename+".spd", args[1:], \
                      spec_width=spec_width, loc_pulse=loc_pulse, xwin=False, \
                      outfile = basename, just_waterfall=just_waterfall, \
                      integrate_spec=integrate_spec, integrate_ts=integrate_ts, \
                      disp_pulse=disp_pulse, tar = None)
Example #9
0
def inject(infile, outfn, prof, period, dm, nbitsout=None, 
           block_size=BLOCKSIZE, pulsar_only=False, inplace=False):
    if isinstance(infile, filterbank.FilterbankFile):
        fil = infile
    elif inplace:
        fil = filterbank.FilterbankFile(infile, 'readwrite')
    else:
        fil = filterbank.FilterbankFile(infile, 'read')
    print("Injecting pulsar signal into: %s" % fil.filename)
    if False:
        delays = psr_utils.delay_from_DM(dm, fil.frequencies)
        delays -= delays[np.argmax(fil.frequencies)]
        get_phases = lambda times: (times-delays)/period % 1
    else:
        get_phases = lambda times: times/period % 1

    # Create the output filterbank file
    if nbitsout is None:
        nbitsout = fil.nbits
    if inplace:
        warnings.warn("Injecting pulsar signal *in-place*")
        outfil = fil
    else:
        # Start an output file
        print("Creating out file: %s" % outfn)
        outfil = filterbank.create_filterbank_file(outfn, fil.header, \
                                            nbits=nbitsout, mode='append')

    if outfil.nbits == 8:
        raise NotImplementedError("This code is out of date. 'delays' is not " \
                                    "done in this way anymore..")
        # Read the first second of data to get the global scaling to use
        onesec = fil.get_timeslice(0, 1).copy()
        onesec_nspec = onesec.shape[0]
        times = np.atleast_2d(np.arange(onesec_nspec)*fil.tsamp).T+delays
        phases = times/period % 1
        onesec += prof(phases)
        minimum = np.min(onesec)
        median = np.median(onesec)
        # Set median to 1/3 of dynamic range
        global_scale = (256.0/3.0) / median
        del onesec
    else:
        # No scaling to be performed
        # These values will cause scaling to keep data unchanged
        minimum = 0
        global_scale = 1

    sys.stdout.write(" %3.0f %%\r" % 0)
    sys.stdout.flush()
    oldprogress = -1
    
    # Loop over data
    lobin = 0
    spectra = fil.get_spectra(0, block_size)
    numread = spectra.shape[0]
    while numread:
        if pulsar_only:
            # Do not write out data from input file
            # zero it out
            spectra *= 0
        hibin = lobin+numread
        # Sample at middle of time bin
        times = (np.arange(lobin, hibin, 1.0/NINTEG_PER_BIN)+0.5/NINTEG_PER_BIN)*fil.dt
        #times = (np.arange(lobin, hibin)+0.5)*fil.dt
        phases = get_phases(times)
        profvals = prof(phases)
        shape = list(profvals.shape)
        shape[1:1] = [NINTEG_PER_BIN]
        shape[0] /= NINTEG_PER_BIN
        profvals.shape = shape
        toinject = profvals.mean(axis=1)
        #toinject = profvals
        if np.ndim(toinject) > 1:
            injected = spectra+toinject
        else:
            injected = spectra+toinject[:,np.newaxis]
        scaled = (injected-minimum)*global_scale
        if inplace:
            outfil.write_spectra(scaled, lobin)
        else:
            outfil.append_spectra(scaled)
        
        # Print progress to screen
        progress = int(100.0*hibin/fil.nspec)
        if progress > oldprogress: 
            sys.stdout.write(" %3.0f %%\r" % progress)
            sys.stdout.flush()
            oldprogress = progress
        
        # Prepare for next iteration
        lobin = hibin 
        spectra = fil.get_spectra(lobin, block_size)
        numread = spectra.shape[0]

    sys.stdout.write("Done   \n")
    sys.stdout.flush()
Example #10
0
    
    # Combine the profiles as required
    profs = fold_pfd.combine_profs(numtoas, numsubbands)

    # PRESTO de-disperses at the high frequency channel so determine a
    # correction to the middle of the band
    if not events:
        subpersumsub = fold_pfd.nsub/numsubbands
        # Calculate the center of the summed subband freqs and delays
        sumsubfreqs = (Num.arange(numsubbands)+0.5)*subpersumsub*fold_pfd.subdeltafreq + \
                      (fold_pfd.lofreq-0.5*fold_pfd.chan_wid)
        # Note:  In the following, we cannot use fold_pfd.hifreqdelay since that
        #        is based on the _barycentric_ high frequency (if the barycentric 
        #        conversion was available).  For TOAs, we need a topocentric
        #        delay, which is based on the topocentric frequency fold_pfd.hifreq
        sumsubdelays = (psr_utils.delay_from_DM(fold_pfd.bestdm, sumsubfreqs) -
                        psr_utils.delay_from_DM(fold_pfd.bestdm, fold_pfd.hifreq))
        sumsubdelays_phs = Num.fmod(sumsubdelays / p_dedisp, 1.0)
        # Save the "higest channel within a subband" freqs/delays for use in
        # later DM/timing correction. PBD 2011/11/03
        sumsubfreqs_hi = sumsubfreqs + \
                fold_pfd.subdeltafreq/2.0 - fold_pfd.chan_wid/2.0
        subdelays2 = psr_utils.delay_from_DM(fold_pfd.bestdm, sumsubfreqs) - \
                psr_utils.delay_from_DM(fold_pfd.bestdm, sumsubfreqs_hi)

    else:
        fold_pfd.subfreqs = Num.asarray([0.0])
        sumsubfreqs = Num.asarray([0.0])
        sumsubdelays = Num.asarray([0.0])
        subdelays2 = Num.asarray([0.0])
        sumsubdelays_phs = Num.asarray([0.0])
Example #11
0
def dspsr(fits_file,
          puls=None,
          par_file=False,
          profile_bins=4096,
          parallel=False,
          DM=560.5,
          Downfact=False,
          SMJD=False,
          width=0.04194304):
    #Read puls
    if isinstance(puls, pd.Series):
        DM = puls.DM
        SMJD = puls.SMJD
        Downfact = puls.Downfact
    else:
        if not SMJD:
            print "Either a valid pulse pandas instance or seconds from beginning of day (SMJD) required. Exiting"
            return 1

    if SMJD > 86400:
        SMJD = SMJD - 86400  #Deal with observations taken over midnight

    #Read par_file
    if not par_file:
        obs_id = os.path.splitext(os.path.basename(fits_file))[0]
        par_file = '/dev/shm/{}_ephemeris'.format(obs_id)
        with open(par_file, 'w') as f:
            f.write(ephemeris.format(width, DM))

    archive_name = os.path.splitext(fits_file)[0]
    puls_folder = os.path.split(archive_name)[0]
    if not os.path.isfile(archive_name + '.ar'):
        readfile = read_fits(fits_file)
        period = width  #readfile['time_resolution'] * profile_bins

        #Delay between maximum and central frequencies
        DM_delay = psr_utils.delay_from_DM(
            DM, readfile['freq_c']) - psr_utils.delay_from_DM(
                DM, readfile['freq_c'] + readfile['bandwidth'] / 2.)
        n_puls = int(DM_delay / period)

        temp_folder = os.path.join('/dev/shm', os.path.basename(archive_name))

        def archive_creation(phase_start=0):
            if os.path.exists(temp_folder): shutil.rmtree(temp_folder)
            os.makedirs(temp_folder)

            #Fold the fits file to create single-pulse archives
            if phase_start: start = period / 2.
            else: start = 0

            with open(os.devnull, 'w') as FNULL:
                _ = subprocess.call([
                    'dspsr', '-S',
                    str(start), '-K', '-b',
                    str(profile_bins), '-s', '-E', par_file, fits_file
                ],
                                    cwd=temp_folder,
                                    stdout=FNULL)

            #Lists of archive names and starting times (s)
            archive_list = np.array(
                glob(os.path.join(temp_folder, 'pulse_*.ar')))
            archive_time_list = np.array([
                psrchive.Archive_load(ar).start_time().get_secs() +
                psrchive.Archive_load(ar).start_time().get_fracsec()
                for ar in archive_list
            ])
            idx_sorted = np.argsort(archive_list)
            archive_list = archive_list[idx_sorted]
            archive_time_list = archive_time_list[idx_sorted]

            #Find archive where dispersed pulse would start
            start_dispersed_puls = SMJD - archive_time_list
            idx_puls = np.where((start_dispersed_puls > 0)
                                & (start_dispersed_puls < period))[0][0]

            #Check that puls is centered
            phase = start_dispersed_puls[idx_puls] / period - start / period

            idx_puls += n_puls
            if phase_start > 0.75: idx_puls += 1

            return phase, archive_list[idx_puls]

        phase, archive = archive_creation()

        if abs(phase - 0.5) > 0.25:
            phase, archive = archive_creation(phase_start=phase)

        shutil.copyfile(os.path.join(temp_folder, archive),
                        archive_name + '.ar')
        shutil.rmtree(temp_folder)
        if os.path.isfile('/dev/shm/{}_ephemeris'.format(obs_id)):
            os.remove('/dev/shm/{}_ephemeris'.format(obs_id))

    #Clean the archive
    if not os.path.isfile(archive_name + '.ar.paz'):
        subprocess.call(['paz', '-e', 'ar.paz', '-r', archive_name + '.ar'],
                        cwd=puls_folder)

    #Create downsampled archive at the closest factor scrunched in polarisation
    if Downfact:
        downfact = int(Downfact)
        while profile_bins % downfact != 0:
            downfact -= 1

        if not os.path.isfile(archive_name + '.ar.paz.pb' + str(downfact)):
            subprocess.call([
                'pam', '-e', 'paz.pb' + str(downfact), '-p', '-b',
                str(downfact), archive_name + '.ar.paz'
            ],
                            cwd=puls_folder)
            #Plot the archive
            psrchive_plots(
                os.path.join(puls_folder,
                             archive_name + '.ar.paz.pb' + str(downfact)))

        #Create compressed archive
        if not os.path.isfile(archive_name + '.ar.paz.Fpb' + str(downfact)):
            subprocess.call([
                'pam', '-e', 'Fpb' + str(downfact), '-F',
                archive_name + '.ar.paz.pb' + str(downfact)
            ],
                            cwd=puls_folder)

    return
Example #12
0
def plot_waterfall(data,
                   start,
                   duration,
                   integrate_ts=False,
                   integrate_spec=False,
                   show_cb=False,
                   cmap_str="gist_yarg",
                   sweep_dms=[],
                   sweep_posns=[],
                   ax_im=None,
                   ax_ts=None,
                   ax_spec=None,
                   interactive=True):
    """ I want a docstring too!
    """

    # Set up axes
    if interactive:
        fig = plt.figure()
        fig.canvas.set_window_title("Frequency vs. Time")

    im_width = 0.6 if integrate_spec else 0.8
    im_height = 0.6 if integrate_ts else 0.8

    if not ax_im:
        ax_im = plt.axes((0.15, 0.15, im_width, im_height))
    if integrate_ts and not ax_ts:
        ax_ts = plt.axes((0.15, 0.75, im_width, 0.2), sharex=ax_im)

    if integrate_spec and not ax_spec:
        ax_spec = plt.axes((0.75, 0.15, 0.2, im_height), sharey=ax_im)

    # Ploting it up
    nbinlim = np.int64(duration / data.dt)

    img = ax_im.imshow(data.data[..., :nbinlim],
                       aspect='auto',
                       cmap=matplotlib.cm.cmap_d[cmap_str],
                       interpolation='nearest',
                       origin='upper',
                       extent=(data.starttime,
                               data.starttime + nbinlim * data.dt,
                               data.freqs.min(), data.freqs.max()))
    if show_cb:
        cb = ax_im.get_figure().colorbar(img)
        cb.set_label("Scaled signal intensity (arbitrary units)")

    #plt.axis('tight')
    # Sweeping it up
    for ii, sweep_dm in enumerate(sweep_dms):
        ddm = sweep_dm - data.dm
        delays = psr_utils.delay_from_DM(ddm, data.freqs)
        delays -= delays.min()

        if sweep_posns is None:
            sweep_posn = 0.0
        elif len(sweep_posns) == 1:
            sweep_posn = sweep_posns[0]
        else:
            sweep_posn = sweep_posns[ii]
        sweepstart = data.dt * data.numspectra * sweep_posn + data.starttime
        sty = SWEEP_STYLES[ii % len(SWEEP_STYLES)]
        ax_im.plot(delays + sweepstart, data.freqs, sty, lw=4, alpha=0.5)

    # Dressing it up
    ax_im.xaxis.get_major_formatter().set_useOffset(False)
    ax_im.set_xlabel("Time")
    ax_im.set_ylabel("Observing frequency (MHz)")

    # Plot Time series
    if integrate_ts:
        Data = np.array(data.data[..., :nbinlim])
        Dedisp_ts = Data.sum(axis=0)
        times = (np.arange(data.numspectra) * data.dt + start)[..., :nbinlim]
        ax_ts.plot(times, Dedisp_ts, "k")
        ax_ts.set_xlim([times.min(), times.max()])
        plt.setp(ax_ts.get_xticklabels(), visible=False)
        plt.setp(ax_ts.get_yticklabels(), visible=False)

    # Plot Spectrum
    if integrate_spec:
        spectrum_window = 0.05 * duration
        window_width = int(spectrum_window / data.dt)  # bins
        burst_bin = nbinlim // 2
        on_spec = np.array(data.data[..., burst_bin - window_width:burst_bin +
                                     window_width])
        Dedisp_spec = on_spec.sum(axis=1)[::-1]

        freqs = np.linspace(data.freqs.min(), data.freqs.max(),
                            len(Dedisp_spec))
        ax_spec.plot(Dedisp_spec, freqs, "k")
        plt.setp(ax_spec.get_xticklabels(), visible=False)
        plt.setp(ax_spec.get_yticklabels(), visible=False)
        ax_spec.set_ylim([data.freqs.min(), data.freqs.max()])
        if integrate_ts:
            ax_ts.axvline(times[burst_bin] - spectrum_window,
                          ls="--",
                          c="grey")
            ax_ts.axvline(times[burst_bin] + spectrum_window,
                          ls="--",
                          c="grey")

    if interactive:
        fig.suptitle("Frequency vs. Time")
        fig.canvas.mpl_connect(
            'key_press_event', lambda ev: (ev.key in
                                           ('q', 'Q') and plt.close(fig)))

        plt.show()
def plot_waterfall(data,
                   start,
                   source_name,
                   duration,
                   dm,
                   ofile,
                   integrate_ts=False,
                   integrate_spec=False,
                   show_cb=False,
                   cmap_str="gist_yarg",
                   sweep_dms=[],
                   sweep_posns=[],
                   ax_im=None,
                   ax_ts=None,
                   ax_spec=None,
                   interactive=True,
                   downsamp=1,
                   nsub=None,
                   subdm=None,
                   width=None,
                   snr=None,
                   csv_file=None,
                   prob=None):
    """ I want a docstring too!
    """

    if source_name is None:
        source_name = "Unknown"

    #Output file
    if ofile is "unknown_cand":
        title = "%s_" + ofile + "_%.3f_%s" % (source_name, start, str(dm))
    else:
        title = source_name + "_" + ofile

    # Set up axes
    fig = plt.figure(figsize=(10, 14))
    #fig.canvas.set_window_title("Frequency vs. Time")
    '''
    im_width = 0.6 if integrate_spec else 0.8
    im_height = 0.6 if integrate_ts else 0.8

    if not ax_im:
        ax_im = plt.axes((0.15, 0.15, im_width, im_height))
    if integrate_ts and not ax_ts:
        ax_ts = plt.axes((0.15, 0.75, im_width, 0.2),sharex=ax_im)

    if integrate_spec and not ax_spec:
        ax_spec = plt.axes((0.75, 0.15, 0.2, im_height),sharey=ax_im)
    '''

    ax_ts = plt.axes((0.1, 0.835, 0.71, 0.145))
    ax_im = plt.axes((0.1, 0.59, 0.71, 0.24), sharex=ax_ts)
    ax_dmvstm = plt.axes((0.1, 0.345, 0.71, 0.24), sharex=ax_ts)
    ax_spec = plt.axes((0.815, 0.59, 0.16, 0.24), sharey=ax_im)
    ax_dmsnr = plt.axes((0.815, 0.345, 0.16, 0.24), sharey=ax_dmvstm)
    ax_orig = plt.axes((0.1, 0.1, 0.71, 0.21))

    data.downsample(downsamp)
    nbinlim = np.int(duration / data.dt)

    #Get window
    spectrum_window = 0.02 * duration
    window_width = int(spectrum_window / data.dt)  # bins
    burst_bin = nbinlim // 2

    #Zap all channels which have more than half bins zero (drop packets)
    zerochan = 1
    arrmedian = np.ones(data.numchans)
    if zerochan:
        for ii in range(data.numchans):
            chan = data.get_chan(ii)
            #if 50% are zero
            if len(chan) - np.count_nonzero(chan) > 0.5 * len(chan):
                arrmedian[ii] = 0.0
        #arrmedian=np.array(arrmedian)

    #Additional zapping from off-pulse spectra
    extrazap = 1
    zapthresh = 4
    if extrazap:
        off_spec1 = np.array(data.data[..., 0:burst_bin -
                                       window_width])  # off-pulse from left
        off_spec2 = np.array(
            data.data[..., burst_bin +
                      window_width:nbinlim])  # off-pulse from right
        off_spec = (np.mean(off_spec1, axis=1) +
                    np.mean(off_spec2, axis=1)) / 2.0  # Total off-pulse
        mask = np.zeros(data.data.shape, dtype=bool)
        masked_val = np.ones(data.data.shape[1], dtype=bool)
        masked_chan = np.array(
            np.where(off_spec > zapthresh * np.std(off_spec)))[0]
        mask[masked_chan] = masked_val
        masked_chan1 = np.array(np.where(arrmedian == 0))[0]
        mask[masked_chan1] = masked_val
        data = data.masked(mask, maskval=0)
        for i in masked_chan:
            ax_spec.axhline(data.freqs[i], alpha=0.4, color='grey')
        for i in masked_chan1:
            ax_spec.axhline(data.freqs[i], alpha=0.4, color='grey')

    # DM-vs-time plot
    dmvstm_array = []
    #Old way
    ''' 
    lodm = int(dm-(dm*0.15))
    if lodm < 0: lodm = 0
    hidm = int(dm+(dm*0.15))
    '''
    band = (data.freqs.max() - data.freqs.min())
    centFreq = (data.freqs.min() + band / 2.0) / (10**3)  # To get it in GHz
    print(width, centFreq, band)
    #This comes from Cordes and McLaughlin (2003) Equation 13.
    FWHM_DM = 506 * float(width) * pow(centFreq, 3) / band
    #The candidate DM might not be exact so using a longer range
    FWHM_DM = 3.0 * FWHM_DM

    lodm = dm - FWHM_DM
    if lodm < 0:
        lodm = 0
        hidm = 2 * dm  # If low DM is zero then range should be 0 to 2*DM
    else:
        hidm = dm + FWHM_DM
    print(FWHM_DM, dm, lodm, hidm)
    dmstep = (hidm - lodm) / 48.0
    datacopy = copy.deepcopy(data)
    #print lodm,hidm
    for ii in np.arange(lodm, hidm, dmstep):
        #for ii in range(400,600,10):
        #Without this, dispersion delay with smaller DM step does not produce delay close to bin width
        data.dedisperse(0, padval='rotate')
        data.dedisperse(ii, padval='rotate')
        Data = np.array(data.data[..., :nbinlim])
        Dedisp_ts = Data.sum(axis=0)
        dmvstm_array.append(Dedisp_ts)
    dmvstm_array = np.array(dmvstm_array)
    #print np.shape(dmvstm_array)
    #np.save('dmvstm_1step.npz',dmvstm_array)
    ax_dmvstm.set_xlabel("Time (sec) ")
    ax_dmvstm.set_ylabel("DM")
    #ax_dmvstm.imshow(dmvstm_array, aspect='auto', cmap=matplotlib.cm.cmap_d[cmap_str], origin='lower',extent=(data.starttime, data.starttime+ nbinlim*data.dt, lodm, hidm))
    ax_dmvstm.imshow(dmvstm_array,
                     aspect='auto',
                     origin='lower',
                     extent=(data.starttime,
                             data.starttime + nbinlim * data.dt, lodm, hidm))
    #cmap=matplotlib.cm.cmap_d[cmap_str])
    #interpolation='nearest', origin='upper')
    plt.setp(ax_im.get_xticklabels(), visible=False)
    plt.setp(ax_ts.get_xticklabels(), visible=False)
    ax_dmvstm.set_ylim(lodm, hidm)
    #extent=(data.starttime, data.starttime+ nbinlim*data.dt, 500, 700)
    #plt.show()
    #fig2 = plt.figure(2)
    #plt.imshow(dmvstm_array,aspect='auto')

    #Plot Freq-vs-time
    data = copy.deepcopy(datacopy)
    #data.downsample(downsamp)
    data.dedisperse(dm, padval='rotate')
    nbinlim = np.int(duration / data.dt)
    #orig
    img = ax_im.imshow(data.data[..., :nbinlim], aspect='auto', \
                cmap=matplotlib.cm.cmap_d[cmap_str], \
                interpolation='nearest', origin='upper', \
                extent=(data.starttime, data.starttime+ nbinlim*data.dt, \
                        data.freqs.min(), data.freqs.max()))
    #ax_im.axvline(x=(data.starttime + nbinlim*data.dt)/2.0,ymin=data.freqs.min(),ymax=data.freqs.max(),lw=3,color='b')
    if show_cb:
        cb = ax_im.get_figure().colorbar(img)
        cb.set_label("Scaled signal intensity (arbitrary units)")
    # Dressing it up
    ax_im.xaxis.get_major_formatter().set_useOffset(False)
    #ax_im.set_xlabel("Time")
    ax_im.set_ylabel("Frequency (MHz)")

    # Plot Time series
    #Data = np.array(data.data[..., :nbinlim])
    Data = np.array(data.data[..., :nbinlim])
    Dedisp_ts = Data.sum(axis=0)
    times = (np.arange(data.numspectra) * data.dt + start)[..., :nbinlim]
    ax_ts.plot(times, Dedisp_ts, "k")
    ax_ts.set_xlim([times.min(), times.max()])
    text1 = "DM: " + "%.2f" % float(data.dm)
    plt.text(1.1,
             0.9,
             text1,
             fontsize=15,
             ha='center',
             va='center',
             transform=ax_ts.transAxes)
    text2 = "Width: " + "%.2f" % float(width)
    plt.text(1.1,
             0.75,
             text2,
             fontsize=15,
             ha='center',
             va='center',
             transform=ax_ts.transAxes)
    text3 = "SNR: " + "%.2f" % float(snr)
    plt.text(1.1,
             0.6,
             text3,
             fontsize=15,
             ha='center',
             va='center',
             transform=ax_ts.transAxes)
    ax_ts.set_title(title, fontsize=14)
    plt.setp(ax_ts.get_xticklabels(), visible=False)
    plt.setp(ax_ts.get_yticklabels(), visible=False)

    #Spectrum and DM-vs-SNR plot
    ax_ts.axvline(times[burst_bin] - spectrum_window, ls="--", c="grey")
    ax_ts.axvline(times[burst_bin] + spectrum_window, ls="--", c="grey")

    #Get spectrum and DM-vs-SNR for the on-pulse window
    on_spec = np.array(data.data[..., burst_bin - window_width:burst_bin +
                                 window_width])
    on_dmsnr = np.array(dmvstm_array[..., burst_bin - window_width:burst_bin +
                                     window_width])
    Dedisp_spec = np.mean(on_spec, axis=1)
    Dedisp_dmsnr = np.mean(on_dmsnr, axis=1)

    #Get off-pulse and DM-vs-SNR for range outside on-pulse window
    off_spec1 = np.array(data.data[..., 0:burst_bin -
                                   window_width])  # off-pulse from left
    off_spec2 = np.array(
        data.data[...,
                  burst_bin + window_width:nbinlim])  # off-pulse from right
    off_spec = (np.mean(off_spec1, axis=1) +
                np.mean(off_spec2, axis=1)) / 2.0  # Total off-pulse
    off_dmsnr1 = np.array(dmvstm_array[..., 0:burst_bin - window_width])
    off_dmsnr2 = np.array(dmvstm_array[..., burst_bin + window_width:nbinlim])
    off_dmsnr = (np.mean(off_dmsnr1, axis=1) +
                 np.mean(off_dmsnr2, axis=1)) / 2.0

    #Get Y-axis for both plots
    dms = np.linspace(lodm, hidm, len(Dedisp_dmsnr))
    freqs = np.linspace(data.freqs.max(), data.freqs.min(), len(Dedisp_spec))

    #Spectrum plot
    ax_spec.plot(Dedisp_spec, freqs, color="red", lw=2)
    ax_spec.plot(off_spec, freqs, color="blue", alpha=0.5, lw=1)
    ttest = float(stats.ttest_ind(Dedisp_spec, off_spec)[0].tolist())
    ttestprob = float(stats.ttest_ind(Dedisp_spec, off_spec)[1].tolist())
    text3 = "t-test"
    plt.text(1.1,
             0.45,
             text3,
             fontsize=12,
             ha='center',
             va='center',
             transform=ax_ts.transAxes)
    text4 = "  %.2f" % (ttest) + "(%.2f" % ((1 - ttestprob) * 100) + "%)"
    plt.text(1.1,
             0.3,
             text4,
             fontsize=12,
             ha='center',
             va='center',
             transform=ax_ts.transAxes)
    if prob:
        text5 = "ML prob: " + "%.2f" % (float(prob))
        print(text5)
        plt.text(1.1,
                 0.1,
                 text5,
                 fontsize=12,
                 ha='center',
                 va='center',
                 transform=ax_ts.transAxes)

    #DMvsSNR plot
    ax_dmsnr.plot(Dedisp_dmsnr, dms, color="red", lw=2)
    ax_dmsnr.plot(off_dmsnr, dms, color="grey", alpha=0.5, lw=1)
    Dedisp_dmsnr_split = np.array_split(Dedisp_dmsnr, 5)
    #Sub-array could be different sizes that's why
    Dedisp_dmsnr_split[0] = Dedisp_dmsnr_split[0].sum()
    Dedisp_dmsnr_split[1] = Dedisp_dmsnr_split[1].sum()
    Dedisp_dmsnr_split[2] = Dedisp_dmsnr_split[2].sum()
    Dedisp_dmsnr_split[3] = Dedisp_dmsnr_split[3].sum()
    Dedisp_dmsnr_split[4] = Dedisp_dmsnr_split[4].sum()

    #Plot settings
    plt.setp(ax_spec.get_xticklabels(), visible=True)
    plt.setp(ax_dmsnr.get_xticklabels(), visible=False)
    plt.setp(ax_spec.get_yticklabels(), visible=False)
    plt.setp(ax_dmsnr.get_yticklabels(), visible=False)
    ax_spec.set_ylim([data.freqs.min(), data.freqs.max()])
    ax_dmsnr.set_ylim(lodm, hidm)

    #Plot original data
    data.dedisperse(0, padval='rotate')
    ax_im.set_ylabel("Frequency (MHz)")
    ax_orig.set_ylabel("Frequency (MHz)")
    ax_orig.set_xlabel("Time (sec)")
    FTdirection = source_name.split("_")[0]

    if FTdirection == 'nT':
        ndata = data.data[..., ::-1]
        print("Will be flipped in Time")
    elif FTdirection == 'nF':
        ndata = data.data[::-1, ...]
        print("Will be flipped in freq")
    elif FTdirection == 'nTnF':
        ndata = data.data[::-1, ::-1]
        print("Will be flipped in time and freq")
    else:
        ndata = data.data
        print("No flip")

    # Sweeping it up
    for ii, sweep_dm in enumerate(sweep_dms):
        ddm = sweep_dm - data.dm

        #delays = psr_utils.delay_from_DM(ddm, data.freqs)
        #delays -= delays.min()

        if sweep_posns is None:
            sweep_posn = 0.0
        elif len(sweep_posns) == 1:
            sweep_posn = sweep_posns[0]
        else:
            sweep_posn = sweep_posns[ii]

        sweepstart = data.dt * data.numspectra * sweep_posn + data.starttime
        #sweepstart = data.dt*data.numspectra + data.starttime

        sty = "b-"

        if FTdirection == 'nT':
            ddm = (-1) * ddm  # Negative DM
            nfreqs = data.freqs
        elif FTdirection == 'nF':
            nfreqs = data.freqs[::-1]
        elif FTdirection == 'nTnF':
            ddm = (-1) * ddm  # Negative DM
            nfreqs = data.freqs[::-1]
        else:
            nfreqs = data.freqs

        delays = psr_utils.delay_from_DM(ddm, data.freqs)
        delays -= delays.min()
        ndelay = (delays + sweepstart)
        ndelay2 = (delays + sweepstart + duration)

        ax_orig.set_xlim(data.starttime,
                         data.starttime + len(data.data[0]) * data.dt)
        ax_orig.set_ylim(data.freqs.min(), data.freqs.max())
        ax_orig.plot(ndelay, nfreqs, "b-", lw=2, alpha=0.7)
        ax_orig.plot(ndelay2, nfreqs, "b-", lw=2, alpha=0.7)

    #Orig
    ax_orig.imshow(ndata, aspect='auto', \
        cmap=matplotlib.cm.cmap_d[cmap_str], \
        interpolation='nearest', origin='upper', \
        extent=(data.starttime, data.starttime + len(data.data[0])*data.dt, \
        data.freqs.min(), data.freqs.max()))
    '''
    ax_orig.imshow(ndata, aspect='auto', \
        cmap=matplotlib.cm.cmap_d[cmap_str], \
        interpolation='nearest', origin='lower', \
        extent=(data.starttime, data.starttime + len(data.data[0])*data.dt, \
        data.freqs.min(), data.freqs.max()))
    '''
    #if interactive:
    #    fig.suptitle("Frequency vs. Time")
    #    fig.canvas.mpl_connect('key_press_event', \
    #            lambda ev: (ev.key in ('q','Q') and plt.close(fig)))
    #oname = "%.3f_%s.png" % (start,str(dm))

    if ofile is "unknown_cand":
        ofile = ofile + "_%.3f_%s.png" % (start, str(dm))

    ttestTrsh1 = 3
    ttestTrsh2 = 1
    probTrsh1 = 0.5
    probTrsh2 = 0.05
    DMleft = Dedisp_dmsnr_split[0]
    DMcent = Dedisp_dmsnr_split[2]
    DMright = Dedisp_dmsnr_split[4]

    prob = 0.0 if prob is None else prob  # Set to 0 if None
    if prob >= probTrsh2:
        ofile = "A_" + ofile
        plt.text(1.1,
                 0.2,
                 "cat: A",
                 fontsize=12,
                 ha='center',
                 va='center',
                 transform=ax_ts.transAxes)
    elif ttest > ttestTrsh1 and DMcent > DMleft and DMcent > DMright:
        ofile = "B_" + ofile
        plt.text(1.1,
                 0.2,
                 "cat: B",
                 fontsize=12,
                 ha='center',
                 va='center',
                 transform=ax_ts.transAxes)
    elif ttest > ttestTrsh2 and DMcent > DMleft and DMcent > DMright:
        plt.text(1.1,
                 0.2,
                 "cat: C",
                 fontsize=12,
                 ha='center',
                 va='center',
                 transform=ax_ts.transAxes)
        ofile = "C_" + ofile

    plt.savefig(ofile)
    #plt.show()
    return ofile, ttest, ttestprob
Example #14
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