Skip to content

Commit

Permalink
Adding detector class for calculating LISA projections and response f…
Browse files Browse the repository at this point in the history
…unction (#4691)

* Added LISA detector class with GPU support

* Fixed bug when calling get_tdi w/out setting t0

* Fixed sampling frequency bug in pyResponseTDI class initialization; fixed bug where orbit file was truncated by default init params

* TDI configuration now actually updates when providing tdi input in get_tdi()

* Added reference_time to methods as kwarg; revised methods to be more consistent with LIGO detector class

* Revised init signature to be more similar to LIGO detector; rebase to most recent PyCBC patch (6/4/24)

* Added polarization to project_wave signature; allow for shifting of orbit file start time

* Add functionality to remove or zero edge data

* edited polarization rotation function; final touches for first draft

* changed t0 to kwarg in init

* fix TypeError in unittest

* fix bug when calling ESAOrbits without lisatools

* fix case where t0 is not None; remove debug statements/white space; edit companion (temp pypmc fix, add FLR)

* Indentation fix in init

* add padding (for signals that taper to zero); more cleanup

* add controls for zero padding data to project_wave; add controls for specifying orbit start times for numerical data

* remove orbit reference time; move TDI arguments to project_wave

* add time conversions (GPS time offset, SSB to LISA); moved more padding code from get_links to project_wave

* add debug statements, adjust SSB to LISA time conversions, fix sky coord labels

* ref time accepts anything castable to float, tweak how TDI chans are processed and saved

* start reworking reference time to replicate bbhx (i.e. reference time inputs are no longer necessarily start time)

* fix reference time to correctly calculate signal start time; fix sample times conversion to be based on reference time

* fixes to start time calculation

* set TDI chans to SSB times, clean up unnecessary attributes

* rebase; update companion.txt to match master

* remove data if signal start time is before orbit start time (WIP)

* cut data if waveform extends outside of orbit file times; remove print statements

* add support for LDC software; rework space-based detector class such that detector flag specifies code base (currently supports LDC, FLR)

* rewrite LDC and FLR implementations as separate classes; rewrite space detector class using ABC

* fixed import errors and removed print statements

* revert changes to companion

* add flr warning message

* move common methods in base class to functions; move non-required attributes from base to child classes

* restructured detector file into module; separated ground- and space-based detectors/utils into different files

* add imports in detector init to get unittest working

* make polarization optional in project_wave

* rerun checks

* fix error when specifying orbits in space_detector

* match detector module to match modifications for injection module

* change channel names, add helper functions to work with injection module modifications

* reorganize base class; add __all__ properties to files; clean up docstrings

---------

Co-authored-by: alcorrei <[email protected]>
  • Loading branch information
acorreia61201 and alcorrei authored Dec 17, 2024
1 parent 29a53e7 commit 0470733
Show file tree
Hide file tree
Showing 3 changed files with 961 additions and 131 deletions.
2 changes: 2 additions & 0 deletions pycbc/detector/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .ground import *
from .space import *
139 changes: 8 additions & 131 deletions pycbc/detector.py → pycbc/detector/ground.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# =============================================================================
#
"""This module provides utilities for calculating detector responses and timing
between observatories.
between ground-based observatories.
"""
import os
import logging
Expand Down Expand Up @@ -655,136 +655,6 @@ def overhead_antenna_pattern(right_ascension, declination, polarization):
return f_plus, f_cross


""" LISA class """


class LISA(object):
"""For LISA detector
"""
def __init__(self):
None

def get_pos(self, ref_time):
"""Return the position of LISA detector for a given reference time
Parameters
----------
ref_time : numpy.ScalarType
Returns
-------
location : numpy.ndarray of shape (3,3)
Returns the position of all 3 sattelites with each row
correspoding to a single axis.
"""
ref_time = Time(val=ref_time, format='gps', scale='utc').jyear
n = np.array(range(1, 4))
kappa, _lambda_ = 0, 0
alpha = 2. * np.pi * ref_time/1 + kappa
beta_n = (n - 1) * 2.0 * pi / 3.0 + _lambda_
a, L = 1., 0.03342293561
e = L/(2. * a * np.sqrt(3))

x = a*cos(alpha) + a*e*(sin(alpha)*cos(alpha)*sin(beta_n) - (1 + sin(alpha)**2)*cos(beta_n))
y = a*sin(alpha) + a*e*(sin(alpha)*cos(alpha)*cos(beta_n) - (1 + cos(alpha)**2)*sin(beta_n))
z = -np.sqrt(3)*a*e*cos(alpha - beta_n)
self.location = np.array([x, y, z])

return self.location

def get_gcrs_pos(self, location):
""" Transforms ICRS frame to GCRS frame
Parameters
----------
loc : numpy.ndarray shape (3,1) units: AU
Cartesian Coordinates of the location
in ICRS frame
Returns
----------
loc : numpy.ndarray shape (3,1) units: meters
GCRS coordinates in cartesian system
"""
loc = location
loc = coordinates.SkyCoord(x=loc[0], y=loc[1], z=loc[2], unit=units.AU,
frame='icrs', representation_type='cartesian').transform_to('gcrs')
loc.representation_type = 'cartesian'
conv = np.float32(((loc.x.unit/units.m).decompose()).to_string())
loc = np.array([np.float32(loc.x), np.float32(loc.y),
np.float32(loc.z)])*conv
return loc

def time_delay_from_location(self, other_location, right_ascension,
declination, t_gps):
"""Return the time delay from the LISA detector to detector for
a signal with the given sky location. In other words return
`t1 - t2` where `t1` is the arrival time in this detector and
`t2` is the arrival time in the other location. Units(AU)
Parameters
----------
other_location : numpy.ndarray of coordinates in ICRS frame
A detector instance.
right_ascension : float
The right ascension (in rad) of the signal.
declination : float
The declination (in rad) of the signal.
t_gps : float
The GPS time (in s) of the signal.
Returns
-------
numpy.ndarray
The arrival time difference between the detectors.
"""
dx = self.location - other_location
cosd = cos(declination)
e0 = cosd * cos(right_ascension)
e1 = cosd * -sin(right_ascension)
e2 = sin(declination)
ehat = np.array([e0, e1, e2])
return dx.dot(ehat) / constants.c.value

def time_delay_from_detector(self, det, right_ascension,
declination, t_gps):
"""Return the time delay from the LISA detector for a signal with
the given sky location in ICRS frame; i.e. return `t1 - t2` where
`t1` is the arrival time in this detector and `t2` is the arrival
time in the other detector.
Parameters
----------
other_detector : detector.Detector
A detector instance.
right_ascension : float
The right ascension (in rad) of the signal.
declination : float
The declination (in rad) of the signal.
t_gps : float
The GPS time (in s) of the signal.
Returns
-------
numpy.ndarray
The arrival time difference between the detectors.
"""
loc = Detector(det, t_gps).get_icrs_pos()
return self.time_delay_from_location(loc, right_ascension,
declination, t_gps)

def time_delay_from_earth_center(self, right_ascension, declination, t_gps):
"""Return the time delay from the earth center in ICRS frame
"""
t_gps = Time(val=t_gps, format='gps', scale='utc')
earth = coordinates.get_body('earth', t_gps,
location=None).transform_to('icrs')
earth.representation_type = 'cartesian'
return self.time_delay_from_location(
np.array([np.float32(earth.x), np.float32(earth.y),
np.float32(earth.z)]), right_ascension,
declination, t_gps)


def ppdets(ifos, separator=', '):
"""Pretty-print a list (or set) of detectors: return a string listing
the given detectors alphabetically and separated by the given string
Expand All @@ -793,3 +663,10 @@ def ppdets(ifos, separator=', '):
if ifos:
return separator.join(sorted(ifos))
return 'no detectors'

__all__ = ['Detector', 'get_available_detectors',
'get_available_lal_detectors',
'gmst_accurate', 'add_detector_on_earth',
'single_arm_frequency_response', 'ppdets',
'overhead_antenna_pattern', 'load_detector_config',
'_ground_detectors',]
Loading

0 comments on commit 0470733

Please sign in to comment.