"""
1) Spread metadata in each folder and assign also an id to each configuration
2) Store in dirs like ICC_BBH_????
SA: 07/31/2024
"""
import os, json
import logging
import numpy as np
from PyART.analysis.scattering_angle import ScatteringAngle
[docs]
def runcmd(cmd, workdir, out=None):
"""
Execute cmd in workdir
"""
base = os.getcwd()
os.makedirs(workdir, exist_ok=True)
os.chdir(workdir)
os.system(cmd)
os.chdir(base)
return
[docs]
def load_puncts(sim_path, fname="puncturetracker-pt_loc..asc"):
full_name = os.path.join(sim_path, fname)
if os.path.exists(full_name):
X = np.loadtxt(full_name)
t = X[:, 8]
x0 = X[:, 22]
y0 = X[:, 32]
x1 = X[:, 23]
y1 = X[:, 33]
x = x0 - x1
y = y0 - y1
r = np.sqrt(x**2 + y**2)
th = -np.unwrap(np.angle(x + 1j * y))
zeros = 0 * t
pdict = {
"t": t,
"r": r,
"th": th,
"x0": x0,
"y0": y0,
"z0": zeros,
"x1": x1,
"y1": y1,
"z1": zeros,
}
else:
pdict = None
return pdict
[docs]
def count_subdirs(path):
subdirs = []
for entry in os.listdir(path):
if entry.startswith("BBH"):
subdirs.append(entry)
return subdirs
[docs]
def get_info_from_name(name, field):
val = None
for elem in name.split("_"):
if field in elem:
theta_str = elem.replace(field, "")
sign = 1.0
if theta_str[0] == "m":
sign = -1.0
theta_str = theta_str[1:]
elif theta_str[0] == "p":
theta_str = theta_str[1:]
val = sign * float(theta_str.replace("p", "."))
break
return val
[docs]
json_file = "ICC_catalogue_optimized_metadata.json"
with open(json_file, "r") as file:
[docs]
data = json.loads(file.read())
os.makedirs(new_dir, exist_ok=True)
[docs]
sims_qeq1_nospin = count_subdirs("qeq1_nospin")
[docs]
sims_qeq1_spin = count_subdirs("qeq1_spin")
# sims_qdf1_nospin = count_subdirs('qdf1_nospin')
[docs]
sims_scat = count_subdirs("scattering_ICC")
[docs]
nsims_qeq1_nospin = len(sims_qeq1_nospin)
[docs]
nsims_qeq1_spin = len(sims_qeq1_spin)
# nsims_qdf1_nospin = len(sims_qdf1_nospin)
[docs]
nsims_scat = len(sims_scat)
# all_sims = sims_qeq1_nospin + sims_qeq1_spin + sims_qdf1_nospin + sims_scat
[docs]
all_sims = sims_qeq1_nospin + sims_qeq1_spin + sims_scat
# load mergers, which have a global json with meta
for i, sim in enumerate(all_sims):
meta = {}
meta["name"] = f"ICC_BBH_{ID:04}"
meta["id"] = f"{ID:04}"
meta["theta"] = get_info_from_name(sim, "th")
meta["b"] = get_info_from_name(sim, "b")
if sim in data:
# info to store
keys2store = ["q", "chi1", "chi2", "E0", "J0", "ecc", "D"]
for k in keys2store:
meta[k] = data[sim][k]
q = meta["q"]
chi1 = meta["chi1"]
chi2 = meta["chi2"]
bool_q1 = abs(q - 1) < 1e-5
bool_nospin = abs(chi1) < 1e-10 and abs(chi2) < 1e-10
if not bool_q1:
raise RuntimeError("q>1 are inaccurate!")
datadir = "qdf1_nospin"
elif bool_nospin:
datadir = "qeq1_nospin"
else:
datadir = "qeq1_spin"
py = meta["J0"] / meta["D"]
p = py / np.sin(meta["theta"] * np.pi / 180)
px = -np.sqrt(p**2 - py**2)
meta["P0"] = [px, py, 0]
datasim = os.path.join(datadir, sim)
meta["scat_angle"] = None
meta["original_name"] = datasim
else: # scatterings
datadir = "scattering_ICC"
datasim = os.path.join(datadir, sim)
if not os.path.exists(datasim):
raise RuntimeError(f"Something wrong carissimo: {datasim}")
sim_path = os.path.join(datadir, sim)
fname = os.path.join(sim_path, "TwoPunctures.bbh")
bbh_meta = parse_nr_metadata(fname)
M1 = bbh_meta["initial-bh-puncture-adm-mass1"]
M2 = bbh_meta["initial-bh-puncture-adm-mass2"]
D = abs(bbh_meta["initial-bh-position1x"] - bbh_meta["initial-bh-position2x"])
M = M1 + M2
meta["q"] = M1 / M2
meta["chi1"] = bbh_meta["initial-bh-spin1z"] / M1**2
meta["chi2"] = bbh_meta["initial-bh-spin2z"] / M2**2
meta["E0"] = bbh_meta["initial-ADM-energy"] / M
meta["J0"] = bbh_meta["initial-ADM-angular-momentumz"] / M**2
meta["ecc"] = None
meta["D"] = D / M
px = bbh_meta["initial-bh-momentum1x"] / M
py = bbh_meta["initial-bh-momentum1y"] / M
meta["P0"] = [px, py, 0]
puncts = load_puncts(sim_path)
if puncts is not None and puncts["r"][-1] > 25:
scat = ScatteringAngle(
puncts=puncts,
nmin=2,
nmax=5,
n_extract=4,
r_cutoff_out_low=25,
r_cutoff_out_high=None,
r_cutoff_in_low=25,
r_cutoff_in_high=100,
verbose=False,
)
meta["scat_angle"] = scat.chi
else:
meta["scat_angle"] = None
meta["original_name"] = sim_path
fname = os.path.join(datasim, "metadata.json")
with open(fname, "w") as file:
file.write(json.dumps(meta, indent=2))
logging.info(f"#{ID:04} created file: {fname}")
new_sim_dir = os.path.join(new_dir, meta["name"])
os.makedirs(new_sim_dir, exist_ok=True)
cmd = f"cp -v {datasim}/* {new_sim_dir}"
runcmd(cmd, workdir=os.getcwd())
logging.info(" ")