Exemplo n.º 1
0
 def test_init_bad_unit(self):
     # bad units on int
     try:
         Phase(2 * u.Unit("m"), 0.3)
     except u.core.UnitConversionError:
         pass
     else:
         print("Exception not thrown")
         raise u.core.UnitConversionError
     # bad units on frac
     try:
         Phase(2, 0.3 * u.Unit("m"))
     except u.core.UnitConversionError:
         pass
     else:
         print("Exception not thrown")
         raise u.core.UnitConversionError
     # bad units on int and frac
     try:
         Phase(2 * u.Unit("m"), 0.3 * u.Unit("m"))
     except u.core.UnitConversionError:
         pass
     else:
         print("Exception not thrown")
         raise u.core.UnitConversionError
Exemplo n.º 2
0
 def test_vector_addition(self):
     phase1 = Phase([0, 2, 2, 2], [0, 0.3, 0.3, 0])
     phase2 = Phase([0, 1, 1, 1], [0, 0.1, 0.2, -0.5])
     phasesum = phase1 + phase2
     assert isinstance(phasesum, Phase)
     assert_equal(phasesum.int, u.Quantity([0, 3, 4, 3]))
     assert_equal(phasesum.frac, u.Quantity([0, 0.4, -0.5, -0.5]))
Exemplo n.º 3
0
 def test_scalar_addition(self, ii1, ff1, ii2, ff2, sumi, sumf):
     phase1 = Phase(ii1, ff1)
     phase2 = Phase(ii2, ff2)
     phasesum = phase1 + phase2
     assert isinstance(phasesum, Phase)
     assert_equal(phasesum.int, u.Quantity(sumi))
     assert_equal(phasesum.frac, u.Quantity(sumf))
Exemplo n.º 4
0
 def test_commutative_vector_addition(self):
     phase1 = Phase([0, 2, 2, 2], [0, 0.3, 0.3, 0])
     phase2 = Phase([0, 1, 1, 1], [0, 0.1, 0.2, -0.5])
     sum1 = phase1 + phase2
     sum2 = phase2 + phase1
     assert_equal(sum1.int, sum2.int)
     assert_equal(sum1.frac, sum2.frac)
Exemplo n.º 5
0
 def test_commutative_scalar_addition(self):
     phase1 = Phase(2, 0.5)
     phase2 = Phase(1, 0.3)
     sum1 = phase1 + phase2
     sum2 = phase2 + phase1
     assert_equal(sum1.int, sum2.int)
     assert_equal(sum1.frac, sum2.frac)
Exemplo n.º 6
0
    def calc_phase_resids(self):
        """Return timing model residuals in pulse phase."""

        # Read any delta_pulse_numbers that are in the TOAs table.
        # These are for PHASE statements, -padd flags, as well as user-inserted phase jumps
        # Check for the column, and if not there then create it as zeros
        try:
            delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"])
        except:
            self.toas.table["delta_pulse_number"] = np.zeros(
                len(self.toas.get_mjds()))
            delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"])

        # Track on pulse numbers, if requested
        if self.track_mode == "use_pulse_numbers":
            pulse_num = self.toas.get_pulse_numbers()
            if pulse_num is None:
                raise ValueError(
                    "Pulse numbers missing from TOAs but track_mode requires them"
                )
            # Compute model phase. For pulse numbers tracking
            # we need absolute phases, since TZRMJD serves as the pulse
            # number reference.
            modelphase = (self.model.phase(self.toas, abs_phase=True) +
                          delta_pulse_numbers)
            # First assign each TOA to the correct relative pulse number, including
            # and delta_pulse_numbers (from PHASE lines or adding phase jumps in GUI)
            residualphase = modelphase - Phase(pulse_num,
                                               np.zeros_like(pulse_num))
            # This converts from a Phase object to a np.float128
            full = residualphase.int + residualphase.frac
        # If not tracking then do the usual nearest pulse number calculation
        else:
            # Compute model phase
            modelphase = self.model.phase(self.toas) + delta_pulse_numbers
            # Here it subtracts the first phase, so making the first TOA be the
            # reference. Not sure this is a good idea.
            if self.subtract_mean:
                modelphase -= Phase(modelphase.int[0], modelphase.frac[0])

            # Here we discard the integer portion of the residual and replace it with 0
            # This is effectively selecting the nearst pulse to compute the residual to.
            residualphase = Phase(np.zeros_like(modelphase.frac),
                                  modelphase.frac)
            # This converts from a Phase object to a np.float128
            full = residualphase.int + residualphase.frac
        # If we are using pulse numbers, do we really want to subtract any kind of mean?
        if not self.subtract_mean:
            return full
        if not self.use_weighted_mean:
            mean = full.mean()
        else:
            # Errs for weighted sum.  Units don't matter since they will
            # cancel out in the weighted sum.
            if np.any(self.toas.get_errors() == 0):
                raise ValueError(
                    "Some TOA errors are zero - cannot calculate residuals")
            w = 1.0 / (self.toas.get_errors().value**2)
            mean, err = weighted_mean(full, w)
        return full - mean
