Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions PyART/analysis/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,12 @@ def __init__(
)

if self.settings["cut_second_waveform"] or self.settings["cut_longer"]:
tmrg1, _, _, _ = WaveForm1.find_max() - WaveForm1.u[0]
tmrg2, _, _, _ = WaveForm2.find_max() - WaveForm2.u[0]
# merger time measured from the start of each waveform. find_max
# returns (t_mrg, A_mrg, omg_mrg, domg_mrg), so only the first entry
# is wanted: subtracting u[0] from the whole tuple relies on numpy
# broadcasting it, which holds only while the entries are np.float64
tmrg1 = WaveForm1.find_max()[0] - WaveForm1.u[0]
tmrg2 = WaveForm2.find_max()[0] - WaveForm2.u[0]
DeltaT = tmrg2 - tmrg1
if DeltaT > 0:
WaveForm2.cut(DeltaT)
Expand Down Expand Up @@ -529,7 +533,9 @@ def _compute_mm_single_mode(self, wf1, wf2, settings):
out = {
"h1f": h1f,
"h2f": h2f,
"j_shift": j_shift * h2.delta_t,
# take the time step from h2f: h2 only exists when wf2 is in the
# time domain and was not served from the cache
"j_shift": j_shift * h2f.delta_t,
"ph_shift": ph_shift,
}
return m, out
Expand Down Expand Up @@ -801,7 +807,9 @@ def _compute_mm_skymax(self, wf1, wf2, settings):
)
mms.append(mm)
out = {} # FIXME: just for consistency with compute_mm_single_mode
return np.average(mm), out
# average over the whole coa_phase x eff_pols grid, not just the last
# entry, which is what the loop above accumulates mms for
return np.average(mms), out

def skymax_match(
self, s, wf, inc, psd, modes, dT=1.0 / 4096, fmin_mm=20.0, fmax=2048.0
Expand Down
71 changes: 46 additions & 25 deletions PyART/catalogs/cataloger.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def __init__(
name = wave.metadata["name"]
self.data[name] = {"Waveform": wave, "Optimizer": None}
except Exception as e:
logging.error(f"Issues with {ID:04}: {e}")
logging.error(f"Issues with {ID}: {e}")
self.nsims = len(self.data)

pass
Expand All @@ -57,7 +57,7 @@ def get_Waveform(self, ID, add_opts={}, verbose=None):
if verbose is None:
verbose = self.verbose
if verbose:
logging.info(f"Loading {self.catalog} waveform with ID:{ID:04}")
logging.info(f"Loading {self.catalog} waveform with ID:{ID}")

if self.catalog == "sxs":
from .sxs import Waveform_SXS
Expand Down Expand Up @@ -148,6 +148,45 @@ def optimize_mismatches_batch(self, batch, optimizer_opts={}, verbose=None):
Optimizer(self.data[name]["Waveform"], **optimizer_opts)
pass

def collect_mismatch_jsons(self, json_tmp_list):
"""
Merge the per-process temporary JSON files produced by a parallel run
into self.json_file, then delete them.

Mismatches already known to the base file are kept: each process starts
from a copy of it and only adds its own batch, so the temporary files
overlap on everything but the entries they computed themselves.

Parameters
----------
json_tmp_list: list of str
paths of the temporary JSON files to merge

Returns
-------
json_data: dict
the merged content, as written to self.json_file
"""
# 1) load original json file if it exists, otherwise load first temp file
if os.path.exists(self.json_file):
json_base = self.json_file
else:
json_base = json_tmp_list[0]
with open(json_base, "r") as file:
json_data = json.loads(file.read())
# 2) add info from temporary json, delete temporary json
for json_tmp in json_tmp_list:
with open(json_tmp, "r") as file:
json_data_tmp = json.loads(file.read())
mismatches = json_data_tmp["mismatches"]
for key in mismatches:
if key not in json_data["mismatches"]:
json_data["mismatches"][key] = mismatches[key]
os.remove(json_tmp)
with open(self.json_file, "w") as file:
file.write(json.dumps(json_data, indent=2))
return json_data

def process_with_redirect(self, process_id, nproc, opts={}):
"""
If we are running in parallel, use log files.
Expand Down Expand Up @@ -238,24 +277,7 @@ def optimize_mismatches(
process.join()

# info stored in the temporary JSONs, collect info
# 1) load original json file if it exists, otherwise load first temp file
if os.path.exists(self.json_file):
json_base = self.json_file
else:
json_base = json_tmp_list[0]
with open(json_base, "r") as file:
json_data = json.loads(file.read())
# 2) add info from temporary json, delete temporary json
for json_tmp in json_tmp_list:
with open(json_tmp, "r") as file:
json_data_tmp = json.loads(file.read())
mismatches = json_data_tmp["mismatches"]
for key in mismatches:
if key not in json_data:
json_data["mismatches"][key] = mismatches[key]
os.remove(json_tmp)
with open(self.json_file, "w") as file:
file.write(json.dumps(json_data, indent=2))
self.collect_mismatch_jsons(json_tmp_list)

# read collated json
optimizer_opts["json_file"] = self.json_file
Expand Down Expand Up @@ -403,6 +425,9 @@ def mm_at_M(self, name, M, mm_settings=None, model_opts={}):

eob = self.get_model_waveform(name, model_opts=model_opts)
nr = self.data[name]["Waveform"]
# copy: the mass is specific to this call, and the caller usually reuses
# the same settings dict across masses
mm_settings = {} if mm_settings is None else dict(mm_settings)
mm_settings["M"] = M
matcher = Matcher(nr, eob, settings=mm_settings)
return matcher.mismatch
Expand All @@ -423,9 +448,6 @@ def mm_vs_M(
ylim=None,
figname=None, # save if not None
):
if figname is not None:
savepng = True

# select waveforms and get colors
subset = self.find_subset(ranges=ranges)
colors_dict = self.get_colors_for_subset(
Expand Down Expand Up @@ -524,8 +546,7 @@ def mm_vs_M(
if ylim is not None:
plt.ylim(ylim)

if figname is None:
figname = f"mismatches_{self.catalog}_{cmap_var}.png"
if figname is not None:
plt.savefig(figname, dpi=200, bbox_inches="tight")
logging.info(f"Figure saved: {figname}")
plt.show()
Expand Down
Loading
Loading