def _compute_rating(self, cand):
     """
     """
     profile = utils.get_scaled_profile(cand.profile, cand.pfd.varprof)
     mgauss = cand.multigaussfit
     chi2 = mgauss.get_chisqr(profile)
     dof = mgauss.get_dof(len(profile))
     return chi2 / dof
Esempio n. 2
0
 def _compute_rating(self, cand):
     """
     """
     profile = utils.get_scaled_profile(cand.profile, cand.pfd.varprof)
     mgauss = cand.multigaussfit
     chi2 = mgauss.get_chisqr(profile)
     dof = mgauss.get_dof(len(profile))
     return chi2/dof
Esempio n. 3
0
 def _compute_rating(self, cand):
     """
     """
     prof = cand.get_from_cache('profile')
     pfd = cand.get_from_cache('pfd')
     mgauss = cand.get_from_cache('multigaussfit')
     
     profile = utils.get_scaled_profile(prof, pfd.varprof)
     chi2 = mgauss.get_chisqr(profile)
     dof = mgauss.get_dof(len(profile))
     return chi2/dof
Esempio n. 4
0
    def _compute_rating(self, cand):
        """
        """
        prof = cand.get_from_cache('profile')
        pfd = cand.get_from_cache('pfd')
        mgauss = cand.get_from_cache('multigaussfit')

        profile = utils.get_scaled_profile(prof, pfd.varprof)
        chi2 = mgauss.get_chisqr(profile)
        dof = mgauss.get_dof(len(profile))
        return chi2 / dof
Esempio n. 5
0
    def _compute_rating(self, cand):
        """Return a rating for the candidate. The rating value is the
            reduced chi2 of the gaussian function fit to the candidate's 
            profile.
        
            Input:
                cand: An SPCandidate object to rate.

            Output:
                value: The rating value.
        """
        profile = utils.get_scaled_profile(cand.profile, cand.spd.varprof)
        sgauss = cand.gaussfit
        chi2 = sgauss.get_chisqr(profile)
        dof = sgauss.get_dof(len(profile))
        return chi2/dof
Esempio n. 6
0
    def _compute_rating(self, cand):
        """Return a rating for the candidate. The rating value is the
            reduced chi2 of the gaussian function fit to the candidate's 
            profile.
        
            Input:
                cand: An SPCandidate object to rate.

            Output:
                value: The rating value.
        """
        profile = utils.get_scaled_profile(cand.profile, cand.spd.varprof)
        sgauss = cand.gaussfit
        chi2 = sgauss.get_chisqr(profile)
        dof = sgauss.get_dof(len(profile))
        return chi2 / dof
Esempio n. 7
0
    def _compute_rating(self, cand):
        """Return a rating for the candidate. The rating value is the
            reduced chi2 of the gaussian function fit to the candidate's 
            profile.
        
            Input:
                cand: A Candidate object to rate.

            Output:
                value: The rating value.
        """
        prof = cand.get_from_cache('profile')
        pfd = cand.get_from_cache('pfd')
        sgauss = cand.get_from_cache('singlegaussfit')
        
        profile = utils.get_scaled_profile(prof, pfd.varprof)
        chi2 = sgauss.get_chisqr(profile)
        dof = sgauss.get_dof(len(profile))
        return chi2/dof
Esempio n. 8
0
    def _compute_data(self, cand):
        """Fit the candidate's profile with multiple gaussian
            components and return the fit's parameters.

            Input:
                cand: A ratings2.0 SPCandidate object.

            Output:
                multigaussfit: The corresponding fit. A MultiGaussFit object.
        """
        data = utils.get_scaled_profile(cand.profile, cand.spd.varprof)

        # Initialize some starting values
        nbins = len(data)

        trial_params = [0.0]

        amplitude = max(data[(0.1 * nbins):(0.4 * nbins)])
        fwhm = 0.02  # full window should be 50 times estimated pulse width
        phase = 0.25  # this is where the single pulse should be placed
        trial_params.append(amplitude)
        trial_params.append(fwhm)
        trial_params.append(phase)

        from scipy.optimize import leastsq

        def func(params):
            #print "DEBUG: params", params
            # since this is single gaussian, params is just [offset, amp, std, phs]
            fit = utils.multigaussfit_from_paramlist(params)
            return fit.get_resids(data)

        new_params, status = leastsq(func, trial_params)
        if status not in (1, 2, 3, 4):
            raise utils.RatingError("Status returned by " \
                                "scipy.optimize.leastsq (%d) " \
                                "indicates the fit failed!" % status)

        new_fit = utils.multigaussfit_from_paramlist(new_params)

        return new_fit
