示例#1
0
def _det_tc(detector_name, ra, dec, tc, ref_frame='geocentric'):
    """Returns the coalescence time of a signal in the given detector.

    Parameters
    ----------
    detector_name : string
        The name of the detector, e.g., 'H1'.
    ra : float
        The right ascension of the signal, in radians.
    dec : float
        The declination of the signal, in radians.
    tc : float
        The GPS time of the coalescence of the signal in the `ref_frame`.
    ref_frame : {'geocentric', string}
        The reference frame that the given coalescence time is defined in.
        May specify 'geocentric', or a detector name; default is 'geocentric'.

    Returns
    -------
    float :
        The GPS time of the coalescence in detector `detector_name`.
    """
    if ref_frame == detector_name:
        return tc
    detector = Detector(detector_name)
    if ref_frame == 'geocentric':
        return tc + detector.time_delay_from_earth_center(ra, dec, tc)
    else:
        other = Detector(ref_frame)
        return tc + detector.time_delay_from_detector(other, ra, dec, tc)
示例#2
0
    def make_strain_from_inj_object(self, inj, delta_t, detector_name):
        """Make a h(t) strain time-series from an injection object as read from
        an hdf file.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)

        # compute the waveform time series
        hp, hc = ringdown_td_approximants[inj['approximant']](delta_t=delta_t,
                                                              **inj)

        hp._epoch += inj['tc']
        hc._epoch += inj['tc']

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp, hc, inj['ra'], inj['dec'],
                                       inj['polarization'])

        return signal
示例#3
0
    def make_strain_from_inj_object(self, inj, delta_t, detector_name):
        """Make a h(t) strain time-series from an injection object as read from
        an hdf file.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)

        # compute the waveform time series
        hp, hc = ringdown_td_approximants[inj['approximant']](
            delta_t=delta_t, **inj)

        hp._epoch += inj['tc']
        hc._epoch += inj['tc']

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp, hc,
                             inj['ra'], inj['dec'], inj['polarization'])

        return signal
示例#4
0
    def make_strain_from_inj_object(self,
                                    inj,
                                    delta_t,
                                    detector_name,
                                    f_lower=None,
                                    distance_scale=1):
        """Make a h(t) strain time-series from an injection object as read from
        a sim_inspiral table, for example.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is 
            no scaling. 

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)
        if f_lower is None:
            f_l = inj.f_lower
        else:
            f_l = f_lower

        name, phase_order = legacy_approximant_name(inj.waveform)

        # compute the waveform time series
        hp, hc = get_td_waveform(inj,
                                 approximant=name,
                                 delta_t=delta_t,
                                 phase_order=phase_order,
                                 f_lower=f_l,
                                 distance=inj.distance,
                                 **self.extra_args)
        hp /= distance_scale
        hc /= distance_scale

        hp._epoch += inj.get_time_geocent()
        hc._epoch += inj.get_time_geocent()

        # taper the polarizations
        hp_tapered = wfutils.taper_timeseries(hp, inj.taper)
        hc_tapered = wfutils.taper_timeseries(hc, inj.taper)

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp_tapered, hc_tapered, inj.longitude,
                                       inj.latitude, inj.polarization)

        return signal
示例#5
0
def _det_tc(detector_name, ra, dec, tc, ref_frame='geocentric'):
    """Returns the coalescence time of a signal in the given detector.

    Parameters
    ----------
    detector_name : string
        The name of the detector, e.g., 'H1'.
    ra : float
        The right ascension of the signal, in radians.
    dec : float
        The declination of the signal, in radians.
    tc : float
        The GPS time of the coalescence of the signal in the `ref_frame`.
    ref_frame : {'geocentric', string}
        The reference frame that the given coalescence time is defined in.
        May specify 'geocentric', or a detector name; default is 'geocentric'.

    Returns
    -------
    float :
        The GPS time of the coalescence in detector `detector_name`.
    """
    if ref_frame == detector_name:
        return tc
    detector = Detector(detector_name)
    if ref_frame == 'geocentric':
        return tc + detector.time_delay_from_earth_center(ra, dec, tc)
    else:
        other = Detector(ref_frame)
        return tc + detector.time_delay_from_detector(other, ra, dec, tc)
示例#6
0
def _optimal_orientation_from_detector(detector_name, tc):
    """ Low-level function to be called from _optimal_dec_from_detector
    and _optimal_ra_from_detector"""

    d = Detector(detector_name)
    ra, dec = d.optimal_orientation(tc)

    return ra, dec
示例#7
0
def _optimal_orientation_from_detector(detector_name, tc):
    """ Low-level function to be called from _optimal_dec_from_detector
    and _optimal_ra_from_detector"""

    d = Detector(detector_name)
    ra, dec = d.optimal_orientation(tc)

    return ra, dec
示例#8
0
文件: inject.py 项目: prayush/pycbc
    def make_strain_from_inj_object(self, inj, delta_t, detector_name, f_lower=None, distance_scale=1):
        """Make a h(t) strain time-series from an injection object as read from
        a sim_inspiral table, for example.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is 
            no scaling. 

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)
        if f_lower is None:
            f_l = inj.f_lower
        else:
            f_l = f_lower

        name, phase_order = legacy_approximant_name(inj.waveform)

        # compute the waveform time series
        hp, hc = get_td_waveform(
            inj,
            approximant=name,
            delta_t=delta_t,
            phase_order=phase_order,
            f_lower=f_l,
            distance=inj.distance,
            **self.extra_args
        )
        hp /= distance_scale
        hc /= distance_scale

        hp._epoch += inj.get_time_geocent()
        hc._epoch += inj.get_time_geocent()

        # taper the polarizations
        hp_tapered = wfutils.taper_timeseries(hp, inj.taper)
        hc_tapered = wfutils.taper_timeseries(hc, inj.taper)

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp_tapered, hc_tapered, inj.longitude, inj.latitude, inj.polarization)

        return signal
示例#9
0
    def make_strain_from_inj_object(self, inj, delta_t, detector_name,
                                    f_lower=None, distance_scale=1):
        """Make a h(t) strain time-series from an injection object.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t). Can be any
            object which has waveform parameters as attributes, such as an
            element in a ``WaveformArray``.
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is
            no scaling.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)
        if f_lower is None:
            f_l = inj.f_lower
        else:
            f_l = f_lower

        # compute the waveform time series
        hp, hc = get_td_waveform(inj, delta_t=delta_t, f_lower=f_l,
                                 **self.extra_args)

        hp /= distance_scale
        hc /= distance_scale

        hp._epoch += inj.tc
        hc._epoch += inj.tc

        # taper the polarizations
        try:
            hp_tapered = wfutils.taper_timeseries(hp, inj.taper)
            hc_tapered = wfutils.taper_timeseries(hc, inj.taper)
        except AttributeError:
            hp_tapered = hp
            hc_tapered = hc

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp_tapered, hc_tapered,
                             inj.ra, inj.dec, inj.polarization)

        return signal
示例#10
0
    def make_strain_from_inj_object(self, inj, delta_t, detector_name,
                                    f_lower=None, distance_scale=1):
        """Make a h(t) strain time-series from an injection object.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t). Can be any
            object which has waveform parameters as attributes, such as an
            element in a ``WaveformArray``.
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is
            no scaling.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)
        if f_lower is None:
            f_l = inj.f_lower
        else:
            f_l = f_lower

        # compute the waveform time series
        hp, hc = get_td_waveform(inj, delta_t=delta_t, f_lower=f_l,
                                 **self.extra_args)

        hp /= distance_scale
        hc /= distance_scale

        hp._epoch += inj.tc
        hc._epoch += inj.tc

        # taper the polarizations
        try:
            hp_tapered = wfutils.taper_timeseries(hp, inj.taper)
            hc_tapered = wfutils.taper_timeseries(hc, inj.taper)
        except AttributeError:
            hp_tapered = hp
            hc_tapered = hc

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp_tapered, hc_tapered,
                             inj.ra, inj.dec, inj.polarization)

        return signal