Exemplo n.º 7
0
    def phase(self, toas, abs_phase=False):
        """Return the model-predicted pulse phase for the given TOAs."""
        # First compute the delays to "pulsar time"
        delay = self.delay(toas)
        phase = Phase(np.zeros(toas.ntoas), np.zeros(toas.ntoas))
        # Then compute the relevant pulse phases
        for pf in self.phase_funcs:
            phase += Phase(pf(toas, delay))

        # If the absolute phase flag is on, use the TZR parameters to compute
        # the absolute phase.
        if abs_phase:
            if "AbsPhase" not in list(self.components.keys()):
                # if no absolute phase (TZRMJD), add the component to the model and calculate it
                from pint.models import absolute_phase

                self.add_component(absolute_phase.AbsPhase())
                self.make_TZR_toa(
                    toas
                )  # TODO:needs timfile to get all toas, but model doesn't have access to timfile. different place for this?
            tz_toa = self.get_TZR_toa(toas)
            tz_delay = self.delay(tz_toa)
            tz_phase = Phase(np.zeros(len(toas.table)),
                             np.zeros(len(toas.table)))
            for pf in self.phase_funcs:
                tz_phase += Phase(pf(tz_toa, tz_delay))
            return phase - tz_phase
        else:
            return phase
Exemplo n.º 8
0
 def test_associative_vector_addition(self):
     phase1 = Phase([0, 2, 2, 2], [0, 0.3, 0.3, 0])
     phase2 = Phase([0, 1, 1, 1], [0, 0.1, 0.2, -0.5])
     phase3 = Phase([1, 5, 2, 3], [0.2, 0.4, -0.3, 0.3])
     sum1 = phase1 + (phase2 + phase3)
     sum2 = (phase1 + phase2) + phase3
     assert_equal(sum1.int, sum2.int)
     assert_equal(sum1.frac, sum2.frac)
Exemplo n.º 9
0
 def test_associative_scalar_addition(self):
     phase1 = Phase(2, 0.5)
     phase2 = Phase(1, 0.3)
     phase3 = Phase(3, -0.1)
     sum1 = phase1 + (phase2 + phase3)
     sum2 = (phase1 + phase2) + phase3
     assert_equal(sum1.int, sum2.int)
     assert_equal(sum1.frac, sum2.frac)
Exemplo n.º 10
0
 def test_vector_negation(self):
     phase1 = Phase([1, -2, -3, 4], [0.1, -0.3, 0.4, -0.2])
     phase2 = -phase1
     sum = phase1 + phase2
     assert_equal(sum.int, u.Quantity(0))
     assert_equal(sum.frac, u.Quantity(0))
     phase01 = -Phase([0, 0], [0, 0])
     assert_equal(phase01.int, u.Quantity(0))
     assert_equal(phase01.frac, u.Quantity(0))
