Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
lscsoft
bilby
Commits
9d0a6aa6
Commit
9d0a6aa6
authored
May 20, 2019
by
Moritz Huebner
Committed by
Gregory Ashton
May 20, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Restructure detector tests
parent
4c579e9d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
243 additions
and
174 deletions
+243
-174
bilby/gw/detector/geometry.py
bilby/gw/detector/geometry.py
+39
-0
bilby/gw/detector/interferometer.py
bilby/gw/detector/interferometer.py
+42
-47
test/detector_test.py
test/detector_test.py
+162
-127
No files found.
bilby/gw/detector/geometry.py
View file @
9d0a6aa6
...
...
@@ -6,6 +6,31 @@ from .. import utils as gwutils
class
InterferometerGeometry
(
object
):
def
__init__
(
self
,
length
,
latitude
,
longitude
,
elevation
,
xarm_azimuth
,
yarm_azimuth
,
xarm_tilt
=
0.
,
yarm_tilt
=
0.
):
"""
Instantiate an Interferometer object.
Parameters
----------
length: float
Length of the interferometer in km.
latitude: float
Latitude North in degrees (South is negative).
longitude: float
Longitude East in degrees (West is negative).
elevation: float
Height above surface in metres.
xarm_azimuth: float
Orientation of the x arm in degrees North of East.
yarm_azimuth: float
Orientation of the y arm in degrees North of East.
xarm_tilt: float, optional
Tilt of the x arm in radians above the horizontal defined by
ellipsoid earth model in LIGO-T980044-08.
yarm_tilt: float, optional
Tilt of the y arm in radians above the horizontal.
"""
self
.
_x_updated
=
False
self
.
_y_updated
=
False
self
.
_vertex_updated
=
False
...
...
@@ -24,6 +49,20 @@ class InterferometerGeometry(object):
self
.
_y
=
None
self
.
_detector_tensor
=
None
def
__eq__
(
self
,
other
):
for
attribute
in
[
'length'
,
'latitude'
,
'longitude'
,
'elevation'
,
'xarm_azimuth'
,
'yarm_azimuth'
,
'xarm_tilt'
,
'yarm_tilt'
]:
if
not
getattr
(
self
,
attribute
)
==
getattr
(
other
,
attribute
):
return
False
return
True
def
__repr__
(
self
):
return
self
.
__class__
.
__name__
+
'(length={}, latitude={}, longitude={}, elevation={}, '
\
'xarm_azimuth={}, yarm_azimuth={}, xarm_tilt={}, yarm_tilt={})'
\
.
format
(
float
(
self
.
length
),
float
(
self
.
latitude
),
float
(
self
.
longitude
),
float
(
self
.
elevation
),
float
(
self
.
xarm_azimuth
),
float
(
self
.
yarm_azimuth
),
float
(
self
.
xarm_tilt
),
float
(
self
.
yarm_tilt
))
@
property
def
latitude
(
self
):
""" Saves latitude in rad internally. Updates related quantities if set to a different value.
...
...
bilby/gw/detector/interferometer.py
View file @
9d0a6aa6
...
...
@@ -95,14 +95,7 @@ class Interferometer(object):
def
__eq__
(
self
,
other
):
if
self
.
name
==
other
.
name
and
\
self
.
length
==
other
.
length
and
\
self
.
latitude
==
other
.
latitude
and
\
self
.
longitude
==
other
.
longitude
and
\
self
.
elevation
==
other
.
elevation
and
\
self
.
xarm_azimuth
==
other
.
xarm_azimuth
and
\
self
.
xarm_tilt
==
other
.
xarm_tilt
and
\
self
.
yarm_azimuth
==
other
.
yarm_azimuth
and
\
self
.
yarm_tilt
==
other
.
yarm_tilt
and
\
self
.
geometry
==
other
.
geometry
and
\
self
.
power_spectral_density
.
__eq__
(
other
.
power_spectral_density
)
and
\
self
.
calibration_model
==
other
.
calibration_model
and
\
self
.
strain_data
==
other
.
strain_data
:
...
...
@@ -113,10 +106,12 @@ class Interferometer(object):
return
self
.
__class__
.
__name__
+
'(name=
\'
{}
\'
, power_spectral_density={}, minimum_frequency={}, '
\
'maximum_frequency={}, length={}, latitude={}, longitude={}, elevation={}, '
\
'xarm_azimuth={}, yarm_azimuth={}, xarm_tilt={}, yarm_tilt={})'
\
.
format
(
self
.
name
,
self
.
power_spectral_density
,
float
(
self
.
minimum_frequency
),
float
(
self
.
maximum_frequency
),
float
(
self
.
length
),
float
(
self
.
latitude
),
float
(
self
.
longitude
),
float
(
self
.
elevation
),
float
(
self
.
xarm_azimuth
),
float
(
self
.
yarm_azimuth
),
float
(
self
.
xarm_tilt
),
float
(
self
.
yarm_tilt
))
.
format
(
self
.
name
,
self
.
power_spectral_density
,
float
(
self
.
strain_data
.
minimum_frequency
),
float
(
self
.
strain_data
.
maximum_frequency
),
float
(
self
.
geometry
.
length
),
float
(
self
.
geometry
.
latitude
),
float
(
self
.
geometry
.
longitude
),
float
(
self
.
geometry
.
elevation
),
float
(
self
.
geometry
.
xarm_azimuth
),
float
(
self
.
geometry
.
yarm_azimuth
),
float
(
self
.
geometry
.
xarm_tilt
),
float
(
self
.
geometry
.
yarm_tilt
))
def
set_strain_data_from_frequency_domain_strain
(
self
,
frequency_domain_strain
,
sampling_frequency
=
None
,
...
...
@@ -250,7 +245,7 @@ class Interferometer(object):
"""
polarization_tensor
=
gwutils
.
get_polarization_tensor
(
ra
,
dec
,
time
,
psi
,
mode
)
return
np
.
einsum
(
'ij,ij->'
,
self
.
detector_tensor
,
polarization_tensor
)
return
np
.
einsum
(
'ij,ij->'
,
self
.
geometry
.
detector_tensor
,
polarization_tensor
)
def
get_detector_response
(
self
,
waveform_polarizations
,
parameters
):
""" Get the detector response for a particular waveform
...
...
@@ -283,11 +278,11 @@ class Interferometer(object):
parameters
[
'ra'
],
parameters
[
'dec'
],
parameters
[
'geocent_time'
])
dt
=
parameters
[
'geocent_time'
]
+
time_shift
-
self
.
strain_data
.
start_time
signal_ifo
[
self
.
frequency_mask
]
=
signal_ifo
[
self
.
frequency_mask
]
*
np
.
exp
(
-
1j
*
2
*
np
.
pi
*
dt
*
self
.
frequency_array
[
self
.
frequency_mask
])
signal_ifo
[
self
.
strain_data
.
frequency_mask
]
=
signal_ifo
[
self
.
strain_data
.
frequency_mask
]
*
np
.
exp
(
-
1j
*
2
*
np
.
pi
*
dt
*
self
.
strain_data
.
frequency_array
[
self
.
strain_data
.
frequency_mask
])
signal_ifo
[
self
.
frequency_mask
]
*=
self
.
calibration_model
.
get_calibration_factor
(
self
.
frequency_array
[
self
.
frequency_mask
],
signal_ifo
[
self
.
strain_data
.
frequency_mask
]
*=
self
.
calibration_model
.
get_calibration_factor
(
self
.
strain_data
.
frequency_array
[
self
.
strain_data
.
frequency_mask
],
prefix
=
'recalib_{}_'
.
format
(
self
.
name
),
**
parameters
)
return
signal_ifo
...
...
@@ -342,7 +337,7 @@ class Interferometer(object):
.
format
(
self
.
strain_data
.
start_time
,
parameters
[
'geocent_time'
]))
signal_ifo
=
self
.
get_detector_response
(
injection_polarizations
,
parameters
)
if
np
.
shape
(
self
.
frequency_domain_strain
).
__eq__
(
np
.
shape
(
signal_ifo
)):
if
np
.
shape
(
self
.
strain_data
.
frequency_domain_strain
).
__eq__
(
np
.
shape
(
signal_ifo
)):
self
.
strain_data
.
frequency_domain_strain
=
\
signal_ifo
+
self
.
strain_data
.
frequency_domain_strain
else
:
...
...
@@ -378,7 +373,7 @@ class Interferometer(object):
"""
return
(
self
.
power_spectral_density
.
get_amplitude_spectral_density_array
(
frequency_array
=
self
.
frequency_array
)
*
frequency_array
=
self
.
strain_data
.
frequency_array
)
*
self
.
strain_data
.
window_factor
**
0.5
)
@
property
...
...
@@ -394,7 +389,7 @@ class Interferometer(object):
"""
return
(
self
.
power_spectral_density
.
get_power_spectral_density_array
(
frequency_array
=
self
.
frequency_array
)
*
frequency_array
=
self
.
strain_data
.
frequency_array
)
*
self
.
strain_data
.
window_factor
)
def
unit_vector_along_arm
(
self
,
arm
):
...
...
@@ -421,7 +416,7 @@ class Interferometer(object):
-------
float: The time delay from geocenter in seconds
"""
return
gwutils
.
time_delay_geocentric
(
self
.
vertex
,
np
.
array
([
0
,
0
,
0
]),
ra
,
dec
,
time
)
return
gwutils
.
time_delay_geocentric
(
self
.
geometry
.
vertex
,
np
.
array
([
0
,
0
,
0
]),
ra
,
dec
,
time
)
def
vertex_position_geocentric
(
self
):
"""
...
...
@@ -434,9 +429,9 @@ class Interferometer(object):
-------
array_like: A 3D array representation of the vertex
"""
return
gwutils
.
get_vertex_position_geocentric
(
self
.
latitude_radians
,
self
.
longitude_radians
,
self
.
elevation
)
return
gwutils
.
get_vertex_position_geocentric
(
self
.
geometry
.
latitude_radians
,
self
.
geometry
.
longitude_radians
,
self
.
geometry
.
elevation
)
def
optimal_snr_squared
(
self
,
signal
):
"""
...
...
@@ -451,8 +446,8 @@ class Interferometer(object):
float: The optimal signal to noise ratio possible squared
"""
return
gwutils
.
optimal_snr_squared
(
signal
=
signal
[
self
.
frequency_mask
],
power_spectral_density
=
self
.
power_spectral_density_array
[
self
.
frequency_mask
],
signal
=
signal
[
self
.
strain_data
.
frequency_mask
],
power_spectral_density
=
self
.
power_spectral_density_array
[
self
.
strain_data
.
frequency_mask
],
duration
=
self
.
strain_data
.
duration
)
def
inner_product
(
self
,
signal
):
...
...
@@ -468,9 +463,9 @@ class Interferometer(object):
float: The optimal signal to noise ratio possible squared
"""
return
gwutils
.
noise_weighted_inner_product
(
aa
=
signal
[
self
.
frequency_mask
],
bb
=
self
.
frequency_domain_strain
[
self
.
frequency_mask
],
power_spectral_density
=
self
.
power_spectral_density_array
[
self
.
frequency_mask
],
aa
=
signal
[
self
.
strain_data
.
frequency_mask
],
bb
=
self
.
strain_data
.
frequency_domain_strain
[
self
.
strain_data
.
frequency_mask
],
power_spectral_density
=
self
.
power_spectral_density_array
[
self
.
strain_data
.
frequency_mask
],
duration
=
self
.
strain_data
.
duration
)
def
matched_filter_snr
(
self
,
signal
):
...
...
@@ -487,9 +482,9 @@ class Interferometer(object):
"""
return
gwutils
.
matched_filter_snr
(
signal
=
signal
[
self
.
frequency_mask
],
frequency_domain_strain
=
self
.
frequency_domain_strain
[
self
.
frequency_mask
],
power_spectral_density
=
self
.
power_spectral_density_array
[
self
.
frequency_mask
],
signal
=
signal
[
self
.
strain_data
.
frequency_mask
],
frequency_domain_strain
=
self
.
strain_data
.
frequency_domain_strain
[
self
.
strain_data
.
frequency_mask
],
power_spectral_density
=
self
.
power_spectral_density_array
[
self
.
strain_data
.
frequency_mask
],
duration
=
self
.
strain_data
.
duration
)
@
property
...
...
@@ -521,13 +516,13 @@ class Interferometer(object):
filename_data
=
'{}/{}_{}_frequency_domain_data.dat'
.
format
(
outdir
,
self
.
name
,
label
)
np
.
savetxt
(
filename_data
,
np
.
array
(
[
self
.
frequency_array
,
self
.
frequency_domain_strain
.
real
,
self
.
frequency_domain_strain
.
imag
]).
T
,
[
self
.
strain_data
.
frequency_array
,
self
.
strain_data
.
frequency_domain_strain
.
real
,
self
.
strain_data
.
frequency_domain_strain
.
imag
]).
T
,
header
=
'f real_h(f) imag_h(f)'
)
np
.
savetxt
(
filename_psd
,
np
.
array
(
[
self
.
frequency_array
,
[
self
.
strain_data
.
frequency_array
,
self
.
amplitude_spectral_density_array
]).
T
,
header
=
'f h(f)'
)
...
...
@@ -536,22 +531,22 @@ class Interferometer(object):
return
fig
,
ax
=
plt
.
subplots
()
df
=
self
.
frequency_array
[
1
]
-
self
.
frequency_array
[
0
]
df
=
self
.
strain_data
.
frequency_array
[
1
]
-
self
.
strain_data
.
frequency_array
[
0
]
asd
=
gwutils
.
asd_from_freq_series
(
freq_data
=
self
.
frequency_domain_strain
,
df
=
df
)
freq_data
=
self
.
strain_data
.
frequency_domain_strain
,
df
=
df
)
ax
.
loglog
(
self
.
frequency_array
[
self
.
frequency_mask
],
asd
[
self
.
frequency_mask
],
ax
.
loglog
(
self
.
strain_data
.
frequency_array
[
self
.
strain_data
.
frequency_mask
],
asd
[
self
.
strain_data
.
frequency_mask
],
color
=
'C0'
,
label
=
self
.
name
)
ax
.
loglog
(
self
.
frequency_array
[
self
.
frequency_mask
],
self
.
amplitude_spectral_density_array
[
self
.
frequency_mask
],
ax
.
loglog
(
self
.
strain_data
.
frequency_array
[
self
.
strain_data
.
frequency_mask
],
self
.
amplitude_spectral_density_array
[
self
.
strain_data
.
frequency_mask
],
color
=
'C1'
,
lw
=
1.0
,
label
=
self
.
name
+
' ASD'
)
if
signal
is
not
None
:
signal_asd
=
gwutils
.
asd_from_freq_series
(
freq_data
=
signal
,
df
=
df
)
ax
.
loglog
(
self
.
frequency_array
[
self
.
frequency_mask
],
signal_asd
[
self
.
frequency_mask
],
ax
.
loglog
(
self
.
strain_data
.
frequency_array
[
self
.
strain_data
.
frequency_mask
],
signal_asd
[
self
.
strain_data
.
frequency_mask
],
color
=
'C2'
,
label
=
'Signal'
)
ax
.
grid
(
True
)
...
...
@@ -594,7 +589,7 @@ class Interferometer(object):
if
notches
is
None
:
notches
=
list
()
timeseries
=
gwpy
.
timeseries
.
TimeSeries
(
data
=
self
.
time_domain_strain
,
times
=
self
.
time_array
)
data
=
self
.
strain_data
.
time_domain_strain
,
times
=
self
.
strain_data
.
time_array
)
zpks
=
[]
if
bandpass_frequencies
is
not
None
:
zpks
.
append
(
gwpy
.
signal
.
filter_design
.
bandpass
(
...
...
@@ -613,10 +608,10 @@ class Interferometer(object):
fig
,
ax
=
plt
.
subplots
()
if
t0
:
x
=
self
.
time_array
-
t0
x
=
self
.
strain_data
.
time_array
-
t0
xlabel
=
'GPS time [s] - {}'
.
format
(
t0
)
else
:
x
=
self
.
time_array
x
=
self
.
strain_data
.
time_array
xlabel
=
'GPS time [s]'
ax
.
plot
(
x
,
strain
)
...
...
test/detector_test.py
View file @
9d0a6aa6
...
...
@@ -14,13 +14,9 @@ import logging
import
deepdish
as
dd
class
TestInterferometer
(
unittest
.
TestCase
):
class
TestInterferometer
Geometry
(
unittest
.
TestCase
):
def
setUp
(
self
):
self
.
name
=
'name'
self
.
power_spectral_density
=
bilby
.
gw
.
detector
.
PowerSpectralDensity
.
from_aligo
()
self
.
minimum_frequency
=
10
self
.
maximum_frequency
=
20
self
.
length
=
30
self
.
latitude
=
1
self
.
longitude
=
2
...
...
@@ -29,24 +25,16 @@ class TestInterferometer(unittest.TestCase):
self
.
yarm_azimuth
=
5
self
.
xarm_tilt
=
0.
self
.
yarm_tilt
=
0.
# noinspection PyTypeChecker
self
.
ifo
=
bilby
.
gw
.
detector
.
Interferometer
(
name
=
self
.
name
,
power_spectral_density
=
self
.
power_spectral_density
,
minimum_frequency
=
self
.
minimum_frequency
,
maximum_frequency
=
self
.
maximum_frequency
,
length
=
self
.
length
,
latitude
=
self
.
latitude
,
longitude
=
self
.
longitude
,
elevation
=
self
.
elevation
,
xarm_azimuth
=
self
.
xarm_azimuth
,
yarm_azimuth
=
self
.
yarm_azimuth
,
xarm_tilt
=
self
.
xarm_tilt
,
yarm_tilt
=
self
.
yarm_tilt
)
self
.
ifo
.
strain_data
.
set_from_frequency_domain_strain
(
np
.
linspace
(
0
,
4096
,
4097
),
sampling_frequency
=
4096
,
duration
=
2
)
self
.
outdir
=
'outdir'
bilby
.
core
.
utils
.
check_directory_exists_and_if_not_mkdir
(
self
.
outdir
)
self
.
geometry
=
bilby
.
gw
.
detector
.
InterferometerGeometry
(
length
=
self
.
length
,
latitude
=
self
.
latitude
,
longitude
=
self
.
longitude
,
elevation
=
self
.
elevation
,
xarm_azimuth
=
self
.
xarm_azimuth
,
yarm_azimuth
=
self
.
yarm_azimuth
,
xarm_tilt
=
self
.
xarm_tilt
,
yarm_tilt
=
self
.
yarm_tilt
)
def
tearDown
(
self
):
del
self
.
name
del
self
.
power_spectral_density
del
self
.
minimum_frequency
del
self
.
maximum_frequency
del
self
.
length
del
self
.
latitude
del
self
.
longitude
...
...
@@ -55,180 +43,253 @@ class TestInterferometer(unittest.TestCase):
del
self
.
yarm_azimuth
del
self
.
xarm_tilt
del
self
.
yarm_tilt
del
self
.
ifo
rmtree
(
self
.
outdir
)
def
test_name_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
name
,
self
.
name
)
def
test_psd_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
power_spectral_density
,
self
.
power_spectral_density
)
def
test_min_freq_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
strain_data
.
minimum_frequency
,
self
.
minimum_frequency
)
def
test_max_freq_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
strain_data
.
maximum_frequency
,
self
.
maximum_frequency
)
del
self
.
geometry
def
test_length_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
length
,
self
.
length
)
self
.
assertEqual
(
self
.
geometry
.
length
,
self
.
length
)
def
test_latitude_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
latitude
,
self
.
latitude
)
self
.
assertEqual
(
self
.
geometry
.
latitude
,
self
.
latitude
)
def
test_longitude_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
longitude
,
self
.
longitude
)
self
.
assertEqual
(
self
.
geometry
.
longitude
,
self
.
longitude
)
def
test_elevation_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
elevation
,
self
.
elevation
)
self
.
assertEqual
(
self
.
geometry
.
elevation
,
self
.
elevation
)
def
test_xarm_azi_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
xarm_azimuth
,
self
.
xarm_azimuth
)
self
.
assertEqual
(
self
.
geometry
.
xarm_azimuth
,
self
.
xarm_azimuth
)
def
test_yarm_azi_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
yarm_azimuth
,
self
.
yarm_azimuth
)
self
.
assertEqual
(
self
.
geometry
.
yarm_azimuth
,
self
.
yarm_azimuth
)
def
test_xarm_tilt_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
xarm_tilt
,
self
.
xarm_tilt
)
self
.
assertEqual
(
self
.
geometry
.
xarm_tilt
,
self
.
xarm_tilt
)
def
test_yarm_tilt_setting
(
self
):
self
.
assertEqual
(
self
.
ifo
.
yarm_tilt
,
self
.
yarm_tilt
)
self
.
assertEqual
(
self
.
geometry
.
yarm_tilt
,
self
.
yarm_tilt
)
def
test_vertex_without_update
(
self
):
_
=
self
.
ifo
.
vertex
_
=
self
.
geometry
.
vertex
with
mock
.
patch
(
'bilby.gw.utils.get_vertex_position_geocentric'
)
as
m
:
m
.
return_value
=
np
.
array
([
1
])
self
.
assertFalse
(
np
.
array_equal
(
self
.
ifo
.
vertex
,
np
.
array
([
1
])))
self
.
assertFalse
(
np
.
array_equal
(
self
.
geometry
.
vertex
,
np
.
array
([
1
])))
def
test_vertex_with_latitude_update
(
self
):
with
mock
.
patch
(
'bilby.gw.utils.get_vertex_position_geocentric'
)
as
m
:
m
.
return_value
=
np
.
array
([
1
])
self
.
ifo
.
latitude
=
5
self
.
assertEqual
(
self
.
ifo
.
vertex
,
np
.
array
([
1
]))
self
.
geometry
.
latitude
=
5
self
.
assertEqual
(
self
.
geometry
.
vertex
,
np
.
array
([
1
]))
def
test_vertex_with_longitude_update
(
self
):
with
mock
.
patch
(
'bilby.gw.utils.get_vertex_position_geocentric'
)
as
m
:
m
.
return_value
=
np
.
array
([
1
])
self
.
ifo
.
longitude
=
5
self
.
assertEqual
(
self
.
ifo
.
vertex
,
np
.
array
([
1
]))
self
.
geometry
.
longitude
=
5
self
.
assertEqual
(
self
.
geometry
.
vertex
,
np
.
array
([
1
]))
def
test_vertex_with_elevation_update
(
self
):
with
mock
.
patch
(
'bilby.gw.utils.get_vertex_position_geocentric'
)
as
m
:
m
.
return_value
=
np
.
array
([
1
])
self
.
ifo
.
elevation
=
5
self
.
assertEqual
(
self
.
ifo
.
vertex
,
np
.
array
([
1
]))
self
.
geometry
.
elevation
=
5
self
.
assertEqual
(
self
.
geometry
.
vertex
,
np
.
array
([
1
]))
def
test_x_without_update
(
self
):
_
=
self
.
ifo
.
x
self
.
ifo
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
_
=
self
.
geometry
.
x
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
assertFalse
(
np
.
array_equal
(
self
.
ifo
.
x
,
self
.
assertFalse
(
np
.
array_equal
(
self
.
geometry
.
x
,
np
.
array
([
1
])))
def
test_x_with_xarm_tilt_update
(
self
):
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
ifo
.
xarm_tilt
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
ifo
.
x
,
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
geometry
.
xarm_tilt
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
geometry
.
x
,
np
.
array
([
1
])))
def
test_x_with_xarm_azimuth_update
(
self
):
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
ifo
.
xarm_azimuth
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
ifo
.
x
,
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
geometry
.
xarm_azimuth
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
geometry
.
x
,
np
.
array
([
1
])))
def
test_x_with_longitude_update
(
self
):
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
ifo
.
longitude
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
ifo
.
x
,
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
geometry
.
longitude
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
geometry
.
x
,
np
.
array
([
1
])))
def
test_x_with_latitude_update
(
self
):
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
ifo
.
latitude
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
ifo
.
x
,
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
geometry
.
latitude
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
geometry
.
x
,
np
.
array
([
1
])))
def
test_y_without_update
(
self
):
_
=
self
.
ifo
.
y
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
_
=
self
.
geometry
.
y
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
assertFalse
(
np
.
array_equal
(
self
.
ifo
.
y
,
self
.
assertFalse
(
np
.
array_equal
(
self
.
geometry
.
y
,
np
.
array
([
1
])))
def
test_y_with_yarm_tilt_update
(
self
):
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
ifo
.
yarm_tilt
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
ifo
.
y
,
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
geometry
.
yarm_tilt
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
geometry
.
y
,
np
.
array
([
1
])))
def
test_y_with_yarm_azimuth_update
(
self
):
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
ifo
.
yarm_azimuth
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
ifo
.
y
,
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
geometry
.
yarm_azimuth
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
geometry
.
y
,
np
.
array
([
1
])))
def
test_y_with_longitude_update
(
self
):
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
ifo
.
longitude
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
ifo
.
y
,
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
geometry
.
longitude
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
geometry
.
y
,
np
.
array
([
1
])))
def
test_y_with_latitude_update
(
self
):
self
.
ifo
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
ifo
.
latitude
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
ifo
.
y
,
self
.
geometry
.
unit_vector_along_arm
=
MagicMock
(
return_value
=
np
.
array
([
1
]))
self
.
geometry
.
latitude
=
0
self
.
assertTrue
(
np
.
array_equal
(
self
.
geometry
.
y
,
np
.
array
([
1
])))
def
test_detector_tensor_without_update
(
self
):
_
=
self
.
ifo
.
detector_tensor
_
=
self
.
geometry
.
detector_tensor
with
mock
.
patch
(
'numpy.einsum'
)
as
m
:
m
.
return_value
=
1
expected
=
np
.
array
([[
-
9.24529394e-06
,
1.02425803e-04
,
3.24550668e-04
],
[
1.02425803e-04
,
1.37390844e-03
,
-
8.61137566e-03
],
[
3.24550668e-04
,
-
8.61137566e-03
,
-
1.36466315e-03
]])
self
.
assertTrue
(
np
.
allclose
(
expected
,
self
.
ifo
.
detector_tensor
))
self
.
assertTrue
(
np
.
allclose
(
expected
,
self
.
geometry
.
detector_tensor
))
def
test_detector_tensor_with_x_azimuth_update
(
self
):
_
=
self
.
ifo
.
detector_tensor
_
=
self
.
geometry
.
detector_tensor
with
mock
.
patch
(
'numpy.einsum'
)
as
m
:
m
.
return_value
=
1
self
.
ifo
.
xarm_azimuth
=
1
self
.
assertEqual
(
0
,
self
.
ifo
.
detector_tensor
)
self
.
geometry
.
xarm_azimuth
=
1
self
.
assertEqual
(
0
,
self
.
geometry
.
detector_tensor
)
def
test_detector_tensor_with_y_azimuth_update
(
self
):
_
=
self
.
ifo
.
detector_tensor
_
=
self
.
geometry
.
detector_tensor
with
mock
.
patch
(
'numpy.einsum'
)
as
m
:
m
.
return_value
=
1
self
.
ifo
.
yarm_azimuth
=
1
self
.
assertEqual
(
0
,
self
.
ifo
.
detector_tensor
)
self
.
geometry
.
yarm_azimuth
=
1
self
.
assertEqual
(
0
,
self
.
geometry
.
detector_tensor
)
def
test_detector_tensor_with_x_tilt_update
(
self
):
_
=
self
.
ifo
.
detector_tensor
_
=
self
.
geometry
.
detector_tensor
with
mock
.
patch
(
'numpy.einsum'
)
as
m
:
m
.
return_value
=
1
self
.
ifo
.
xarm_tilt
=
1
self
.
assertEqual
(
0
,
self
.
ifo
.
detector_tensor
)
self
.
geometry
.
xarm_tilt
=
1
self
.
assertEqual
(
0
,
self
.
geometry
.
detector_tensor
)
def
test_detector_tensor_with_y_tilt_update
(
self
):
_
=
self
.
ifo
.
detector_tensor
_
=
self
.
geometry
.
detector_tensor
with
mock
.
patch
(
'numpy.einsum'
)
as
m
:
m
.
return_value
=
1
self
.
ifo
.
yarm_tilt
=
1
self
.
assertEqual
(
0
,
self
.
ifo
.
detector_tensor
)
self
.
geometry
.
yarm_tilt
=
1
self
.
assertEqual
(
0
,
self
.
geometry
.
detector_tensor
)
def
test_detector_tensor_with_longitude_update
(
self
):
with
mock
.
patch
(
'numpy.einsum'
)
as
m
:
m
.
return_value
=
1
self
.
ifo
.
longitude
=
1
self
.
assertEqual
(
0
,
self
.
ifo
.
detector_tensor
)
self
.
geometry
.
longitude
=
1
self
.
assertEqual
(
0
,
self
.
geometry
.
detector_tensor
)
def
test_detector_tensor_with_latitude_update
(
self
):
with
mock
.
patch
(
'numpy.einsum'
)
as
m
:
_
=
self
.
ifo
.
detector_tensor
_
=
self
.
geometry
.
detector_tensor
m
.
return_value
=
1
self
.
geometry
.
latitude
=
1
self
.
assertEqual
(
self
.
geometry
.
detector_tensor
,
0
)
def
test_unit_vector_along_arm_default
(
self
):
with
self
.
assertRaises
(
ValueError
):
self
.
geometry
.
unit_vector_along_arm
(
'z'
)
def
test_unit_vector_along_arm_x
(
self
):
with
mock
.
patch
(
'numpy.array'
)
as
m
:
m
.
return_value
=
1
self
.
geometry
.
xarm_tilt
=
0
self
.
geometry
.
xarm_azimuth
=
0
self
.
geometry
.
yarm_tilt
=
0
self
.
geometry
.
yarm_azimuth
=
90
self
.
assertAlmostEqual
(
self
.
geometry
.
unit_vector_along_arm
(
'x'
),
1
)
def
test_unit_vector_along_arm_y
(
self
):
with
mock
.
patch
(
'numpy.array'
)
as
m
:
m
.
return_value
=
1
self
.
ifo
.
latitude
=
1
self
.
assertEqual
(
self
.
ifo
.
detector_tensor
,
0
)
self
.
geometry
.
xarm_tilt
=
0
self
.
geometry
.
xarm_azimuth
=
90
self
.
geometry
.
yarm_tilt
=
0
self
.
geometry
.
yarm_azimuth
=
180
self
.
assertAlmostEqual
(
self
.
geometry
.
unit_vector_along_arm
(
'y'
),
-
1
)
def
test_repr
(
self
):
expected
=
'InterferometerGeometry(length={}, latitude={}, longitude={}, elevation={}, xarm_azimuth={}, '
\
'yarm_azimuth={}, xarm_tilt={}, yarm_tilt={})'
\
.
format
(
float
(
self
.
length
),
float
(
self
.
latitude
),
float
(
self
.
longitude
),
float
(
self
.
elevation
),
float
(
self
.
xarm_azimuth
),
float
(
self
.
yarm_azimuth
),
float
(
self
.
xarm_tilt
),
float
(
self
.
yarm_tilt
))
self
.
assertEqual
(
expected
,
repr
(
self
.
geometry
))
class
TestInterferometer
(
unittest
.
TestCase
):