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

View File

@ -1,5 +1,5 @@
from __future__ import annotations
from typing import List, Union, Optional, Iterator
from typing import List, Union, Optional, Iterator, Generator
import pickle, numpy as np
from pathlib import Path
from _squish import AreaEnergy, RadialALEnergy, RadialTEnergy
@ -102,141 +102,3 @@ class Energy:
@property
def title_str(self) -> 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 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):
@ -36,6 +183,8 @@ class Flow(Simulation):
def initial_data(self) -> Dict:
info = {
"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,
"thres": self.thres,
"accel": self.accel
@ -126,6 +275,8 @@ class Search(Simulation):
def initial_data(self) -> Dict:
info = {
"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,
"thres": self.thres,
"accel": self.accel,
@ -205,6 +356,8 @@ class Shrink(Simulation):
def initial_data(self) -> Dict:
info = {
"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,
"thres": self.thres,
"accel": self.accel,
@ -241,3 +394,9 @@ class Shrink(Simulation):
width -= self.delta
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():
# Loading configuration and settings.
Path('simulations').mkdir(exist_ok=True)
Path('figures').mkdir(exist_ok=True)
parser = argparse.ArgumentParser("PackSim")
parser.add_argument('sim_conf', metavar='/path/to/config.json',
help="configuration file for a simulation")