Exemplo n.º 11
0
 def test_scalar_negation(self):
     phase1 = Phase(2, 0.3)
     phase2 = -phase1
     sum = phase1 + phase2
     assert_equal(sum.int, u.Quantity(0))
     assert_equal(sum.frac, u.Quantity(0))
     phase01 = -Phase(0, 0)
     assert_equal(phase01.int, u.Quantity(0))
     assert_equal(phase01.frac, u.Quantity(0))
Exemplo n.º 12
0
 def test_vector_addition_with_scalar(self):
     vecphase = Phase([0, 2, 2, 2], [0, 0.3, 0.3, 0])
     scalarphase = Phase(1, 0.1)
     sum1 = vecphase + scalarphase
     assert isinstance(sum1, Phase)
     assert_equal(sum1.int, u.Quantity([1, 3, 3, 3]))
     assert_equal(sum1.frac, u.Quantity([0.1, 0.4, 0.4, 0.1]))
     # check commutivity
     sum2 = scalarphase + vecphase
     assert isinstance(sum2, Phase)
     assert_equal(sum1.int, sum2.int)
     assert_equal(sum1.frac, sum2.frac)
Exemplo n.º 13
0
    def evalabsphase(self, t):
        """Return the phase at time t, computed with this polyco entry"""
        dt = (data2longdouble(t) - self.tmid.value) * MIN_PER_DAY
        # Compute polynomial by factoring out the dt's
        phase = Phase(self.coeffs[self.ncoeff -
                                  1])  # Compute phase using two long double
        for i in range(self.ncoeff - 2, -1, -1):
            pI = Phase(dt * phase.int)
            pF = Phase(dt * phase.frac)
            c = Phase(self.coeffs[i])
            phase = pI + pF + c

        # Add DC term
        phase += self.rphase + Phase(dt * 60.0 * self.f0)
        return phase
Exemplo n.º 14
0
    def calc_phase_resids(self, weighted_mean=True, set_pulse_nums=False):
        """Return timing model residuals in pulse phase."""
        rs = self.model.phase(self.toas)
        rs -= Phase(rs.int[0], rs.frac[0])
        try:
            delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"])
        except:
            self.toas.table["delta_pulse_number"] = np.zeros(len(self.toas.get_mjds()))
            delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"])
        if set_pulse_nums:
            self.toas.table["delta_pulse_number"] = np.zeros(len(self.toas.get_mjds()))
            delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"])
        full = Phase(np.zeros_like(rs.frac), rs.frac) + delta_pulse_numbers
        full = full.int + full.frac

        # Track on pulse numbers, if necessary
        if getattr(self.model, "TRACK").value == "-2":
            pulse_num = self.toas.get_pulse_numbers()
            if pulse_num is None:
                raise ValueError(
                    "Pulse numbers missing from TOAs but TRACK -2 requires them"
                )

            pn_act = np.trunc(full)
            addPhase = pn_act - pulse_num
            full -= pn_act
            full += addPhase

            if not weighted_mean:
                full -= full.mean()
            else:
                w = 1.0 / (np.array(self.toas.get_errors()) ** 2)
                wm = (full * w).sum() / w.sum()
                full -= wm
            return full

        if not weighted_mean:
            full -= full.mean()
        else:
            # Errs for weighted sum.  Units don't matter since they will
            # cancel out in the weighted sum.
            if np.any(self.toas.get_errors() == 0):
                raise ValueError("TOA errors are zero - cannot calculate residuals")
            w = 1.0 / (np.array(self.toas.get_errors()) ** 2)
            wm = (full * w).sum() / w.sum()
            full -= wm
        return full
