Exemplo n.º 1
0
def create_FIR_whitener_kernel(length, duration, sample_rate, psd):
    assert psd
    #
    # Add another COMPLEX16TimeSeries and COMPLEX16FrequencySeries for kernel's FFT (Leo)
    #

    # Add another FFT plan for kernel FFT (Leo)
    fwdplan_kernel = lal.CreateForwardCOMPLEX16FFTPlan(length, 1)
    kernel_tseries = lal.CreateCOMPLEX16TimeSeries(
        name="timeseries of whitening kernel",
        epoch=LIGOTimeGPS(0.),
        f0=0.,
        deltaT=1.0 / sample_rate,
        length=length,
        sampleUnits=lal.Unit("strain"))
    kernel_fseries = lal.CreateCOMPLEX16FrequencySeries(
        name="freqseries of whitening kernel",
        epoch=LIGOTimeGPS(0),
        f0=0.0,
        deltaF=1.0 / duration,
        length=length,
        sampleUnits=lal.Unit("strain s"))

    #
    # Obtain a kernel of zero-latency whitening filter and
    # adjust its length (Leo)
    #

    psd_fir_kernel = reference_psd.PSDFirKernel()
    (kernel, latency,
     fir_rate) = psd_fir_kernel.psd_to_linear_phase_whitening_fir_kernel(
         psd, nyquist=sample_rate / 2.0)
    (
        kernel, theta
    ) = psd_fir_kernel.linear_phase_fir_kernel_to_minimum_phase_whitening_fir_kernel(
        kernel, fir_rate)
    kernel = kernel[-1::-1]
    # FIXME this is off by one sample, but shouldn't be. Look at the miminum phase function
    # assert len(kernel) == length
    if len(kernel) < length:
        kernel = numpy.append(kernel, numpy.zeros(length - len(kernel)))
    else:
        kernel = kernel[:length]

    kernel_tseries.data.data = kernel

    #
    # FFT of the kernel
    #

    lal.COMPLEX16TimeFreqFFT(kernel_fseries, kernel_tseries,
                             fwdplan_kernel)  #FIXME

    return kernel_fseries
Exemplo n.º 2
0
def _parse_series(elem, creatorfunc, delta_target_unit_string):
    t, = elem.getElementsByTagName(ligolw.Time.tagName)
    a, = elem.getElementsByTagName(ligolw.Array.tagName)
    dims = a.getElementsByTagName(ligolw.Dim.tagName)
    f0 = ligolw_param.get_param(elem, u"f0")

    if t.Type != u"GPS":
        raise ValueError("epoch Type must be GPS")
    epoch = t.pcdata

    # Target units: inverse seconds
    inverse_seconds_unit = lal.Unit("s^-1")

    delta_target_unit = lal.Unit(delta_target_unit_string)

    # Parse units of f0 field
    f0_unit = lal.Unit(str(f0.Unit))

    # Parse units of deltaF field
    delta_unit = lal.Unit(str(dims[0].Unit))

    # Parse units of data
    sample_unit = lal.Unit(str(a.Unit))

    # Initialize data structure
    series = creatorfunc(
        str(a.Name),
        epoch,
        f0.pcdata * float(f0_unit / inverse_seconds_unit),
        dims[0].Scale * float(delta_unit / delta_target_unit),
        sample_unit,
        len(a.array.T)
    )

    # Assign data
    if np.iscomplexobj(series.data.data):
        series.data.data = a.array[1] + 1j * a.array[2]
    else:
        series.data.data = a.array[1]

    # Done!
    return series