Esempio n. 9
0
    def _compute_data(self, cand):
        """Fit the candidate's profile with multiple gaussian
            components and return the fit's parameters.

            Input:
                cand: A ratings2.0 SPCandidate object.

            Output:
                multigaussfit: The corresponding fit. A MultiGaussFit object.
        """
        data = utils.get_scaled_profile(cand.profile, cand.spd.varprof)

        # Initialize some starting values
        nbins = len(data)
 
        trial_params = [0.0]
 
        amplitude = max(data[(0.1*nbins):(0.4*nbins)])
        fwhm = 0.02 # full window should be 50 times estimated pulse width
        phase = 0.25 # this is where the single pulse should be placed
        trial_params.append(amplitude)
        trial_params.append(fwhm)
        trial_params.append(phase)
                
        from scipy.optimize import leastsq
        def func(params):
            #print "DEBUG: params", params
            # since this is single gaussian, params is just [offset, amp, std, phs]
            fit = utils.multigaussfit_from_paramlist(params)
            return fit.get_resids(data)

        new_params, status = leastsq(func, trial_params)
        if status not in (1,2,3,4):
            raise utils.RatingError("Status returned by " \
                                "scipy.optimize.leastsq (%d) " \
                                "indicates the fit failed!" % status)

        new_fit = utils.multigaussfit_from_paramlist(new_params)
        
        return new_fit