Exemplo n.º 15
0
 def __init__(self, tmid, mjdspan, rph_int, rph_frac, f0, ncoeff, coeffs):
     self.tmid = data2longdouble(tmid) * u.day
     self.mjdspan = data2longdouble(mjdspan / MIN_PER_DAY) * u.day
     self.tstart = self.tmid - (self.mjdspan / 2)
     self.tstop = self.tmid + (self.mjdspan / 2)
     self.f0 = data2longdouble(f0)
     self.ncoeff = ncoeff
     self.rphase = Phase(rph_int, rph_frac)
     self.coeffs = data2longdouble(coeffs)
Exemplo n.º 16
0
 def test_scalar_multiplication(self):
     phase = Phase(2, 0.1)
     product1 = phase * 0
     assert isinstance(product1, Phase)
     assert_equal(product1.int, u.Quantity(0))
     assert_equal(product1.frac, u.Quantity(0))
     product2 = phase * 1
     assert_equal(product2.int, phase.int)
     assert_equal(product2.frac, phase.frac)
     product3 = phase * 2
     assert_equal(product3.int, u.Quantity(4))
     assert_equal(product3.frac, u.Quantity(0.2))
Exemplo n.º 17
0
 def test_vector_multiplication(self):
     phase = Phase([2, 1, -3], [0.1, -0.4, 0.2])
     product1 = phase * 0
     assert isinstance(product1, Phase)
     assert_equal(product1.int, u.Quantity([0, 0, 0]))
     assert_equal(product1.frac, u.Quantity([0, 0, 0]))
     product2 = phase * 1
     assert_equal(product2.int, phase.int)
     assert_equal(product2.frac, phase.frac)
     product3 = phase * 2
     assert_equal(product3.int, u.Quantity([4, 1, -6]))
     assert_equal(product3.frac, u.Quantity([0.2, 0.2, 0.4]))
Exemplo n.º 18
0
 def __init__(self, tmid, mjdspan, rphaseInt, rphaseFrac, f0, ncoeff,
              coeffs, obs):
     self.tmid = tmid * u.day
     self.mjdspan = mjdspan * u.day
     self.tstart = data2longdouble(
         self.tmid) - data2longdouble(self.mjdspan) / 2.0
     self.tstop = data2longdouble(
         self.tmid) + data2longdouble(self.mjdspan) / 2.0
     self.rphase = Phase(rphaseInt, rphaseFrac)
     self.f0 = data2longdouble(f0)
     self.ncoeff = ncoeff
     self.coeffs = data2longdouble(coeffs)
     self.obs = obs
Exemplo n.º 19
0
    def eval_abs_phase(self, t):
        """
        Polyco evaluate absolute phase for a time array.

        Parameters
        ---------
        t: numpy.ndarray or a single number.
           An time array in MJD. Time sample should be in order

        Returns
        ---------
        out: PINT Phase class
             Polyco evaluated absolute phase for t.

        phase = refPh + DT*60*F0 + COEFF(1) + COEFF(2)*DT + COEFF(3)*DT**2 + ...
        """
        if not isinstance(t, (np.ndarray, list)):
            t = np.array([t])

        entryIndex = self.find_entry(t)
        phaseInt = ()
        phaseFrac = ()
        # Compute phase for time in each entry
        for i in range(len(self.polycoTable)):
            mask = np.where(
                entryIndex == i)  # Build mask for time in each entry
            t_in_entry = t[mask]
            if len(t_in_entry) == 0:
                continue
            # Calculate the phase as an array
            absp = self.polycoTable["entry"][i].evalabsphase(t_in_entry)
            phaseInt += (absp.int, )
            phaseFrac += (absp.frac, )
            # Maybe add sort function here, since the time has been masked.
        phaseInt = np.hstack(phaseInt).value
        phaseFrac = np.hstack(phaseFrac).value
        absPhase = Phase(phaseInt, phaseFrac)

        return absPhase
Exemplo n.º 20
0
 def test_init_scalar(self, inti, fraci, intf, fracf):
     phase = Phase(inti, fraci)
     assert isinstance(phase, Phase)
     assert_equal(phase.int, u.Quantity(intf))
     assert_equal(phase.frac, u.Quantity(fracf))