Exemplo n.º 3
0
def parse_REAL8FrequencySeries(elem):
    t, = elem.getElementsByTagName(ligolw.Time.tagName)
    a, = elem.getElementsByTagName(ligolw.Array.tagName)
    dims = a.getElementsByTagName(ligolw.Dim.tagName)
    f0 = ligolw_param.get_param(elem, u"f0")

    epoch = lal.LIGOTimeGPS(str(t.pcdata))

    # Target units: inverse seconds
    inverse_seconds_unit = lal.Unit()
    lal.ParseUnitString(inverse_seconds_unit, "s^-1")

    # Parse units of f0 field
    f0_unit = lal.Unit()
    lal.ParseUnitString(f0_unit, str(f0.get_unit()))

    # Parse units of deltaF field
    deltaF_unit = lal.Unit()
    lal.ParseUnitString(deltaF_unit, str(dims[0].getAttribute(u"Unit")))

    # Parse units of data
    sample_unit = lal.Unit()
    lal.ParseUnitString(sample_unit, str(a.getAttribute(u"Unit")))

    # Parse data
    data = a.array[1]

    # Initialize data structure
    series = lal.CreateREAL8FrequencySeries(
        str(a.getAttribute(u"Name")), epoch,
        float(f0.pcdata) * lal.UnitRatio(f0_unit, inverse_seconds_unit),
        float(dims[0].getAttribute(u"Scale")) *
        lal.UnitRatio(deltaF_unit, inverse_seconds_unit), sample_unit,
        len(data))

    # Copy data
    series.data.data = data

    # Done!
    return series
Exemplo n.º 4
0
def to_lal_unit(aunit):
    """Convert the input unit into a `LALUnit`

    For example::

       >>> u = to_lal_unit('m**2 / kg ** 4')
       >>> print(u)
       m^2 kg^-4

    Parameters
    ----------
    aunit : `~astropy.units.Unit`, `str`
        the input unit

    Returns
    -------
    unit : `LALUnit`
        the LALUnit representation of the input

    Raises
    ------
    ValueError
        if LAL doesn't understand the base units for the input
    """
    if isinstance(aunit, string_types):
        aunit = units.Unit(aunit)
    aunit = aunit.decompose()
    lunit = lal.Unit()
    for base, power in zip(aunit.bases, aunit.powers):
        # try this base
        try:
            lalbase = LAL_UNIT_FROM_ASTROPY[base]
        except KeyError:
            lalbase = None
            # otherwise loop through the equivalent bases
            for eqbase in base.find_equivalent_units():
                try:
                    lalbase = LAL_UNIT_FROM_ASTROPY[eqbase]
                except KeyError:
                    continue
        # if we didn't find anything, raise an exception
        if lalbase is None:
            raise ValueError("LAL has no unit corresponding to %r" % base)
        lunit *= lalbase**power
    return lunit
Exemplo n.º 5
0
 def snr_time_series(self):
     try:
         name = self._snr_name
     except ValueError:
         # C interface raises ValueError if the internal snr
         # pointer is NULL
         return None
     series = lal.CreateCOMPLEX8TimeSeries(
         name,
         lal.LIGOTimeGPS(self._snr_epoch_gpsSeconds,
                         self._snr_epoch_gpsNanoSeconds), self._snr_f0,
         self._snr_deltaT, lal.Unit(self._snr_sampleUnits),
         self._snr_data_length)
     # we want to be able to keep the table row object in memory
     # for an extended period of time so we need to be able to
     # release the memory used by the SNR time series when we no
     # longer need it, and so we copy the data here instead of
     # holding a reference to the original memory.  if we
     # allowed references to the original memory to leak out
     # into Python land we could never know if it's safe to free
     # it
     series.data.data[:] = self._snr_data
     return series
