-
Jean-Baptiste Bayle authoredJean-Baptiste Bayle authored
report.py 28.75 KiB
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
"""Produce various plots as a reporting and diagnostic tool.
The 'report' continuous-integration job runs various simulations with
different configurations (mostly individually-enabled noises), and produces
plots. These plots are used as quick human-eye diagnostic tool.
"""
import datetime
import logging
import os
from multiprocessing import Process
import matplotlib.pyplot as plt
import numpy as np
from h5py import File
from matplotlib.backends.backend_pdf import PdfPages
from scipy.signal import welch
from lisainstrument import Instrument, __version__
from lisainstrument.containers import ForEachMOSA, ForEachSC
logging.basicConfig()
logging.getLogger().setLevel(logging.INFO)
PARALLEL = False
"""bool: Whether to run reports in parallel"""
NPERSEG = 2**16 # ~ 65_000
"""int: Number of segments for Welch averaging"""
SIZE = NPERSEG * 3 # ~ 196_000
"""int: Size of simulations [samples]"""
def main():
"""Main function."""
logging.info("Starting report")
processes = [
Process(target=func)
for func in [
no_noise,
laser,
testmass,
oms,
backlink,
clock,
ranging,
modulation,
jitter,
dws,
moc_time_correlation,
]
]
for process in processes:
process.start()
if not PARALLEL:
process.join()
if PARALLEL:
for process in processes:
process.join()
logging.info("Report complete")
def no_noise():
"""No-noise simulation."""
logging.info("Running no-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.disable_all_noises()
instru.write('no-noise.h5', mode='w')
with PdfPages('no-noise.pdf') as pdf:
plot_measurements(instru, pdf)
write_metadata('no-noise', instru.orbit_file, pdf)
def laser():
"""Laser-noise simulation."""
logging.info("Running laser-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.disable_all_noises(but='laser')
instru.write('laser-noise_temp.h5', mode='w', keep_all=True)
with PdfPages('laser-noise.pdf') as pdf:
with File('laser-noise_temp.h5', 'r') as hdf5:
laser_noises = hdf5['laser_noises'][()]
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.physics_t, laser_noises[mosa], label=mosa)
plt.ylabel('Frequency [Hz]')
plt.title('Laser noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, laser_noises[mosa], label=mosa)
plt.ylabel('ASD [Hz/sqrt(Hz)]')
plt.title('Laser noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('laser-noise', instru.orbit_file, pdf)
copy_final_measurements('laser-noise.h5', 'laser-noise_temp.h5')
def testmass():
"""Test mass-noise simulation."""
logging.info("Running test mass-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.laser_asds = ForEachMOSA(0)
instru.modulation_asds = ForEachMOSA(0)
instru.disable_clock_noises()
instru.disable_ranging_noises()
instru.disable_jitters()
instru.backlink_asds = ForEachMOSA(0)
instru.oms_isi_carrier_asds = ForEachMOSA(0)
instru.oms_isi_usb_asds = ForEachMOSA(0)
instru.oms_tmi_carrier_asds = ForEachMOSA(0)
instru.oms_tmi_usb_asds = ForEachMOSA(0)
instru.oms_rfi_carrier_asds = ForEachMOSA(0)
instru.oms_rfi_usb_asds = ForEachMOSA(0)
instru.dws_asds = ForEachMOSA(0)
instru.sync_asds = ForEachSC(0)
instru.write('testmass-noise_temp.h5', mode='w', keep_all=True)
with PdfPages('testmass-noise.pdf') as pdf:
with File('testmass-noise_temp.h5', 'r') as hdf5:
testmass_noises = hdf5['testmass_noises'][()]
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.physics_t, testmass_noises[mosa], label=mosa)
plt.ylabel('Velocity [m/s]')
plt.title('Test-mass noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, testmass_noises[mosa], label=mosa)
plt.ylabel('ASD [m/s/sqrt(Hz)]')
plt.title('Test-mass noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('testmass-noise', instru.orbit_file, pdf)
copy_final_measurements('testmass-noise.h5', 'testmass-noise_temp.h5')
def oms():
"""OMS-noise simulation."""
logging.info("Running OMS-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.laser_asds = ForEachMOSA(0)
instru.modulation_asds = ForEachMOSA(0)
instru.disable_clock_noises()
instru.disable_ranging_noises()
instru.disable_jitters()
instru.backlink_asds = ForEachMOSA(0)
instru.testmass_asds = ForEachMOSA(0)
instru.dws_asds = ForEachMOSA(0)
instru.sync_asds = ForEachSC(0)
instru.write('oms-noise_temp.h5', mode='w', keep_all=True)
with PdfPages('oms-noise.pdf') as pdf:
with File('oms-noise_temp.h5', 'r') as hdf5:
oms_isi_carrier_noises = hdf5['oms_isi_carrier_noises'][()]
oms_tmi_carrier_noises = hdf5['oms_tmi_carrier_noises'][()]
oms_rfi_carrier_noises = hdf5['oms_rfi_carrier_noises'][()]
oms_isi_usb_noises = hdf5['oms_isi_usb_noises'][()]
oms_tmi_usb_noises = hdf5['oms_tmi_usb_noises'][()]
oms_rfi_usb_noises = hdf5['oms_rfi_usb_noises'][()]
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, oms_isi_carrier_noises[mosa], label=mosa)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('OMS ISI carrier noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, oms_tmi_carrier_noises[mosa], label=mosa)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('OMS TMI carrier noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, oms_rfi_carrier_noises[mosa], label=mosa)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('OMS RFI carrier noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, oms_isi_usb_noises[mosa], label=mosa)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('OMS ISI upper-sideband noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, oms_tmi_usb_noises[mosa], label=mosa)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('OMS TMI upper-sideband noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, oms_rfi_usb_noises[mosa], label=mosa)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('OMS RFI upper-sideband noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('oms-noise', instru.orbit_file, pdf)
copy_final_measurements('oms-noise.h5', 'oms-noise_temp.h5')
def backlink():
"""Backlink-noise simulation."""
logging.info("Running backlink-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.laser_asds = ForEachMOSA(0)
instru.modulation_asds = ForEachMOSA(0)
instru.disable_clock_noises()
instru.disable_ranging_noises()
instru.disable_jitters()
instru.testmass_asds = ForEachMOSA(0)
instru.oms_isi_carrier_asds = ForEachMOSA(0)
instru.oms_isi_usb_asds = ForEachMOSA(0)
instru.oms_tmi_carrier_asds = ForEachMOSA(0)
instru.oms_tmi_usb_asds = ForEachMOSA(0)
instru.oms_rfi_carrier_asds = ForEachMOSA(0)
instru.oms_rfi_usb_asds = ForEachMOSA(0)
instru.dws_asds = ForEachMOSA(0)
instru.sync_asds = ForEachSC(0)
instru.write('backlink-noise_temp.h5', mode='w', keep_all=True)
with PdfPages('backlink-noise.pdf') as pdf:
with File('backlink-noise_temp.h5', 'r') as hdf5:
backlink_noises = hdf5['backlink_noises'][()]
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, backlink_noises[mosa], label=mosa)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('Backlink noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('backlink-noise', instru.orbit_file, pdf)
copy_final_measurements('backlink-noise.h5', 'backlink-noise_temp.h5')
def clock():
"""Clock-noise simulation."""
logging.info("Running clock-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.laser_asds = ForEachMOSA(0)
instru.modulation_asds = ForEachMOSA(0)
instru.disable_ranging_noises()
instru.disable_jitters()
instru.disable_pathlength_noises()
instru.dws_asds = ForEachMOSA(0)
instru.sync_asds = ForEachSC(0)
instru.write('clock-noise_temp.h5', mode='w', keep_all=True)
with PdfPages('clock-noise.pdf') as pdf:
with File('clock-noise_temp.h5', 'r') as hdf5:
clock_noise_offsets = hdf5['clock_noise_offsets'][()]
clock_noise_fluctuations = hdf5['clock_noise_fluctuations'][()]
plt.figure(figsize=(16, 8))
for sc in instru.SCS:
plot_tseries(instru.physics_t, clock_noise_offsets[sc], label=sc)
plt.ylabel('Fractional frequency deviations')
plt.title('Clock noise offsets')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for sc in instru.SCS:
plot_tseries(instru.physics_t, clock_noise_fluctuations[sc], label=sc)
plt.ylabel('Fractional frequency deviations')
plt.title('Clock noise fluctuations')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for sc in instru.SCS:
plot_asd(instru.physics_t, clock_noise_fluctuations[sc], label=sc)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('Clock noise fluctuations')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('clock-noise', instru.orbit_file, pdf)
copy_final_measurements('clock-noise.h5', 'clock-noise_temp.h5')
def ranging():
"""Ranging-noise simulation."""
logging.info("Running ranging-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.laser_asds = ForEachMOSA(0)
instru.modulation_asds = ForEachMOSA(0)
instru.disable_clock_noises()
instru.disable_jitters()
instru.disable_pathlength_noises()
instru.dws_asds = ForEachMOSA(0)
instru.sync_asds = ForEachSC(0)
instru.write('ranging-noise_temp.h5', mode='w', keep_all=True)
with PdfPages('ranging-noise.pdf') as pdf:
with File('ranging-noise_temp.h5', 'r') as hdf5:
ranging_noises = hdf5['ranging_noises'][()]
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.physics_t, instru.ranging_biases[mosa], label=mosa)
plt.ylabel('Time [s]')
plt.title('Ranging bias')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.physics_t, ranging_noises[mosa], label=mosa)
plt.ylabel('Time [s]')
plt.title('Ranging noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, ranging_noises[mosa], label=mosa)
plt.ylabel('ASD [s/sqrt(Hz)]')
plt.title('Ranging noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('ranging-noise', instru.orbit_file, pdf)
copy_final_measurements('ranging-noise.h5', 'ranging-noise_temp.h5')
def modulation():
"""Modulation-noise simulation."""
logging.info("Running modulation-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.laser_asds = ForEachMOSA(0)
instru.disable_clock_noises()
instru.disable_ranging_noises()
instru.disable_jitters()
instru.disable_pathlength_noises()
instru.dws_asds = ForEachMOSA(0)
instru.sync_asds = ForEachSC(0)
instru.write('modulation-noise_temp.h5', mode='w', keep_all=True)
with PdfPages('modulation-noise.pdf') as pdf:
with File('modulation-noise_temp.h5', 'r') as hdf5:
modulation_noises = hdf5['modulation_noises'][()]
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.physics_t, modulation_noises[mosa], label=mosa)
plt.ylabel('Fractional frequency deviations')
plt.title('Modulation noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, modulation_noises[mosa], label=mosa)
plt.ylabel('ASD [/sqrt(Hz)]')
plt.title('Modulation noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('modulation-noise', instru.orbit_file, pdf)
copy_final_measurements('modulation-noise.h5', 'modulation-noise_temp.h5')
def jitter():
"""Angular jitter-noise simulation."""
logging.info("Running angular jitter-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.laser_asds = ForEachMOSA(0)
instru.modulation_asds = ForEachMOSA(0)
instru.disable_clock_noises()
instru.disable_ranging_noises()
instru.disable_pathlength_noises()
instru.dws_asds = ForEachMOSA(0)
instru.sync_asds = ForEachSC(0)
instru.write('jitter-noise_temp.h5', mode='w', keep_all=True)
with PdfPages('jitter-noise.pdf') as pdf:
with File('jitter-noise_temp.h5', 'r') as hdf5:
sc_jitter_phis = hdf5['sc_jitter_phis'][()]
sc_jitter_etas = hdf5['sc_jitter_etas'][()]
sc_jitter_thetas = hdf5['sc_jitter_thetas'][()]
mosa_jitter_phis = hdf5['mosa_jitter_phis'][()]
plt.figure(figsize=(16, 8))
for sc in instru.SCS:
plot_asd(instru.physics_t, sc_jitter_phis[sc], label=f'Phi {sc}')
plot_asd(instru.physics_t, sc_jitter_etas[sc], label=f'Eta {sc}')
plot_asd(instru.physics_t, sc_jitter_thetas[sc], label=f'Theta {sc}')
plt.ylabel('ASD [rad/s/sqrt(Hz)]')
plt.title('Spacecraft angular jitter noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, mosa_jitter_phis[mosa], label=f'Phi {mosa}')
plot_asd(instru.physics_t, instru.mosa_jitter_etas[mosa], label=f'Eta {mosa}')
plt.ylabel('ASD [rad/s/sqrt(Hz)]')
plt.title('MOSA angular jitter noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('jitter-noise', instru.orbit_file, pdf)
copy_final_measurements('jitter-noise.h5', 'jitter-noise_temp.h5')
def dws():
"""DWS-noise simulation."""
logging.info("Running DWS-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.laser_asds = ForEachMOSA(0)
instru.modulation_asds = ForEachMOSA(0)
instru.disable_clock_noises()
instru.disable_ranging_noises()
instru.disable_pathlength_noises()
instru.disable_jitters()
instru.sync_asds = ForEachSC(0)
instru.write('dws-noise.h5', mode='w')
with PdfPages('dws-noise.pdf') as pdf:
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.physics_t, instru.dws_phi_noises[mosa], label=f'Phi {mosa}')
plot_tseries(instru.physics_t, instru.dws_eta_noises[mosa], label=f'Eta {mosa}')
plt.ylabel('Angular velocity [rad/s]')
plt.title('DWS measurement noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.physics_t, instru.dws_phi_noises[mosa], label=f'Phi {mosa}')
plot_asd(instru.physics_t, instru.dws_eta_noises[mosa], label=f'Eta {mosa}')
plt.ylabel('ASD [rad/s/sqrt(Hz)]')
plt.title('DWS measurement noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('dws-noise', instru.orbit_file, pdf)
def moc_time_correlation():
"""MOC time correlation-noise simulation."""
logging.info("Running MOC time correlation-noise simulation")
instru = Instrument(
size=SIZE,
orbits='tests/esa-trailing-orbits-2-0.h5',
concurrent=True,
)
instru.disable_all_noises(but='moc-time-correlation')
instru.write('moc-time-correlation-noise.h5', mode='w')
with PdfPages('moc-time-correlation-noise.pdf') as pdf:
with File('moc-time-correlation-noise.h5', 'r') as hdf5:
moc_time_correlations = hdf5['moc_time_correlations'][()]
plt.figure(figsize=(16, 8))
for sc in instru.SCS:
plot_tseries(instru.telemetry_t, moc_time_correlations[sc], label=sc)
plt.ylabel('Time [s]')
plt.title('MOC time correlation noise')
plt.legend()
pdf.savefig()
plt.close()
plt.figure(figsize=(16, 8))
for sc in instru.SCS:
plot_asd(instru.telemetry_t, moc_time_correlations[sc], label=sc)
plt.ylabel('ASD [s/sqrt(Hz)]')
plt.title('MOC time correlation noise')
plt.legend()
pdf.savefig()
plt.close()
plot_measurements(instru, pdf)
write_metadata('moc-time-correlation-noise', instru.orbit_file, pdf)
def plot_measurements(instru, pdf):
"""Generate plots for all measurements.
Args:
instru (Instrument): instrument instance
pdf (PdfPages): PDF file instance
"""
# Retrieve data from output file to plot them
with File(instru.filename, 'r') as hdf5:
isi_carriers = hdf5['isi_carriers'][()]
isi_carrier_offsets = hdf5['isi_carrier_offsets'][()]
tmi_carriers = hdf5['tmi_carriers'][()]
tmi_carrier_offsets = hdf5['tmi_carrier_offsets'][()]
rfi_carriers = hdf5['rfi_carriers'][()]
rfi_carrier_offsets = hdf5['rfi_carrier_offsets'][()]
isi_usbs = hdf5['isi_usbs'][()]
isi_usb_offsets = hdf5['isi_usb_offsets'][()]
tmi_usbs = hdf5['tmi_usbs'][()]
tmi_usb_offsets = hdf5['tmi_usb_offsets'][()]
rfi_usbs = hdf5['rfi_usbs'][()]
rfi_usb_offsets = hdf5['rfi_usb_offsets'][()]
isi_carrier_fluctuations = hdf5['isi_carrier_fluctuations'][()]
tmi_carrier_fluctuations = hdf5['tmi_carrier_fluctuations'][()]
rfi_carrier_fluctuations = hdf5['rfi_carrier_fluctuations'][()]
isi_usb_fluctuations = hdf5['isi_usb_fluctuations'][()]
tmi_usb_fluctuations = hdf5['tmi_usb_fluctuations'][()]
rfi_usb_fluctuations = hdf5['rfi_usb_fluctuations'][()]
mprs = hdf5['mprs'][()]
isi_dws_phis = hdf5['isi_dws_phis'][()]
isi_dws_etas = hdf5['isi_dws_etas'][()]
moc_time_correlations = hdf5['moc_time_correlations'][()]
# Time-domain ISI carrier total and offset beatnote frequencies
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.t, isi_carriers[mosa], label=f'{mosa} (total)')
for mosa in instru.MOSAS:
plot_tseries(instru.t, isi_carrier_offsets[mosa], linestyle='--', label=f'{mosa} (offsets)')
plt.ylabel('Frequency [Hz]')
plt.title('Total ISI carrier beatnote frequencies')
plt.legend()
pdf.savefig()
plt.close()
# Time-domain TMI carrier total and offset beatnote frequencies
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.t, tmi_carriers[mosa], label=f'{mosa} (total)')
for mosa in instru.MOSAS:
plot_tseries(instru.t, tmi_carrier_offsets[mosa], linestyle='--', label=f'{mosa} (offsets)')
plt.ylabel('Frequency [Hz]')
plt.title('Total TMI carrier beatnote frequencies')
plt.legend()
pdf.savefig()
plt.close()
# Time-domain RFI carrier total and offset beatnote frequencies
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.t, rfi_carriers[mosa], label=f'{mosa} (total)')
for mosa in instru.MOSAS:
plot_tseries(instru.t, rfi_carrier_offsets[mosa], linestyle='--', label=f'{mosa} (offsets)')
plt.ylabel('Frequency [Hz]')
plt.title('Total RFI carrier beatnote frequencies')
plt.legend()
pdf.savefig()
plt.close()
# Time-domain ISI upper-sideband total and offset beatnote frequencies
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.t, isi_usbs[mosa], label=f'{mosa} (total)')
for mosa in instru.MOSAS:
plot_tseries(instru.t, isi_usb_offsets[mosa], linestyle='--', label=f'{mosa} (offsets)')
plt.ylabel('Frequency [Hz]')
plt.title('Total ISI upper-sideband beatnote frequencies')
plt.legend()
pdf.savefig()
plt.close()
# Time-domain TMI upper-sideband total and offset beatnote frequencies
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.t, tmi_usbs[mosa], label=f'{mosa} (total)')
for mosa in instru.MOSAS:
plot_tseries(instru.t, tmi_usb_offsets[mosa], linestyle='--', label=f'{mosa} (offsets)')
plt.ylabel('Frequency [Hz]')
plt.title('Total TMI upper-sideband beatnote frequencies')
plt.legend()
pdf.savefig()
plt.close()
# Time-domain RFI upper-sideband total and offset beatnote frequencies
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.t, rfi_usbs[mosa], label=f'{mosa} (total)')
for mosa in instru.MOSAS:
plot_tseries(instru.t, rfi_usb_offsets[mosa], linestyle='--', label=f'{mosa} (offsets)')
plt.ylabel('Frequency [Hz]')
plt.title('Total RFI upper-sideband beatnote frequencies')
plt.legend()
pdf.savefig()
plt.close()
# ASD ISI carrier beatnote frequency fluctuations
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.t, isi_carrier_fluctuations[mosa], label=mosa)
plt.ylabel('ASD [Hz/sqrt(Hz)]')
plt.title('ISI carrier beatnote frequency fluctuations')
plt.legend()
pdf.savefig()
plt.close()
# ASD TMI carrier beatnote frequency fluctuations
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.t, tmi_carrier_fluctuations[mosa], label=mosa)
plt.ylabel('ASD [Hz/sqrt(Hz)]')
plt.title('TMI carrier beatnote frequency fluctuations')
plt.legend()
pdf.savefig()
plt.close()
# ASD RFI carrier beatnote frequency fluctuations
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.t, rfi_carrier_fluctuations[mosa], label=mosa)
plt.ylabel('ASD [Hz/sqrt(Hz)]')
plt.title('RFI carrier beatnote frequency fluctuations')
plt.legend()
pdf.savefig()
plt.close()
# ASD ISI upper-sideband beatnote frequency fluctuations
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.t, isi_usb_fluctuations[mosa], label=mosa)
plt.ylabel('ASD [Hz/sqrt(Hz)]')
plt.title('ISI upper-sideband beatnote frequency fluctuations')
plt.legend()
pdf.savefig()
plt.close()
# ASD TMI upper-sideband beatnote frequency fluctuations
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.t, tmi_usb_fluctuations[mosa], label=mosa)
plt.ylabel('ASD [Hz/sqrt(Hz)]')
plt.title('TMI upper-sideband beatnote frequency fluctuations')
plt.legend()
pdf.savefig()
plt.close()
# ASD RFI upper-sideband beatnote frequency fluctuations
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.t, rfi_usb_fluctuations[mosa], label=mosa)
plt.ylabel('ASD [Hz/sqrt(Hz)]')
plt.title('RFI upper-sideband beatnote frequency fluctuations')
plt.legend()
pdf.savefig()
plt.close()
# Time-domain MPR measurements
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_tseries(instru.t, mprs[mosa], label=mosa)
plt.ylabel('MPR [s]')
plt.title('Measured pseudo-ranges (MPRs)')
plt.legend()
pdf.savefig()
plt.close()
# ASD MPR measurements
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.t, mprs[mosa], detrend='linear', label=mosa)
plt.ylabel('ASD [s/sqrt(Hz)]')
plt.title('Measured pseudo-ranges (MPRs)')
plt.legend()
pdf.savefig()
plt.close()
# ASD DWS measurements
plt.figure(figsize=(16, 8))
for mosa in instru.MOSAS:
plot_asd(instru.t, isi_dws_phis[mosa], label=f'DWS Phi {mosa}')
for mosa in instru.MOSAS:
plot_asd(instru.t, isi_dws_etas[mosa], label=f'DWS Eta {mosa}')
plt.ylabel('ASD [rad/s/sqrt(Hz)]')
plt.title('Differential wavefront sensor (DWS) measurements')
plt.legend()
pdf.savefig()
plt.close()
# Time-domain MOC time correlations
plt.figure(figsize=(16, 8))
for sc in instru.SCS:
plot_tseries(instru.telemetry_t, moc_time_correlations[sc], skip=0, label=sc)
plt.ylabel('Deviation [s]')
plt.title('MOC time correlations')
plt.legend()
pdf.savefig()
plt.close()
def plot_tseries(x, y, skip=100, **kwargs):
"""Plot time series."""
if 'alpha' not in kwargs:
kwargs['alpha'] = 0.7
x, y = np.broadcast_arrays(x, y)
plt.plot(x[skip:], y[skip:], **kwargs)
plt.xlabel('Time [s]')
plt.grid(True)
def plot_asd(x, y, detrend=None, **kwargs):
"""Plot amplitude spectral density."""
if 'alpha' not in kwargs:
kwargs['alpha'] = 0.7
x, y = np.broadcast_arrays(x, y)
freq, psd = welch(
y[300:],
fs=1.0 / (x[1] - x[0]),
nperseg=NPERSEG,
window=('kaiser', 40),
detrend=detrend)
plt.loglog(freq, np.sqrt(psd), **kwargs)
plt.xlabel('Frequency [Hz]')
plt.grid(True)
def write_metadata(config, orbits, pdf):
"""Write metadata.
Args:
config (str): description of instrument configuration
orbits (str): description of orbit file
pdf(PdfPages): PDF file instance
"""
info = pdf.infodict()
info['Title'] = 'LISA Instrument Report'
info['Author'] = 'LISA Instrument Continuous Integration'
info['InstrumentConfiguration'] = config
info['OrbitFile'] = orbits
info['Version'] = __version__
info['CreationDate'] = datetime.datetime.now()
info['ModDate'] = datetime.datetime.now()
def copy_final_measurements(filename, temp_filename):
"""Copy all the final measurements from a HDF5 file to another."""
final_measurements = ['isi_carriers', 'isi_carrier_offsets', 'tmi_carriers', 'tmi_carrier_offsets',\
'rfi_carriers', 'rfi_carrier_offsets', 'isi_usbs', 'isi_usb_offsets',\
'tmi_usbs', 'tmi_usb_offsets', 'rfi_usbs', 'rfi_usb_offsets',\
'isi_carrier_fluctuations', 'tmi_carrier_fluctuations', 'rfi_carrier_fluctuations',\
'isi_usb_fluctuations', 'tmi_usb_fluctuations', 'rfi_usb_fluctuations',\
'mprs', 'isi_dws_phis', 'isi_dws_etas', 'moc_time_correlations']
with File(filename, 'w') as hdf5:
with File(temp_filename, 'r') as temp_hdf5:
for name in final_measurements:
temp_hdf5.copy(name, hdf5)
os.remove(temp_filename)
if __name__ == "__main__":
main()