Exemplo n.º 21
0
def random_models(
    fitter, rs_mean, ledge_multiplier=4, redge_multiplier=4, iter=1, npoints=100
):
    """Uses the covariance matrix to produce gaussian weighted random models.

    Returns fake toas for plotting and a list of the random models' phase resid objects.
    rs_mean determines where in residual phase the lines are plotted,
    edge_multipliers determine how far beyond the selected toas the random models are plotted.
    This uses an approximate method based on the cov matrix, it doesn't use MCMC.

    Parameters
    ----------
    fitter
        fitter object with model and toas to vary from
    rs_mean
        average phase residual for toas in fitter object, used to plot random models
    ledge_multiplier
        how far the lines will plot to the left in multiples of the fit toas span, default 4
    redge_multiplier
        how far the lines will plot to the right in multiples of the fit toas span, default 4
    iter
        how many random models will be computed, default 1
    npoints
        how many fake toas will be reated for the random lines, default 100

    Returns
    -------
        TOAs object containing the evenly spaced fake toas to plot the random lines with
        list of residual objects for the random models (one residual object each)
    """
    params = fitter.model.get_params_dict("free", "num")
    mean_vector = params.values()
    # remove the first column and row (absolute phase)
    cov_matrix = (((fitter.covariance_matrix.matrix[1:]).T)[1:]).T
    fac = fitter.fac[1:]
    f_rand = deepcopy(fitter)
    mrand = f_rand.model

    # scale by fac
    log.debug("errors", np.sqrt(np.diag(cov_matrix)))
    log.debug("mean vector", mean_vector)
    mean_vector = np.array(list(mean_vector)) * fac
    cov_matrix = ((cov_matrix * fac).T * fac).T

    toa_mjds = fitter.toas.get_mjds()
    minMJD, maxMJD = toa_mjds.min(), toa_mjds.max()
    spanMJDs = maxMJD - minMJD
    # ledge and redge _multiplier control how far the fake toas extend
    # in either direction of the selected points
    x = simulation.make_fake_toas_uniform(
        minMJD - spanMJDs * ledge_multiplier,
        maxMJD + spanMJDs * redge_multiplier,
        npoints,
        mrand,
    )
    x2 = simulation.make_fake_toas_uniform(minMJD, maxMJD, npoints, mrand)

    rss = []
    random_models = []
    for i in range(iter):
        # create a set of randomized parameters based on mean vector and covariance matrix
        rparams_num = np.random.multivariate_normal(mean_vector, cov_matrix)
        # scale params back to real units
        for j in range(len(mean_vector)):
            rparams_num[j] /= fac[j]
        rparams = OrderedDict(zip(params.keys(), rparams_num))
        # print("randomized parameters",rparams)
        f_rand.set_params(rparams)
        rs = mrand.phase(x, abs_phase=True) - fitter.model.phase(x, abs_phase=True)
        rs2 = mrand.phase(x2, abs_phase=True) - fitter.model.phase(x2, abs_phase=True)
        # from calc_phase_resids in residuals
        rs -= Phase(0.0, rs2.frac.mean() - rs_mean)
        # TODO: use units here!
        rs = ((rs.int + rs.frac).value / fitter.model.F0.value) * 10 ** 6
        rss.append(rs)
        random_models.append(deepcopy(mrand))

    return x, rss, random_models
