Compute a spectrogram

Compute the spectrogram of a set of SFTs. This is useful to produce visualizations of the Doppler modulation of a CW signal.

  9 import os
 10
 11 import matplotlib.pyplot as plt
 12 import numpy as np
 13
 14 import pyfstat
 15
 16 # not github-action compatible
 17 # plt.rcParams["font.family"] = "serif"
 18 # plt.rcParams["font.size"] = 18
 19 # plt.rcParams["text.usetex"] = True
 20
 21 # workaround deprecation warning
 22 # see https://github.com/matplotlib/matplotlib/issues/21723
 23 plt.rcParams["axes.grid"] = False
 24
 25 label = "PyFstatExampleSpectrogramNormPower"
 26 outdir = os.path.join("PyFstat_example_data", label)
 27 logger = pyfstat.set_up_logger(label=label, outdir=outdir)
 28
 29 signal = True  # turn off for pure noise spectrogram
 30 binary = True  # turn off for simpler isolated neutron star signal
 31 transient = False  # turn on for a time-limited signal
 32
 33 # this sets how strong the signal is compared to the noise (higher value -> weaker)
 34 depth = 5
 35
 36 # Define the tstart and duration of each segment of data,
 37 # including some gaps like in real observing runs.
 38 gap_duration = 10 * 86400
 39 Tsft = 1800
 40 segments = [
 41     {"tstart": 1000000000, "duration": 120 * 86400},
 42     {"tstart": 1000000000 + 120 * 86400 + gap_duration, "duration": 300 * 86400},
 43     {"tstart": 1000000000 + 420 * 86400 + 2 * gap_duration, "duration": 120 * 86400},
 44 ]
 45
 46 # Generate timestamps for each segment and concatenate them.
 47 timestamps = {
 48     "H1": np.concatenate(
 49         [
 50             segment["tstart"] + Tsft * np.arange(segment["duration"] // Tsft)
 51             for segment in segments
 52         ]
 53     )
 54 }
 55
 56 # general parameters to configure the data to simulate
 57 data_parameters = {
 58     "sqrtSX": 1e-23,
 59     "timestamps": timestamps,
 60     "detectors": "H1",
 61     "Tsft": 1800,
 62 }
 63 # For pure noise, we need to select the frequency range ourselves.
 64 # For signals, PyFstat auto-estimates this.
 65 if not signal:
 66     data_parameters.update(
 67         {
 68             "F0": 100.0,
 69             "Band": 0.1,
 70         }
 71     )
 72
 73 # parameters for a signal to inject (if signal==True)
 74 signal_parameters = {
 75     "F0": 100.0,
 76     "F1": 0,
 77     "F2": 0,
 78     "Alpha": 0.0,
 79     "Delta": 0.5,
 80     "tref": segments[0]["tstart"],
 81     "h0": data_parameters["sqrtSX"] / depth if signal else 0.0,
 82     "cosi": 1.0,
 83 }
 84 # optionally add binary orbital parameters
 85 if binary:
 86     signal_parameters.update(
 87         {
 88             "tp": segments[0]["tstart"],
 89             "asini": 25.0,
 90             "period": 50 * 86400,
 91         }
 92     )
 93
 94 # optionally add transient parameters
 95 if transient:
 96     signal_parameters.update(
 97         {
 98             "transientStartTime": segments[1]["tstart"],
 99             "transientTau": segments[1]["duration"],
100             "transientWindowType": "exp",  # exponentially decaying signal amplitude
101         }
102     )
103 # making data
104 data = pyfstat.Writer(
105     label=label,
106     outdir=outdir,
107     **data_parameters,
108     signal_parameters=signal_parameters,
109 )
110 data.make_data()
111
112 # make the plot
113 ax = pyfstat.utils.plot_spectrogram(
114     sftfilepattern=data.sftfilepath,
115     detector=data_parameters["detectors"],
116     sqrtSX=data_parameters["sqrtSX"],
117     quantity="normpower",
118     savefig=True,
119     outdir=outdir,
120     label=label,
121 )

Gallery generated by Sphinx-Gallery