示例#11
0
def generate_signal(param_set):
    hp, hc = get_td_waveform(
        approximant=
        'SEOBNRv4',  #This approximant is only appropriate for BBH mergers
        mass1=param_set['m1'],
        mass2=param_set['m2'],
        spin1z=param_set['x1'],
        spin2z=param_set['x2'],
        inclination_range=param_set['inc'],
        coa_phase=param_set['coa'],
        distance=param_set['dist'],
        delta_t=1.0 / param_set['f'],
        f_lower=30)

    time = 100000000

    det_h1 = Detector('H1')
    det_l1 = Detector('L1')
    det_v1 = Detector('V1')

    hp = fade_on(hp, 0.25)
    hc = fade_on(hc, 0.25)

    sig_h1 = det_h1.project_wave(hp, hc, param_set['ra'], param_set['dec'],
                                 param_set['pol'])
    sig_l1 = det_l1.project_wave(hp, hc, param_set['ra'], param_set['dec'],
                                 param_set['pol'])
    sig_v1 = det_v1.project_wave(hp, hc, param_set['ra'], param_set['dec'],
                                 param_set['pol'])

    return {'H1': sig_h1, 'L1': sig_l1, 'V1': sig_v1}
示例#12
0
    def __init__(self, num_templates, analysis_block, background_statistic,
                 stat_files, ifos,
                 ifar_limit=100,
                 timeslide_interval=.035,
                 coinc_threshold=.002,
                 return_background=False):
        """
        Parameters
        ----------
        num_templates: int
            The size of the template bank
        analysis_block: int
            The number of seconds in each analysis segment
        background_statistic: str
            The name of the statistic to rank coincident events.
        stat_files: list of strs
            List of filenames that contain information used to construct
            various coincident statistics.
        ifos: list of strs
            List of ifo names that are being analyzed. At the moment this must
            be two items such as ['H1', 'L1'].
        ifar_limit: float
            The largest inverse false alarm rate in years that we would like to
            calculate.
        timeslide_interval: float
            The time in seconds between consecutive timeslide offsets.
        coinc_threshold: float
            Amount of time allowed to form a coincidence in addition to the
            time of flight in seconds.
        return_background: boolean
            If true, background triggers will also be included in the file
            output.
        """
        from . import stat
        self.num_templates = num_templates
        self.analysis_block = analysis_block

        stat_class = stat.get_statistic(background_statistic)
        self.stat_calculator = stat_class(stat_files, ifos)

        self.timeslide_interval = timeslide_interval
        self.return_background = return_background

        self.ifos = ifos
        if len(self.ifos) != 2:
            raise ValueError("Only a two ifo analysis is supported at this time")

        self.lookback_time = (ifar_limit * lal.YRJUL_SI * timeslide_interval) ** 0.5
        self.buffer_size = int(numpy.ceil(self.lookback_time / analysis_block))

        det0, det1 = Detector(ifos[0]), Detector(ifos[1])
        self.time_window = det0.light_travel_time_to_detector(det1) + coinc_threshold
        self.coincs = CoincExpireBuffer(self.buffer_size, self.ifos)

        self.singles = {}
示例#13
0
def batch_project(
    detector: Detector,
    extrinsics: Union[np.recarray, Dict[str, np.ndarray]],
    waveforms: np.ndarray,
    static_args: Dict[str, Union[str,float]],
    sample_frequencies: Optional[np.ndarray]=None,
    distance_scale: bool=False,
    time_shift: bool=False,
):
    # get frequency bins (we handle numpy arrays rather than PyCBC arrays with .sample_frequencies attributes)
    if sample_frequencies is None:
        sample_frequencies = get_sample_frequencies(
            f_final=static_args['f_final'],
            delta_f=static_args['delta_f']
        )
    
    # check waveform matrix inputs
    assert waveforms.shape[1] == 2, "2nd dim in waveforms must be plus and cross polarizations."
    assert waveforms.shape[0] == len(extrinsics), "waveform batch and extrinsics length must match."

    if distance_scale:
        # scale waveform amplitude according to sample d_L parameter
        scale = static_args.get('distance', 1000)  / extrinsics['distance']  # default d_L = 1
        waveforms = np.array(waveforms) * scale[:, None, None]

    # calculate antenna pattern given arrays of extrinsic parameters
    fp, fc = detector.antenna_pattern(
        extrinsics['ra'], extrinsics['dec'], extrinsics['psi'],
        static_args.get('ref_time', 0.)
    )

    # batch project
    projections = fp[:, None]*waveforms[:, 0, :] + fc[:, None]*waveforms[:, 1, :]

    # if distance_scale:
    #     # scale waveform amplitude according to sample d_L parameter
    #     scale = static_args.get('distance', 1000)  / extrinsics['distance']  # default d_L = 1
    #     projections *= scale[:, None]
    
    if time_shift:    
        assert waveforms.shape[-1] == sample_frequencies.shape[0], "delta_f and fd_length do not match."
        
        # calculate geocentric time for the given detector
        dt = detector.time_delay_from_earth_center(extrinsics['ra'], extrinsics['dec'], static_args.get('ref_time', 0.))
    
        # Calculate time shift due to sampled t_c parameters
        dt += extrinsics['time'] - static_args.get('ref_time', 0.)  # default ref t_c = 0
        
        dt = dt.astype(match_precision(sample_frequencies, real=True))
        shift = np.exp(- 2j * np.pi * dt[:, None] * sample_frequencies[None, :])
        projections *= shift

    return projections
示例#14
0
def project_waveform(hp, hc, skyloc=(0.0, 0.0), polarization=0.0, detector_name="H1"):
    """
    Project the hp,c polarisations onto detector detname for sky location skyloc
    and polarisation pol
    """

    detector = Detector(detector_name)

    signal = detector.project_wave(hp, hc, skyloc[0], skyloc[1],
            polarization)

    return signal
示例#15
0
 def __init__(self, rFrameGeneratorClass, epoch, detectors=None,
         variable_args=(), **frozen_params):
     # initialize frozen & current parameters:
     self.current_params = frozen_params.copy()
     self._static_args = frozen_params.copy()
     # we'll separate out frozen location parameters from the frozen
     # parameters that are sent to the rframe generator
     self.frozen_location_args = {}
     loc_params = set(frozen_params.keys()) & self.location_args
     for param in loc_params:
         self.frozen_location_args[param] = frozen_params.pop(param)
     # set the order of the variable parameters
     self.variable_args = tuple(variable_args)
     # variables that are sent to the rFrame generator
     rframe_variables = list(set(self.variable_args) - self.location_args)
     # initialize the radiation frame generator
     self.rframe_generator = rFrameGeneratorClass(
         variable_args=rframe_variables, **frozen_params)
     self.set_epoch(epoch)
     # if detectors are provided, convert to detector type; also ensure that
     # location variables are specified
     if detectors is not None:
         # FIXME: use the following when we switch to 2.7
         #self.detectors = {det: Detector(det) for det in detectors}
         self.detectors = dict([(det, Detector(det)) for det in detectors])
         missing_args = [arg for arg in self.location_args if not
             (arg in self.current_params or arg in self.variable_args)]
         if any(missing_args):
             raise ValueError("detectors provided, but missing location "
                 "parameters %s. " %(', '.join(missing_args)) +
                 "These must be either in the frozen params or the "
                 "variable args.")
     else:
         self.detectors = {'RF': None}
     self.detector_names = sorted(self.detectors.keys())
示例#16
0
    def _worker_init_fn(self, worker_id: int = None):
        self.detectors = {ifo: Detector(ifo) for ifo in self.ifos}

        self.data = np.load(self.data_dir / self.data_file, mmap_mode='r')

        # save asds as stacked numpy array for faster compute
        if self.psd_dir is not None:
            asds = []
            for ifo in self.ifos:
                psd = load_psd_from_file(self.psd_dir / f'{ifo}_PSD.npy')
                asds.append(psd[:self.static_args['fd_length']]**0.5)
            self.asds = np.stack(asds)

        if self.ref_ifo is not None:
            # psd = load_psd_from_file(self.psd_dir / f'{self.ref_ifo}_PSD.npy')
            self.asds /= self.asds[self.ifos.index(self.ref_ifo)]

        self.asds = self.asds.astype(self.real_dtype)
        self.parameters = self.parameters.astype(self.real_dtype)
        self.mean = self.mean.astype(self.real_dtype)
        self.std = self.std.astype(self.real_dtype)

        # reduced basis encoder
        self.encoder.load(n=self.n, mmap_mode='r', verbose=True)
        for param in self.encoder.parameters():
            param.requires_grad = False