Exemplo n.º 22
0
def tempo_polyco_table_reader(filename):
    """Read tempo style polyco file to an astropy table.

    Tempo style: The polynomial ephemerides are written to file 'polyco.dat'.  Entries
    are listed sequentially within the file.  The file format is::

        ====  =======   ============================================
        Line  Columns     Item
        ====  =======   ============================================
         1       1-10   Pulsar Name
                11-19   Date (dd-mmm-yy)
                20-31   UTC (hhmmss.ss)
                32-51   TMID (MJD)
                52-72   DM
                74-79   Doppler shift due to earth motion (10^-4)
                80-86   Log_10 of fit rms residual in periods
         2       1-20   Reference Phase (RPHASE)
                21-38   Reference rotation frequency (F0)
                39-43   Observatory number
                44-49   Data span (minutes)
                50-54   Number of coefficients
                55-75   Observing frequency (MHz)
                76-80   Binary phase
         3*      1-25   Coefficient 1 (COEFF(1))
                26-50   Coefficient 2 (COEFF(2))
                51-75   Coefficient 3 (COEFF(3))
        ====  =======   ============================================
        * Subsequent lines have three coefficients each, up to NCOEFF

    One polyco file could include more then one entrie

    The pulse phase and frequency at time T are then calculated as::

        DT = (T-TMID)*1440
        PHASE = RPHASE + DT*60*F0 + COEFF(1) + DT*COEFF(2) + DT^2*COEFF(3) + ....
        FREQ(Hz) = F0 + (1/60)*(COEFF(2) + 2*DT*COEFF(3) + 3*DT^2*COEFF(4) + ....)

    Parameters
    ----------
    filename : str
        Name of the input poloco file.

    References
    ----------
    http://tempo.sourceforge.net/ref_man_sections/tz-polyco.txt
    """
    f = open(filename, "r")
    # Read entries to the end of file
    entries = []
    while True:
        # Read first line
        line1 = f.readline()
        if len(line1) == 0:
            break

        fields = line1.split()
        psrname = fields[0].strip()
        date = fields[1].strip()
        utc = fields[2]
        tmid = np.longdouble(fields[3])
        dm = float(fields[4])
        doppler = float(fields[5])
        logrms = float(fields[6])
        # Read second line
        line2 = f.readline()
        fields = line2.split()
        refPhaseInt, refPhaseFrac = fields[0].split(".")
        refPhaseInt = data2longdouble(refPhaseInt)
        refPhaseFrac = data2longdouble("." + refPhaseFrac)
        if refPhaseInt < 0:
            refPhaseFrac = -refPhaseFrac

        refF0 = data2longdouble(fields[1])
        obs = fields[2]
        mjdSpan = data2longdouble(
            fields[3]) / MIN_PER_DAY  # Here change to constant
        nCoeff = int(fields[4])
        obsfreq = float(fields[5].strip())

        try:
            binaryPhase = data2longdouble(fields[6])
        except ValueError:
            binaryPhase = data2longdouble(0.0)

        # Read coefficients
        nCoeffLines = int(np.ceil(nCoeff / 3))

        # if nCoeff%3>0:
        #    nCoeffLines += 1
        coeffs = []

        for i in range(nCoeffLines):
            line = f.readline()
            for c in line.split():
                coeffs.append(data2longdouble(c))
        coeffs = np.array(coeffs)

        tmid = tmid * u.day
        mjdspan = mjdSpan * u.day
        tstart = data2longdouble(tmid) - data2longdouble(mjdspan) / 2.0
        tstop = data2longdouble(tmid) + data2longdouble(mjdspan) / 2.0
        rphase = Phase(refPhaseInt, refPhaseFrac)
        refF0 = data2longdouble(refF0)
        coeffs = data2longdouble(coeffs)
        entry = PolycoEntry(tmid, mjdspan, refPhaseInt, refPhaseFrac, refF0,
                            nCoeff, coeffs, obs)

        entries.append((
            psrname,
            date,
            utc,
            tmid.value,
            dm,
            doppler,
            logrms,
            binaryPhase,
            mjdspan,
            tstart,
            tstop,
            obs,
            obsfreq,
            entry,
        ))
    entry_list = []
    for ii in range(len(entries[0])):
        entry_list.append([t[ii] for t in entries])

    # Construct the polyco data table
    pTable = table.Table(
        entry_list,
        names=(
            "psr",
            "date",
            "utc",
            "tmid",
            "dm",
            "doppler",
            "logrms",
            "binary_phase",
            "mjd_span",
            "t_start",
            "t_stop",
            "obs",
            "obsfreq",
            "entry",
        ),
        meta={"name": "Polyco Data Table"},
    )

    pTable["index"] = np.arange(len(entries))
    return pTable
