squish/scripts/defects.py

88 lines
2.2 KiB
Python

from __future__ import annotations
from typing import List
import argparse, pickle, numpy as np, os
from pathlib import Path
import matplotlib.pyplot as plt
from squish import Simulation
from squish.common import OUTPUT_DIR
def main():
parser = argparse.ArgumentParser("Graphs average defects at N.")
parser.add_argument('sims_path', metavar='path/to/data',
help="folder that contains simulation files at various Ns.")
parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=False,
help="suppress all normal output")
args = parser.parse_args()
data = {}
for file in Path(args.sims_path).iterdir():
sim, frames = Simulation.load(file / "data.squish")
avg_defects = 0
count = 0
for frame in frames:
if np.var(frame["stats"]["avg_radius"]) > 1e-8:
avg_defects += np.count_nonzero(frame["stats"]["site_edge_count"] != 6)
count += 1
avg_defects /= (1 if count == 0 else count)
data[sim.domain.n] = avg_defects
data = sorted(data.items())
ns, defects = np.array([x[0] for x in data]), np.array([x[1] for x in data])
corrected = []
for i, x in enumerate(defects):
if x == 0:
corrected.append(defects[i+1])
else:
corrected.append(x)
fig, ax = plt.subplots(1, 2, figsize=(16, 8))
plt.subplots_adjust(.07, .12, .97, .9)
fig.suptitle("Defects at N")
m0, b0 = np.polyfit(ns, defects, 1)
ax[0].plot(ns, defects)
ax[0].plot(ns, m0*ns+b0, label=f"Slope: {m0:.5f}")
ax[0].grid(zorder=0)
ax[0].legend()
ax[0].set_xlabel("N")
ax[0].set_ylabel("Average Defects")
x, y = np.log10(ns), np.log10(corrected)
m, b = np.polyfit(x, y, 1)
x2, y2 = x[14:], np.log10(defects[14:])
m2, b2 = np.polyfit(x2, y2, 1)
ax[1].plot(x, y, linestyle='dotted', color='C0')
ax[1].plot(x, np.log10(defects))
ax[1].plot(x, m*x+b, label=f"All N: {m:.5f}")
ax[1].plot(x2, m2*x2+b2, label=f"N $\\geq$ 25: {m2:.5f}")
ax[1].grid(zorder=0)
ax[1].legend()
ax[1].set_xlabel("log10 N")
ax[1].set_ylabel("log10 Average Defects")
fig.savefig(OUTPUT_DIR / "DefectsN.png")
print(f"Wrote to {OUTPUT_DIR / 'DefectsN.png'}")
if __name__ == '__main__':
os.environ["QT_log10GING_RULES"] = "*=false"
try:
main()
except KeyboardInterrupt:
print("Program terminated by user.")