2022-05-06 09:51:43 +02:00
|
|
|
from typing import Dict
|
2022-05-04 13:42:57 +02:00
|
|
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
import numpy as np
|
|
|
|
from matplotlib.axes import Axes
|
|
|
|
from matplotlib.figure import Figure
|
2022-05-09 15:20:10 +02:00
|
|
|
from numpy import linalg
|
2022-05-04 13:42:57 +02:00
|
|
|
from pandas import DataFrame
|
2022-05-10 13:29:20 +02:00
|
|
|
from pyvista import Plotter
|
2022-05-04 13:42:57 +02:00
|
|
|
|
2022-05-06 13:23:31 +02:00
|
|
|
from paths import base_dir
|
2022-05-11 14:22:34 +02:00
|
|
|
from read_vr_files import read_velo_halos
|
2022-05-04 13:42:57 +02:00
|
|
|
from readfiles import read_file, read_halo_file
|
|
|
|
from remap_particle_IDs import IDScaler
|
2022-05-10 13:29:20 +02:00
|
|
|
from threed import plotdf3d
|
2022-05-05 11:53:43 +02:00
|
|
|
from utils import print_progress, memory_usage
|
2022-05-04 13:42:57 +02:00
|
|
|
|
2022-05-05 11:25:42 +02:00
|
|
|
|
2022-05-06 13:23:31 +02:00
|
|
|
def apply_offset_to_list(value_list, offset):
|
|
|
|
result_list = []
|
|
|
|
for value in value_list:
|
|
|
|
value = apply_offset(value, offset)
|
|
|
|
result_list.append(value)
|
|
|
|
return result_list
|
|
|
|
|
|
|
|
|
|
|
|
def apply_offset(value, offset):
|
|
|
|
box_size = 100
|
|
|
|
if value > box_size / 2:
|
|
|
|
value -= box_size
|
|
|
|
value -= offset
|
|
|
|
return value
|
2022-05-05 11:25:42 +02:00
|
|
|
|
2022-05-06 13:23:31 +02:00
|
|
|
|
2022-05-10 13:29:20 +02:00
|
|
|
def compare_halo_resolutions(reference_resolution: int, comparison_resolution: int,
|
2022-05-11 14:22:34 +02:00
|
|
|
plot=False, plot3d=False, single=False, velo_halos=False):
|
2022-05-09 15:20:10 +02:00
|
|
|
reference_dir = base_dir / f"shannon_{reference_resolution}_100"
|
|
|
|
comparison_dir = base_dir / f"shannon_{comparison_resolution}_100/"
|
2022-05-06 13:23:31 +02:00
|
|
|
comparison_id = reference_dir.name + "_" + comparison_dir.name
|
2022-05-11 14:22:34 +02:00
|
|
|
if velo_halos:
|
|
|
|
comparison_id += "_velo"
|
2022-05-05 11:25:42 +02:00
|
|
|
ref_masses = []
|
|
|
|
comp_masses = []
|
|
|
|
ref_sizes = []
|
|
|
|
comp_sizes = []
|
2022-05-05 11:53:43 +02:00
|
|
|
matches = []
|
2022-05-09 15:20:10 +02:00
|
|
|
distances = []
|
2022-05-05 11:25:42 +02:00
|
|
|
|
|
|
|
print("reading reference file")
|
|
|
|
df_ref, ref_meta = read_file(reference_dir)
|
2022-05-11 14:22:34 +02:00
|
|
|
if velo_halos:
|
|
|
|
df_ref_halo, ref_halo_lookup, _ = read_velo_halos(reference_dir, skip_unbound=True,recursivly=False)
|
|
|
|
else:
|
|
|
|
df_ref_halo = read_halo_file(reference_dir)
|
2022-05-05 11:25:42 +02:00
|
|
|
|
|
|
|
print("reading comparison file")
|
|
|
|
df_comp, comp_meta = read_file(comparison_dir)
|
2022-05-11 14:22:34 +02:00
|
|
|
if velo_halos:
|
|
|
|
df_comp_halo, comp_halo_lookup, _ = read_velo_halos(comparison_dir, skip_unbound=True,recursivly=False)
|
|
|
|
else:
|
|
|
|
df_comp_halo = read_halo_file(comparison_dir)
|
2022-05-05 11:25:42 +02:00
|
|
|
|
2022-05-06 09:51:43 +02:00
|
|
|
print("precalculating halo memberships")
|
2022-05-11 14:22:34 +02:00
|
|
|
if not velo_halos:
|
|
|
|
ref_halo_lookup = precalculate_halo_membership(df_ref, df_ref_halo)
|
|
|
|
comp_halo_lookup = precalculate_halo_membership(df_comp, df_comp_halo)
|
2022-05-06 09:51:43 +02:00
|
|
|
|
2022-05-05 11:53:43 +02:00
|
|
|
print(f"Memory ref: {memory_usage(df_ref):.2f} MB")
|
|
|
|
print(f"Memory comp: {memory_usage(df_comp):.2f} MB")
|
2022-05-05 11:25:42 +02:00
|
|
|
|
2022-05-05 11:53:43 +02:00
|
|
|
for index, original_halo in df_ref_halo.iterrows():
|
|
|
|
print(f"{index} of {len(df_ref_halo)} original halos")
|
2022-05-06 09:51:43 +02:00
|
|
|
halo_particle_ids = ref_halo_lookup[int(index)]
|
2022-05-05 11:25:42 +02:00
|
|
|
ref_halo = df_ref_halo.loc[index]
|
2022-05-06 13:23:31 +02:00
|
|
|
offset_x, offset_y = ref_halo.X, ref_halo.Y
|
2022-05-05 11:53:43 +02:00
|
|
|
# cumulative_mass_profile(particles_in_ref_halo, ref_halo, ref_meta, plot=plot)
|
2022-05-05 11:25:42 +02:00
|
|
|
|
2022-05-05 11:53:43 +02:00
|
|
|
prev_len = len(halo_particle_ids)
|
2022-05-05 11:25:42 +02:00
|
|
|
if reference_resolution < comparison_resolution:
|
|
|
|
print("upscaling IDs")
|
|
|
|
upscaled_ids = set()
|
|
|
|
scaler = IDScaler(reference_resolution, comparison_resolution)
|
|
|
|
for id in halo_particle_ids:
|
|
|
|
upscaled_ids.update(set(scaler.upscale(id)))
|
|
|
|
halo_particle_ids = upscaled_ids
|
|
|
|
after_len = len(upscaled_ids)
|
2022-05-05 11:53:43 +02:00
|
|
|
print(f"{prev_len} => {after_len} (factor {after_len / prev_len})")
|
2022-05-05 11:25:42 +02:00
|
|
|
if comparison_resolution < reference_resolution:
|
|
|
|
print("downscaling IDs")
|
|
|
|
downscaled_ids = set()
|
|
|
|
scaler = IDScaler(comparison_resolution, reference_resolution)
|
|
|
|
for id in halo_particle_ids:
|
|
|
|
downscaled_ids.add(scaler.downscale(id))
|
|
|
|
halo_particle_ids = downscaled_ids
|
2022-05-05 11:53:43 +02:00
|
|
|
after_len = len(halo_particle_ids)
|
|
|
|
print(f"{prev_len} => {after_len} (factor {prev_len / after_len})")
|
2022-05-05 11:25:42 +02:00
|
|
|
|
2022-05-05 11:53:43 +02:00
|
|
|
print("look up halo particles in comparison dataset")
|
2022-05-06 09:51:43 +02:00
|
|
|
halo_particles = df_comp.loc[list(halo_particle_ids)]
|
2022-05-05 11:25:42 +02:00
|
|
|
|
2022-05-11 14:22:34 +02:00
|
|
|
halos_in_particles = set()
|
|
|
|
if velo_halos:
|
|
|
|
for halo_id, halo_set in comp_halo_lookup.items():
|
|
|
|
if halo_particle_ids.isdisjoint(halo_set):
|
|
|
|
continue
|
|
|
|
# print(len(halo_particle_ids))
|
|
|
|
# if int(index)==461:
|
|
|
|
# print(halo_id,int(index))
|
|
|
|
# print("halo_particle_ids",halo_particle_ids)
|
|
|
|
# print("halo_set",halo_set)
|
|
|
|
# print(halo_particle_ids.isdisjoint(halo_set))
|
|
|
|
# # exit()
|
|
|
|
halos_in_particles.add(halo_id)
|
|
|
|
else:
|
|
|
|
halos_in_particles = set(halo_particles["FOFGroupIDs"])
|
|
|
|
halos_in_particles.discard(2147483647)
|
|
|
|
# print(f"{len(halos_in_particles)} halos found in new particles")
|
|
|
|
# print(halos_in_particles)
|
|
|
|
# print(halos_in_particles_alt)
|
|
|
|
# print(halos_in_particles == halos_in_particles_alt)
|
|
|
|
# exit()
|
|
|
|
# assert halos_in_particles == halos_in_particles_alt
|
|
|
|
# continue
|
2022-05-05 11:25:42 +02:00
|
|
|
if plot:
|
|
|
|
fig: Figure = plt.figure()
|
|
|
|
ax: Axes = fig.gca()
|
2022-05-06 13:23:31 +02:00
|
|
|
halo_particles.to_csv(f"halo{index}.csv")
|
|
|
|
ax.scatter(apply_offset_to_list(halo_particles["X"], offset_x),
|
|
|
|
apply_offset_to_list(halo_particles["Y"], offset_y), s=1,
|
|
|
|
alpha=.3, label="Halo")
|
2022-05-10 13:29:20 +02:00
|
|
|
if plot3d:
|
|
|
|
pl = Plotter()
|
|
|
|
plotdf3d(pl, halo_particles, color="#b3cde3") # light blue
|
2022-05-11 14:22:34 +02:00
|
|
|
pl.set_focus((ref_halo.X, ref_halo.Y, ref_halo.Z))
|
2022-05-05 11:25:42 +02:00
|
|
|
# ax.scatter(particles_in_ref_halo["X"], particles_in_ref_halo["Y"], s=1, alpha=.3, label="RefHalo")
|
|
|
|
# plt.legend()
|
|
|
|
# plt.show()
|
|
|
|
best_halo = None
|
|
|
|
best_halo_match = 0
|
2022-05-11 14:22:34 +02:00
|
|
|
if not halos_in_particles:
|
|
|
|
print("something doesn't make any sense") # TODO
|
|
|
|
continue
|
2022-05-05 11:25:42 +02:00
|
|
|
|
2022-05-06 13:23:31 +02:00
|
|
|
for i, halo_id in enumerate(halos_in_particles):
|
2022-05-05 11:25:42 +02:00
|
|
|
# print("----------", halo, "----------")
|
2022-05-05 11:53:43 +02:00
|
|
|
# halo_data = df_comp_halo.loc[halo]
|
2022-05-06 09:51:43 +02:00
|
|
|
# particles_in_comp_halo: DataFrame = df_comp.loc[df_comp["FOFGroupIDs"] == halo]
|
2022-05-06 13:23:31 +02:00
|
|
|
particle_ids_in_comp_halo = comp_halo_lookup[halo_id]
|
2022-05-06 09:51:43 +02:00
|
|
|
halo_size = len(particle_ids_in_comp_halo)
|
|
|
|
# df = particles_in_comp_halo.join(halo_particles, how="inner", rsuffix="ref")
|
|
|
|
shared_particles = particle_ids_in_comp_halo.intersection(halo_particle_ids)
|
|
|
|
shared_size = len(shared_particles)
|
2022-05-11 14:22:34 +02:00
|
|
|
print(shared_size)
|
|
|
|
if not shared_size:
|
|
|
|
raise RuntimeError()
|
|
|
|
size_match = shared_size / halo_size
|
|
|
|
|
|
|
|
# if shared_size==halo_size:
|
|
|
|
# raise Exception("match")
|
2022-05-10 13:29:20 +02:00
|
|
|
if plot or plot3d:
|
2022-05-06 09:51:43 +02:00
|
|
|
df = df_comp.loc[list(shared_particles)]
|
2022-05-10 13:29:20 +02:00
|
|
|
if plot:
|
2022-05-06 13:23:31 +02:00
|
|
|
color = f"C{i + 1}"
|
|
|
|
|
|
|
|
ax.scatter(apply_offset_to_list(df["X"], offset_x), apply_offset_to_list(df["Y"], offset_y), s=1,
|
|
|
|
alpha=.3, c=color)
|
|
|
|
comp_halo = df_comp_halo.loc[halo_id]
|
|
|
|
# circle = Circle((apply_offset(comp_halo.X, offset_x), apply_offset(comp_halo.Y, offset_y)),
|
|
|
|
# comp_halo["Sizes"] / 1000, zorder=10,
|
|
|
|
# linewidth=1, edgecolor=color, fill=None
|
|
|
|
# )
|
|
|
|
# ax.add_artist(circle)
|
2022-05-10 13:29:20 +02:00
|
|
|
if plot3d:
|
|
|
|
plotdf3d(pl, df, color="#fed9a6") # light orange
|
2022-05-06 09:51:43 +02:00
|
|
|
# print_progress(i, len(halos_in_particles), halo)
|
2022-05-05 11:25:42 +02:00
|
|
|
# ax.scatter(particles_in_comp_halo["X"], particles_in_comp_halo["Y"], s=2, alpha=.3, label=f"shared {halo}")
|
|
|
|
if shared_size > best_halo_match:
|
|
|
|
best_halo_match = shared_size
|
2022-05-06 13:23:31 +02:00
|
|
|
best_halo = halo_id
|
2022-05-05 11:25:42 +02:00
|
|
|
|
|
|
|
comp_halo = df_comp_halo.loc[best_halo]
|
|
|
|
|
|
|
|
print(ref_halo)
|
|
|
|
print(comp_halo)
|
2022-05-11 14:22:34 +02:00
|
|
|
if velo_halos:
|
|
|
|
ref_sizes.append(ref_halo.Rvir)
|
|
|
|
comp_sizes.append(comp_halo.Rvir)
|
|
|
|
ref_masses.append(ref_halo.Mass_tot)
|
|
|
|
comp_masses.append(comp_halo.Mass_tot)
|
|
|
|
else:
|
|
|
|
ref_sizes.append(0)
|
|
|
|
ref_masses.append(ref_halo["Masses"])
|
|
|
|
comp_sizes.append(0)
|
|
|
|
comp_masses.append(comp_halo["Masses"])
|
2022-05-09 15:20:10 +02:00
|
|
|
distances.append(linalg.norm(
|
|
|
|
np.array([ref_halo.X, ref_halo.Y, ref_halo.Z]) - np.array([comp_halo.X, comp_halo.Y, comp_halo.Z])
|
|
|
|
))
|
2022-05-06 09:51:43 +02:00
|
|
|
matches.append(best_halo_match / len(halo_particles))
|
2022-05-05 11:25:42 +02:00
|
|
|
# exit()
|
|
|
|
if plot:
|
2022-05-06 13:23:31 +02:00
|
|
|
print(f"plotting with offsets ({offset_x},{offset_y})")
|
|
|
|
# ax.legend()
|
2022-05-05 11:25:42 +02:00
|
|
|
ax.set_title(f"{reference_dir.name} vs. {comparison_dir.name} (Halo {index})")
|
|
|
|
fig.savefig("out.png", dpi=300)
|
|
|
|
plt.show()
|
2022-05-10 13:29:20 +02:00
|
|
|
if plot3d:
|
|
|
|
pl.show()
|
2022-05-05 11:25:42 +02:00
|
|
|
if single:
|
|
|
|
break
|
|
|
|
|
2022-05-09 15:20:10 +02:00
|
|
|
df = DataFrame(np.array([matches, distances, ref_sizes, comp_sizes, ref_masses, comp_masses]).T,
|
|
|
|
columns=["matches", "distances", "ref_sizes", "comp_sizes", "ref_masses", "comp_masses"])
|
2022-05-05 11:25:42 +02:00
|
|
|
print(df)
|
2022-05-09 15:20:10 +02:00
|
|
|
outfile = comparison_id + ".csv"
|
|
|
|
print(f"saving to {outfile}")
|
2022-05-06 13:23:31 +02:00
|
|
|
df.to_csv(comparison_id + ".csv", index=False)
|
2022-05-05 11:53:43 +02:00
|
|
|
return df, reference_dir.name + "_" + comparison_dir.name
|
2022-05-05 11:25:42 +02:00
|
|
|
|
|
|
|
|
2022-05-06 09:51:43 +02:00
|
|
|
def precalculate_halo_membership(df_comp, df_comp_halo):
|
|
|
|
pointer = 0
|
|
|
|
comp_halo_lookup: Dict[int, set[int]] = {}
|
|
|
|
for i, halo in df_comp_halo.iterrows():
|
|
|
|
print_progress(i, len(df_comp_halo), halo["Sizes"])
|
|
|
|
size = int(halo["Sizes"])
|
|
|
|
halo_id = int(i)
|
|
|
|
halo_particles = df_comp.iloc[pointer:pointer + size]
|
|
|
|
|
|
|
|
# check_id = halo_particles["FOFGroupIDs"].to_numpy()
|
|
|
|
# assert (check_id == i).all()
|
|
|
|
# assert (check_id==check_id[0]
|
|
|
|
pointer += size
|
|
|
|
ids = set(halo_particles.index.to_list())
|
|
|
|
comp_halo_lookup[halo_id] = ids
|
|
|
|
return comp_halo_lookup
|
|
|
|
|
|
|
|
|
2022-05-05 11:25:42 +02:00
|
|
|
if __name__ == '__main__':
|
|
|
|
compare_halo_resolutions(
|
|
|
|
reference_resolution=128,
|
2022-05-10 13:29:20 +02:00
|
|
|
comparison_resolution=512,
|
2022-05-09 15:20:10 +02:00
|
|
|
plot=False,
|
2022-05-11 14:22:34 +02:00
|
|
|
plot3d=False,
|
|
|
|
velo_halos=False,
|
2022-05-05 11:25:42 +02:00
|
|
|
single=False
|
|
|
|
)
|