import time
import numpy as np
from bilby.core.utils.constants import speed_of_light
from bilby.core.utils.conversion import theta_phi_to_ra_dec
from bilby.gw.detector import get_empty_interferometer, Interferometer
from bilby_rust.time import greenwich_mean_sidereal_time
from bilby_rust.geometry import antenna_response
def cartesian_to_spherical(vec):
r = np.linalg.norm(vec)
theta = np.arccos(vec[-1] / r)
phi = np.arctan2(vec[1], vec[0])
return theta, phi
class FrequencyDependentInterferometer(Interferometer):
def optimal_orientation(self, time):
theta, phi = cartesian_to_spherical(np.cross(self.geometry.y, self.geometry.x))
gmst = greenwich_mean_sidereal_time(time) % (2 * np.pi)
return theta_phi_to_ra_dec(theta, phi, gmst)
@property
def free_spectral_range(self):
return speed_of_light / (2 * self.geometry.length * 1e3)
def antenna_response(self, ra, dec, time, psi, mode, frequency=None):
if frequency is None and getattr(self, "_frequencies", None) is None:
frequency = super().antenna_response(ra, dec, time, psi, mode)
elif frequency is None:
frequency = self._frequencies
return antenna_response(
self.geometry.x,
self.geometry.y,
ra,
dec,
time,
psi,
mode,
frequency,
self.free_spectral_range,
)
def get_detector_response(self, waveform_polarizations, parameters, frequencies=None):
old_values = self._frequencies
if frequencies is not None:
self._frequencies = frequencies
else:
self._frequencies = self.strain_data.frequency_array
response = super().get_detector_response(waveform_polarizations, parameters, frequencies)
self._frequencies = old_values
return response
@classmethod
def from_name(cls, name):
ifo = get_empty_interferometer(name)
if isinstance(ifo, Interferometer):
ifo.__class__ = cls
elif isinstance(ifo, list):
for elem in ifo:
elem.__class__ = cls
return ifo
ifo = FrequencyDependentInterferometer.from_name("CE")
start = time.time()
args = (0.0, 0.0, np.ones(1000) * 1e9, 0.0, "plus", np.linspace(10, 4096, 1000))
for _ in range(10000):
_ = ifo.antenna_response(*args)
end = time.time()
print("10000 iterations in {:.6f} seconds".format(end - start))
print("Average time per iteration: {:.6f} seconds".format((end - start) / 10000))