ml4gw 0.6.1__py3-none-any.whl → 0.6.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ml4gw might be problematic. Click here for more details.

@@ -263,7 +263,7 @@ class SplineInterpolate(torch.nn.Module):
263
263
  return torch.linalg.solve(self.BxT_Bx, Z_Bx.mT).mT
264
264
 
265
265
  # Adding batch/channel dimension handling
266
- # ByT @ Z @ Bx
266
+ # ByT @ Z @ BxW
267
267
  ByT_Z_Bx = torch.einsum("ij,bcik,kl->bcjl", self.By, Z, self.Bx)
268
268
  # (ByT @ By)^-1 @ (ByT @ Z @ Bx) = By^-1 @ Z @ Bx
269
269
  E = torch.linalg.solve(self.ByT_By, ByT_Z_Bx)
@@ -157,20 +157,30 @@ class IMRPhenomD(TaylorF2):
157
157
  chi22,
158
158
  xi,
159
159
  distance,
160
+ fRD=None, # used for passing ringdown frequency from phenom_p
161
+ fDM=None, # used for passing damping frequency from phenom_p
160
162
  ):
161
163
  ins_amp, ins_Damp = self.phenom_d_inspiral_amp(
162
164
  Mf, eta, eta2, Seta, xi, chi1, chi2, chi12, chi22
163
165
  )
164
166
  int_amp, int_Damp = self.phenom_d_int_amp(
165
- Mf, eta, eta2, Seta, chi1, chi2, chi12, chi22, xi
167
+ Mf, eta, eta2, Seta, chi1, chi2, chi12, chi22, xi, fRD, fDM
166
168
  )
167
169
  mrd_amp, mrd_Damp = self.phenom_d_mrd_amp(
168
- Mf, eta, eta2, chi1, chi2, xi
170
+ Mf, eta, eta2, chi1, chi2, xi, fRD, fDM
169
171
  )
170
172
 
171
173
  gamma2 = self.gamma2_fun(eta, eta2, xi)
172
174
  gamma3 = self.gamma3_fun(eta, eta2, xi)
173
- fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
175
+
176
+ # merger ringdown
177
+ if (fRD is None) != (fDM is None):
178
+ raise ValueError(
179
+ "Both fRD and fDM must either be provided or both be None"
180
+ )
181
+ if (fRD is None) and (fDM is None):
182
+ fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
183
+
174
184
  Mf_peak = self.fmaxCalc(fRD, fDM, gamma2, gamma3)
175
185
  # Geometric peak and joining frequencies
176
186
  Mf_peak = (torch.ones_like(Mf).mT * Mf_peak).mT
@@ -201,10 +211,27 @@ class IMRPhenomD(TaylorF2):
201
211
  return amp, Damp
202
212
 
203
213
  def phenom_d_int_amp(
204
- self, Mf, eta, eta2, Seta, chi1, chi2, chi12, chi22, xi
214
+ self,
215
+ Mf,
216
+ eta,
217
+ eta2,
218
+ Seta,
219
+ chi1,
220
+ chi2,
221
+ chi12,
222
+ chi22,
223
+ xi,
224
+ fRD=None, # used for passing ringdown frequency from phenom_p
225
+ fDM=None, # used for passing damping frequency from phenom_p
205
226
  ):
206
227
  # merger ringdown
207
- fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
228
+ if (fRD is None) != (fDM is None):
229
+ raise ValueError(
230
+ "Both fRD and fDM must either be provided or both be None"
231
+ )
232
+ if (fRD is None) and (fDM is None):
233
+ fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
234
+
208
235
  # Geometric frequency definition from PhenomD header file
209
236
  AMP_fJoin_INS = 0.014
210
237
 
@@ -220,7 +247,9 @@ class IMRPhenomD(TaylorF2):
220
247
  v1, d1 = self.phenom_d_inspiral_amp(
221
248
  Mf1, eta, eta2, Seta, xi, chi1, chi2, chi12, chi22
222
249
  )
223
- v3, d2 = self.phenom_d_mrd_amp(Mf3, eta, eta2, chi1, chi2, xi)
250
+ v3, d2 = self.phenom_d_mrd_amp(
251
+ Mf3, eta, eta2, chi1, chi2, xi, fRD, fDM
252
+ )
224
253
  v2 = (
225
254
  torch.ones_like(Mf).mT * self.AmpIntColFitCoeff(eta, eta2, xi)
226
255
  ).mT