Exemplo n.º 6
0
assert (is_value_and_type(tsw + tmy, tsw + tsw, LIGOTimeGPS))
assert (is_value_and_type(tmy + tsw, tsw + tsw, LIGOTimeGPS))
assert (is_value_and_type(tsw - tmy, tsw - tsw, LIGOTimeGPS))
assert (is_value_and_type(tmy - tsw, tsw - tsw, LIGOTimeGPS))
assert (is_value_and_type(tsw * tmy, tsw * tsw, LIGOTimeGPS))
assert (is_value_and_type(tmy * tsw, tsw * tsw, LIGOTimeGPS))
assert (is_value_and_type(tsw / tmy, tsw / tsw, LIGOTimeGPS))
assert (is_value_and_type(tmy / tsw, tsw / tsw, LIGOTimeGPS))
assert (lal.swig_lal_test_noptrgps(tmy) == lal.swig_lal_test_noptrgps(tsw))
del tsw
lal.CheckMemoryLeaks()
print("PASSED LIGOTimeGPS operations (Python specific)")

# check LALUnit operations
print("checking LALUnit operations ...")
u1 = lal.Unit("kg m s^-2")
assert (type(lal.Unit(u1)) is lal.Unit)
assert (is_value_and_type(u1, lal.NewtonUnit, lal.Unit))
assert (str(u1) == "m kg s^-2")
u2 = lal.MeterUnit * lal.KiloGramUnit / lal.SecondUnit**2
assert (is_value_and_type(u2, u1, lal.Unit))
u2 = lal.MeterUnit**(1, 2) * lal.KiloGramUnit**(1, 2) * lal.SecondUnit**-1
assert (is_value_and_type(u2, u1**(1, 2), lal.Unit))
try:
    lal.SecondUnit**(1, 0)
    expected_exception = True
except:
    pass
assert (not expected_exception)
u1 *= lal.MeterUnit
assert (is_value_and_type(u1, lal.JouleUnit, lal.Unit))
Exemplo n.º 7
0
assert (tmy + tsw == tsw + tsw and isinstance(tmy + tsw, LIGOTimeGPS))
assert (tsw - tmy == tsw - tsw and isinstance(tsw - tmy, LIGOTimeGPS))
assert (tmy - tsw == tsw - tsw and isinstance(tmy - tsw, LIGOTimeGPS))
assert (tsw * tmy == tsw * tsw and isinstance(tsw * tmy, LIGOTimeGPS))
assert (tmy * tsw == tsw * tsw and isinstance(tmy * tsw, LIGOTimeGPS))
if swig_division_coercion_works:  # FIXME: https://github.com/swig/swig/pull/617
    assert (tsw / tmy == tsw / tsw and isinstance(tsw / tmy, LIGOTimeGPS))
    assert (tmy / tsw == tsw / tsw and isinstance(tmy / tsw, LIGOTimeGPS))
assert (lal.swig_lal_test_noptrgps(tmy) == lal.swig_lal_test_noptrgps(tsw))
del tsw
lal.CheckMemoryLeaks()
print("PASSED LIGOTimeGPS operations (Python specific)")

# check LALUnit operations
print("checking LALUnit operations ...")
u1 = lal.Unit("kg m s^-2")
assert (isinstance(lal.Unit(u1), lal.Unit))
assert (u1 == lal.NewtonUnit and isinstance(u1, lal.Unit))
assert (str(u1) == "m kg s^-2")
if swig_division_coercion_works:  # FIXME: https://github.com/swig/swig/pull/617
    u2 = lal.MeterUnit * lal.KiloGramUnit / lal.SecondUnit**2
    assert (u1 == u2 and isinstance(u2, lal.Unit))
u2 = lal.MeterUnit**(1, 2) * lal.KiloGramUnit**(1, 2) * lal.SecondUnit**-1
assert (u1**(1, 2) == u2 and isinstance(u2, lal.Unit))
try:
    lal.SecondUnit**(1, 0)
    expected_exception = True
except:
    pass
assert (not expected_exception)
u1 *= lal.MeterUnit
Exemplo n.º 8
0
import math
from scipy import optimize

# LAL imports
import lal
import lalsimulation

# My own imports
from .decorator import memoized


log = logging.getLogger('BAYESTAR')


# Useful sample units
unitInverseHertz = lal.Unit('s')
unitInverseSqrtHertz = lal.Unit('s^1/2')


