Example #1
0
def test_is_par_file():
    """
    Test failure of is_par_file.
    """

    assert is_par_file("blah_blah_blah") is False

    # test par files that don't contain required attributes
    brokenpar = "broken.par"

    values = {
        "F": [100.0],
        "RAJ": 0.1,
        "DECJ": -0.1,
        "PSRJ": "J0101-0101",
    }

    for leavekey in list(values.keys()):
        keys = list(values.keys())
        psr = PulsarParametersPy()
        for key in keys:
            if key != leavekey:
                psr[key] = values[key]

        psr.pp_to_par(brokenpar)

        assert is_par_file(brokenpar) is False

        os.remove(brokenpar)
Example #2
0
def test_one():
    par = PulsarParametersPy()
    par['F'] = [123.456789, -9.87654321e-12]  # set frequency
    par['DELTAF'] = [0.0, 0.0]  # frequency difference
    par['RAJ'] = lal.TranslateHMStoRAD('01:23:34.5')  # set right ascension
    par['DECJ'] = lal.TranslateDMStoRAD('-45:01:23.4')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('58000')
    par['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds
    par['H0'] = 5.6e-26
    par['COSIOTA'] = -0.2
    par['PSI'] = 0.4
    par['PHI0'] = 2.3

    freqfactor = 2.  # set frequency factor

    for det in t1output.keys():
        # convert into GPS times
        gpstimes = lalpulsar.CreateTimestampVector(len(t1output[det]))
        for i, time in enumerate(t1output[det][:, 0]):
            gpstimes.data[i] = lal.LIGOTimeGPS(time)

        detector = lalpulsar.GetSiteInfo(det)

        # set the response function look-up table
        dt = t1output[det][1, 0] - t1output[det][0, 0]  # time step
        resp = lalpulsar.DetResponseLookupTable(t1output[det][0, 0], detector,
                                                par['RAJ'], par['DECJ'], 2880,
                                                dt)

        # get the heterodyned file SSB delay
        hetSSBdelay = lalpulsar.HeterodynedPulsarGetSSBDelay(
            par.PulsarParameters(), gpstimes, detector, edat, tdat,
            lalpulsar.TIMECORRECTION_TCB)

        fullsignal = lalpulsar.HeterodynedPulsarGetModel(
            par.PulsarParameters(), freqfactor, 1, 0, 0, gpstimes, hetSSBdelay,
            0, None, 0, resp, edat, tdat, lalpulsar.TIMECORRECTION_TCB)

        # check output matches that from lalapps_pulsar_parameter_estimation_nested
        if np.any(
                np.abs(fullsignal.data.data.real -
                       t1output[det][:, 1]) > 1e-34):
            return False
        elif np.any(
                np.abs(fullsignal.data.data.imag -
                       t1output[det][:, 2]) > 1e-34):
            return False

    return True
Example #3
0
def is_par_file(parfile):
    """
    Check if a TEMPO-style pulsar parameter file is valid.

    Parameters
    ----------
    parfile: str
        The path to a file.

    Returns
    -------
    ispar: bool
        Returns True is if it is a valid parameter file.
    """

    # check that the file is ASCII text (see, e.g.,
    # https://stackoverflow.com/a/1446571/1862861)

    if os.path.isfile(parfile):
        msg = subprocess.Popen(["file", "--mime", "--dereference", parfile],
                               stdout=subprocess.PIPE).communicate()[0]
        if "text/plain" in msg.decode():
            psr = PulsarParametersPy(parfile)
            # file must contain a frequency, right ascension, declination and
            # pulsar name
            # file must contain right ascension and declination
            if (psr["F"] is None or (psr["RAJ"] is None and psr["RA"] is None)
                    or (psr["DECJ"] is None and psr["DEC"] is None)
                    or get_psr_name(psr) is None):
                return False

            return True

    return False
Example #4
0
def test_three(harmonic):
    parhet = PulsarParametersPy()
    parhet['F'] = [123.4567, -9.876e-12]  # set frequency
    parhet['RAJ'] = lal.TranslateHMStoRAD('01:23:34.6')  # set right ascension
    parhet['DECJ'] = lal.TranslateDMStoRAD('-45:01:23.5')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('58000')
    parhet['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds
    parhet['C22'] = 5.6e-26
    parhet['C21'] = 1.4e-25
    parhet['COSIOTA'] = -0.2
    parhet['PSI'] = 0.4
    parhet['PHI21'] = 2.3
    parhet['PHI22'] = 4.5

    parinj = PulsarParametersPy()
    parinj['F'] = [123.456789, -9.87654321e-12]  # set frequency
    parinj['RAJ'] = lal.TranslateHMStoRAD('01:23:34.5')  # set right ascension
    parinj['DECJ'] = lal.TranslateDMStoRAD('-45:01:23.4')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('58000')
    parinj['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds
    parinj['C22'] = 5.6e-26
    parinj['C21'] = 1.4e-25
    parinj['COSIOTA'] = -0.2
    parinj['PSI'] = 0.4
    parinj['PHI21'] = 2.3
    parinj['PHI22'] = 4.5

    det = 'H1'  # the detector
    detector = lalpulsar.GetSiteInfo(det)

    freqfactor = float(harmonic)  # set frequency factor

    # convert into GPS times
    gpstimes = lalpulsar.CreateTimestampVector(len(t3output[harmonic]))
    for i, time in enumerate(t3output[harmonic][:, 0]):
        gpstimes.data[i] = lal.LIGOTimeGPS(time)

    # set the response function look-up table
    dt = t3output[harmonic][1, 0] - t3output[harmonic][0, 0]  # time step
    resp = lalpulsar.DetResponseLookupTable(t3output[harmonic][0, 0], detector,
                                            parhet['RAJ'], parhet['DECJ'],
                                            2880, dt)

    # get the heterodyned file SSB delay
    hetSSBdelay = lalpulsar.HeterodynedPulsarGetSSBDelay(
        parhet.PulsarParameters(), gpstimes, detector, edat, tdat,
        lalpulsar.TIMECORRECTION_TCB)

    fullsignal = lalpulsar.HeterodynedPulsarGetModel(
        parinj.PulsarParameters(), parhet.PulsarParameters(), freqfactor, 1, 0,
        0, gpstimes, hetSSBdelay, 1, None, 0, None, 0, None, 0, resp, edat,
        tdat, lalpulsar.TIMECORRECTION_TCB)

    # check output matches that from lalapps_pulsar_parameter_estimation_nested
    assert_allclose(fullsignal.data.data.real, t3output[harmonic][:, 1])
    assert_allclose(fullsignal.data.data.imag, t3output[harmonic][:, 2])
Example #5
0
def test_get_psr_name():
    """
    Test extraction of pulsar name.
    """

    for item, name in zip(
        ["PSRJ", "PSRB", "PSR", "NAME"],
        ["J0123+1234", "B0124+12", "J0123+1234", "B0124+12"],
    ):
        psr = PulsarParametersPy()
        psr[item] = name

        assert get_psr_name(psr) == name
Example #6
0
    def _read_par(self, par):
        """
        Read a TEMPO-style parameter file into a PulsarParameterPy object.
        """

        if isinstance(par, PulsarParametersPy):
            return par

        if isinstance(par, string_types):
            try:
                return PulsarParametersPy(par)
            except IOError:
                raise IOError(
                    "Could not read in parameter file: '{}'".format(par))
        else:
            raise TypeError("The parameter file must be a string")
Example #7
0
    def parfiles(self, parfiles):
        pfs = {}

        if parfiles is not None:
            if isinstance(parfiles, dict):
                pfs = parfiles

                for psr in pfs:
                    if not is_par_file(pfs[psr]):
                        raise IOError(
                            "{} is not a pulsar parameter file".format(
                                pfs[psr]))
            elif isinstance(parfiles, str):
                if os.path.isdir(parfiles):
                    if parfiles == os.path.join(self.basedir, "pulsars"):
                        raise ValueError(
                            "Parameter files directory must be different from "
                            "'{}', which is reserved for the output directories"
                            .format(parfiles))

                    for pf in os.listdir(parfiles):
                        parfile = os.path.join(parfiles, pf)
                        if is_par_file(parfile):
                            psr = PulsarParametersPy(parfile)

                            # add parfile to dictionary
                            for name in ["PSRJ", "PSRB", "PSR", "NAME"]:
                                if psr[name] is not None:
                                    pfs[psr[name]] = parfile
                else:
                    raise ValueError("Path is not a valid directory")
            else:
                raise TypeError(
                    "Must give directory or dictionary of pulsar parameter files"
                )
            self._parfiles = pfs
            self.npulsars = len(self._parfiles)
        else:
            self._parfiles = None
            self.npulsars = None
Example #8
0
def test_five():
    par = PulsarParametersPy()
    par['F'] = [123.456789, -9.87654321e-12]  # set frequency
    par['DELTAF'] = [0.0, 0.0]  # frequency difference
    par['RAJ'] = lal.TranslateHMStoRAD('01:23:34.5')  # set right ascension
    par['DECJ'] = lal.TranslateDMStoRAD('-45:01:23.4')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('58000')
    par['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds
    par['HPLUS'] = 5.6e-26
    par['HCROSS'] = 1.3e-26
    par['HVECTORX'] = 1.4e-26
    par['HVECTORY'] = 2.3e-26
    par['HSCALARB'] = 4.5e-26
    par['HSCALARL'] = 3.1e-26
    par['PHI0TENSOR'] = 0.4
    par['PSITENSOR'] = 1.2
    par['PHI0SCALAR'] = 3.1
    par['PSISCALAR'] = 0.2
    par['PHI0VECTOR'] = 4.5
    par['PSIVECTOR'] = 2.4
    par['PHI0'] = 2.3

    freqfactor = 2.  # set frequency factor

    det = 'H1'  # detector
    detector = lalpulsar.GetSiteInfo(det)

    gpstimes = lalpulsar.CreateTimestampVector(len(t5output))
    for i, time in enumerate(t5output[:, 0]):
        gpstimes.data[i] = lal.LIGOTimeGPS(time)

    # set the response function look-up table
    dt = t5output[1, 0] - t5output[0, 0]  # time step
    resp = lalpulsar.DetResponseLookupTable(t5output[0, 0], detector,
                                            par['RAJ'], par['DECJ'], 2880, dt)

    # get the heterodyned file SSB delay
    hetSSBdelay = lalpulsar.HeterodynedPulsarGetSSBDelay(
        par.PulsarParameters(), gpstimes, detector, edat, tdat,
        lalpulsar.TIMECORRECTION_TCB)

    fullsignal = lalpulsar.HeterodynedPulsarGetModel(
        par.PulsarParameters(),
        freqfactor,
        1,
        0,
        1,  # use non-GR modes
        gpstimes,
        hetSSBdelay,
        0,
        None,
        0,
        resp,
        edat,
        tdat,
        lalpulsar.TIMECORRECTION_TCB)

    # check output matches that from lalapps_pulsar_parameter_estimation_nested
    if np.any(np.abs(fullsignal.data.data.real - t5output[:, 1]) > 1e-34):
        return False
    elif np.any(np.abs(fullsignal.data.data.imag - t5output[:, 2]) > 1e-34):
        return False

    return True
Example #9
0
def test_four():
    parhet = PulsarParametersPy()
    parhet['F'] = [123.4567, -9.876e-12]  # set frequency
    parhet['RAJ'] = lal.TranslateHMStoRAD('01:23:34.6')  # set right ascension
    parhet['DECJ'] = lal.TranslateDMStoRAD('-45:01:23.5')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('58000')
    parhet['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds
    parhet['H0'] = 5.6e-26
    parhet['COSIOTA'] = -0.2
    parhet['PSI'] = 0.4
    parhet['PHI0'] = 2.3
    parhet['BINARY'] = 'BT'
    T0 = lal.TranslateStringMJDTTtoGPS('58121.3')
    parhet['T0'] = T0.gpsSeconds + 1e-9 * T0.gpsNanoSeconds
    parhet['OM'] = np.deg2rad(2.2)
    parhet['A1'] = 8.9
    parhet['PB'] = 0.54 * 86400.
    parhet['ECC'] = 0.0001

    parinj = PulsarParametersPy()
    parinj['F'] = [123.456789, -9.87654321e-12]  # set frequency
    parinj['DELTAF'] = parinj['F'] - parhet['F']  # frequency difference
    parinj['RAJ'] = lal.TranslateHMStoRAD('01:23:34.5')  # set right ascension
    parinj['DECJ'] = lal.TranslateDMStoRAD('-45:01:23.4')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('58000')
    parinj['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds
    parinj['H0'] = 5.6e-26
    parinj['COSIOTA'] = -0.2
    parinj['PSI'] = 0.4
    parinj['PHI0'] = 2.3
    parinj['BINARY'] = 'BT'
    T0 = lal.TranslateStringMJDTTtoGPS('58121.3')
    parinj['T0'] = T0.gpsSeconds + 1e-9 * T0.gpsNanoSeconds
    parinj['OM'] = np.deg2rad(1.2)
    parinj['A1'] = 8.9
    parinj['PB'] = 0.54 * 86400.
    parinj['ECC'] = 0.0001

    freqfactor = 2.  # set frequency factor
    det = 'H1'  # the detector

    # convert into GPS times
    gpstimes = lalpulsar.CreateTimestampVector(len(t4output))
    for i, time in enumerate(t4output[:, 0]):
        gpstimes.data[i] = lal.LIGOTimeGPS(time)

    detector = lalpulsar.GetSiteInfo(det)

    # set the response function look-up table
    dt = t4output[1, 0] - t4output[0, 0]  # time step
    resp = lalpulsar.DetResponseLookupTable(t4output[0, 0], detector,
                                            parhet['RAJ'], parhet['DECJ'],
                                            2880, dt)

    # get the heterodyned file SSB delay
    hetSSBdelay = lalpulsar.HeterodynedPulsarGetSSBDelay(
        parhet.PulsarParameters(), gpstimes, detector, edat, tdat,
        lalpulsar.TIMECORRECTION_TCB)

    # get the heterodyned file BSB delay
    hetBSBdelay = lalpulsar.HeterodynedPulsarGetBSBDelay(
        parhet.PulsarParameters(), gpstimes, hetSSBdelay, edat)

    fullsignal = lalpulsar.HeterodynedPulsarGetModel(
        parinj.PulsarParameters(),
        freqfactor,
        1,  # phase is varying between par files
        0,  # not using ROQ
        0,  # not using non-tensorial modes
        gpstimes,
        hetSSBdelay,
        1,  # the SSB delay should be updated compared to hetSSBdelay
        hetBSBdelay,
        1,  # the BSB delay should be updated compared to hetBSBdelay
        resp,
        edat,
        tdat,
        lalpulsar.TIMECORRECTION_TCB)

    # check output matches that from lalapps_pulsar_parameter_estimation_nested
    if np.any(np.abs(fullsignal.data.data.real - t4output[:, 1]) > 1e-33):
        return False
    elif np.any(np.abs(fullsignal.data.data.imag - t4output[:, 2]) > 1e-33):
        return False
    else:
        return True
Example #10
0
    def __init__(self,
                 data,
                 priors,
                 par=None,
                 det=None,
                 likelihood="studentst",
                 numba=False):

        super().__init__(dict())  # initialise likelihood class

        # set the data
        if isinstance(data, HeterodynedData):
            # convert HeterodynedData to MultiHeterodynedData object
            if data.detector is None:
                raise ValueError("'data' must contain a named detector.")

            if data.par is None:
                raise ValueError(
                    "'data' must contain a heterodyne parameter file.")

            self.data = MultiHeterodynedData(data)
        elif isinstance(data, MultiHeterodynedData):
            if None in data.pars:
                raise ValueError("A data set does not have an associated "
                                 "heterodyned parameter set.")

            self.data = data
        else:
            raise TypeError(
                "'data' must be a HeterodynedData or MultiHeterodynedData object."
            )

        if not isinstance(priors, bilby.core.prior.PriorDict):
            raise TypeError("Prior must be a bilby PriorDict")
        else:
            self.priors = priors

        # set the likelihood function
        self.likelihood = likelihood
        self._noise_log_likelihood = -np.inf  # initialise noise log likelihood
        self.numba = numba

        # check if prior includes (non-DeltaFunction) non-amplitude parameters,
        # i.e., will the phase evolution have to be included in the search,
        # or binary parameters
        self.include_phase = False
        self.include_binary = False
        self.include_glitch = False
        self.update_ssb = False
        for key in self.priors:
            if (key.upper() not in self.AMPLITUDE_PARAMS + self.BINARY_PARAMS +
                    self.POSITIONAL_PARAMETERS) and not self._is_vector_param(
                        key.upper()):
                raise ValueError(
                    "Unknown parameter '{}' being used!".format(key))

            if key.upper() not in self.AMPLITUDE_PARAMS:
                if self.priors[key].is_fixed:
                    # check if it's the same value as the par files
                    for het in self.data:
                        if self._is_vector_param(key.upper()):
                            name, idx = self._vector_param_name_index(
                                key.upper())
                            checkval = het.par[name][idx]
                        else:
                            checkval = het.par[key.upper()]

                        if checkval != self.priors[key].peak:
                            self.include_phase = True
                            if key.upper() in self.BINARY_PARAMS:
                                self.include_binary = True
                            elif key.upper() in self.POSITIONAL_PARAMETERS:
                                self.update_ssb = True
                            elif len(key) > 2:
                                if key.upper()[0:2] == "GL":
                                    self.include_glitch = True
                            break
                else:
                    self.include_phase = True
                    if key.upper() in self.BINARY_PARAMS:
                        self.include_binary = True
                    elif key.upper() in self.POSITIONAL_PARAMETERS:
                        self.update_ssb = True
                    elif len(key) > 2:
                        if key.upper()[0:2] == "GL":
                            self.include_glitch = True

        # check if any non-GR "amplitude" parameters are set
        self.nonGR = False
        for key in self.priors:
            if key.upper() in self.NONGR_AMPLITUDE_PARAM:
                self.nonGR = True

        # set up signal model classes
        self.models = []
        self.basepars = []
        for het in self.data:
            self.models.append(
                HeterodynedCWSimulator(
                    het.par,
                    het.detector,
                    het.times,
                    earth_ephem=het.ephemearth,
                    sun_ephem=het.ephemsun,
                ))
            # copy of heterodyned parameters
            newpar = PulsarParametersPy()
            for item in het.par.items():
                newpar[item[0]] = item[1]
            self.basepars.append(newpar)

        # if phase evolution is not in the model set the pre-summed products
        # of the data and antenna patterns
        if not self.include_phase:
            self.dot_products()
Example #11
0
def test_seven():
    parhet = PulsarParametersPy()
    parhet['F'] = [153.4567, -2.876e-11]  # set frequency
    parhet['RAJ'] = lal.TranslateHMStoRAD('04:23:34.6')  # set right ascension
    parhet['DECJ'] = lal.TranslateDMStoRAD('-05:01:23.5')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('55810')
    parhet['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds

    parinj = PulsarParametersPy()
    parinj['F'] = [153.456789, -2.87654321e-11]  # set frequency
    parinj['RAJ'] = lal.TranslateHMStoRAD('04:23:34.5')  # set right ascension
    parinj['DECJ'] = lal.TranslateDMStoRAD('-05:01:23.4')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('55810')
    parinj['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds
    parinj['BINARY'] = 'BT'
    T0 = lal.TranslateStringMJDTTtoGPS('58121.3')
    parinj['T0'] = T0.gpsSeconds + 1e-9 * T0.gpsNanoSeconds
    parinj['OM'] = np.deg2rad(7.2)
    parinj['A1'] = 14.9
    parinj['PB'] = 1.03 * 86400.0
    parinj['ECC'] = 0.0002
    parinj['GLF0'] = [7.4e-6, 3.4e-7]
    parinj['GLF1'] = [-3.2e-12, -1.2e-14]
    parinj['GLF0D'] = [1.2e-5, -0.4e-6]
    parinj['GLTD'] = [0.41 * 86400, 1.45 * 86400]
    parinj['GLPH'] = [0.3, 0.91]
    glep1 = lal.TranslateStringMJDTTtoGPS('55818.08161090822')
    glep2 = lal.TranslateStringMJDTTtoGPS('55818.08276831563')
    parinj['GLEP'] = [
        glep1.gpsSeconds + 1e-9 * glep1.gpsNanoSeconds,
        glep2.gpsSeconds + 1e-9 * glep2.gpsNanoSeconds
    ]
    waveep = lal.TranslateStringMJDTTtoGPS('55818.0')
    parinj['WAVEEPOCH'] = waveep.gpsSeconds + 1e-9 * waveep.gpsNanoSeconds
    parinj['WAVE_OM'] = 0.005
    parinj['WAVESIN'] = [0.098, 0.078, -0.03]
    parinj['WAVECOS'] = [0.056, -0.071, -0.12]

    freqfactor = 2.  # set frequency factor
    det = 'H1'  # the detector

    # convert into GPS times
    gpstimes = lalpulsar.CreateTimestampVector(len(t7output))
    for i, time in enumerate(np.linspace(1000000000.0, 1000000540.0, 10)):
        gpstimes.data[i] = lal.LIGOTimeGPS(time)

    detector = lalpulsar.GetSiteInfo(det)

    # replicate coarse heterodyne in which no SSB/BSB delay is applied
    hetSSBdelay = lal.CreateREAL8Vector(len(t6output))
    hetBSBdelay = lal.CreateREAL8Vector(len(t6output))
    for i in range(len(t6output)):
        hetSSBdelay.data[i] = 0.0
        hetBSBdelay.data[i] = 0.0

    # get the heterodyne glitch phase (which should be zero)
    glphase = lalpulsar.HeterodynedPulsarGetGlitchPhase(
        parhet.PulsarParameters(), gpstimes, hetSSBdelay, hetBSBdelay)

    assert_equal(glphase.data, np.zeros(len(t7output)))

    # get the FITWAVES phase (which should be zero)
    fwphase = lalpulsar.HeterodynedPulsarGetFITWAVESPhase(
        parhet.PulsarParameters(), gpstimes, hetSSBdelay, parhet["F0"])

    assert_equal(fwphase.data, np.zeros(len(t7output)))

    fullphase = lalpulsar.HeterodynedPulsarPhaseDifference(
        parinj.PulsarParameters(),
        parhet.PulsarParameters(),
        gpstimes,
        freqfactor,
        hetSSBdelay,
        1,  # the SSB delay should be updated compared to hetSSBdelay
        hetBSBdelay,
        1,  # the BSB delay should be updated compared to hetBSBdelay
        glphase,
        1,  # the glitch phase should be updated compared to glphase
        fwphase,
        1,  # the FITWAVES phase should be updated compare to fwphase
        detector,
        edat,
        tdat,
        lalpulsar.TIMECORRECTION_TCB)

    # check output matches that from lalapps_heterodyne_pulsar
    assert_allclose(2.0 * np.pi * np.fmod(fullphase.data, 1.),
                    t7output,
                    rtol=1e-3)
Example #12
0
def test_six():
    parhet = PulsarParametersPy()
    parhet['F'] = [123.4567, -9.876e-12]  # set frequency
    parhet['RAJ'] = lal.TranslateHMStoRAD('01:23:34.6')  # set right ascension
    parhet['DECJ'] = lal.TranslateDMStoRAD('-45:01:23.5')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('58000')
    parhet['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds

    parinj = PulsarParametersPy()
    parinj['F'] = [123.456789, -9.87654321e-12]  # set frequency
    parinj['RAJ'] = lal.TranslateHMStoRAD('01:23:34.5')  # set right ascension
    parinj['DECJ'] = lal.TranslateDMStoRAD('-45:01:23.4')  # set declination
    pepoch = lal.TranslateStringMJDTTtoGPS('58000')
    parinj['PEPOCH'] = pepoch.gpsSeconds + 1e-9 * pepoch.gpsNanoSeconds
    parinj['BINARY'] = 'BT'
    T0 = lal.TranslateStringMJDTTtoGPS('58121.3')
    parinj['T0'] = T0.gpsSeconds + 1e-9 * T0.gpsNanoSeconds
    parinj['OM'] = np.deg2rad(1.2)
    parinj['A1'] = 8.9
    parinj['PB'] = 0.54 * 86400.0
    parinj['ECC'] = 0.0001
    parinj['GLF0'] = [5.4e-6, 3.4e-7]
    parinj['GLF1'] = [-3.2e-13, -1.2e-14]
    parinj['GLF0D'] = [1.2e-5, -0.4e-6]
    parinj['GLTD'] = [0.31 * 86400, 0.45 * 86400]
    parinj['GLPH'] = [0.3, 0.7]
    glph1 = lal.TranslateStringMJDTTtoGPS('55818.08161090822')
    glph2 = lal.TranslateStringMJDTTtoGPS('55818.08276831563')
    parinj['GLEP'] = [
        glph1.gpsSeconds + 1e-9 * glph1.gpsNanoSeconds,
        glph2.gpsSeconds + 1e-9 * glph2.gpsNanoSeconds
    ]

    freqfactor = 2.  # set frequency factor
    det = 'H1'  # the detector

    # convert into GPS times
    gpstimes = lalpulsar.CreateTimestampVector(len(t6output))
    for i, time in enumerate(np.linspace(1000000000.0, 1000000540.0, 10)):
        gpstimes.data[i] = lal.LIGOTimeGPS(time)

    detector = lalpulsar.GetSiteInfo(det)

    # replicate coarse heterodyne in which no SSB/BSB delay is applied
    hetSSBdelay = lal.CreateREAL8Vector(len(t6output))
    hetBSBdelay = lal.CreateREAL8Vector(len(t6output))
    for i in range(len(t6output)):
        hetSSBdelay.data[i] = 0.0
        hetBSBdelay.data[i] = 0.0

    # get the heterodyne glitch phase (which should be zero)
    glphase = lalpulsar.HeterodynedPulsarGetGlitchPhase(
        parhet.PulsarParameters(), gpstimes, hetSSBdelay, hetBSBdelay)

    fullphase = lalpulsar.HeterodynedPulsarPhaseDifference(
        parinj.PulsarParameters(),
        parhet.PulsarParameters(),
        gpstimes,
        freqfactor,
        hetSSBdelay,
        1,  # the SSB delay should be updated compared to hetSSBdelay
        hetBSBdelay,
        1,  # the BSB delay should be updated compared to hetBSBdelay
        glphase,
        1,  # the glitch phase should be updated compared to glphase
        None,
        0,
        detector,
        edat,
        tdat,
        lalpulsar.TIMECORRECTION_TCB)

    # check output matches that from lalapps_heterodyne_pulsar
    assert_allclose(2.0 * np.pi * np.fmod(fullphase.data, 1.),
                    t6output,
                    rtol=1e-4)
Example #13
0
    def test_parse_parfile(self):
        """
        Test parsing of a pulsar '.par' parameter file.
        """

        # set data
        times = np.linspace(1000000000.0, 1000086340.0, 1440)
        data = np.random.normal(
            0.0, 1e-25,
            size=1440) + 1j * np.random.normal(0.0, 1e-25, size=1440)

        # set detector
        det = "H1"

        parcontent = """\
PSRJ     J0123+3456
RAJ      01:23:45.6789
DECJ     34:56:54.321
F0       567.89
F1       -1.2e-12
PEPOCH   56789
H0       9.87e-26
COSIOTA  0.3
PSI      1.1
PHI0     2.4
"""

        # try passing a none str or PulsarParameterPy object
        parfile = 1
        with pytest.raises(TypeError):
            HeterodynedData(data, times=times, detector=det, par=parfile)

        parfile = "J0123+3456.par"

        # try reading parfile that doesn't exists
        with pytest.raises(IOError):
            HeterodynedData(data, times=times, detector=det, par=parfile)

        # add content to the par file
        with open(parfile, "w") as fp:
            fp.write(parcontent)

        het = HeterodynedData(data, times=times, detector=det, par=parfile)

        assert isinstance(het.par, PulsarParametersPy)
        assert len(het.par["F"]) == 2
        assert (het.par["F"][0] == 567.89) and (het.par["F"][1] == -1.2e-12)
        assert ((het.par["H0"] == 9.87e-26) and (het.par["COSIOTA"] == 0.3)
                and (het.par["PSI"] == 1.1) and (het.par["PHI0"] == 2.4))
        assert het.par["RAJ"] == lal.TranslateHMStoRAD("01:23:45.6789")
        assert het.par["DECJ"] == lal.TranslateDMStoRAD("34:56:54.321")
        pepoch = lal.TranslateStringMJDTTtoGPS("56789")
        assert het.par["PEPOCH"] == (pepoch.gpsSeconds +
                                     1e-9 * pepoch.gpsNanoSeconds)

        # pass parameters as PulsarParametersPy object
        del het

        par = PulsarParametersPy(parfile)
        het = HeterodynedData(data, times=times, detector=det, par=par)

        assert isinstance(het.par, PulsarParametersPy)
        assert len(het.par["F"]) == len(par["F"])
        assert (het.par["F"][0] == par["F"][0]) and (het.par["F"][1]
                                                     == par["F"][1])
        assert ((het.par["H0"] == par["H0"])
                and (het.par["COSIOTA"] == par["COSIOTA"])
                and (het.par["PSI"] == par["PSI"])
                and (het.par["PHI0"] == par["PHI0"]))
        assert het.par["RAJ"] == par["RAJ"]
        assert het.par["DECJ"] == par["DECJ"]
        assert het.par["PEPOCH"] == par["PEPOCH"]

        os.remove(parfile)
Example #14
0
    def create_pulsars(self):
        """
        Create the pulsar parameter files based on the supplied distributions.
        """

        # pulsar parameter/injection file directory
        self.pulsardir = os.path.join(self.basedir, "pulsars")
        self.makedirs(self.pulsardir)

        self.pulsars = {}
        self.priors = {}
        for i in range(self.npulsars):
            # generate fake pulsar parameters
            if self.posdist is not None:
                skyloc = self.posdist.sample()

                if self._posdist_type in ["galactocentric", "galactic"]:
                    # transform coordinates if required
                    gpos = (
                        Galactocentric(
                            x=skyloc["x"] * u.kpc,
                            y=skyloc["y"] * u.kpc,
                            z=skyloc["z"] * u.kpc,
                        ) if self._posdist_type == "galactocentric" else
                        Galactic(
                            l=skyloc["l"] * u.rad,  # noqa: E741
                            b=skyloc["b"] * u.rad,
                            distance=skyloc["dist"] * u.kpc,
                        ))
                    eqpos = gpos.transform_to(ICRS)
                    skyloc["ra"] = eqpos.ra.rad
                    skyloc["dec"] = eqpos.dec.rad
                    skyloc["dist"] = eqpos.distance.value

            if self.fdist is not None:
                freq = self.fdist.sample()

            # generate orientation parameters
            orientation = self.oridist.sample()

            if self.parfiles is None:
                pulsar = PulsarParametersPy()
                pulsar["RAJ"] = skyloc["ra"]
                pulsar["DECJ"] = skyloc["dec"]
                pulsar["DIST"] = (skyloc["dist"] * u.kpc).to("m").value

                # set pulsar name from sky position
                rastr = "".join(
                    pulsar.convert_to_tempo_units(
                        "RAJ", pulsar["RAJ"]).split(":")[:2])
                decstr = "".join(
                    pulsar.convert_to_tempo_units(
                        "DECJ", pulsar["DECJ"]).split(":")[:2])
                decstr = decstr if decstr[0] == "-" else ("+" + decstr)
                pname = "J{}{}".format(rastr, decstr)
                pnameorig = str(pname)  # copy of original name
                counter = 1
                while pname in self.pulsars:
                    anum = int_to_alpha(counter)
                    pname = pnameorig + anum
                    counter += 1

                pulsar["PSRJ"] = pname
                pulsar["F"] = [freq]

                for param in ["psi", "iota", "phi0"]:
                    pulsar[param.upper()] = orientation[param]

                # output file name
                pfile = os.path.join(self.pulsardir, "{}.par".format(pname))
                injfile = pfile

                self.priors[pname] = self.prior
            else:
                pfile = list(self.parfiles.values())[i]
                pulsar = PulsarParametersPy(pfile)
                pname = list(self.parfiles.keys())[i]
                injfile = os.path.join(self.pulsardir, "{}.par".format(pname))

                if pulsar["DIST"] is None or (self.overwrite
                                              and "dist" in skyloc):
                    # add distance if not present in parameter file
                    pulsar["DIST"] = (skyloc["dist"] * u.kpc).to("m").value

                for param in ["psi", "iota", "phi0"]:
                    # add orientation values if not present in parameter file
                    if pulsar[param.upper()] is None or (self.overwrite and
                                                         param in orientation):
                        pulsar[param.upper()] = orientation[param]

                if isinstance(self.prior, dict) and pname in self.prior:
                    # there are individual pulsar priors
                    self.priors[pname] = self.prior[pname]
                else:
                    self.priors[pname] = self.prior

            # check whether to add distance uncertainties to priors
            if self.distance_err is not None:
                dist = None
                if isinstance(self.distance_err, float):
                    # set truncated Gaussian prior
                    dist = bilby.core.prior.TruncatedGaussian(
                        pulsar["DIST"],
                        self.distance_err * pulsar["DIST"],
                        0.0,
                        np.inf,
                        name="dist",
                    )
                elif pname in self.distance_err:
                    if isinstance(self.distance_err[pname], float):
                        dist = bilby.core.prior.TruncatedGaussian(
                            pulsar["DIST"],
                            self.distance_err[pname] * pulsar["DIST"],
                            0.0,
                            np.inf,
                            name="dist",
                        )
                    elif isinstance(self.distance_err[pname],
                                    bilby.core.prior.Prior):
                        dist = self.distance_err[pname]

                if dist is not None and "dist" not in self.priors[pname]:
                    # only add distance if not already specified
                    self.priors[pname]["dist"] = dist

            # set amplitude value
            amp = self.ampdist.sample() if self.ampdist is not None else None
            if self.ampdist.name == "q22" and (pulsar["Q22"] is None
                                               or self.overwrite):
                pulsar["Q22"] = amp
            elif self.ampdist.name == "h0" and (pulsar["H0"] is None
                                                or self.overwrite):
                pulsar["H0"] = amp
            elif (self.ampdist.name.lower() in [
                    "epsilon", "ell", "ellipticity"
            ]) and (pulsar["Q22"] is None or self.overwrite):
                # convert ellipticity to Q22 using fiducial moment of inertia
                pulsar["Q22"] = ellipticity_to_q22(amp)

            with open(injfile, "w") as fp:
                fp.write(str(pulsar))

            self.pulsars[pname] = {}
            self.pulsars[pname]["file"] = pfile
            self.pulsars[pname]["injection_file"] = injfile
            self.pulsars[pname]["parameters"] = pulsar
Example #15
0
    def setup_class(cls):
        # create dummy frame cache files
        cls.dummydir = "testing_frame_cache"
        os.makedirs(cls.dummydir, exist_ok=True)
        cls.dummy_cache_files = []
        for i in range(0, 5):
            dummyfile = os.path.join(cls.dummydir,
                                     "frame_cache_{0:01d}.cache".format(i))
            cls.dummy_cache_files.append(dummyfile)
            with open(dummyfile, "w") as fp:
                fp.write("blah\n")

        # create some fake data frames using lalapps_Makefakedata_v5
        mfd = shutil.which("lalapps_Makefakedata_v5")

        cls.fakedatadir = "testing_fake_frame_cache"
        cls.fakedatadetectors = ["H1", "L1"]
        cls.fakedatachannels = [
            "{}:FAKE_DATA".format(det) for det in cls.fakedatadetectors
        ]
        cls.fakedatastarts = [1000000000, 1000000000 + 86400 * 2]
        cls.fakedataduration = 86400

        os.makedirs(cls.fakedatadir, exist_ok=True)

        cls.fakedatabandwidth = 8  # Hz
        sqrtSn = 1e-29  # noise amplitude spectral density
        cls.fakedataname = "FAKEDATA"

        # Create two pulsars to inject: one isolated and one binary
        cls.fakepulsarpar = []

        # requirements for Makefakedata pulsar input files
        isolatedstr = """\
Alpha = {alpha}
Delta = {delta}
Freq = {f0}
f1dot = {f1}
f2dot = {f2}
refTime = {pepoch}
h0 = {h0}
cosi = {cosi}
psi = {psi}
phi0 = {phi0}
"""

        binarystr = """\
orbitasini = {asini}
orbitPeriod = {period}
orbitTp = {Tp}
orbitArgp = {argp}
orbitEcc = {ecc}
"""

        transientstr = """\
transientWindowType = {wintype}
transientStartTime = {tstart}
transientTau = {tau}
"""

        # FIRST PULSAR (ISOLATED)
        f0 = 6.9456 / 2.0  # source rotation frequency (Hz)
        f1 = -9.87654e-11 / 2.0  # source rotational frequency derivative (Hz/s)
        f2 = 2.34134e-18 / 2.0  # second frequency derivative (Hz/s^2)
        alpha = 0.0  # source right ascension (rads)
        delta = 0.5  # source declination (rads)
        pepoch = 1000000000  # frequency epoch (GPS)

        # GW parameters
        h0 = 3.0e-24  # GW amplitude
        phi0 = 1.0  # GW initial phase (rads)
        cosiota = 0.1  # cosine of inclination angle
        psi = 0.5  # GW polarisation angle (rads)

        mfddic = {
            "alpha": alpha,
            "delta": delta,
            "f0": 2 * f0,
            "f1": 2 * f1,
            "f2": 2 * f2,
            "pepoch": pepoch,
            "h0": h0,
            "cosi": cosiota,
            "psi": psi,
            "phi0": phi0,
        }

        cls.fakepulsarpar.append(PulsarParametersPy())
        cls.fakepulsarpar[0]["PSRJ"] = "J0000+0000"
        cls.fakepulsarpar[0]["H0"] = h0
        cls.fakepulsarpar[0]["PHI0"] = phi0 / 2.0
        cls.fakepulsarpar[0]["PSI"] = psi
        cls.fakepulsarpar[0]["COSIOTA"] = cosiota
        cls.fakepulsarpar[0]["F"] = [f0, f1, f2]
        cls.fakepulsarpar[0]["RAJ"] = alpha
        cls.fakepulsarpar[0]["DECJ"] = delta
        cls.fakepulsarpar[0]["PEPOCH"] = pepoch
        cls.fakepulsarpar[0]["EPHEM"] = "DE405"
        cls.fakepulsarpar[0]["UNITS"] = "TDB"

        cls.fakepardir = "testing_fake_par_dir"
        os.makedirs(cls.fakepardir, exist_ok=True)
        cls.fakeparfile = []
        cls.fakeparfile.append(os.path.join(cls.fakepardir, "J0000+0000.par"))
        cls.fakepulsarpar[0].pp_to_par(cls.fakeparfile[-1])

        injfile = os.path.join(cls.fakepardir, "inj.dat")
        with open(injfile, "w") as fp:
            fp.write("[Pulsar 1]\n")
            fp.write(isolatedstr.format(**mfddic))
            fp.write("\n")

        # SECOND PULSAR (BINARY SYSTEM)
        f0 = 3.8654321 / 2.0  # source rotation frequency (Hz)
        f1 = 9.87654e-13 / 2.0  # source rotational frequency derivative (Hz/s)
        f2 = -1.34134e-20 / 2.0  # second frequency derivative (Hz/s^2)
        alpha = 1.3  # source right ascension (rads)
        delta = -0.4  # source declination (rads)
        pepoch = 1000086400  # frequency epoch (GPS)

        # GW parameters
        h0 = 7.5e-25  # GW amplitude
        phi0 = 0.7  # GW initial phase (rads)
        cosiota = 0.6  # cosine of inclination angle
        psi = 1.1  # GW polarisation angle (rads)

        # binary parameters
        asini = 1.4  # projected semi-major axis (ls)
        period = 0.1 * 86400  # orbital period (s)
        Tp = 999992083  # time of periastron (GPS)
        argp = 0.0  # argument of perisatron (rad)
        ecc = 0.09  # the orbital eccentricity

        mfddic = {
            "alpha": alpha,
            "delta": delta,
            "f0": 2 * f0,
            "f1": 2 * f1,
            "f2": 2 * f2,
            "pepoch": pepoch,
            "h0": h0,
            "cosi": cosiota,
            "psi": psi,
            "phi0": phi0,
        }

        mfdbindic = {
            "asini": asini,
            "Tp": Tp,
            "period": period,
            "argp": argp,
            "ecc": ecc,
        }

        cls.fakepulsarpar.append(PulsarParametersPy())
        cls.fakepulsarpar[1]["PSRJ"] = "J1111+1111"
        cls.fakepulsarpar[1]["H0"] = h0
        cls.fakepulsarpar[1]["PHI0"] = phi0 / 2.0
        cls.fakepulsarpar[1]["PSI"] = psi
        cls.fakepulsarpar[1]["COSIOTA"] = cosiota
        cls.fakepulsarpar[1]["F"] = [f0, f1, f2]
        cls.fakepulsarpar[1]["RAJ"] = alpha
        cls.fakepulsarpar[1]["DECJ"] = delta
        cls.fakepulsarpar[1]["PEPOCH"] = pepoch
        cls.fakepulsarpar[1]["BINARY"] = "BT"
        cls.fakepulsarpar[1]["E"] = ecc
        cls.fakepulsarpar[1]["A1"] = asini
        cls.fakepulsarpar[1]["T0"] = Tp
        cls.fakepulsarpar[1]["OM"] = argp
        cls.fakepulsarpar[1]["PB"] = period
        cls.fakepulsarpar[1]["EPHEM"] = "DE405"
        cls.fakepulsarpar[1]["UNITS"] = "TDB"

        cls.fakeparfile.append(os.path.join(cls.fakepardir, "J1111+1111.par"))
        cls.fakepulsarpar[1].pp_to_par(cls.fakeparfile[-1])

        with open(injfile, "a") as fp:
            fp.write("[Pulsar 2]\n")
            fp.write(isolatedstr.format(**mfddic))
            fp.write(binarystr.format(**mfdbindic))
            fp.write("\n")

        # THIRD PULSAR (GLITCHING PULSAR)
        f0 = 5.3654321 / 2.0  # source rotation frequency (Hz)
        f1 = -4.57654e-10 / 2.0  # source rotational frequency derivative (Hz/s)
        f2 = 1.34134e-18 / 2.0  # second frequency derivative (Hz/s^2)
        alpha = 4.6  # source right ascension (rads)
        delta = -0.9  # source declination (rads)
        pepoch = 1000000000 + 1.5 * 86400  # frequency epoch (GPS)

        # glitch parameters
        df0 = 0.0001  # EM glitch frequency jump
        df1 = 1.2e-11  # EM glitch frequency derivative jump
        df2 = -4.5e-19  # EM glitch frequency second derivative jump
        dphi = 1.1  # EM glitch phase offset
        glepoch = pepoch  # glitch epoch

        # GW parameters
        h0 = 8.7e-25  # GW amplitude
        phi0 = 0.142  # GW initial phase (rads)
        cosiota = -0.3  # cosine of inclination angle
        psi = 0.52  # GW polarisation angle (rads)

        # binary parameters
        asini = 2.9  # projected semi-major axis (ls)
        period = 0.3 * 86400  # orbital period (s)
        Tp = 999995083  # time of periastron (GPS)
        argp = 0.5  # argument of perisatron (rad)
        ecc = 0.09  # the orbital eccentricity

        # for MFD I need to create this as two transient pulsars using a
        # rectangular window cutting before and after the glitch
        mfddic = {
            "alpha": alpha,
            "delta": delta,
            "f0": 2 * f0,
            "f1": 2 * f1,
            "f2": 2 * f2,
            "pepoch": pepoch,
            "h0": h0,
            "cosi": cosiota,
            "psi": psi,
            "phi0": phi0,
        }

        mfdbindic = {
            "asini": asini,
            "Tp": Tp,
            "period": period,
            "argp": argp,
            "ecc": ecc,
        }

        mfdtransientdic = {
            "wintype": "rect",
            "tstart": cls.fakedatastarts[0],
            "tau": 86400,
        }

        # signal before the glitch
        with open(injfile, "a") as fp:
            fp.write("[Pulsar 3]\n")
            fp.write(isolatedstr.format(**mfddic))
            fp.write(binarystr.format(**mfdbindic))
            fp.write(transientstr.format(**mfdtransientdic))
            fp.write("\n")

        mfddic["f0"] = 2 * (f0 + df0)
        mfddic["f1"] = 2 * (f1 + df1)
        mfddic["f2"] = 2 * (f2 + df2)
        mfddic["phi0"] = phi0 + 2 * dphi

        mfdtransientdic["tstart"] = cls.fakedatastarts[1]

        # signal after the glitch
        with open(injfile, "a") as fp:
            fp.write("[Pulsar 4]\n")
            fp.write(isolatedstr.format(**mfddic))
            fp.write(binarystr.format(**mfdbindic))
            fp.write(transientstr.format(**mfdtransientdic))

        cls.fakepulsarpar.append(PulsarParametersPy())
        cls.fakepulsarpar[2]["PSRJ"] = "J2222+2222"
        cls.fakepulsarpar[2]["H0"] = h0
        cls.fakepulsarpar[2]["PHI0"] = phi0 / 2.0
        cls.fakepulsarpar[2]["PSI"] = psi
        cls.fakepulsarpar[2]["COSIOTA"] = cosiota
        cls.fakepulsarpar[2]["F"] = [f0, f1, f2]
        cls.fakepulsarpar[2]["RAJ"] = alpha
        cls.fakepulsarpar[2]["DECJ"] = delta
        cls.fakepulsarpar[2]["PEPOCH"] = pepoch
        cls.fakepulsarpar[2]["BINARY"] = "BT"
        cls.fakepulsarpar[2]["E"] = ecc
        cls.fakepulsarpar[2]["A1"] = asini
        cls.fakepulsarpar[2]["T0"] = Tp
        cls.fakepulsarpar[2]["OM"] = argp
        cls.fakepulsarpar[2]["PB"] = period
        cls.fakepulsarpar[2]["EPHEM"] = "DE405"
        cls.fakepulsarpar[2]["UNITS"] = "TDB"
        cls.fakepulsarpar[2]["GLEP"] = [glepoch]
        cls.fakepulsarpar[2]["GLF0"] = [df0]
        cls.fakepulsarpar[2]["GLF1"] = [df1]
        cls.fakepulsarpar[2]["GLF2"] = [df2]
        cls.fakepulsarpar[2]["GLPH"] = [dphi / (2 * np.pi)]

        cls.fakeparfile.append(os.path.join(cls.fakepardir, "J2222+2222.par"))
        cls.fakepulsarpar[2].pp_to_par(cls.fakeparfile[-1])

        # set ephemeris files
        efile = download_file(DOWNLOAD_URL.format("earth00-40-DE405.dat.gz"),
                              cache=True)
        sfile = download_file(DOWNLOAD_URL.format("sun00-40-DE405.dat.gz"),
                              cache=True)

        for datastart in cls.fakedatastarts:
            for i in range(len(cls.fakedatachannels)):
                cmds = [
                    "-F",
                    cls.fakedatadir,
                    "--outFrChannels={}".format(cls.fakedatachannels[i]),
                    "-I",
                    cls.fakedatadetectors[i],
                    "--sqrtSX={0:.1e}".format(sqrtSn),
                    "-G",
                    str(datastart),
                    "--duration={}".format(cls.fakedataduration),
                    "--Band={}".format(cls.fakedatabandwidth),
                    "--fmin",
                    "0",
                    '--injectionSources="{}"'.format(injfile),
                    "--outLabel={}".format(cls.fakedataname),
                    '--ephemEarth="{}"'.format(efile),
                    '--ephemSun="{}"'.format(sfile),
                ]

                # run makefakedata
                sp.run([mfd] + cmds)

        # create dummy segment file
        cls.dummysegments = [(1000000000, 1000000600),
                             (1000000800, 1000000900)]
        cls.dummysegmentfile = os.path.join(cls.fakedatadir,
                                            "fakesegments.txt")
        with open(cls.dummysegmentfile, "w") as fp:
            for segs in cls.dummysegments:
                fp.write("{} {}\n".format(segs[0], segs[1]))