Exemplo n.º 23
0
 def test_precision(self):
     phase = Phase(1e5, 0.1)
     phase2 = phase + Phase(0, 1e-9)
     assert_equal(phase2.int, u.Quantity(1e5))
     assert_equal(phase2.frac, u.Quantity(0.100000001))
Exemplo n.º 24
0
    def calc_phase_resids(self, weighted_mean=True, set_pulse_nums=False):
        """Return timing model residuals in pulse phase."""
        # Please define what set_pulse_nums means!

        # Read any delta_pulse_numbers that are in the TOAs table.
        # These are for PHASE statements, -padd flags, as well as user-inserted phase jumps
        # Check for the column, and if not there then create it as zeros
        try:
            delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"])
        except:
            self.toas.table["delta_pulse_number"] = np.zeros(len(self.toas.get_mjds()))
            delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"])

        # I have no idea what this is trying to do. It just sets delta_pulse_number to zero
        # This will wipe out any PHASE or -padd commands from the .tim file!!!
        if set_pulse_nums:
            self.toas.table["delta_pulse_number"] = np.zeros(len(self.toas.get_mjds()))
            delta_pulse_numbers = Phase(self.toas.table["delta_pulse_number"])

        # Compute model phase
        rs = self.model.phase(self.toas)

        # Track on pulse numbers, if requested
        if getattr(self.model, "TRACK").value == "-2":
            pulse_num = self.toas.get_pulse_numbers()
            if pulse_num is None:
                raise ValueError(
                    "Pulse numbers missing from TOAs but TRACK -2 requires them"
                )
            # Compute model phase. For pulse numbers tracking
            # we need absolute phases, since TZRMJD serves as the pulse
            # number reference.
            rs = self.model.phase(self.toas, abs_phase=True) + delta_pulse_numbers
            # First assign each TOA to the correct relative pulse number
            rs -= Phase(pulse_num, np.zeros_like(pulse_num))
            # Then subtract the constant offset since that is irrelevant
            rs -= Phase(rs.int[0], rs.frac[0])
            full = rs.int + rs.frac

        # If not tracking then do the usual nearest pulse number calculation
        else:
            # Compute model phase
            rs = self.model.phase(self.toas) + delta_pulse_numbers
            # Here it subtracts the first phase, so making the first TOA be the
            # reference. Not sure this is a good idea.
            rs -= Phase(rs.int[0], rs.frac[0])

            # What exactly is full?
            full = Phase(np.zeros_like(rs.frac), rs.frac)
            # This converts full from a Phase object to a np.float128
            full = full.int + full.frac

        # If we are using pulse numbers, do we really want to subtract any kind of mean?
        # Perhaps there should be an option to not subtract any mean?
        if not weighted_mean:
            full -= full.mean()
        else:
            # Errs for weighted sum.  Units don't matter since they will
            # cancel out in the weighted sum.
            if np.any(self.toas.get_errors() == 0):
                raise ValueError(
                    "Some TOA errors are zero - cannot calculate residuals"
                )
            w = 1.0 / (np.array(self.toas.get_errors()) ** 2)
            wm = (full * w).sum() / w.sum()
            full -= wm
        return full
Exemplo n.º 25
0
 def test_init_array(self):
     phase = Phase([0, 2, -4, 1.2, 5], [0, 0.3, 0.5, 0, 1.4])
     assert isinstance(phase, Phase)
     assert_equal(phase.int, u.Quantity([0, 2, -3, 1, 6]))
     assert_equal(phase.frac, u.Quantity([0, 0.3, -0.5, 0.2, 0.4]))