dingo.gw.transforms package

Submodules

dingo.gw.transforms.detector_transforms module

class dingo.gw.transforms.detector_transforms.ApplyCalibrationToWaveform(ifo_list, data_domain)

Bases: object

Apply calibration correction to the waveform based on calibration parameters in extrinsic_parameters.

Detector calibration uncertainty is modeled as described in https://dcc.ligo.org/LIGO-T1400682/public

Gravitational wave data \(d\) is assumed to be of the form

\[d(f) = h_{obs}(f) + n(f),\]

where \(h_{obs}\) is the observed waveform and \(n\) is the noise. Since the detector is not perfectly calibrated, the observed waveform is not identical to the true waveform \(h(f)\). Rather, it is assumed to have corrections of the form

\[h_{obs}(f) = h(f) * (1 + \delta A(f)) * \exp(i \delta \phi(f)) = h(f) * \alpha(f),\]

where \(\delta A(f)\) and \(\delta \phi(f)\) are frequency-dependent amplitude and phase errors. Under the calibration model, these are parametrized with cubic splines, defined in terms of calibration parameters \(A_i\) and \(\phi_i\), defined at log-spaced frequency nodes,

\[\begin{split} \delta A(f) &= \mathrm{spline}(f; {f_i, \delta A_i}), \\ \delta \phi(f) &= \mathrm{spline}(f; {f_i, \delta \phi_i}). \end{split}\]

Calibration parameters (delta A, delta phi) should be in sample[“extrinsic_parameters”] with keys like “recalib_H1_amplitude_0”, “recalib_H1_phase_0”, etc.

  • If values are arrays of shape (N,), applies N calibration curves, adding a leading dimension to the waveform.

  • If values are scalars, applies a single calibration curve.

  • If no calibration parameters found, passes through unchanged.

The calibration spline model is lazily initialized on the first call, inferring num_calibration_nodes from the number of calibration parameters present.

Parameters:
  • ifo_list (InterferometerList) – List of Interferometers present in the analysis.

  • data_domain (Domain) – Domain on which data is defined.

class dingo.gw.transforms.detector_transforms.GetDetectorTimes(ifo_list, ref_time)

Bases: object

Compute the time shifts in the individual detectors based on the sky position (ra, dec), the geocent_time and the ref_time.

class dingo.gw.transforms.detector_transforms.ProjectOntoDetectors(ifo_list, domain, ref_time)

Bases: object

Project the GW polarizations onto the detectors in ifo_list. This does not sample any new parameters, but relies on the parameters provided in sample[‘extrinsic_parameters’]. Specifically, this transform applies the following operations:

  1. Rescale polarizations to account for sampled luminosity distance

  2. Project polarizations onto the antenna patterns using the ref_time and the extrinsic parameters (ra, dec, psi)

  3. Time shift the strains in the individual detectors according to the times <ifo.name>_time provided in the extrinsic parameters.

class dingo.gw.transforms.detector_transforms.SampleCalibrationParameters(ifo_list, data_domain, calibration_envelope, num_calibration_curves, num_calibration_nodes, correction_type='data')

Bases: object

Expand out a waveform using several detector calibration draws. These multiple draws are intended to be used for marginalizing over calibration uncertainty.

The calibration parameters are not known precisely, rather they are assumed to be normally distributed, with mean 0 and standard deviation determined by the “calibration envelope”, which varies from event to event.

Therefore, for each detector waveform, this transform draws a collection of \(N\) calibration curves \(\{(\delta A^n(f), \delta \phi^n(f))\}_{n=1}^N\) according to a calibration envelope, and applies them to generate \(N\) observed waveforms \(\{h^n_{ obs}(f)\}\). This is intended to be used for marginalizing over the calibration uncertainty when evaluating the likelihood for importance sampling.

This transform should be followed by ApplyCalibrationToWaveform to apply the sampled calibration curves to the waveform.