@@ -239,9 +268,18 @@ class IMRPhenomD(TaylorF2):
239
268
  )
240
269
  return amp, Damp
241
270
 
242
- def phenom_d_mrd_amp(self, Mf, eta, eta2, chi1, chi2, xi):
271
+ # fRD and fDM are to be passed for generating phenom_p waveforms
272
+ # and remain None for phenom_d
273
+ def phenom_d_mrd_amp(
274
+ self, Mf, eta, eta2, chi1, chi2, xi, fRD=None, fDM=None
275
+ ):
243
276
  # merger ringdown
244
- fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
277
+ if (fRD is None) != (fDM is None):
278
+ raise ValueError(
279
+ "Both fRD and fDM must either be provided or both be None"
280
+ )
281
+ if (fRD is None) and (fDM is None):
282
+ fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
245
283
 
246
284
  gamma1 = self.gamma1_fun(eta, eta2, xi)
247
285
  gamma2 = self.gamma2_fun(eta, eta2, xi)
@@ -384,17 +422,26 @@ class IMRPhenomD(TaylorF2):
384
422
 
385
423
  return amp, Damp
386
424
 
387
- def phenom_d_phase(self, Mf, mass_1, mass_2, eta, eta2, chi1, chi2, xi):
425
+ # fRD and fDM are to be passed for generating phenom_p waveforms
426
+ # and remain None for phenom_d
427
+ def phenom_d_phase(
428
+ self, Mf, mass_1, mass_2, eta, eta2, chi1, chi2, xi, fRD=None, fDM=None
429
+ ):
388
430
  ins_phase, ins_Dphase = self.phenom_d_inspiral_phase(
389
431
  Mf, mass_1, mass_2, eta, eta2, xi, chi1, chi2
390
432
  )
391
433
  int_phase, int_Dphase = self.phenom_d_int_phase(Mf, eta, eta2, xi)
392
434
  mrd_phase, mrd_Dphase = self.phenom_d_mrd_phase(
393
- Mf, eta, eta2, chi1, chi2, xi
435
+ Mf, eta, eta2, chi1, chi2, xi, fRD, fDM
394
436
  )
395
437
 
396
438
  # merger ringdown
397
- fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
439
+ if (fRD is None) != (fDM is None):
440
+ raise ValueError(
441
+ "Both fRD and fDM must either be provided or both be None"
442
+ )
443
+ if (fRD is None) and (fDM is None):
444
+ fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
398
445
  # definitions in Eq. (35) of arXiv:1508.07253
399
446
  # PHI_fJoin_INS in header LALSimIMRPhenomD.h
400
447
  # C1 continuity at intermediate region i.e. f_1
@@ -415,7 +462,7 @@ class IMRPhenomD(TaylorF2):
415
462
  fRDJoin, eta, eta2, xi
416
463
  )
417
464
  mrd_phase_rd, mrd_Dphase_rd = self.phenom_d_mrd_phase(
418
- fRDJoin, eta, eta2, chi1, chi2, xi
465
+ fRDJoin, eta, eta2, chi1, chi2, xi, fRD, fDM
419
466
  )
420
467
  PhiIntTempVal = (int_phase_rd.mT / eta).mT + C1Int + C2Int * fRDJoin
421
468
  # C2MRD = int_Dphase_rd - mrd_Dphase_rd
@@ -454,7 +501,11 @@ class IMRPhenomD(TaylorF2):
454
501
 
455
502
  return phasing, Dphasing
456
503
 
457
- def phenom_d_mrd_phase(self, Mf, eta, eta2, chi1, chi2, xi):
504
+ # fRD and fDM are to be passed for generating phenom_p waveforms
505
+ # and remain None for phenom_d
506
+ def phenom_d_mrd_phase(
507
+ self, Mf, eta, eta2, chi1, chi2, xi, fRD=None, fDM=None
508
+ ):
458
509
  alpha1 = self.alpha1Fit(eta, eta2, xi)
459
510
  alpha2 = self.alpha2Fit(eta, eta2, xi)
460
511
  alpha3 = self.alpha3Fit(eta, eta2, xi)