示例#17
0
文件: inject.py 项目: rmacas/pycbc
def projector(detector_name, inj, hp, hc, distance_scale=1):
    """ Use the injection row to project the polarizations into the
    detector frame
    """
    detector = Detector(detector_name)

    hp /= distance_scale
    hc /= distance_scale

    try:
        tc = inj.tc
        ra = inj.ra
        dec = inj.dec
    except:
        tc = inj.get_time_geocent()
        ra = inj.longitude
        dec = inj.latitude

    hp.start_time += tc
    hc.start_time += tc

    # taper the polarizations
    try:
        hp_tapered = wfutils.taper_timeseries(hp, inj.taper)
        hc_tapered = wfutils.taper_timeseries(hc, inj.taper)
    except AttributeError:
        hp_tapered = hp
        hc_tapered = hc

    projection_method = 'lal'
    if hasattr(inj, 'detector_projection_method'):
        projection_method = inj.detector_projection_method

    logging.info('Injecting at %s, method is %s', tc, projection_method)

    # compute the detector response and add it to the strain
    signal = detector.project_wave(
        hp_tapered,
        hc_tapered,
        ra,
        dec,
        inj.polarization,
        method=projection_method,
        reference_time=tc,
    )
    return signal
示例#18
0
    def get_gate_times(self):
        """Gets the time to apply a gate based on the current sky position.

        If the parameter ``gatefunc`` is set to ``'hmeco'``, the gate times
        will be calculated based on the hybrid MECO of the given set of
        parameters; see ``get_gate_times_hmeco`` for details. Otherwise, the
        gate times will just be retrieved from the ``t_gate_start`` and
        ``t_gate_end`` parameters.

        .. warning::
            Since the normalization of the likelihood is currently not
            being calculated, it is recommended that you do not use
            ``gatefunc``, instead using fixed gate times.

        Returns
        -------
        dict :
            Dictionary of detector names -> (gate start, gate width)
        """
        params = self.current_params
        try:
            gatefunc = self.current_params['gatefunc']
        except KeyError:
            gatefunc = None
        if gatefunc == 'hmeco':
            return self.get_gate_times_hmeco()
        # gate input for ringdown analysis which consideres a start time
        # and an end time
        gatestart = params['t_gate_start']
        gateend = params['t_gate_end']
        # we'll need the sky location for determining time shifts
        ra = self.current_params['ra']
        dec = self.current_params['dec']
        gatetimes = {}
        for det in self._invpsds:
            thisdet = Detector(det)
            # account for the time delay between the waveforms of the
            # different detectors
            gatestartdelay = gatestart + thisdet.time_delay_from_earth_center(
                ra, dec, gatestart)
            gateenddelay = gateend + thisdet.time_delay_from_earth_center(
                ra, dec, gateend)
            dgatedelay = gateenddelay - gatestartdelay
            gatetimes[det] = (gatestartdelay, dgatedelay)
        return gatetimes
示例#19
0
def project_onto_detector(
    detector: Detector,
    sample: Union[np.recarray, Dict[str, float]],
    hp: Union[np.ndarray, FrequencySeries],
    hc: Union[np.ndarray, FrequencySeries],
    static_args: Dict[str, Union[str, float]],
    sample_frequencies: Optional[np.ndarray]=None,
    as_pycbc: bool=True,
    time_shift: bool=False,
) -> Union[np.ndarray, FrequencySeries]:
    """Takes a plus and cross waveform polarization (i.e. generated by intrinsic parameters)
    and projects them onto a specified interferometer using a PyCBC.detector.Detector.
    """
    # input handling
    assert type(hp) == type(hc), "Plus and cross waveform types must match."
    if isinstance(hp, FrequencySeries):
        assert np.all(hp.sample_frequencies == hc.sample_frequencies), "FrequencySeries.sample_frequencies do not match."
        sample_frequencies = hp.sample_frequencies
    assert sample_frequencies is not None, "Waveforms not FrequencySeries type or frequency series array not provided."
    
    # project intrinsic waveform onto detector
    fp, fc = detector.antenna_pattern(sample['ra'], sample['dec'], sample['psi'], static_args.get('ref_time', 0.))
    h = fp*hp + fc*hc

    # scale waveform amplitude according to ratio to reference distance
    h *= static_args.get('distance', 1)  / sample['distance']  # default d_L = 1

    if time_shift:        
        # Calculate time shift at detector and add to geocentric time
        dt = detector.time_delay_from_earth_center(sample['ra'], sample['dec'], static_args.get('ref_time', 0.))
        dt += sample['time'] - static_args.get('ref_time', 0.)  # default ref t_c = 0
        dt = dt.astype(match_precision(sample_frequencies))
        h *= np.exp(- 2j * np.pi * dt * sample_frequencies).astype(match_precision(h, real=False))
        
    # output desired type
    if isinstance(h, FrequencySeries):
        if as_pycbc:
            return h
        else:
            return h.data
    else:
        if as_pycbc:
            return FrequencySeries(h, delta_f=static_args['delta_f'], copy=False)
        else:
            return h
示例#20
0
    def make_strain_from_inj_object(self,
                                    inj,
                                    delta_t,
                                    detector_name,
                                    distance_scale=1):
        """Make a h(t) strain time-series from an injection object as read from
        an hdf file.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        distance_scale: float, optional
            Factor to scale the distance of an injection with. The default (=1)
            is no scaling.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)

        # compute the waveform time series
        hp, hc = ringdown_td_approximants[inj['approximant']](
            inj, delta_t=delta_t, **self.extra_args)

        hp._epoch += inj['tc']
        hc._epoch += inj['tc']

        if distance_scale != 1:
            hp /= distance_scale
            hc /= distance_scale

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp, hc, inj['ra'], inj['dec'],
                                       inj['polarization'])

        return signal
示例#21
0
    def __init__(self,
                 variable_params,
                 data,
                 low_frequency_cutoff,
                 sample_rate=32768,
                 polarization_samples=None,
                 **kwargs):

        variable_params, kwargs = self.setup_distance_marginalization(
            variable_params, marginalize_phase=True, **kwargs)
        super(SingleTemplate, self).__init__(variable_params, data,
                                             low_frequency_cutoff, **kwargs)

        # Generate template waveforms
        df = data[self.detectors[0]].delta_f
        p = self.static_params.copy()
        if 'distance' in p:
            _ = p.pop('distance')
        if 'inclination' in p:
            _ = p.pop('inclination')
        hp, _ = get_fd_waveform(delta_f=df, distance=1, inclination=0, **p)

        # Extend template to high sample rate
        flen = int(int(sample_rate) / df) / 2 + 1
        hp.resize(flen)
        #polarization array to marginalize over if num_samples given
        self.pflag = 0
        if polarization_samples is not None:
            self.polarization = numpy.linspace(0, 2 * numpy.pi,
                                               int(polarization_samples))
            self.pflag = 1

        # Calculate high sample rate SNR time series
        self.sh = {}
        self.hh = {}
        self.det = {}
        for ifo in self.data:
            flow = self.kmin[ifo] * df
            fhigh = self.kmax[ifo] * df
            # Extend data to high sample rate
            self.data[ifo].resize(flen)
            self.det[ifo] = Detector(ifo)
            snr, _, _ = pyfilter.matched_filter_core(
                hp,
                self.data[ifo],
                psd=self.psds[ifo],
                low_frequency_cutoff=flow,
                high_frequency_cutoff=fhigh)

            self.sh[ifo] = 4 * df * snr
            self.hh[ifo] = pyfilter.sigmasq(hp,
                                            psd=self.psds[ifo],
                                            low_frequency_cutoff=flow,
                                            high_frequency_cutoff=fhigh)
        self.time = None
示例#22
0
    def __init__(self,
                 data,
                 psds,
                 low_frequency_cutoff=None,
                 high_frequency_cutoff=None,
                 sample_rate=32768,
                 **kwargs):

        super(SingleTemplate, self).__init__(data=data, **kwargs)

        if low_frequency_cutoff is not None:
            low_frequency_cutoff = float(low_frequency_cutoff)

        if high_frequency_cutoff is not None:
            high_frequency_cutoff = float(high_frequency_cutoff)

        # Generate template waveforms
        df = data[tuple(data.keys())[0]].delta_f
        p = self.static_params.copy()
        if 'distance' in p:
            p.pop('distance')
        if 'inclination' in p:
            p.pop('inclination')

        hp, _ = get_fd_waveform(delta_f=df, distance=1, inclination=0, **p)

        if high_frequency_cutoff is None:
            high_frequency_cutoff = len(data[tuple(data.keys())[0]] - 1) * df

        # Extend data and template to high sample rate
        flen = int(sample_rate / df) / 2 + 1
        hp.resize(flen)
        for ifo in data:
            data[ifo].resize(flen)

        # Calculate high sample rate SNR time series
        self.sh = {}
        self.hh = {}
        self.det = {}
        for ifo in data:
            self.det[ifo] = Detector(ifo)
            snr, _, _ = pyfilter.matched_filter_core(
                hp,
                data[ifo],
                psd=psds[ifo],
                low_frequency_cutoff=low_frequency_cutoff,
                high_frequency_cutoff=high_frequency_cutoff)

            self.sh[ifo] = 4 * df * snr
            self.hh[ifo] = -0.5 * pyfilter.sigmasq(
                hp,
                psd=psds[ifo],
                low_frequency_cutoff=low_frequency_cutoff,
                high_frequency_cutoff=high_frequency_cutoff)
        self.time = None
示例#23
0
    def make_strain_from_inj_object(self, inj, delta_t, detector_name,
                                    distance_scale=1):
        """Make a h(t) strain time-series from an injection object as read from
        an hdf file.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        distance_scale: float, optional
            Factor to scale the distance of an injection with. The default (=1)
            is no scaling.

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)

        # compute the waveform time series
        hp, hc = ringdown_td_approximants[inj['approximant']](
            inj, delta_t=delta_t, **self.extra_args)

        hp._epoch += inj['tc']
        hc._epoch += inj['tc']

        if distance_scale != 1:
            hp /= distance_scale
            hc /= distance_scale

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp, hc,
                             inj['ra'], inj['dec'], inj['polarization'])

        return signal
