Changed loading function, and only create folder with save.

This commit is contained in:
Kenneth Jao 2021-09-24 05:54:44 -04:00
parent 3841e6fe6b
commit 4f23f0c43f
4 changed files with 164 additions and 145 deletions

View File

@ -1,2 +1,3 @@
from .common import DomainParams, Energy, Simulation from .common import DomainParams, Energy
from .simulation import Simulation
from .diagram import Diagram from .diagram import Diagram

View File

@ -1,5 +1,5 @@
from __future__ import annotations from __future__ import annotations
from typing import List, Union, Optional, Iterator from typing import List, Union, Optional, Iterator, Generator
import pickle, numpy as np import pickle, numpy as np
from pathlib import Path from pathlib import Path
from _squish import AreaEnergy, RadialALEnergy, RadialTEnergy from _squish import AreaEnergy, RadialALEnergy, RadialTEnergy
@ -101,142 +101,4 @@ class Energy:
@property @property
def title_str(self) -> str: def title_str(self) -> str:
return self.mode.title_str return self.mode.title_str
class Simulation:
"""Generic container for simulations.
Attributes:
domain (DomainParams): Domain Parameters for this simulation.
energy (Energy): energy being used for caluclations.
path (Path): Path to location of where to store simulation files.
frames (List[VoronoiContainer]): Stores frames of the simulation.
"""
__slots__ = ['domain', 'energy', 'path', 'frames']
def __init__(self, domain: DomainParams, energy: Energy, name: Optional[str] = None) -> None:
self.domain, self.energy = domain, energy
self.frames = []
if name is None:
self.path = generate_filepath(self, OUTPUT_DIR)
else:
self.path = OUTPUT_DIR / name
self.path.mkdir()
def __iter__(self) -> Iterator:
return iter(self.frames)
def __getitem__(self, key: int) -> Energy:
return self.frames[key]
def __len__(self) -> int:
return len(self.frames)
def add_frame(self, points: Optional[numpy.ndarray]) -> None:
if points is None:
points = np.random.random_sample((self.domain.n, 2)) * self.domain.dim
else:
if points.shape[1] != 2 or len(points.shape) > 2:
raise ValueError("Sites should be 2 dimensional!")
if points.shape[0] != self.domain.n:
raise ValueError("Number of sites provided do not match the array!")
self.frames.append(self.energy.mode(*self.domain, points % self.domain.dim))
def get_distinct(self) -> List[int]:
"""Gets the distinct configurations based on the average radii of the sites.
and returns the number of configurations for each distinct configuration.
"""
distinct_avg_radii, distinct_count, new_frames = [], [], []
for frame in self.frames:
avg_radii = np.sort(frame.stats["avg_radius"])
is_in = False
for i, dist_radii in enumerate(distinct_avg_radii):
if np.allclose(avg_radii, dist_radii, atol=1e-5):
is_in = True
distinct_count[i] += 1
break
if not is_in:
distinct_avg_radii.append(avg_radii)
new_frames.append(frame)
self.frames = new_frames
return distinct_count
def save(self, info: Dict) -> None:
path = self.path / 'data.squish'
with open(path, 'wb') as out:
pickle.dump(info, out, pickle.HIGHEST_PROTOCOL)
def frame_data(self, index: int) -> None:
f = self[index]
info = {
"arr": f.site_arr,
"domain": (f.n, f.h, f.w, f.r),
"energy": f.attr_str,
"stats": f.stats
}
return info
# all_info = []
# for frame in self.frames:
# frame_info = dict()
# frame_info["arr"] = frame.site_arr
# frame_info["energy"] = {AreaEnergy: "area", RadialALEnergy: "radial-al",
# RadialTEnergy: "radial-t"}[self.energy]
# frame_info["params"] = (frame.n, frame.w, frame.h, frame.r)
# all_info.append(frame_info)
# class_name = {Flow: "flow", Search: "search", Shrink: "shrink"}[self.__class__]
# with open(path, 'wb') as output:
# pickle.dump((all_info, class_name), output, pickle.HIGHEST_PROTOCOL)
# print("Wrote to " + path, flush=True)
@staticmethod
def load(path: str) -> Simulation:
with open(path, 'rb') as infile:
while True:
try:
yield pickle.load(infile)
except EOFError:
break
@staticmethod
def load_old(filename: str) -> Simulation:
"""
Loads the points at every point into a file.
:param filename: [str] name of the file
"""
frames = []
with open(filename, 'rb') as data:
all_info, sim_class = pickle.load(data)
if type(sim_class) == str:
sim_class = {"flow": Flow, "search": Search, "shrink": Shrink}[sim_class]
sim = sim_class(*all_info[0]["params"], "radial-t", 0,0)
for frame_info in all_info:
frames.append(sim.energy(*frame_info["params"], frame_info["arr"]))
#frames[-1].stats = frame_info["stats"]
sim.frames = frames
return sim