# Memoize FFT plans
CreateForwardCOMPLEX16FFTPlan = memoized(lal.CreateForwardCOMPLEX16FFTPlan)
CreateForwardREAL8FFTPlan = memoized(lal.CreateForwardREAL8FFTPlan)
CreateReverseCOMPLEX16FFTPlan = memoized(lal.CreateReverseCOMPLEX16FFTPlan)
CreateReverseREAL8FFTPlan = memoized(lal.CreateReverseREAL8FFTPlan)


def ceil_pow_2(n):
    """Return the least integer power of 2 that is greater than or equal to n.

    >>> ceil_pow_2(128.0)
    128.0
Exemplo n.º 9
0
    prefix = detector.frDetector.prefix
    detectors.append(prefix)
    parser.add_option(
        '--' + prefix,
        choices=psd_names,
        metavar='func',
        help='PSD function for {0} detector [optional]'.format(name))

# Parse command line.
opts, args = parser.parse_args()
if args:
    parser.error('Did not expect any positional command line arguments')

psds = {}

unit = lal.Unit()
unit = lal.UnitInvert(unit, lal.HertzUnit)
n = int(opts.f_max // opts.df)
epoch = lal.LIGOTimeGPS()

progress = glue.text_progress_bar.ProgressBar()

for detector in detectors:
    psd_name = getattr(opts, detector)
    if psd_name is None:
        continue
    psd_func = getattr(lalsimulation, psd_name_prefix + psd_name)
    series = lal.CreateREAL8FrequencySeries(None, epoch, 0, opts.df, unit, n)
    fmt = '%s (%%d / %d)' % (detector, n)
    for i in progress.iterate(range(1, n), format=fmt):
        f = i * opts.df
Exemplo n.º 10
0
    def __init__(self,
                 template_table,
                 approximant,
                 psd,
                 f_low,
                 time_slices,
                 autocorrelation_length=None,
                 fhigh=None):
        self.template_table = template_table
        self.approximant = approximant
        self.f_low = f_low
        self.time_slices = time_slices
        self.autocorrelation_length = autocorrelation_length
        self.fhigh = fhigh
        self.sample_rate_max = max(time_slices["rate"])
        self.duration = max(time_slices["end"])
        self.length_max = int(round(self.duration * self.sample_rate_max))

        if self.fhigh is None:
            self.fhigh = self.sample_rate_max / 2.
        # Some input checking to avoid incomprehensible error messages
        if not self.template_table:
            raise ValueError("template list is empty")
        if self.f_low < 0.:
            raise ValueError("f_low must be >= 0. %s" % repr(self.f_low))

        # working f_low to actually use for generating the waveform.  pick
        # template with lowest chirp mass, compute its duration starting
        # from f_low;  the extra time is 10% of this plus 3 cycles (3 /
        # f_low);  invert to obtain f_low corresponding to desired padding.
        # NOTE:  because SimInspiralChirpStartFrequencyBound() does not
        # account for spin, we set the spins to 0 in the call to
        # SimInspiralChirpTimeBound() regardless of the component's spins.
        template = min(self.template_table, key=lambda row: row.mchirp)
        tchirp = lalsim.SimInspiralChirpTimeBound(self.f_low,
                                                  template.mass1 * lal.MSUN_SI,
                                                  template.mass2 * lal.MSUN_SI,
                                                  0., 0.)
        self.working_f_low = lalsim.SimInspiralChirpStartFrequencyBound(
            1.1 * tchirp + 3. / self.f_low, template.mass1 * lal.MSUN_SI,
            template.mass2 * lal.MSUN_SI)

        # Add duration of PSD to template length for PSD ringing, round up to power of 2 count of samples
        self.working_length = templates.ceil_pow_2(self.length_max +
                                                   round(1. / psd.deltaF *
                                                         self.sample_rate_max))
        self.working_duration = float(
            self.working_length) / self.sample_rate_max

        if psd is not None:
            # Smooth the PSD and interpolate to required resolution
            self.psd = condition_psd(psd,
                                     1.0 / self.working_duration,
                                     minfs=(self.working_f_low, self.f_low),
                                     maxfs=(self.sample_rate_max / 2.0 * 0.90,
                                            self.sample_rate_max / 2.0))

        if FIR_WHITENER:
            # Compute a frequency response of the time-domain whitening kernel and effectively taper the psd by zero-ing some elements for a FIR kernel
            self.kernel_fseries = taperzero_fseries(create_FIR_whitener_kernel(self.working_length, self.working_duration, self.sample_rate_max, self.psd),\
                        minfs = (self.working_f_low, self.f_low),\
                        maxfs = (self.sample_rate_max / 2.0 * 0.90, self.sample_rate_max / 2.0)\
                       )

        self.revplan = lal.CreateReverseCOMPLEX16FFTPlan(
            self.working_length, 1)
        self.fwdplan = lal.CreateForwardREAL8FFTPlan(self.working_length, 1)
        self.tseries = lal.CreateCOMPLEX16TimeSeries(
            name="timeseries",
            epoch=LIGOTimeGPS(0.),
            f0=0.,
            deltaT=1.0 / self.sample_rate_max,
            length=self.working_length,
            sampleUnits=lal.Unit("strain"))
        self.fworkspace = lal.CreateCOMPLEX16FrequencySeries(
            name="template",
            epoch=LIGOTimeGPS(0),
            f0=0.0,
            deltaF=1.0 / self.working_duration,
            length=self.working_length // 2 + 1,
            sampleUnits=lal.Unit("strain s"))

        # Calculate the maximum ring down time or maximum shift time
        if approximant in templates.gstlal_IMR_approximants:
            self.max_ringtime = max([
                chirptime.ringtime(
                    row.mass1 * lal.MSUN_SI + row.mass2 * lal.MSUN_SI,
                    chirptime.overestimate_j_from_chi(
                        max(row.spin1z, row.spin2z)))
                for row in self.template_table
            ])
        else:
            if self.sample_rate_max > 2. * self.fhigh:
                # Calculate the maximum time we need to shift the early warning
                # waveforms forward by, calculated by the 3.5 approximation from
                # fhigh to ISCO.
                self.max_shift_time = max([
                    spawaveform.chirptime(
                        row.mass1, row.mass2, 7, fhigh, 0.,
                        spawaveform.computechi(row.mass1, row.mass2,
                                               row.spin1z, row.spin2z))
                    for row in self.template_table
                ])
Exemplo n.º 11
0
__author__ = "Leo Singer <*****@*****.**>"

# General imports
import numpy as np
import math
from scipy import optimize

# LAL imports
import lal
import lalsimulation

# My own imports
from .decorator import memoized

# Useful sample units
unitInverseHertz = lal.Unit()
unitInverseSqrtHertz = lal.Unit()
lal.UnitInvert(unitInverseHertz, lal.lalHertzUnit)
lal.UnitSqrt(unitInverseSqrtHertz, unitInverseHertz)

# Memoize FFT plans
CreateForwardCOMPLEX16FFTPlan = memoized(lal.CreateForwardCOMPLEX16FFTPlan)
CreateForwardREAL8FFTPlan = memoized(lal.CreateForwardREAL8FFTPlan)
CreateReverseCOMPLEX16FFTPlan = memoized(lal.CreateReverseCOMPLEX16FFTPlan)
CreateReverseREAL8FFTPlan = memoized(lal.CreateReverseREAL8FFTPlan)


def ceil_pow_2(number):
    """Return the least integer power of 2 that is greater than or equal to number."""
    # frexp splits floats into mantissa and exponent, ldexp does the opposite.
    # For positive numbers, mantissa is in [0.5, 1.).