Esempio n. 10
0
    def _compute_data(self, cand):
        """Fit the candidate's profile with multiple gaussian
            components and return the fit's parameters.

            Input:
                cand: A ratings2.0 Candidate object.

            Output:
                multigaussfit: The corresponding fit. A MultiGaussFit object.
        """
        prof = cand.get_from_cache('profile')
        pfd = cand.get_from_cache('pfd')
        data = utils.get_scaled_profile(prof, pfd.varprof)

        # Initialize some starting values
        nbins      = len(data)
        ngaussians = 0
        # After normalization the first parameter (offset) should be close to zero
        prev_params = [0.0]
        # Nothing fit yet, so residuals are just the data values
        prev_residuals = data - np.zeros_like(data) 
        # No need to normalize chi^2 by variance since we already did that to the
        # data
        prev_chi2  = sum(prev_residuals*prev_residuals)
        prev_dof   = nbins
        fit        = True
 
        # We will now start fitting Gaussian profile components until the
        # additional components are no longer statistically needed to improve the
        # fit.  The starting parameter guesses for each new component will come
        # from the highest remaining residual and from the previous best-fit values
        # for previous components
        while fit:
            ngaussians  += 1
            # Update values based on results of previous run
            trial_params = list(prev_params)
 
            # Guess the parameters for the next profile component
            amplitude = max(prev_residuals)
            # Base FWHM on stats.norm normalization
            fwhm = 2*np.sqrt(2*np.log(2))/(np.sqrt(2*np.pi)*amplitude)
            phase = np.argmax(prev_residuals)/float(nbins)
            trial_params.append(amplitude)
            trial_params.append(fwhm)
            trial_params.append(phase)
            if self.USE_MPFIT:
                # params_dict is used by mpfit to get initial values and constraints on
                # parameters
                params_dict = []
                for ii,param in enumerate(trial_params):
                    if ii == 0:
                        # The first parameter is the offset, which can be negative and
                        # should be allowed to vary more
                        params_dict.append({"value"  : param,
                                            "fixed"  : False,
                                            "limited": [False,False],
                                            "limits" : [0.0,0.0]})
                    elif (ii - 1)%3 == 1:
                        # This is the FWHM, and is allowed to vary between
                        # 1/nbins and 1.0
                        params_dict.append({"value"  : param,
                                            "fixed"  : False,
                                            "limited": [True, True],
                                            "limits" : [1.0/nbins, 1.0]})
                    else:
                        # Limits are set assuming that our initial guesses were correct
                        # to within 25%...
                        params_dict.append({"value"  : param,
                                            "fixed"  : False,
                                            "limited": [True,True],
                                            "limits" : [0.25*param,1.75*param]})

                # Define the fitting function for mpfit
                def func(params, fjac=None, errs=None):
                    fit = utils.multigaussfit_from_paramlist(params)
                    # Return values are [status, residuals]
                    return [0, fit.get_resids(data)]
             
                # Now fit
                mpfit_out     = mpfit.mpfit(func, parinfo=params_dict, quiet=True)
                # Store the new best-fit parameters
                new_params    = mpfit_out.params
            else:
                import scipy.optimize
                def func(params):
                    #print "DEBUG: params", params
                    fit = utils.multigaussfit_from_paramlist(params)
                    return fit.get_resids(data)

                new_params, status = scipy.optimize.leastsq(func, trial_params)
                if status not in (1,2,3,4):
                    raise utils.RatingError("Status returned by " \
                                        "scipy.optimize.leastsq (%d) " \
                                        "indicates the fit failed!" % status)

            # Calculate the new residuals and statistics
            new_fit = utils.multigaussfit_from_paramlist(new_params)
            #print "DEBUG: new_fit", new_fit
            new_residuals = new_fit.get_resids(data)
            new_chi2      = new_fit.get_chisqr(data)
            new_dof       = new_fit.get_dof(len(data)) # Degrees-of-freedom
            # Calculate the F-statistic for the fit, i.e. the probability that the
            # additional profile component is /not/ required by the data
            F_stat        = psr_utils.Ftest(prev_chi2, prev_dof, \
                                                new_chi2, new_dof)
 
            # If the F-test probability is greater than some threshold, then the
            # additional Gaussian did not significantly improve the fit and we
            # should stop.  The nan test is needed because if the fit is /worse/
            # then Ftest doesn't return a valid number.  Also stop if we reach
            # the maximum number of Gaussian profile components. Stop if the
            # fwhm of the added component is greater than 1.0
            if F_stat > self.F_stat_threshold or np.isnan(F_stat) \
                   or ngaussians > self.max_gaussians \
                   or new_fit.components[-1].fwhm > 1.0 \
                   or new_fit.components[-1].fwhm < 1.0/nbins:
                fit    = False
            # Otherwise, keep fitting and update the parameters for the next pass
            else:
                fit            = True
                prev_params    = new_params
                prev_residuals = new_residuals
                prev_chi2      = new_chi2
                prev_dof       = new_dof
 
        # We stop when a fit is no longer needed, so we have to return the values
        # from the /previous/ run (otherwise we return the unneeded fit)
        #print "DEBUG: prev_params", prev_params
        finalfit = utils.multigaussfit_from_paramlist(prev_params)
        #print "DEBUG: finalfit", finalfit
        return finalfit 