示例#24
0
    def finalize_template_events(self,
                                 perform_coincidence=True,
                                 coinc_window=0.0):
        # Set ids
        for ifo in self.ifos:
            num_events = len(self.template_event_dict[ifo])
            new_event_ids = numpy.arange(self.event_index,
                                         self.event_index + num_events)
            self.template_event_dict[ifo]['event_id'] = new_event_ids
            self.event_index = self.event_index + num_events

        if perform_coincidence:
            if not len(self.ifos) == 2:
                err_msg = "Coincidence currently only supported for 2 ifos."
                raise ValueError(err_msg)
            ifo1 = self.ifos[0]
            ifo2 = self.ifos[1]
            end_times1 = self.template_event_dict[ifo1]['time_index'] /\
              float(self.opt.sample_rate[ifo1]) + self.opt.gps_start_time[ifo1]
            end_times2 = self.template_event_dict[ifo2]['time_index'] /\
              float(self.opt.sample_rate[ifo2]) + self.opt.gps_start_time[ifo2]
            light_travel_time = Detector(ifo1).light_travel_time_to_detector(
                Detector(ifo2))
            coinc_window = coinc_window + light_travel_time
            # FIXME: Remove!!!
            coinc_window = 2.0
            if len(end_times1) and len(end_times2):
                idx_list1, idx_list2, _ = \
                                 coinc.time_coincidence(end_times1, end_times2,
                                                        coinc_window)
                if len(idx_list1):
                    for idx1, idx2 in zip(idx_list1, idx_list2):
                        event1 = self.template_event_dict[ifo1][idx1]
                        event2 = self.template_event_dict[ifo2][idx2]
                        self.coinc_list.append((event1, event2))
        for ifo in self.ifos:
            self.events = numpy.append(self.events,
                                       self.template_event_dict[ifo])
            self.template_event_dict[ifo] = numpy.array([],
                                                        dtype=self.event_dtype)
示例#25
0
    def _worker_init_fn(self, worker_id: int = None):
        self.detectors = {ifo: Detector(ifo) for ifo in self.ifos}

        self.data = np.load(self.data_dir / self.data_file, mmap_mode='c')

        # save asds as stacked numpy array for faster compute
        if self.psd_dir is not None:
            asds = []
            for ifo in self.ifos:
                psd = load_psd_from_file(self.psd_dir / f'{ifo}_PSD.npy')
                asds.append(psd[:self.static_args['fd_length']]**0.5)

            self.asds = np.stack(asds).astype(self.complex_dtype)
示例#26
0
    def setUp(self):
        available_detectors = get_available_detectors()
        available_detectors = [a[0] for a in available_detectors]
        self.assertTrue('H1' in available_detectors)
        self.assertTrue('L1' in available_detectors)
        self.assertTrue('V1' in available_detectors)
        self.detectors = [Detector(d) for d in ['H1', 'L1', 'V1']]
        self.sample_rate = 4096.
        self.earth_time = lal.REARTH_SI / lal.C_SI

        # create a few random injections
        self.injections = []
        start_time = float(lal.GPSTimeNow())
        taper_choices = ('TAPER_NONE', 'TAPER_START', 'TAPER_END',
                         'TAPER_STARTEND')
        for i, taper in zip(xrange(20), itertools.cycle(taper_choices)):
            inj = MyInjection()
            inj.end_time = start_time + 40000 * i + \
                    numpy.random.normal(scale=3600)
            random = numpy.random.uniform
            inj.mass1 = random(low=1., high=20.)
            inj.mass2 = random(low=1., high=20.)
            inj.distance = random(low=0.9, high=1.1) * 1e6 * lal.PC_SI
            inj.latitude = numpy.arccos(random(low=-1, high=1))
            inj.longitude = random(low=0, high=2 * lal.PI)
            inj.inclination = numpy.arccos(random(low=-1, high=1))
            inj.polarization = random(low=0, high=2 * lal.PI)
            inj.taper = taper
            self.injections.append(inj)

        # create LIGOLW document
        xmldoc = ligolw.Document()
        xmldoc.appendChild(ligolw.LIGO_LW())

        # create sim inspiral table, link it to document and fill it
        sim_table = lsctables.New(lsctables.SimInspiralTable)
        xmldoc.childNodes[-1].appendChild(sim_table)
        for i in xrange(len(self.injections)):
            row = sim_table.RowType()
            self.injections[i].fill_sim_inspiral_row(row)
            row.process_id = 'process:process_id:0'
            row.simulation_id = 'sim_inspiral:simulation_id:%d' % i
            sim_table.append(row)

        # write document to temp file
        self.inj_file = tempfile.NamedTemporaryFile(suffix='.xml')
        ligolw_utils.write_fileobj(xmldoc, self.inj_file)
    def __init__(self,
                 variable_params,
                 data,
                 low_frequency_cutoff,
                 sample_rate=32768,
                 **kwargs):
        super(SingleTemplate, self).__init__(variable_params, data,
                                             low_frequency_cutoff, **kwargs)

        # Generate template waveforms
        df = data[self.detectors[0]].delta_f
        p = self.static_params.copy()
        if 'distance' in p:
            _ = p.pop('distance')
        if 'inclination' in p:
            _ = p.pop('inclination')
        hp, _ = get_fd_waveform(delta_f=df, distance=1, inclination=0, **p)

        # Extend template to high sample rate
        flen = int(int(sample_rate) / df) / 2 + 1
        hp.resize(flen)

        # Calculate high sample rate SNR time series
        self.sh = {}
        self.hh = {}
        self.det = {}
        for ifo in self.data:
            flow = self.kmin[ifo] * df
            fhigh = self.kmax[ifo] * df
            # Extend data to high sample rate
            self.data[ifo].resize(flen)
            self.det[ifo] = Detector(ifo)
            snr, _, _ = pyfilter.matched_filter_core(
                hp,
                self.data[ifo],
                psd=self.psds[ifo],
                low_frequency_cutoff=flow,
                high_frequency_cutoff=fhigh)

            self.sh[ifo] = 4 * df * snr
            self.hh[ifo] = -0.5 * pyfilter.sigmasq(hp,
                                                   psd=self.psds[ifo],
                                                   low_frequency_cutoff=flow,
                                                   high_frequency_cutoff=fhigh)
        self.time = None
def detector_projection(hp, hc, **kwargs):
    """Returns the waveform projected onto different detectors.
    
    Arguments
    ---------
    hp : TimeSeries
        TimeSeries object containing the "plus" polarization of a GW
    hc : TimeSeries
        TimeSeries object containing the "cross" polarization of a GW
    
    Returns
    -------
    list
        A list containing the signals projected onto the detectors specified in
        in kwargs['detectors].
    """
    end_time = kwargs['end_time']
    detectors = kwargs['detectors']
    declination = kwargs['declination']
    right_ascension = kwargs['right_ascension']
    polarization = kwargs['polarization']

    del kwargs['end_time']
    del kwargs['detectors']
    del kwargs['declination']
    del kwargs['right_ascension']
    del kwargs['polarization']

    detectors = [Detector(d) for d in detectors]

    hp.start_time += end_time
    hc.start_time += end_time

    ret = [
        d.project_wave(TimeSeries(hp), TimeSeries(hc), right_ascension,
                       declination, polarization) for d in detectors
    ]

    return (ret)