Parameters:
  • ifo_list (InterferometerList) – List of Interferometers present in the analysis.

  • data_domain (Domain) – Domain on which data is defined.

  • calibration_envelope (dict) – Dictionary of the form {"H1": filepath, "L1": filepath}, where the filepaths are strings pointing to “.txt” files containing calibration envelopes.

  • num_calibration_curves (int) – Number of calibration curves to sample.

  • num_calibration_nodes (int) – Number of log-spaced frequency nodes for the spline.

  • correction_type (str = "data") – Whether envelopes are over eta (“data”) or alpha (“template”).

class dingo.gw.transforms.detector_transforms.TimeShiftStrain(ifo_list, domain)

Bases: object

Time shift the strains in the individual detectors according to the times <ifo.name>_time provided in the extrinsic parameters.

dingo.gw.transforms.detector_transforms.time_delay_from_geocenter(ifo: Interferometer, ra: float | ndarray | Tensor, dec: float | ndarray | Tensor, time: float)

Calculate time delay between ifo and geocenter. Identical to method ifo.time_delay_from_geocenter(ra, dec, time), but the present implementation allows for batched computation, i.e., it also accepts arrays and tensors for ra and dec.

Implementation analogous to bilby-cython implementation https://git.ligo.org/colm.talbot/bilby-cython/-/blob/main/bilby_cython/geometry.pyx, which is in turn based on XLALArrivaTimeDiff in TimeDelay.c.

Parameters:
  • ifo (bilby.gw.detector.interferometer.Interferometer) – bilby interferometer object.

  • ra (Union[float, np.array, torch.Tensor]) – Right ascension of the source in radians. Either float, or float array/tensor.

  • dec (Union[float, np.array, torch.Tensor]) – Declination of the source in radians. Either float, or float array/tensor.

  • time (float) – GPS time in the geocentric frame.

Returns:

float

Return type:

Time delay between the two detectors in the geocentric frame

dingo.gw.transforms.general_transforms module

class dingo.gw.transforms.general_transforms.UnpackDict(selected_keys)

Bases: object

Unpacks the dictionary to prepare it for final output of the dataloader. Only returns elements specified in selected_keys.

dingo.gw.transforms.gnpe_transforms module

class dingo.gw.transforms.gnpe_transforms.GNPEBase(kernel_dict, operators)

Bases: ABC

A base class for Group Equivariant Neural Posterior Estimation [1].

This implements GNPE for approximate equivariances. For exact equivariances, additional processing should be implemented within a subclass.

[1]: https://arxiv.org/abs/2111.13139

inverse(a, k)
multiply(a, b, k)
perturb(g, k)

Generate proxy variables based on initial parameter values.

Parameters:
  • g (Union[np.float64, float, torch.Tensor]) – Initial parameter values

  • k (str) – Parameter name. This is used to identify the group binary operator.

Return type:

Proxy variables in the same format as g.

sample_proxies(input_parameters)

Given input parameters, perturbs based on the kernel to produce “proxy” (“hatted”) parameters, i.e., samples

hat g ~ p(hat g | g).

Typically the GNPE NDE will be conditioned on hat g. Furthermore, these proxy parameters will be used to transform the data to simplify it.

Parameters:

input_parametersdict

Initial parameter values to be perturbed. dict values can be either floats (for training) or torch Tensors (for inference).

rtype:

A dict of proxy parameters.

class dingo.gw.transforms.gnpe_transforms.GNPECoalescenceTimes(ifo_list, kernel, exact_global_equivariance=True, inference=False)

Bases: GNPEBase

GNPE [1] Transformation for detector coalescence times.

For each of the detector coalescence times, a proxy is generated by adding a perturbation epsilon from the GNPE kernel to the true detector time. This proxy is subtracted from the detector time, such that the overall time shift only amounts to -epsilon in training. This standardizes the input data to the inference network, since the applied time shifts are always restricted to the range of the kernel.