@@ -462,9 +513,14 @@ class IMRPhenomD(TaylorF2):
462
513
  alpha5 = self.alpha5Fit(eta, eta2, xi)
463
514
 
464
515
  # merger ringdown
465
- fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
466
- f_minus_alpha5_fRD = (Mf.t() - alpha5 * fRD).t()
516
+ if (fRD is None) != (fDM is None):
517
+ raise ValueError(
518
+ "Both fRD and fDM must either be provided or both be None"
519
+ )
520
+ if (fRD is None) and (fDM is None):
521
+ fRD, fDM = self.fring_fdamp(eta, eta2, chi1, chi2)
467
522
 
523
+ f_minus_alpha5_fRD = (Mf.t() - alpha5 * fRD).t()
468
524
  # Leading 1/eta is not multiplied at this stage
469
525
  mrd_phasing = (Mf.t() * alpha1).t()
470
526
  mrd_phasing -= (1 / Mf.t() * alpha2).t()
@@ -1,13 +1,21 @@
1
+ """
2
+ Based on the JAX implementation of IMRPhenomPv2 from
3
+ https://github.com/tedwards2412/ripple/blob/main/src/ripplegw/waveforms/IMRPhenomPv2.py
4
+ """
5
+
1
6
  from typing import Dict, Optional, Tuple
2
7
 
3
8
  import torch
4
9
  from jaxtyping import Float
5
10
  from torch import Tensor
6
11
 
7
- from ml4gw.constants import MPC_SEC, MTSUN_SI, PI
8
- from ml4gw.types import BatchTensor, FrequencySeries1d
9
- from ml4gw.waveforms.conversion import rotate_y, rotate_z
10
-
12
+ from ...constants import MPC_SEC, MTSUN_SI, PI
13
+ from ...types import BatchTensor, FrequencySeries1d
14
+ from ..conversion import (
15
+ chirp_mass_and_mass_ratio_to_components,
16
+ rotate_y,
17
+ rotate_z,
18
+ )
11
19
  from .phenom_d import IMRPhenomD
12
20
 
13
21
 
@@ -75,15 +83,15 @@ class IMRPhenomPv2(IMRPhenomD):
75
83
  if tc is None:
76
84
  tc = torch.zeros_like(chirp_mass)
77
85
 
78
- m2 = chirp_mass * (1.0 + mass_ratio) ** 0.2 / mass_ratio**0.6
79
- m1 = m2 * mass_ratio
86
+ m1, m2 = chirp_mass_and_mass_ratio_to_components(
87
+ chirp_mass, mass_ratio
88
+ )
80
89
 
81
90
  # # flip m1 m2. For some reason LAL uses this convention for PhenomPv2
82
91
  m1, m2 = m2, m1
83
92
  s1x, s2x = s2x, s1x
84
93
  s1y, s2y = s2y, s1y
85
94
  s1z, s2z = s2z, s1z