示例#29
0
    def __init__(self,
                 variable_params,
                 data,
                 low_frequency_cutoff,
                 fiducial_params=None,
                 epsilon=0.5,
                 **kwargs):
        super(Relative, self).__init__(variable_params, data,
                                       low_frequency_cutoff, **kwargs)
        # check that all of the frequency cutoffs are the same
        # FIXME: this can probably be loosened at some point
        kmins = list(self.kmin.values())
        kmaxs = list(self.kmax.values())
        if any(kk != kmins[0] for kk in kmins):
            raise ValueError("All lower frequency cutoffs must be the same")
        if any(kk != kmaxs[0] for kk in kmaxs):
            raise ValueError("All high frequency cutoffs must be the same")
        # store data and frequencies
        d0 = list(self.data.values())[0]
        self.f = numpy.array(d0.sample_frequencies)
        self.df = d0.delta_f
        self.end_time = float(d0.end_time)
        self.det = {ifo: Detector(ifo) for ifo in self.data}
        self.epsilon = float(epsilon)
        # store data and psds as arrays for faster computation
        self.comp_data = {ifo: d.numpy() for ifo, d in self.data.items()}
        self.comp_psds = {ifo: p.numpy() for ifo, p in self.psds.items()}
        # store fiducial waveform params
        self.fid_params = fiducial_params

        # get detector-specific arrival times relative to end of data
        dt = {
            ifo:
            self.det[ifo].time_delay_from_earth_center(self.fid_params['ra'],
                                                       self.fid_params['dec'],
                                                       self.fid_params['tc'])
            for ifo in self.data
        }
        self.ta = {
            ifo: self.fid_params['tc'] + dt[ifo] - self.end_time
            for ifo in self.data
        }

        # generate fiducial waveform
        f_lo = kmins[0] * self.df
        f_hi = kmaxs[0] * self.df
        logging.info("Generating fiducial waveform from %s to %s Hz", f_lo,
                     f_hi)
        # prune low frequency samples to avoid waveform errors
        nbelow = sum(self.f < 10)
        fpoints = Array(self.f.astype(numpy.float64))[nbelow:]
        approx = self.static_params['approximant']
        fid_hp, fid_hc = get_fd_waveform_sequence(approximant=approx,
                                                  sample_points=fpoints,
                                                  **self.fid_params)
        self.h00 = {}
        for ifo in self.data:
            # make copy of fiducial wfs, adding back in low frequencies
            hp0 = numpy.concatenate([[0j] * nbelow, fid_hp.copy()])
            hc0 = numpy.concatenate([[0j] * nbelow, fid_hc.copy()])
            fp, fc = self.det[ifo].antenna_pattern(
                self.fid_params['ra'], self.fid_params['dec'],
                self.fid_params['polarization'], self.fid_params['tc'])
            tshift = numpy.exp(-2.0j * numpy.pi * self.f * self.ta[ifo])
            self.h00[ifo] = numpy.array(hp0 * fp + hc0 * fc) * tshift

        # compute frequency bins
        logging.info("Computing frequency bins")
        nbin, fbin, fbin_ind = setup_bins(f_full=self.f,
                                          f_lo=kmins[0] * self.df,
                                          f_hi=kmaxs[0] * self.df,
                                          eps=self.epsilon)
        logging.info("Using %s bins for this model", nbin)
        # store bins and edges in sample and frequency space
        self.edges = fbin_ind
        self.fedges = numpy.array(fbin).astype(numpy.float64)
        self.bins = numpy.array([(self.edges[i], self.edges[i + 1])
                                 for i in range(len(self.edges) - 1)])
        self.fbins = numpy.array([(fbin[i], fbin[i + 1])
                                  for i in range(len(fbin) - 1)])
        # store low res copy of fiducial waveform
        self.h00_sparse = {
            ifo: self.h00[ifo].copy().take(self.edges)
            for ifo in self.h00
        }

        # compute summary data
        logging.info("Calculating summary data at frequency resolution %s Hz",
                     self.df)
        self.sdat = self.summary_data()
示例#30
0
from pycbc.detector import Detector
from pycbc.waveform import get_td_waveform

# Time, orientation and location of the source in the sky
ra = 1.7
dec = 1.7
pol = 0.2
inc = 0
time = 1000000000

# We can calcualate the antenna pattern for Hanford at
# the specific sky location
d = Detector("H1")

# We get back the fp and fc antenna pattern weights.
fp, fc = d.antenna_pattern(ra, dec, pol, time)
print("fp={}, fc={}".format(fp, fc))

# These factors allow us to project a signal into what the detector would
# observe

## Generate a waveform
hp, hc = get_td_waveform(approximant="IMRPhenomD", mass1=10, mass2=10,
                         f_lower=30, delta_t=1.0/4096, inclination=inc,
                         distance=400)

## Apply the factors to get the detector frame strain
ht = fp * hp + fc * hc


# The projection process can also take into account the rotation of the
示例#31
0
def get_detector_signals(static_arguments, waveform_params, event_time,
                         waveform):
    """
    Project the raw `waveform` (i.e., the tuple `(h_plus, h_cross)`
    returned by :func:`get_waveform()`) onto the antenna patterns of
    the detectors in Hanford and Livingston. This requires the position
    of the source in the sky, which is contained in `waveform_params`.

    Args:
        static_arguments (dict): The static arguments (e.g., the
            waveform approximant and the sampling rate) defined in the
            `*.ini` configuration file.
        waveform_params (dict): The parameters that were used as inputs
            for the waveform simulation, although this method will only
            require the following parameters to be present:
        
                - ``ra`` = Right ascension of the source
                - ``dec`` = Declination of the source
                - ``polarization`` = Polarization angle of the source
                
        event_time (int): The GPS time for the event, which, by
            convention, is the time at which the simulated signal
            reaches its maximum amplitude in the `H1` channel.
        waveform (tuple): The pure simulated wavefrom, represented by
            a tuple `(h_plus, h_cross)`, which is usually generated
            by :func:`get_waveform()`.

    Returns:
        A dictionary with keys `{'H1'}` that contains the pure
        signal as it would be observed at Hanford and Livingston.
    """

    # Retrieve the two polarization modes from the waveform tuple
    h_plus, h_cross = waveform

    # Extract the parameters we will need later for the projection
    right_ascension = 2 * np.pi * waveform_params['ra']
    declination = np.arcsin(1 - 2 * waveform_params['dec'])
    polarization = waveform_params['polarization']

    # Store the detector signals we will get through projection
    detector_signals = {}

    # Set up detectors
    detectors = {'H1': Detector('H1')}

    # Set up the detector based on its name
    detector = detectors['H1']

    # Calculate the antenna pattern for this detector
    f_plus, f_cross = \
        detector.antenna_pattern(right_ascension=right_ascension,
                                 declination=declination,
                                 polarization=polarization,
                                 t_gps=100)

    # Calculate the time offset from H1 for this detector
    delta_t_h1 = \
        detector.time_delay_from_detector(other_detector=detectors['H1'],
                                          right_ascension=right_ascension,
                                          declination=declination,
                                          t_gps=100)

    # Project the waveform onto the antenna pattern
    detector_signal = f_plus * h_plus + f_cross * h_cross

    # Map the signal from geocentric coordinates to the specific
    # reference frame of the detector. This depends on whether we have
    # simulated the waveform in the time or frequency domain:
    if static_arguments['domain'] == 'time':
        offset = 100 + delta_t_h1 + detector_signal.start_time
        detector_signal = detector_signal.cyclic_time_shift(offset)
        detector_signal.start_time = event_time - 100
    elif static_arguments['domain'] == 'frequency':
        offset = 100 + delta_t_h1
        detector_signal = detector_signal.cyclic_time_shift(offset)
        detector_signal.start_time = event_time - 100
        detector_signal = detector_signal.to_timeseries()
    else:
        raise ValueError('Invalid domain! Must be "time" or "frequency"!')

    # Store the result
    detector_signals['H1'] = detector_signal

    return detector_signals