View File

@ -5,7 +5,154 @@ import pickle, numpy as np
from scipy.linalg import null_space from scipy.linalg import null_space
from timeit import default_timer as timer from timeit import default_timer as timer
from .common import DomainParams, Energy, Simulation from .common import DomainParams, Energy, generate_filepath, OUTPUT_DIR
class Simulation:
"""Generic container for simulations.
Attributes:
domain (DomainParams): Domain Parameters for this simulation.
energy (Energy): energy being used for caluclations.
path (Path): Path to location of where to store simulation files.
frames (List[VoronoiContainer]): Stores frames of the simulation.
"""
__slots__ = ['domain', 'energy', 'path', 'frames']
def __init__(self, domain: DomainParams, energy: Energy, name: Optional[str] = None) -> None:
self.domain, self.energy = domain, energy
self.frames = []
if name is None:
self.path = generate_filepath(self, OUTPUT_DIR)
else:
self.path = OUTPUT_DIR / name
def __iter__(self) -> Iterator:
return iter(self.frames)
def __getitem__(self, key: int) -> Energy:
return self.frames[key]
def __len__(self) -> int:
return len(self.frames)
def add_frame(self, points: Optional[numpy.ndarray]) -> None:
if points is None:
points = np.random.random_sample((self.domain.n, 2)) * self.domain.dim
else:
if points.shape[1] != 2 or len(points.shape) > 2:
raise ValueError("Sites should be 2 dimensional!")
if points.shape[0] != self.domain.n:
raise ValueError("Number of sites provided do not match the array!")
self.frames.append(self.energy.mode(*self.domain, points % self.domain.dim))
def get_distinct(self) -> List[int]:
"""Gets the distinct configurations based on the average radii of the sites.
and returns the number of configurations for each distinct configuration.
"""
distinct_avg_radii, distinct_count, new_frames = [], [], []
for frame in self.frames:
avg_radii = np.sort(frame.stats["avg_radius"])
is_in = False
for i, dist_radii in enumerate(distinct_avg_radii):
if np.allclose(avg_radii, dist_radii, atol=1e-5):
is_in = True
distinct_count[i] += 1
break
if not is_in:
distinct_avg_radii.append(avg_radii)
new_frames.append(frame)
self.frames = new_frames
return distinct_count
def save(self, info: Dict) -> None:
self.path.mkdir(exist_ok=True)
path = self.path / 'data.squish'
with open(path, 'ab') as out:
pickle.dump(info, out, pickle.HIGHEST_PROTOCOL)
def frame_data(self, index: int) -> None:
f = self[index]
info = {
"arr": f.site_arr,
"domain": (f.n, f.h, f.w, f.r),
"energy": f.energy,
"stats": f.stats
}
return info
# all_info = []
# for frame in self.frames:
# frame_info = dict()
# frame_info["arr"] = frame.site_arr
# frame_info["energy"] = {AreaEnergy: "area", RadialALEnergy: "radial-al",
# RadialTEnergy: "radial-t"}[self.energy]
# frame_info["params"] = (frame.n, frame.w, frame.h, frame.r)
# all_info.append(frame_info)
# class_name = {Flow: "flow", Search: "search", Shrink: "shrink"}[self.__class__]
# with open(path, 'wb') as output:
# pickle.dump((all_info, class_name), output, pickle.HIGHEST_PROTOCOL)
# print("Wrote to " + path, flush=True)
@staticmethod
def load(path: str) -> Tuple[Simulation, Generator]:
def frames() -> Dict:
with open(path, 'rb') as infile:
while True:
try:
yield pickle.load(infile)
except EOFError:
break
with open(path, 'rb') as infile:
sim_info = pickle.load(infile)
domain = DomainParams(*sim_info["domain"])
energy = Energy(sim_info["energy"])
sim = STR_TO_SIM[sim_info["mode"]](domain, energy, *list(sim_info.values())[3:])
return sim, frames()
@staticmethod
def load_old(filename: str) -> Simulation:
"""
Loads the points at every point into a file.
:param filename: [str] name of the file
"""
frames = []
with open(filename, 'rb') as data:
all_info, sim_class = pickle.load(data)
if type(sim_class) == str:
sim_class = {"flow": Flow, "search": Search, "shrink": Shrink}[sim_class]
sim = sim_class(*all_info[0]["params"], "radial-t", 0,0)
for frame_info in all_info:
frames.append(sim.energy(*frame_info["params"], frame_info["arr"]))
#frames[-1].stats = frame_info["stats"]
sim.frames = frames
return sim
class Flow(Simulation): class Flow(Simulation):
@ -36,6 +183,8 @@ class Flow(Simulation):
def initial_data(self) -> Dict: def initial_data(self) -> Dict:
info = { info = {
"mode": self.attr_str, "mode": self.attr_str,
"domain": (self.domain.n, self.domain.w, self.domain.h, self.domain.r),
"energy": self.energy.attr_str,
"step_size": self.step_size, "step_size": self.step_size,
"thres": self.thres, "thres": self.thres,
"accel": self.accel "accel": self.accel
@ -126,6 +275,8 @@ class Search(Simulation):
def initial_data(self) -> Dict: def initial_data(self) -> Dict:
info = { info = {
"mode": self.attr_str, "mode": self.attr_str,
"domain": (self.domain.n, self.domain.w, self.domain.h, self.domain.r),
"energy": self.energy.attr_str,
"step_size": self.step_size, "step_size": self.step_size,
"thres": self.thres, "thres": self.thres,
"accel": self.accel, "accel": self.accel,
@ -205,6 +356,8 @@ class Shrink(Simulation):
def initial_data(self) -> Dict: def initial_data(self) -> Dict:
info = { info = {
"mode": self.attr_str, "mode": self.attr_str,
"domain": (self.domain.n, self.domain.w, self.domain.h, self.domain.r),
"energy": self.energy.attr_str,
"step_size": self.step_size, "step_size": self.step_size,
"thres": self.thres, "thres": self.thres,
"accel": self.accel, "accel": self.accel,
@ -241,3 +394,9 @@ class Shrink(Simulation):
width -= self.delta width -= self.delta
i += 1 i += 1
STR_TO_SIM = {
"flow": Flow,
"search": Search,
"shrink": Shrink
}

View File

@ -45,9 +45,6 @@ def check_params(container: Dict, needed: List[str], valid: Dict) -> None:
def main(): def main():
# Loading configuration and settings. # Loading configuration and settings.
Path('simulations').mkdir(exist_ok=True)
Path('figures').mkdir(exist_ok=True)
parser = argparse.ArgumentParser("PackSim") parser = argparse.ArgumentParser("PackSim")
parser.add_argument('sim_conf', metavar='/path/to/config.json', parser.add_argument('sim_conf', metavar='/path/to/config.json',
help="configuration file for a simulation") help="configuration file for a simulation")