Esempio n. 11
0
def main():
    pfdfn = sys.argv[1]

    pfd = prepfold.pfd(pfdfn)

    cand = candidate.Candidate(pfd.topo_p1, pfd.bary_p1, pfd.bestdm, \
                        psr_utils.ra_to_rad(pfd.rastr)*psr_utils.RADTODEG, \
                        psr_utils.dec_to_rad(pfd.decstr)*psr_utils.RADTODEG, \
                        pfdfn)

    print "Loaded %s" % cand.pfdfn
    print "    Best topo period (s): %f" % cand.topo_period
    print "    Best bary period (s): %f" % cand.bary_period
    print "    Best DM (cm^-3/pc): %f" % cand.dm
    print "    RA (J2000 - deg): %f" % cand.raj_deg
    print "    Dec (J2000 - deg): %f" % cand.decj_deg

    print "-"*10
    pprint.pprint(cand.__dict__)
    print "-"*10

    intstats.add_data(cand)

    print "Added subint stats to cand"
    pprint.pprint(cand.__dict__)
    print "-"*10

    print "Subint stats object:"
    pprint.pprint(cand.subint_stats.__dict__)
    print "-"*10

    print "Sub-int Stats:"
    print "On-fraction (area): %g" % cand.subint_stats.get_on_frac()
    print "On-fraction (peak): %g" % cand.subint_stats.get_peak_on_frac()
    print "Area SNR stddev: %g" % cand.subint_stats.get_snr_stddev()
    print "Peak SNR stddev: %g" % cand.subint_stats.get_peak_snr_stddev()
    print "Avg correlation coefficient: %g" % cand.subint_stats.get_avg_corrcoef()
    
    mgauss = cand.multigaussfit
    tvph = cand.time_vs_phase
    onpulse_region = mgauss.get_onpulse_region(tvph.nbin)
    offpulse_region = np.bitwise_not(onpulse_region)
    m = np.ma.masked_array(onpulse_region, mask=offpulse_region)
    onpulse_ranges = np.ma.notmasked_contiguous(m)
    print onpulse_ranges
    prof = utils.get_scaled_profile(cand.profile, cand.pfd.varprof)
    imax = plt.axes([0.1,0.1,0.5,0.7])
    plt.imshow(scale2d(tvph.data), interpolation='nearest', \
            aspect='auto', origin='lower', cmap=matplotlib.cm.gist_yarg)
    for opr in onpulse_ranges:
        onpulse_bin = (opr.start, opr.stop)
        if onpulse_bin[0] < onpulse_bin[1]:
            plt.axvspan(onpulse_bin[0], onpulse_bin[1]+1, fc='g', alpha=0.2, lw=0)
        else:
            plt.axvspan(onpulse_bin[0], tvph.nbin, fc='g', alpha=0.2, lw=0)
            plt.axvspan(-0.5, onpulse_bin[1]+1, fc='g', alpha=0.2, lw=0)
        

    plt.axes([0.1,0.8,0.5,0.15], sharex=imax)
    plt.plot(prof, 'k-', label='Profile')
    plt.plot(mgauss.make_gaussians(len(prof)), 'r--', label='Fit')
    for ii, opr in enumerate(onpulse_ranges):
        onpulse_bin = (opr.start, opr.stop)
        if ii == 0:
            lbl = 'On-pulse'
        else:
            lbl = '_nolabel_'
        if onpulse_bin[0] < onpulse_bin[1]:
            plt.axvspan(onpulse_bin[0], onpulse_bin[1]+1, fc='g', alpha=0.2, lw=0, label=lbl)
        else:
            plt.axvspan(onpulse_bin[0], tvph.nbin, fc='g', alpha=0.2, lw=0, label=lbl)
            plt.axvspan(-0.5, onpulse_bin[1]+1, fc='g', alpha=0.2, lw=0, label='_nolabel_')
    plt.legend(loc='best', prop=dict(size='xx-small'))
    
    plt.axes([0.6,0.1,0.15,0.7], sharey=imax)
    snrs = cand.subint_stats.snrs
    plt.plot(snrs, np.arange(len(snrs)), 'mo', label='SNR (area)')
    plt.axvline(5.0, c='m', ls='--', lw=2)
    peaksnrs = cand.subint_stats.peak_snrs
    plt.plot(peaksnrs, np.arange(len(peaksnrs)), 'cD', label='SNR (peak)')
    plt.axvline(3.0, c='c', ls='--', lw=2)
    plt.legend(loc='best', prop=dict(size='xx-small'))
   
    plt.axes([0.75,0.1,0.15,0.7], sharey=imax)
    corrcoefs = cand.subint_stats.corr_coefs
    plt.plot(corrcoefs, np.arange(len(corrcoefs)), 'k.')
    imax.set_xlim(-0.5,tvph.nbin-0.5)
    imax.set_ylim(-0.5,tvph.nsubint-0.5)
    plt.show()