示例#32
0
    def _loglr(self, return_unmarginalized=False):
        r"""Computes the log likelihood ratio,

        .. math::

            \log \mathcal{L}(\Theta) = \sum_i
                \left<h_i(\Theta)|d_i\right> -
                \frac{1}{2}\left<h_i(\Theta)|h_i(\Theta)\right>,

        at the current parameter values :math:`\Theta`.

        Returns
        -------
        float
            The value of the log likelihood ratio.
        """
        params = self.current_params
        try:
            wfs = self.waveform_generator.generate(**params)
        except NoWaveformError:
            return self._nowaveform_loglr()
        except FailedWaveformError as e:
            if self.ignore_failed_waveforms:
                return self._nowaveform_loglr()
            else:
                raise e

        # ---------------------------------------------------------------------
        # Some optimizations not yet taken:
        # * higher m calculations could have a lot of redundancy
        # * fp/fc need not be calculated except where polarization is different
        # * may be possible to simplify this by making smarter use of real/imag
        # ---------------------------------------------------------------------
        lr = 0.
        hds = {}
        hhs = {}
        for det, modes in wfs.items():
            if det not in self.dets:
                self.dets[det] = Detector(det)

            fp, fc = self.dets[det].antenna_pattern(self.current_params['ra'],
                                                    self.current_params['dec'],
                                                    self.pol,
                                                    self.current_params['tc'])

            # loop over modes and prepare the waveform modes
            # we will sum up zetalm = glm <ulm, d> + i glm <vlm, d>
            # over all common m so that we can apply the phase once
            zetas = {}
            rlms = {}
            slms = {}
            for mode in modes:
                l, m = mode
                ulm, vlm = modes[mode]

                # whiten the waveforms
                # the kmax of the waveforms may be different than internal kmax
                kmax = min(max(len(ulm), len(vlm)), self._kmax[det])
                slc = slice(self._kmin[det], kmax)
                ulm[self._kmin[det]:kmax] *= self._weight[det][slc]
                vlm[self._kmin[det]:kmax] *= self._weight[det][slc]

                # the inner products
                # <ulm, d>
                ulmd = ulm[slc].inner(self._whitened_data[det][slc]).real
                # <vlm, d>
                vlmd = vlm[slc].inner(self._whitened_data[det][slc]).real

                # add inclination, and pack into a complex number
                import lal
                glm = lal.SpinWeightedSphericalHarmonic(
                    self.current_params['inclination'], 0, -2, l, m).real

                if m not in zetas:
                    zetas[m] = 0j
                zetas[m] += glm * (ulmd + 1j*vlmd)

                # Get condense set of the parts of the waveform that only diff
                # by m, this is used next to help calculate <h, h>
                r = glm * ulm
                s = glm * vlm

                if m not in rlms:
                    rlms[m] = r
                    slms[m] = s
                else:
                    rlms[m] += r
                    slms[m] += s

            # now compute all possible <hlm, hlm>
            rr_m = {}
            ss_m = {}
            rs_m = {}
            sr_m = {}
            combos = itertools.combinations_with_replacement(rlms.keys(), 2)
            for m, mprime in combos:
                r = rlms[m]
                s = slms[m]
                rprime = rlms[mprime]
                sprime = slms[mprime]
                rr_m[mprime, m] = r[slc].inner(rprime[slc]).real
                ss_m[mprime, m] = s[slc].inner(sprime[slc]).real
                rs_m[mprime, m] = s[slc].inner(rprime[slc]).real
                sr_m[mprime, m] = r[slc].inner(sprime[slc]).real
                # store the conjugate for easy retrieval later
                rr_m[m, mprime] = rr_m[mprime, m]
                ss_m[m, mprime] = ss_m[mprime, m]
                rs_m[m, mprime] = sr_m[mprime, m]
                sr_m[m, mprime] = rs_m[mprime, m]
            # now apply the phase to all the common ms
            hpd = 0.
            hcd = 0.
            hphp = 0.
            hchc = 0.
            hphc = 0.
            for m, zeta in zetas.items():
                phase_coeff = self.phase_fac(m)

                # <h+, d> = (exp[i m phi] * zeta).real()
                # <hx, d> = -(exp[i m phi] * zeta).imag()
                z = phase_coeff * zeta
                hpd += z.real
                hcd -= z.imag

                # now calculate the contribution to <h, h>
                cosm = phase_coeff.real
                sinm = phase_coeff.imag

                for mprime in zetas:
                    pcprime = self.phase_fac(mprime)

                    cosmprime = pcprime.real
                    sinmprime = pcprime.imag
                    # needed components
                    rr = rr_m[m, mprime]
                    ss = ss_m[m, mprime]
                    rs = rs_m[m, mprime]
                    sr = sr_m[m, mprime]
                    # <hp, hp>
                    hphp += rr * cosm * cosmprime \
                        + ss * sinm * sinmprime \
                        - rs * cosm * sinmprime \
                        - sr * sinm * cosmprime
                    # <hc, hc>
                    hchc += rr * sinm * sinmprime \
                        + ss * cosm * cosmprime \
                        + rs * sinm * cosmprime \
                        + sr * cosm * sinmprime
                    # <hp, hc>
                    hphc += -rr * cosm * sinmprime \
                        + ss * sinm * cosmprime \
                        + sr * sinm * sinmprime \
                        - rs * cosm * cosmprime

            # Now apply the polarizations and calculate the loglr
            # We have h = Fp * hp + Fc * hc
            # loglr = <h, d> - <h, h>/2
            #       = Fp*<hp, d> + Fc*<hc, d>
            #          - (1/2)*(Fp*Fp*<hp, hp> + Fc*Fc*<hc, hc>
            #                   + 2*Fp*Fc<hp, hc>)
            # (in the last line we have made use of the time series being
            #  real, so that <a, b> = <b, a>).
            hd = fp * hpd + fc * hcd
            hh = fp * fp * hphp + fc * fc * hchc + 2 * fp * fc * hphc
            hds[det] = hd
            hhs[det] = hh
            lr += hd - 0.5 * hh

        if return_unmarginalized:
            return self.pol, self.phase, lr, hds, hhs

        lr_total = special.logsumexp(lr) - numpy.log(self.nsamples)

        # store the maxl values
        idx = lr.argmax()
        setattr(self._current_stats, 'maxl_polarization', self.pol[idx])
        setattr(self._current_stats, 'maxl_phase', self.phase[idx])
        return float(lr_total)
示例#33
0
    def _loglr(self):
        r"""Computes the log likelihood ratio,

        .. math::

            \log \mathcal{L}(\Theta) = \sum_i
                \left<h_i(\Theta)|d_i\right> -
                \frac{1}{2}\left<h_i(\Theta)|h_i(\Theta)\right>,

        at the current parameter values :math:`\Theta`.

        Returns
        -------
        float
            The value of the log likelihood ratio.
        """
        params = self.current_params
        try:
            if self.all_ifodata_same_rate_length:
                wfs = self.waveform_generator.generate(**params)
            else:
                wfs = {}
                for det in self.data:
                    wfs.update(self.waveform_generator[det].generate(**params))
        except NoWaveformError:
            return self._nowaveform_loglr()
        except FailedWaveformError as e:
            if self.ignore_failed_waveforms:
                return self._nowaveform_loglr()
            else:
                raise e

        lr = sh_total = hh_total = 0.
        for det, (hp, hc) in wfs.items():
            if det not in self.dets:
                self.dets[det] = Detector(det)
            fp, fc = self.dets[det].antenna_pattern(self.current_params['ra'],
                                                    self.current_params['dec'],
                                                    self.pol,
                                                    self.current_params['tc'])

            # the kmax of the waveforms may be different than internal kmax
            kmax = min(max(len(hp), len(hc)), self._kmax[det])
            slc = slice(self._kmin[det], kmax)

            # whiten both polarizations
            hp[self._kmin[det]:kmax] *= self._weight[det][slc]
            hc[self._kmin[det]:kmax] *= self._weight[det][slc]

            # h = fp * hp + hc * hc
            # <h, d> = fp * <hp,d> + fc * <hc,d>
            # the inner products
            cplx_hpd = self._whitened_data[det][slc].inner(hp[slc])  # <hp, d>
            cplx_hcd = self._whitened_data[det][slc].inner(hc[slc])  # <hc, d>

            cplx_hd = fp * cplx_hpd + fc * cplx_hcd

            # <h, h> = <fp * hp + fc * hc, fp * hp + fc * hc>
            # = Real(fpfp * <hp,hp> + fcfc * <hc,hc> + \
            #  fphc * (<hp, hc> + <hc, hp>))
            hphp = hp[slc].inner(hp[slc]).real  # < hp, hp>
            hchc = hc[slc].inner(hc[slc]).real  # <hc, hc>

            # Below could be combined, but too tired to figure out
            # if there should be a sign applied if so
            hphc = hp[slc].inner(hc[slc]).real  # <hp, hc>
            hchp = hc[slc].inner(hp[slc]).real  # <hc, hp>

            hh = fp * fp * hphp + fc * fc * hchc + fp * fc * (hphc + hchp)
            # store
            setattr(self._current_stats, '{}_optimal_snrsq'.format(det), hh)
            sh_total += cplx_hd
            hh_total += hh

        lr = self.marginalize_loglr(sh_total, hh_total, skip_vector=True)
        lr_total = special.logsumexp(lr) - numpy.log(len(self.pol))

        # store the maxl polarization
        idx = lr.argmax()
        setattr(self._current_stats, 'maxl_polarization', self.pol[idx])
        setattr(self._current_stats, 'maxl_loglr', lr[idx])

        # just store the maxl optimal snrsq
        for det in wfs:
            p = '{}_optimal_snrsq'.format(det)
            setattr(self._current_stats, p,
                    getattr(self._current_stats, p)[idx])

        return float(lr_total)