To preserve information at inference time, conditioning of the inference network on the proxies is required. To that end, the proxies are stored in sample[ ‘gnpe_proxies’].

We can enforce an exact equivariance under global time translations, by subtracting one proxy (by convention: the first one, usually for H1 ifo) from all other proxies, and from the geocent time, see [1]. This is enabled with the flag exact_global_equivariance.

Note that this transform does not modify the data itself. It only determines the amount by which to time-shift the data.

[1]: arxiv.org/abs/2111.13139

Parameters:
  • ifo_list (bilby.gw.detector.InterferometerList) – List of interferometers.

  • kernel (str) – Defines a Bilby prior, to be used for all interferometers.

  • exact_global_equivariance (bool = True) – Whether to impose the exact global time translation symmetry.

  • inference (bool = False) – Whether to use inference or training mode.

dingo.gw.transforms.inference_transforms module

class dingo.gw.transforms.inference_transforms.CopyToExtrinsicParameters(*parameter_list)

Bases: object

Copy parameters specified in self.parameter_list from sample[“parameters”] to sample[“extrinsic_parameters”].

class dingo.gw.transforms.inference_transforms.ExpandStrain(num_samples)

Bases: object

Expand the waveform of sample by adding a batch axis and copying the waveform num_samples times along this new axis. This is useful for generating num_samples samples at inference time.

class dingo.gw.transforms.inference_transforms.PostCorrectGeocentTime(inverse=False)

Bases: object

Post correction for geocent time: add GNPE proxy (only necessary if exact equivariance is enforced)

class dingo.gw.transforms.inference_transforms.ResetSample(extrinsic_parameters_keys=None)

Bases: object

Resets sample:
  • waveform was potentially modified by gnpe transforms, so reset to waveform_

  • optionally remove all non-required extrinsic parameters

class dingo.gw.transforms.inference_transforms.ToTorch(device='cpu')

Bases: object

Convert all numpy arrays sample to torch tensors and push them to the specified device. All items of sample that are not numpy arrays (e.g., dicts of arrays) remain unchanged.

dingo.gw.transforms.noise_transforms module

class dingo.gw.transforms.noise_transforms.AddWhiteNoiseComplex

Bases: object

Adds white noise with a standard deviation determined by self.scale to the complex strain data.

class dingo.gw.transforms.noise_transforms.RepackageStrainsAndASDS(ifos, first_index=0)

Bases: object

Repackage the strains and the asds into an [num_ifos, 3, num_bins] dimensional tensor. Order of ifos is provided by self.ifos. By convention, [:,i,:] is used for:

i = 0: strain.real i = 1: strain.imag i = 2: 1 / (asd * 1e23)

class dingo.gw.transforms.noise_transforms.SampleNoiseASD(asd_dataset)

Bases: object

Sample a batch of random ASDs for each detector and place them in sample[‘asds’].

class dingo.gw.transforms.noise_transforms.WhitenAndScaleStrain(scale_factor)

Bases: object

Whiten the strain data by dividing w.r.t. the corresponding asds, and scale it with 1/scale_factor.

In uniform frequency domain the scale factor should be

1 / np.sqrt(4.0 * delta_f).

This accounts for frequency binning

class dingo.gw.transforms.noise_transforms.WhitenFixedASD(domain: UniformFrequencyDomain, asd_file: str | None = None, inverse: bool = False, precision=None)

Bases: object

Whiten frequency-series data according to an ASD specified in a file. This uses the ASD files contained in Bilby.

Parameters:
  • domain (UniformFrequencyDomain) – ASD is interpolated to the associated frequency grid.

  • asd_file (str) – Name of the ASD file. If None, use the aligo ASD. [Default: None]

  • inverse (bool) – Whether to apply the inverse whitening transform, to un-whiten data. [Default: False]

  • precision (str ("single", "double")) – If not None, sets precision of ASD to specified precision.

class dingo.gw.transforms.noise_transforms.WhitenStrain