Esempio n. 12
0
    def _compute_data(self, cand):
        """Fit the candidate's profile with multiple gaussian
            components and return the fit's parameters.

            Input:
                cand: A ratings2.0 Candidate object.

            Output:
                multigaussfit: The corresponding fit. A MultiGaussFit object.
        """
        prof = cand.get_from_cache('profile')
        pfd = cand.get_from_cache('pfd')
        data = utils.get_scaled_profile(prof, pfd.varprof)

        # Initialize some starting values
        nbins = len(data)
        ngaussians = 0
        # After normalization the first parameter (offset) should be close to zero
        prev_params = [0.0]
        # Nothing fit yet, so residuals are just the data values
        prev_residuals = data - np.zeros_like(data)
        # No need to normalize chi^2 by variance since we already did that to the
        # data
        prev_chi2 = sum(prev_residuals * prev_residuals)
        prev_dof = nbins
        fit = True

        # We will now start fitting Gaussian profile components until the
        # additional components are no longer statistically needed to improve the
        # fit.  The starting parameter guesses for each new component will come
        # from the highest remaining residual and from the previous best-fit values
        # for previous components
        while fit:
            ngaussians += 1
            # Update values based on results of previous run
            trial_params = list(prev_params)

            # Guess the parameters for the next profile component
            amplitude = max(prev_residuals)
            # Base FWHM on stats.norm normalization
            fwhm = 2 * np.sqrt(
                2 * np.log(2)) / (np.sqrt(2 * np.pi) * amplitude)
            phase = np.argmax(prev_residuals) / float(nbins)
            trial_params.append(amplitude)
            trial_params.append(fwhm)
            trial_params.append(phase)
            if self.USE_MPFIT:
                # params_dict is used by mpfit to get initial values and constraints on
                # parameters
                params_dict = []
                for ii, param in enumerate(trial_params):
                    if ii == 0:
                        # The first parameter is the offset, which can be negative and
                        # should be allowed to vary more
                        params_dict.append({
                            "value": param,
                            "fixed": False,
                            "limited": [False, False],
                            "limits": [0.0, 0.0]
                        })
                    elif (ii - 1) % 3 == 1:
                        # This is the FWHM, and is allowed to vary between
                        # 1/nbins and 1.0
                        params_dict.append({
                            "value": param,
                            "fixed": False,
                            "limited": [True, True],
                            "limits": [1.0 / nbins, 1.0]
                        })
                    else:
                        # Limits are set assuming that our initial guesses were correct
                        # to within 25%...
                        params_dict.append({
                            "value":
                            param,
                            "fixed":
                            False,
                            "limited": [True, True],
                            "limits": [0.25 * param, 1.75 * param]
                        })

                # Define the fitting function for mpfit
                def func(params, fjac=None, errs=None):
                    fit = utils.multigaussfit_from_paramlist(params)
                    # Return values are [status, residuals]
                    return [0, fit.get_resids(data)]

                # Now fit
                mpfit_out = mpfit.mpfit(func, parinfo=params_dict, quiet=True)
                # Store the new best-fit parameters
                new_params = mpfit_out.params
            else:
                import scipy.optimize

                def func(params):
                    #print "DEBUG: params", params
                    fit = utils.multigaussfit_from_paramlist(params)
                    return fit.get_resids(data)

                new_params, status = scipy.optimize.leastsq(func, trial_params)
                if status not in (1, 2, 3, 4):
                    raise utils.RatingError("Status returned by " \
                                        "scipy.optimize.leastsq (%d) " \
                                        "indicates the fit failed!" % status)

            # Calculate the new residuals and statistics
            new_fit = utils.multigaussfit_from_paramlist(new_params)
            #print "DEBUG: new_fit", new_fit
            new_residuals = new_fit.get_resids(data)
            new_chi2 = new_fit.get_chisqr(data)
            new_dof = new_fit.get_dof(len(data))  # Degrees-of-freedom
            # Calculate the F-statistic for the fit, i.e. the probability that the
            # additional profile component is /not/ required by the data
            F_stat        = psr_utils.Ftest(prev_chi2, prev_dof, \
                                                new_chi2, new_dof)

            # If the F-test probability is greater than some threshold, then the
            # additional Gaussian did not significantly improve the fit and we
            # should stop.  The nan test is needed because if the fit is /worse/
            # then Ftest doesn't return a valid number.  Also stop if we reach
            # the maximum number of Gaussian profile components. Stop if the
            # fwhm of the added component is greater than 1.0
            if F_stat > self.F_stat_threshold or np.isnan(F_stat) \
                   or ngaussians > self.max_gaussians \
                   or new_fit.components[-1].fwhm > 1.0 \
                   or new_fit.components[-1].fwhm < 1.0/nbins:
                fit = False
            # Otherwise, keep fitting and update the parameters for the next pass
            else:
                fit = True
                prev_params = new_params
                prev_residuals = new_residuals
                prev_chi2 = new_chi2
                prev_dof = new_dof

        # We stop when a fit is no longer needed, so we have to return the values
        # from the /previous/ run (otherwise we return the unneeded fit)
        #print "DEBUG: prev_params", prev_params
        finalfit = utils.multigaussfit_from_paramlist(prev_params)
        #print "DEBUG: finalfit", finalfit
        return finalfit