示例#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 _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)
示例#3
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
示例#4
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
示例#5
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