Bases: object

Whiten the strain data by dividing w.r.t. the corresponding asds.

dingo.gw.transforms.parameter_transforms module

class dingo.gw.transforms.parameter_transforms.SampleExtrinsicParameters(extrinsic_prior_dict)

Bases: object

Sample extrinsic parameters and add them to sample in a separate dictionary.

property reproduction_dict
class dingo.gw.transforms.parameter_transforms.SelectStandardizeRepackageParameters(parameters_dict, standardization_dict, inverse=False, as_type=None, device='cpu')

Bases: object

This transformation selects the parameters in standardization_dict, normalizes them by setting p = (p - mean) / std, and repackages the selected parameters to a numpy array.

as_type: str = None

only applies, if self.inverse == True * if None, data type is kept * if ‘dict’, dict with * if ‘pandas’, use pandas.DataFrame

class dingo.gw.transforms.parameter_transforms.StandardizeParameters(mu, std)

Bases: object

Standardize parameters according to the transform (x - mu) / std.

Initialize the standardization transform with means and standard deviations for each parameter

Parameters:
  • mu (Dict[str, float]) – The (estimated) means

  • std (Dict[str, float]) – The (estimated) standard deviations

inverse(samples)

De-standardize the parameter array according to the specified means and standard deviations.

Parameters:
  • samples (Dict[Dict, Dict]) – A nested dictionary with keys ‘parameters’, ‘waveform’, ‘noise_summary’.

  • mu (Only parameters included in)

  • transformed. (std get)

dingo.gw.transforms.utils module

dingo.gw.transforms.utils.get_batch_size_of_input_sample(input_sample: dict) Tuple[bool, int]
Parameters:

input_sample (dict) – The input sample to transform. Can contain keys of parameters, polarizations

Returns:

A tuple containing a boolean indicating if the input sample is batched and an integer representing the batch size of the input sample

Return type:

Tuple[bool, int]

dingo.gw.transforms.waveform_transforms module

class dingo.gw.transforms.waveform_transforms.CropMaskStrainRandom(domain: UniformFrequencyDomain | MultibandedFrequencyDomain, f_min_upper: float | None = None, f_max_lower: float | None = None, cropping_probability: float = 1.0, independent_detectors: bool = True, independent_lower_upper: bool = True, deterministic_fmin_fmax: list[float | None] | list[list[float | None]] | None = None)

Bases: object

Apply random cropping of strain, by masking waveform and ASD outside the crop.

Parameters:
  • domain (UniformFrequencyDomain | MultibandedFrequencyDomain) – Domain of the waveform data, has to be a frequency domain type.

  • f_min_upper (float) – New f_min is sampled in range [domain.f_min, f_min_upper]. Sampling of f_min is uniform in bins (not in frequency) when the frequency domain is not uniform (e.g., MultibandedFrequencyDomain).

  • f_max_lower (float) – New f_max is sampled in range [f_max_lower, domain.f_max]. Sampling of f_max is uniform in bins (not in frequency) when the frequency domain is not uniform (e.g., MultibandedFrequencyDomain).

  • cropping_probability (float) – probability for a given sample to be cropped

  • independent_detectors (bool) – If True, crop boundaries are sampled independently for different detectors.

  • independent_lower_upper (bool) – If True, the cropping probability is applied to lower and upper boundaries individually. If False, then with a probability of P = cropping_probability both lower and upper cropping is applied, and with 1-P, no cropping is applied from either direction.

  • deterministic_fmin_fmax (None | list[float | None] | list[list[float | None]]) – If not None, then cropping will be applied with fixed f_min and f_max, as specified by this argument. Can either be a single list [f_min, f_max], or a list of lists [[f_min_1, f_max_1], [f_min_2, f_max_2], …] for the different detectors.

class dingo.gw.transforms.waveform_transforms.DecimateAll(multibanded_frequency_domain: MultibandedFrequencyDomain)

Bases: object

