Allow access to antenna response and position
For the use of LISA GW Response in pyRing I would like to enable direct access to the antennae response and position as a separate function.
The pattern dictionary can later be extended to include other modes (vector and scalar) similar to the implementation in the LAL python wrapper.
Ideally with some refactoring this class would inherit from Response and become the base class for ResponseFromStrain instead of the inverse.
Let me know what you think of this idea and if you have any suggestions.
I'd be happy to implement it and open a merge request.
class AntennaResponse(ResponseFromStrain):
def compute_hplus(self, t):
pass
def compute_hcross(self, t):
pass
def compute_gw_antenna_response_and_position(self, t, link):
# pylint: disable=too-many-locals
# Adapted from compute_gw_response
logger.info("Computing gravitational-wave response for links %s", link)
# Broadcast times if needed
t = np.array(t, ndmin=1)
if t.ndim == 1:
t = np.tile(t[:, np.newaxis], len(link)) # (N, M)
# Compute emission and reception time at spacecraft
logger.debug("Computing emission time at spacecraft")
trec = t # (N, M)
temi = np.copy(t) # (N, M)
for link_index, a_link in enumerate(link):
temi[:, link_index] -= self.ltt[a_link](t[:, link_index]) # (N, M)
# Compute spacecraft positions at emission and reception
try:
logger.debug("Computing receiver position at reception time")
xrec = np.empty((*t.shape, 3)) # (N, M, 3)
for i, (a_link, a_receiver) in enumerate(zip(link, receiver(link))):
xrec[:, i, 0] = self.x[a_receiver](trec[:, i]) # (N,)
xrec[:, i, 1] = self.y[a_receiver](trec[:, i]) # (N,)
xrec[:, i, 2] = self.z[a_receiver](trec[:, i]) # (N,)
logger.debug("Computing emitter position at emission time")
xemi = np.empty((*t.shape, 3)) # (N, M, coord)
for i, (a_link, an_emitter) in enumerate(zip(link, emitter(link))):
xemi[:, i, 0] = self.x[an_emitter](temi[:, i]) # (N,)
xemi[:, i, 1] = self.y[an_emitter](temi[:, i]) # (N,)
xemi[:, i, 2] = self.z[an_emitter](temi[:, i]) # (N,)
except ValueError as error:
logger.error("Missing orbit information")
raise ValueError("missing orbit information, use longer orbit file or adjust sampling") from error
# Compute link unit vector
logger.debug("Computing link unit vector")
n = (xrec - xemi) # (N, M, 3)
# Normalise each of the three components
n /= norm(n)[..., np.newaxis] # (N, M, 3)
# Compute equivalent emission and reception time at the Sun
logger.debug("Computing equivalent reception time at the Sun")
trec_sun = trec - dot(xrec, self.k) / c # (N, M)
logger.debug("Computing equivalent emission time at the Sun")
temi_sun = temi - dot(xemi, self.k) / c # (N, M)
positions = {"trec_sun": trec_sun, "temi_sun": temi_sun, "xrec": xrec, "xemi": xemi, "n": n}
# Compute antenna pattern functions
logger.debug("Computing antenna pattern functions")
xiplus = dot(n, self.u) ** 2 - dot(n, self.v) ** 2 # (N, M)
xicross = 2 * dot(n, self.u) * dot(n, self.v) # (N, M)
# Additional modes can be added here (scalar, vector)
patterns = {"fp": xiplus, "fc": xicross}
return patterns, positions
Edited by Simon Maenaut