86
-
87
95
  (
88
96
  chi1_l,
89
97
  chi2_l,
@@ -320,42 +328,61 @@ class IMRPhenomPv2(IMRPhenomD):
320
328
  phic: Orbital phase at peak of the underlying non precessing model
321
329
  M: Total mass (Solar masses)
322
330
  """
323
-
324
331
  M_s = M * MTSUN_SI
325
332
  Mf = torch.outer(M_s, fs)
326
- fRD, _ = self.phP_get_fRD_fdamp(m1, m2, chi1, chi2, chip)
333
+ fRD, fDM = self.phP_get_fRD_fdamp(m1, m2, chi1, chi2, chip)
334
+ # pass M_s * ringdown and M_s * damping frequency to PhenomD functions
335
+ MfRD, MfDM = M_s * fRD, M_s * fDM
327
336
 
328
- phase, _ = self.phenom_d_phase(Mf, m1, m2, eta, eta2, chi1, chi2, xi)
337
+ phase, _ = self.phenom_d_phase(
338
+ Mf, m1, m2, eta, eta2, chi1, chi2, xi, MfRD, MfDM
339
+ )
329
340
  phase = (phase.mT - (phic + PI / 4.0)).mT
341
+ # why are they subtracting 2*phic?
342
+ # https://git.ligo.org/lscsoft/lalsuite/-/blob/master/lalsimulation/lib/LALSimIMRPhenomP.c#L1316
343
+
330
344
  Amp = self.phenom_d_amp(
331
- Mf, m1, m2, eta, eta2, Seta, chi1, chi2, chi12, chi22, xi, distance
345
+ Mf,
346
+ m1,
347
+ m2,
348
+ eta,
349
+ eta2,
350
+ Seta,
351
+ chi1,
352
+ chi2,
353
+ chi12,
354
+ chi22,
355
+ xi,
356
+ distance,
357
+ MfRD,
358
+ MfDM,
332
359
  )[0]
333
360
  Amp0 = self.get_Amp0(Mf, eta)
334
361
  dist_s = distance * MPC_SEC
335
362
  Amp = ((Amp0 * Amp).mT * (M_s**2.0) / dist_s).mT
336
- # phase -= 2. * phic; # line 1316 ???
363
+
337
364
  hPhenom = Amp * (torch.exp(-1j * phase))
338
365
 
339
- fRDs = torch.outer(
340
- fRD, torch.linspace(0.5, 1.5, 101, device=fRD.device)
341
- )
342
- delta_fRds = torch.median(torch.diff(fRDs, axis=1), axis=1)[0]
366
+ # calculating derivative of phase with frequency following
367
+ # https://git.ligo.org/lscsoft/lalsuite/-/blame/master/lalsimulation/lib/LALSimIMRPhenomP.c?page=2#L1057 # noqa: E501
368
+ n_fixed = 1000
369
+ x = torch.linspace(0.8, 1.2, n_fixed, device=fRD.device)
370
+ fRDs = torch.outer(fRD, x)
371
+ delta_fRds = (1.2 * fRD - 0.8 * fRD) / (n_fixed - 1)
343
372
  MfRDs = torch.zeros_like(fRDs)
344
373
  for i in range(fRD.shape[0]):
345
374
  MfRDs[i, :] = torch.outer(M_s, fRDs[i, :])[i, :]
346
375
  RD_phase = self.phenom_d_phase(
347
- MfRDs, m1, m2, eta, eta2, chi1, chi2, xi
376
+ MfRDs, m1, m2, eta, eta2, chi1, chi2, xi, MfRD, MfDM
348
377
  )[0]
349
378
  diff = torch.diff(RD_phase, axis=1)
350
379
  diffRDphase = (diff[:, 1:] + diff[:, :-1]) / (
351
380
  2 * delta_fRds.unsqueeze(1)
352
381
  )
353
- diffRDphase = -diffRDphase[:, 50]
354
- # MfRD = torch.outer(M_s, fRD)
355
- # Dphase = torch.diag(
356
- # -self.phenom_d_phase(
357
- # MfRD, m1, m2, eta, eta2, chi1, chi2, xi)[1] * M_s
358
- # ).view(-1, 1)
382
+ # reshape x to have same shape as diffRDphase
383
+ x = x[1:-1].unsqueeze(0).expand(diffRDphase.shape)
384
+ # interpolate at x = 1, as thats the same as f = fRD
385
+ diffRDphase = -self.interpolate(torch.tensor([1]), x, diffRDphase)
359
386
  return hPhenom, diffRDphase
360
387
 
361
388
  # Utility functions
@@ -752,9 +779,9 @@ class IMRPhenomPv2(IMRPhenomD):
752
779
  eta2 = eta * eta
753
780
  # m1 > m2, the convention used in phenomD
754
781
  # (not the convention of internal phenomP)
755
- mass_ratio = m1 / m2
782
+ q_factor = m1 / M
756
783
  af_parallel = self.FinalSpin0815(eta, eta2, chi1_l, chi2_l)
757
- Sperp = chip * mass_ratio * mass_ratio
784
+ Sperp = chip * q_factor * q_factor
758
785
  af = torch.copysign(
759
786
  torch.ones_like(af_parallel), af_parallel
760
787
  ) * torch.sqrt(Sperp * Sperp + af_parallel * af_parallel)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: ml4gw
3
- Version: 0.6.1
3
+ Version: 0.6.2
4
4
  Summary: Tools for training torch models on gravitational wave data
5
5
  Author: Alec Gunny
6
6
  Author-email: alec.gunny@ligo.org
@@ -28,7 +28,7 @@ ml4gw/transforms/scaler.py,sha256=souOt-hOO4M6dqPNXOspfmeU2V9622yGoIMNvju5JZI,25
28
28
  ml4gw/transforms/snr_rescaler.py,sha256=3XXCTaXc2dzzpXRZx7iqRwImvYtRSJLM5fHdBGfpoUs,2351
29
29
  ml4gw/transforms/spectral.py,sha256=gTHUeC0gGYbzgBZHb_FxC_4zdhl5H-XCiLg1hrvKB70,4393
30
30
  ml4gw/transforms/spectrogram.py,sha256=HS3Rf5iB7JjhlSESRDdFGUwCtIBdvUaJUDulkB4Lmos,6162
31
- ml4gw/transforms/spline_interpolation.py,sha256=GkyAVLrtZODIIDLkBdAngO9jqEHRzvEFTdxjNM7U1Bc,13526
31
+ ml4gw/transforms/spline_interpolation.py,sha256=oXih-gLMbIbI36DPKLTk39WcjiNUJN_rcQia_k3OrMY,13527
32
32
  ml4gw/transforms/transform.py,sha256=BuzTbPFxp18OEGP9Tu9jBGtvqy3len1cqvqg5X37DiY,2512
33
33
  ml4gw/transforms/waveforms.py,sha256=LkYCvxPqYhHa2yYZTvPE6j0E4HFy16b5ndCRQb7WfcA,3196
34
34
  ml4gw/transforms/whitening.py,sha256=Aw_ogq93CYCATiHWBqSZ-qsUtaHAMA3k009ZRtQTtHA,9596
@@ -40,12 +40,12 @@ ml4gw/waveforms/adhoc/__init__.py,sha256=XVwP4t8TMUj87WY3yMGRTkXsv7_lVr1w8p8iKBW
40
40
  ml4gw/waveforms/adhoc/ringdown.py,sha256=m8IBQTxKBBGFqBtWGEO4KG3DEYR8TTnNyGVdVLaMKa8,3316
41
41
  ml4gw/waveforms/adhoc/sine_gaussian.py,sha256=-MtrI7ydwBTk4K0O4tdkC8-w5OifQszdnWN9__I4XzY,3569
42
42
  ml4gw/waveforms/cbc/__init__.py,sha256=hGbPsFNAIveYJnff8qKY8RWeBPFtZoYcnGHxraPWtWI,99
43
- ml4gw/waveforms/cbc/phenom_d.py,sha256=3JhN77Xl5foqjmdDJSw4GrTYcaOr1RxXdL1XjUAb8IY,47053
43
+ ml4gw/waveforms/cbc/phenom_d.py,sha256=0pcVAt7b1cjTbphdClPCjenv2sC8bp6oXGGlEUyW-mY,48973
44
44
  ml4gw/waveforms/cbc/phenom_d_data.py,sha256=WA1FBxUp9fo1IQaV_OLJ_5g5gI166mY1FtG9n25he9U,53447
45
- ml4gw/waveforms/cbc/phenom_p.py,sha256=Y8L2r3UPkJeQqJNwknWBmcG_nO2Z_aXJ_DfWc_lzJhg,26720
45
+ ml4gw/waveforms/cbc/phenom_p.py,sha256=nCVu6Tb-xeplch3MUrso_jiThyiNeuIFPnizBan5RfM,27563
46
46
  ml4gw/waveforms/cbc/taylorf2.py,sha256=_s-faE8yWMULMxGd4VvzPI54R3G-O2TF2G4-T2m2rDM,10510
47
47
  ml4gw/waveforms/conversion.py,sha256=zPkaGkMVqsdrF0fS3ZscyP-2jX8YK40d4smUoJb4gj4,6903
48
48
  ml4gw/waveforms/generator.py,sha256=dO6RQ96EC87p2q0tEkxA62XkkJc1xARFO1SKcGvyDhM,1272
49
- ml4gw-0.6.1.dist-info/METADATA,sha256=APoH6HIVkaBFuDLHQQ58NVmu9VJ5zBuo26cLwjHBrE4,5785
50
- ml4gw-0.6.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
51
- ml4gw-0.6.1.dist-info/RECORD,,
49
+ ml4gw-0.6.2.dist-info/METADATA,sha256=BhP0NjJl1RhuBauJBL3Vu9Rw2iZTIWkJyyLzLsg0D_o,5785
50
+ ml4gw-0.6.2.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
51
+ ml4gw-0.6.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: poetry-core 2.0.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any