Transform operator for decimation to multibanded frequency domain.

Parameters:

multibanded_frequency_domain (MultibandedFrequencyDomain) – New domain of the decimated data. Original data must be in multibanded_frequency_domain.base_domain

class dingo.gw.transforms.waveform_transforms.DecimateWaveformsAndASDS(multibanded_frequency_domain: MultibandedFrequencyDomain, decimation_mode: str)

Bases: object

Transform operator for decimation of unwhitened waveforms and corresponding ASDS to multibanded frequency domain (MFD).

For decimation, we have two options.

1) decimation_mode = whitened In this case, the GW data is whitened first,

dw = d / ASD,

and then decimated to the MFD,

dw_mfd = decimate(dw).

In this case, the effective ASD in the MFD is given by

ASD_mfd = 1 / decimate(1 / ASD).

See [1] for details. ASD_mfd can then be provided to the inference network.

2) decimation_mode = unwhitened In this case, the GW data is first decimated,

d_mfd = decimate(d)

and then whitened.

dw_mfd = d_mfd / ASD_mfd.

In this case, the ASD_mfd that whitens the data d_mfd is given by

ASD_mfd = decimate(ASD ** 2) ** 0.5.

In other words, in this case we need to decimate the PSD. See [1] for details.

Method 1) better preserves the signal.

[1] https://github.com/dingo-gw/dingo/blob/fede5c01524f3e205acf5750c0a0f101ff17e331/binary_neutron_stars/prototyping/psd_decimation.ipynb

Parameters:
  • multibanded_frequency_domain (MultibandedFrequencyDomain) – New domain of the decimated data. Original data must be in multibanded_frequency_domain.base_domain

  • decimation_mode (str) – One of [“whitened”, “unwhitened”]. Determines whether decimation is performed on whitened data or on unwhitened data. See class docstring for details.

class dingo.gw.transforms.waveform_transforms.MaskDataForFrequencyRangeUpdate(domain: UniformFrequencyDomain | MultibandedFrequencyDomain, minimum_frequency: dict[str, float] | float | None = None, maximum_frequency: dict[str, float] | float | None = None, print_output: bool = False)

Bases: object

Set waveform to zero and ASD to one according to minimum_frequency and maximum_frequency.

Parameters:
  • minimum_frequency (Optional[float | dict[str, float]]) – Update of f_min. If a float, the same value will be used for all detectors.

  • maximum_frequency (Optional[float | dict[str, float]]) – Update of f_max. If a float, the same value will be used for all detectors.

  • print_output (bool) – Whether to write print statements to the console.

dingo.gw.transforms.waveform_transforms.check_sample_in_domain(sample, domain: UniformFrequencyDomain) bool
dingo.gw.transforms.waveform_transforms.create_mask_based_on_frequency_update(sample_frequencies: array, detectors: list[str], minimum_frequency: dict[str, float] | float | None = None, maximum_frequency: dict[str, float] | float | None = None) dict[slice(<class 'str'>, <built-in function array>, None)]

Creates a mask for each detector containing True for sample_frequencies not affected by the frequency updates for minimum and maximum frequencies.

Parameters:
  • sample_frequencies (np.array) – Frequency values for which we want to create a mask. Assumed to be the same for all detectors.

  • detectors (list[str]) – List of detector names.

  • minimum_frequency (Optional[float | dict[str, float]]) – Update of f_min. If a float, the same value will be used for all detectors.

  • maximum_frequency (Optional[float | dict[str, float]]) – Update of f_max. If a float, the same value will be used for all detectors.

Returns:

frequency_masks – Dictionary providing a boolean mask for the sample frequencies of each detector based on provided frequency updates. True for values to keep, False for values to mask.

Return type:

dict

dingo.gw.transforms.waveform_transforms.decimate_recursive(d: dict, mfd: MultibandedFrequencyDomain)

In-place decimation of nested dicts of arrays.

Parameters:

Module contents