22 from numpy.testing
import assert_allclose
30 sftnames = list(glob.glob(os.path.join(testdir, globstr)))
31 assert len(sftnames) == 1
33 app =
"lalpulsar_SFTvalidate"
34 cl = app +
" " + sftname
35 print(
"Executing: " + cl)
36 out = subprocess.check_output(
37 cl, shell=
True, stderr=subprocess.STDOUT, universal_newlines=
True
39 print(
"{:s}: {}".format(app, out))
40 catalog = lalpulsar.SFTdataFind(sftname,
None)
41 sfts = lalpulsar.LoadSFTs(catalog, fmin, fmax)
46 sfts1, sfts2, plotnamebase="plot", label1="SFTs1", label2="SFTs2", title=""
48 minlen =
min(sfts1.length, sfts2.length)
49 if sfts1.length != sfts2.length:
51 "Inconsistent SFT vector lengths {:d}!={:d} for {:s}, {:s}. Will only plot the first {:d}.".format(
52 sfts1.length, sfts2.length, label1, label2, minlen
56 plotnamebase +=
"-" + label1 +
"-" + label2
57 for k, (sft1, sft2)
in enumerate(zip(sfts1.data, sfts2.data)):
58 if sft1.epoch != sft2.epoch:
60 "Inconsistent epochs {:d}!={:d} in SFT {:d} of {:s}, {:s}".format(
61 sft1.epoch.gpsSeconds, sft2.epoch.gpsSeconds, k, label1, label2
64 title_this_epoch = title +
", epoch={:d}".format(sft1.epoch.gpsSeconds)
65 plotnamebase_this_epoch = plotnamebase +
"_{:d}".format(sft1.epoch.gpsSeconds)
66 freqs1 = sft1.f0 + sft1.deltaF * np.arange(0, sft1.data.length)
67 freqs2 = sft2.f0 + sft2.deltaF * np.arange(0, sft2.data.length)
68 sft1_abs = np.abs(sft1.data.data)
69 sft2_abs = np.abs(sft2.data.data)
70 plt.plot(freqs1, sft1_abs, label=label1, color=
"black")
71 plt.plot(freqs2, sft2_abs, label=label2, color=
"red")
72 plt.xlabel(
"frequency [Hz]")
73 plt.ylabel(
"|complex SFT bin|")
74 plt.title(title_this_epoch)
76 plotfile = os.path.join(testdir, plotnamebase_this_epoch +
"-comparison.png")
77 print(
"Plotting to " + plotfile)
80 plt.plot(freqs1, np.abs(sft1.data.data - sft2.data.data), color=
"black")
81 plt.xlabel(
"frequency [Hz]")
82 plt.ylabel(
"|{:s}-{:s}|".format(label1, label2))
83 plt.title(title_this_epoch)
84 plotfile = os.path.join(testdir, plotnamebase_this_epoch +
"-absdiff.png")
85 print(
"Plotting to " + plotfile)
89 freqs1, np.abs(sft1.data.data - sft2.data.data) / sft2_abs, color=
"black"
91 plt.xlabel(
"frequency [Hz]")
92 plt.ylabel(
"|{:s}-{:s}|/|{:s}|".format(label1, label2, label2))
93 plt.title(title_this_epoch)
94 plotfile = os.path.join(testdir, plotnamebase_this_epoch +
"-reldiff.png")
95 print(
"Plotting to " + plotfile)
98 plt.plot(sft2_abs, np.abs(sft1.data.data - sft2.data.data),
".", color=
"black")
99 plt.xlabel(
"|{:s}|".format(label2))
100 plt.ylabel(
"|{:s}-{:s}|".format(label1, label2))
101 plt.title(title_this_epoch)
102 plotfile = os.path.join(
103 testdir, plotnamebase_this_epoch +
"-absdiff-vs-abs2.png"
105 print(
"Plotting to " + plotfile)
106 plt.savefig(plotfile)
110 np.abs(sft1.data.data - sft2.data.data) / sft2_abs,
114 plt.xlabel(
"|{:s}|".format(label2))
115 plt.ylabel(
"|{:s}-{:s}|/|{:s}|".format(label1, label2, label2))
116 plt.title(title_this_epoch)
117 plotfile = os.path.join(
118 testdir, plotnamebase_this_epoch +
"-reldiff-vs-abs2.png"
120 print(
"Plotting to " + plotfile)
121 plt.savefig(plotfile)
126 ref_gwf =
"V-V1_mfdv5-1257741529-2048.gwf"
127 ref_sft =
"V-3_V1_1024SFT_mfdv5-1257741529-2048.sft"
128 ref_sfdb =
"V1-mfdv5_20191114_043831.SFDB09"
134 startTime = 1257741529
138 Tsft =
int(ref_sft.split(
"SFT")[0].split(
"_")[-1])
139 Toverlap =
int(0.5 * Tsft)
142 print(
"\n=== Running WriteSFTsfromSFDBs on reference SFDB file ===\n")
145 "lalpulsar_WriteSFTsfromSFDBs",
156 print(
"Executing: " + cl_SFDB)
157 subprocess.check_call(cl_SFDB, shell=
True)
162 print(
"\n=== Reading reference SFTs from MFDv5 ===\n")
168 print(
"=== Comparing outputs of WriteSFTsfromSFDBs and MFDv5: overall properties ===\n")
172 "nSFTs: {} vs {}".format(sfts_from_sfdb.length, sfts_ref.length)
175 "Epochs: {} vs {}".format(
176 [sft.epoch
for sft
in sfts_from_sfdb.data], [sft.epoch
for sft
in sfts_ref.data]
181 if sfts_from_sfdb.length == sfts_ref.length + 1:
183 "Inconsistent SFT vector lengths {:d}=={:d}+1 from SFDBs vs referenc SFT. This is expected.".format(
184 sfts_from_sfdb.length, sfts_ref.length
187 assert sfts_from_sfdb.length == sfts_ref.length + 1
188 mean_sfts = np.zeros(sfts_ref.length)
189 for k, (sft1, sft2)
in enumerate(zip(sfts_from_sfdb.data, sfts_ref.data)):
190 print(
"Comparing SFT number {:d}...".format(k))
192 deltaF_sfdb = sft1.deltaF
193 nBins_sfdb = sft1.data.length
194 abs_sfdb = np.abs(sft1.data.data)
195 max_sfdb = np.max(abs_sfdb)
196 maxbin_sfdb = np.argmax(abs_sfdb)
197 maxfreq_sfdb = f0_sfdb + deltaF_sfdb * maxbin_sfdb
198 without_maxbin = np.arange(nBins_sfdb) != maxbin_sfdb
199 abs_without = abs_sfdb[without_maxbin]
200 mean_sfdb = np.mean(abs_without)
201 stdev_sfdb = mean_sfdb * np.std(abs_without / mean_sfdb)
203 deltaF_sfts = sft2.deltaF
204 nBins_sfts = sft2.data.length
205 abs_sfts = np.abs(sft2.data.data)
206 max_sfts = np.max(abs_sfts)
207 maxbin_sfts = np.argmax(abs_sfts)
208 maxfreq_sfts = f0_sfts + deltaF_sfts * maxbin_sfts
209 abs_without = abs_sfts[np.arange(nBins_sfts) != maxbin_sfts]
210 mean_sfts[k] = np.mean(abs_without)
211 stdev_sfts = mean_sfts[k] * np.std(abs_without / mean_sfts[k])
212 print(
"IFO: {} vs {}".format(sft1.name, sft2.name))
213 print(
"f0: {} vs {}".format(f0_sfdb, f0_sfts))
215 "df: {} vs {}".format(deltaF_sfdb, deltaF_sfts)
218 "nBins: {} vs {}".format(nBins_sfdb, nBins_sfts)
221 "max in bin: {} vs {}".format(maxbin_sfdb, maxbin_sfts)
223 print(
"freq of max: {:.4f} vs {:.4f}".format(maxfreq_sfdb, maxfreq_sfts))
224 print(
"max |value|: {:.4e} vs {:.4e}".format(max_sfdb, max_sfts))
225 print(
"background mean: {:.4e} vs {:.4e}".format(mean_sfdb, mean_sfts[k]))
226 print(
"background stdev: {:.4e} vs {:.4e}".format(stdev_sfdb, stdev_sfts))
227 assert sft1.name == sft2.name
228 assert abs(f0_sfdb - f0_sfts) < atol_freq
229 assert abs(deltaF_sfdb - deltaF_sfts) < atol_freq
230 assert nBins_sfdb == nBins_sfts
231 assert maxbin_sfdb == maxbin_sfts
232 assert abs(max_sfdb - max_sfts) / max_sfts < 0.01
233 assert abs(maxfreq_sfdb - maxfreq_sfts) < atol_freq
234 assert abs(mean_sfdb - mean_sfts[k]) / mean_sfts[k] < 0.001
235 assert abs(stdev_sfdb - stdev_sfts) / stdev_sfts < 0.001
237 print(
"\n=== Optional: comparison plots ===\n")
241 matplotlib.use(
"Agg")
242 from matplotlib
import pyplot
as plt
247 plotnamebase=IFOs[0],
250 title=
"Tsft={:d}, Toverlap={:d}".format(Tsft, Toverlap),
254 "Cannot import matplotlib to make comparison plots, continuing with numerical comparisons."
256 except Exception
as e:
258 "Failed to create comparison plots, continuing with numerical comparisons. Exception was:"
264 "\n=== Comparing outputs of WriteSFTsfromSFDBs and MFDv5: actual per-bin data ===\n"
269 for k, (sft1, sft2)
in enumerate(zip(sfts_from_sfdb.data, sfts_ref.data)):
270 atol = 0.02 * mean_sfts[k]
271 maxdiff =
max(np.abs(sft1.data.data - sft2.data.data))
273 "Comparing SFT number {:d}: max absolute difference is {:g} (allowed: {:g})".format(
277 assert_allclose(sft1.data.data, sft2.data.data, rtol=0, atol=atol, verbose=
True)
279 print(
"All SFDB checks passed (or skipped).")
def validate_and_load_SFTs(globstr, fmin, fmax)
def plot_SFTs_comparison(sfts1, sfts2, plotnamebase="plot", label1="SFTs1", label2="SFTs2", title="")