示例#34
0
文件: coinc.py 项目: tjmassin/pycbc
 def win(ifo1, ifo2):
     d1 = Detector(ifo1)
     d2 = Detector(ifo2)
     return d1.light_travel_time_to_detector(d2) + slop
示例#35
0
    def apply(self, strain, detector_name, f_lower=None, distance_scale=1):
        """Add injections (as seen by a particular detector) to a time series.

        Parameters
        ----------
        strain : TimeSeries
            Time series to inject signals into, of type float32 or float64.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, foat}, optional
            Factor to scale the distance of an injection with. The default is
            no scaling.

        Returns
        -------
        None

        Raises
        ------
        TypeError
            For invalid types of `strain`.
        """
        if strain.dtype not in (float32, float64):
            raise TypeError("Strain dtype must be float32 or float64, not " \
                    + str(strain.dtype))

        lalstrain = strain.lal()
        detector = Detector(detector_name)
        earth_travel_time = lal.REARTH_SI / lal.C_SI
        t0 = float(strain.start_time) - earth_travel_time
        t1 = float(strain.end_time) + earth_travel_time

        # pick lalsimulation injection function
        add_injection = injection_func_map[strain.dtype]

        for inj in self.table:
            # roughly estimate if the injection may overlap with the segment
            end_time = inj.get_time_geocent()
            #CHECK: This is a hack (10.0s); replace with an accurate estimate
            inj_length = 10.0
            eccentricity = 0.0
            polarization = 0.0
            start_time = end_time - 2 * inj_length
            if end_time < t0 or start_time > t1:
                continue

            # compute the waveform time series
            hp, hc = sim.SimBurstSineGaussian(float(inj.q),
                                              float(inj.frequency),
                                              float(inj.hrss),
                                              float(eccentricity),
                                              float(polarization),
                                              float(strain.delta_t))
            hp = TimeSeries(hp.data.data[:], delta_t=hp.deltaT, epoch=hp.epoch)
            hc = TimeSeries(hc.data.data[:], delta_t=hc.deltaT, epoch=hc.epoch)
            hp._epoch += float(end_time)
            hc._epoch += float(end_time)
            if float(hp.start_time) > t1:
                continue

            # compute the detector response, taper it if requested
            # and add it to the strain
            strain = wfutils.taper_timeseries(strain, inj.taper)
            signal_lal = hp.astype(strain.dtype).lal()
            add_injection(lalstrain, signal_lal, None)

        strain.data[:] = lalstrain.data.data[:]
示例#36
0
文件: coinc.py 项目: cdcapano/pycbc
    def __init__(self, num_templates, analysis_block, background_statistic,
                 stat_files, ifos,
                 ifar_limit=100,
                 timeslide_interval=.035,
                 coinc_threshold=.002,
                 return_background=False):
        """
        Parameters
        ----------
        num_templates: int
            The size of the template bank
        analysis_block: int
            The number of seconds in each analysis segment
        background_statistic: str
            The name of the statistic to rank coincident events.
        stat_files: list of strs
            List of filenames that contain information used to construct
            various coincident statistics.
        ifos: list of strs
            List of ifo names that are being analyzed. At the moment this must
            be two items such as ['H1', 'L1'].
        ifar_limit: float
            The largest inverse false alarm rate in years that we would like to
            calculate.
        timeslide_interval: float
            The time in seconds between consecutive timeslide offsets.
        coinc_threshold: float
            Amount of time allowed to form a coincidence in addition to the
            time of flight in seconds.
        return_background: boolean
            If true, background triggers will also be included in the file
            output.
        """
        from . import stat
        self.num_templates = num_templates
        self.analysis_block = analysis_block

        # Only pass a valid stat file for this ifo pair
        for fname in stat_files:
            f = h5py.File(fname, 'r')
            ifos_set = set([f.attrs['ifo0'], f.attrs['ifo1']])
            f.close()
            if ifos_set == set(ifos):
                stat_files = [fname]
                logging.info('Setup ifos %s-%s with file %s and stat %s',
                             ifos[0], ifos[1], fname, background_statistic)

        self.stat_calculator = stat.get_statistic(background_statistic)(stat_files)

        self.timeslide_interval = timeslide_interval
        self.return_background = return_background

        self.ifos = ifos
        if len(self.ifos) != 2:
            raise ValueError("Only a two ifo analysis is supported at this time")

        self.lookback_time = (ifar_limit * lal.YRJUL_SI * timeslide_interval) ** 0.5
        self.buffer_size = int(numpy.ceil(self.lookback_time / analysis_block))

        det0, det1 = Detector(ifos[0]), Detector(ifos[1])
        self.time_window = det0.light_travel_time_to_detector(det1) + coinc_threshold
        self.coincs = CoincExpireBuffer(self.buffer_size, self.ifos)

        self.singles = {}
示例#37
0
# coding: utf-8

# In[4]:

from pycbc.detector import Detector

# In[5]:

det_h1 = Detector('H1')
det_l1 = Detector('L1')
det_v1 = Detector('V1')

# In[6]:

end_time = 1192529720
declination = 0.65
right_ascension = 4.67
polarization = 2.34

# In[7]:

det_h1.antenna_pattern(right_ascension, declination, polarization, end_time)
示例#38
0
文件: inject.py 项目: shasvath/pycbc
    def apply(self, strain, detector_name, f_lower=None, distance_scale=1,
              simulation_ids=None):
        """Add injections (as seen by a particular detector) to a time series.

        Parameters
        ----------
        strain : TimeSeries
            Time series to inject signals into, of type float32 or float64.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is 
            no scaling. 
        simulation_ids: iterable, optional
            If given, only inject signals with the given simulation IDs.

        Returns
        -------
        None

        Raises
        ------
        TypeError
            For invalid types of `strain`.
        """

        if not strain.dtype in (float32, float64):
            raise TypeError("Strain dtype must be float32 or float64, not " \
                    + str(strain.dtype))

        lalstrain = strain.lal()    
        detector = Detector(detector_name)
        earth_travel_time = lal.REARTH_SI / lal.C_SI
        t0 = float(strain.start_time) - earth_travel_time
        t1 = float(strain.end_time) + earth_travel_time

        # pick lalsimulation injection function
        add_injection = injection_func_map[strain.dtype]

        injections = self.table
        if simulation_ids:
            injections = [inj for inj in injections \
                          if inj.simulation_id in simulation_ids]

        for inj in injections:
            if f_lower is None:
                f_l = inj.f_lower
            else:
                f_l = f_lower

            if inj.numrel_data != None and inj.numrel_data != "":
                # performing NR waveform injection
                # reading Hp and Hc from the frame files
                swigrow = self.getswigrow(inj)
                import lalinspiral
                Hp, Hc = lalinspiral.NRInjectionFromSimInspiral(swigrow,
                                                                strain.delta_t)
                # converting to pycbc timeseries
                hp = TimeSeries(Hp.data.data[:], delta_t=Hp.deltaT,
                                epoch=Hp.epoch)
                hc = TimeSeries(Hc.data.data[:], delta_t=Hc.deltaT,
                                epoch=Hc.epoch)
                hp /= distance_scale
                hc /= distance_scale
                end_time = float(hp.get_end_time())
                start_time = float(hp.get_start_time())
                if end_time < t0 or start_time > t1:
                    continue
            else:
                # roughly estimate if the injection may overlap with the segment
                end_time = inj.get_time_geocent()
                inj_length = sim.SimInspiralTaylorLength(
                    strain.delta_t, inj.mass1 * lal.MSUN_SI,
                    inj.mass2 * lal.MSUN_SI, f_l, 0)
                start_time = end_time - 2 * inj_length
                if end_time < t0 or start_time > t1:
                   continue
                   
                name, phase_order = legacy_approximant_name(inj.waveform)

                # compute the waveform time series
                hp, hc = get_td_waveform(
                    inj, approximant=name, delta_t=strain.delta_t,
                    phase_order=phase_order,
                    f_lower=f_l, distance=inj.distance * distance_scale,
                    **self.extra_args)

                hp._epoch += float(end_time)
                hc._epoch += float(end_time)
                if float(hp.start_time) > t1:
                   continue

            # compute the detector response, taper it if requested
            # and add it to the strain
            signal = detector.project_wave(
                    hp, hc, inj.longitude, inj.latitude, inj.polarization)
            # the taper_timeseries function converts to a LAL TimeSeries
            signal = signal.astype(strain.dtype)
            signal_lal = wfutils.taper_timeseries(signal, inj.taper, return_lal=True)
            add_injection(lalstrain, signal_lal, None)

        strain.data[:] = lalstrain.data.data[:]
示例#39
0
from pycbc.detector import Detector

apx = 'SEOBNRv4'
# NOTE: Inclination runs from 0 to pi, with poles at 0 and pi
#       coa_phase runs from 0 to 2 pi.
hp, hc = get_td_waveform(approximant=apx,
                         mass1=10,
                         mass2=10,
                         spin1z=0.9,
                         spin2z=0.4,
                         inclination=1.23,
                         coa_phase=2.45,
                         delta_t=1.0/4096,
                         f_lower=40)

det_h1 = Detector('H1')
det_l1 = Detector('L1')
det_v1 = Detector('V1')

# Choose a GPS end time, sky location, and polarization phase for the merger
# NOTE: Right ascension and polarization phase runs from 0 to 2pi
#       Declination runs from pi/2. to -pi/2 with the poles at pi/2. and -pi/2.
end_time = 1192529720
declination = 0.65
right_ascension = 4.67
polarization = 2.34
hp.start_time += end_time
hc.start_time += end_time

signal_h1 = det_h1.project_wave(hp, hc,  right_ascension, declination, polarization)
signal_l1 = det_l1.project_wave(hp, hc,  right_ascension, declination, polarization)
示例#40
0
def get_td_waveform_resp(params):
    """
    Generate time domain data of gw detector response

    This function will produce data of a gw detector response based on a
    numerical relativity waveform.

    Parameters
    ----------
    params: object
        The fields of this object correspond to the kwargs of the
        `pycbc.waveform.get_td_waveform()` method and the positional
        arguments of `pycbc.detector.Detector.antenna_pattern()`. For the later
        the fields should be supplied as `params.ra`, `.dec`, `.polarization`
        and `.geocentric_end_time`

    Returns
    -------
    h_plus: pycbc.Types.TimeSeries
    h_cross: pycbc.Types.TimeSeries
    pats: dictionary
        Dictionary containing 'H1' and 'L1' keys. Each key maps to an object
        of containing the field `.f_plus` and `.f_cross` corresponding to
        the plus and cross antenna patterns for the two ifos 'H1' and 'L1'.
    """

    # # construct waveform string that can be parsed by lalsimulation
    waveform_string = params.approximant
    if not pn_orders[params.order] == -1:
        waveform_string += params.order
    name, phase_order = legacy_approximant_name(waveform_string)

    # Populate additional fields of params object
    params.mchirp, params.eta = pnutils.mass1_mass2_to_mchirp_eta(
        params.mass1, params.mass2)
    params.waveform           = waveform_string
    params.approximant        = name
    params.phase_order        = phase_order

    # generate waveform
    h_plus, h_cross = get_td_waveform(params)

    # Generate antenna patterns for all ifos
    pats = {}
    for ifo in params.instruments:

        # get Detector instance for IFO
        det = Detector(ifo)

        # get antenna pattern
        f_plus, f_cross = det.antenna_pattern(
            params.ra,
            params.dec,
            params.polarization,
            params.geocentric_end_time)

        # Populate antenna patterns with new pattern
        pat         = type('AntennaPattern', (object,), {})
        pat.f_plus  = f_plus
        pat.f_cross = f_cross
        pats[ifo]   = pat

    return h_plus, h_cross, pats
示例#41
0
    def make_strain_from_inj_object(self, inj, delta_t, detector_name,
                                    f_lower=None, distance_scale=1):
        """Make a h(t) strain time-series from an injection object as read from
        a sim_inspiral table, for example.

        Parameters
        -----------
        inj : injection object
            The injection object to turn into a strain h(t).
        delta_t : float
            Sample rate to make injection at.
        detector_name : string
            Name of the detector used for projecting injections.
        f_lower : {None, float}, optional
            Low-frequency cutoff for injected signals. If None, use value
            provided by each injection.
        distance_scale: {1, float}, optional
            Factor to scale the distance of an injection with. The default is 
            no scaling. 

        Returns
        --------
        signal : float
            h(t) corresponding to the injection.
        """
        detector = Detector(detector_name)
        if f_lower is None:
            f_l = inj.f_lower
        else:
            f_l = f_lower

        # FIXME: Old NR interface will soon be removed. Do not use!
        if inj.numrel_data != None and inj.numrel_data != "":
            # performing NR waveform injection
            # reading Hp and Hc from the frame files
            swigrow = self.getswigrow(inj)
            import lalinspiral
            Hp, Hc = lalinspiral.NRInjectionFromSimInspiral(swigrow, delta_t)
            # converting to pycbc timeseries
            hp = TimeSeries(Hp.data.data[:], delta_t=Hp.deltaT,
                            epoch=Hp.epoch)
            hc = TimeSeries(Hc.data.data[:], delta_t=Hc.deltaT,
                            epoch=Hc.epoch)
            hp /= distance_scale
            hc /= distance_scale
        else:
            name, phase_order = legacy_approximant_name(inj.waveform)

            # compute the waveform time series
            hp, hc = get_td_waveform(
                inj, approximant=name, delta_t=delta_t,
                phase_order=phase_order,
                f_lower=f_l, distance=inj.distance,
                **self.extra_args)
            hp /= distance_scale
            hc /= distance_scale

            hp._epoch += inj.get_time_geocent()
            hc._epoch += inj.get_time_geocent()

        # taper the polarizations
        hp_tapered = wfutils.taper_timeseries(hp, inj.taper)
        hc_tapered = wfutils.taper_timeseries(hc, inj.taper)

        # compute the detector response and add it to the strain
        signal = detector.project_wave(hp_tapered, hc_tapered,
                             inj.longitude, inj.latitude, inj.polarization)

        return signal
示例#42
0
 def win(ifo1, ifo2):
     d1 = Detector(ifo1)
     d2 = Detector(ifo2)
     return d1.light_travel_time_to_detector(d2) + slop
示例#43
0
from pycbc.detector import Detector
from astropy.utils import iers

# Make sure the documentation can be built without an internet connection
iers.conf.auto_download = False

# The source of the gravitational waves
right_ascension = 0.7
declination = -0.5

# Reference location will be the Hanford detector
# see the `time_delay_from_earth_center` method to use use geocentric time
# as the reference
dref = Detector("H1")

# Time in GPS seconds that the GW passes
time = 100000000

# Time that the GW will (or has) passed through the given detector
for ifo in ["H1", "L1", "V1"]:
    d = Detector(ifo)
    dt = d.time_delay_from_detector(dref, right_ascension, declination, time)
    st = "GW passed through {} {} seconds relative to passing by Hanford"
    print(st.format(ifo, dt))
示例#44
0
                                 coa_phase=params['coa_phase'],
                                 distance=100)


hp_tapered = wfutils.taper_timeseries(hp, 'TAPER_START')
hc_tapered = wfutils.taper_timeseries(hc, 'TAPER_START')

hp_tapered.data[:] /= pycbc.filter.sigma(hp_tapered)
hc_tapered.data[:] /= pycbc.filter.sigma(hc_tapered)

now = timeit.time.time()

print "took %f sec to extract pols"%(now-then)

# Generate the signal in the detector
detector = Detector(detector_name)

#longitude=float(sys.argv[1])
#latitude=float(sys.argv[2])
polarization=float(sys.argv[3])

# MAP from LALINF
latitude=0.0#-1.26907692672 * 180 / np.pi
longitude=0.0#0.80486732096 * 180 / np.pi

signal = detector.project_wave(hp_tapered, hc_tapered, longitude,
        latitude, polarization)
signal.data[:] /= pycbc.filter.sigma(signal)

tlen = max(len(hp_tapered), len(signal))
hp_tapered.resize(tlen+1)