refactor: restructure dice environment handling and update Python version requirement
This commit is contained in:
@@ -1,16 +1,39 @@
|
||||
from pydantic import TypeAdapter
|
||||
|
||||
import diceplayer.dice.dice_input as dice_input
|
||||
from diceplayer.config import DiceConfig
|
||||
from diceplayer.environment import System
|
||||
|
||||
from pydantic import TypeAdapter
|
||||
from pydantic.dataclasses import dataclass
|
||||
|
||||
import subprocess
|
||||
from itertools import islice
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
from typing import Final, List, Self
|
||||
|
||||
|
||||
type DiceEnvironment = tuple[str, int, int, int]
|
||||
DiceEnvironmentAdapter = TypeAdapter(DiceEnvironment)
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class DiceEnvironmentItem:
|
||||
atom: str
|
||||
x: float
|
||||
y: float
|
||||
z: float
|
||||
|
||||
|
||||
DiceEnvironmentItemAdapter = TypeAdapter(DiceEnvironmentItem)
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class DiceEnvironment:
|
||||
number_of_sites: int
|
||||
thickness: List[float]
|
||||
items: List[DiceEnvironmentItem]
|
||||
|
||||
@classmethod
|
||||
def new(cls, thickness: List[float]) -> Self:
|
||||
return cls(number_of_sites=0, thickness=thickness, items=[])
|
||||
|
||||
def add_site(self, site: DiceEnvironmentItem):
|
||||
self.items.append(site)
|
||||
self.number_of_sites += 1
|
||||
|
||||
|
||||
DICE_FLAG_LINE: Final[int] = -2
|
||||
@@ -28,7 +51,10 @@ class DiceWrapper:
|
||||
|
||||
with open(output_path, "w") as outfile, open(input_path, "r") as infile:
|
||||
exit_status = subprocess.call(
|
||||
self.dice_config.progname, stdin=infile, stdout=outfile, cwd=self.working_directory
|
||||
self.dice_config.progname,
|
||||
stdin=infile,
|
||||
stdout=outfile,
|
||||
cwd=self.working_directory,
|
||||
)
|
||||
|
||||
if exit_status != 0:
|
||||
@@ -41,22 +67,37 @@ class DiceWrapper:
|
||||
|
||||
raise RuntimeError(f"Dice simulation failed with exit status {exit_status}")
|
||||
|
||||
def parse_results(self, system: System) -> list[DiceEnvironment]:
|
||||
NUMBER_OF_HEADER_LINES = 2
|
||||
NUMBER_OF_PRIMARY_ATOMS = len(system.molecule[0].atom)
|
||||
|
||||
def parse_results(self) -> list[DiceEnvironment]:
|
||||
results = []
|
||||
for output_file in sorted(self.working_directory.glob("phb*.xyz")):
|
||||
with open(output_file, "r") as f:
|
||||
for _ in range(NUMBER_OF_HEADER_LINES + NUMBER_OF_PRIMARY_ATOMS):
|
||||
next(f, None)
|
||||
|
||||
for line in f:
|
||||
if line.strip() == "":
|
||||
break
|
||||
positions_file = self.working_directory / "phb.xyz"
|
||||
if not positions_file.exists():
|
||||
raise RuntimeError(f"Positions file not found at {self.working_directory}")
|
||||
|
||||
results.append(
|
||||
DiceEnvironmentAdapter.validate_python(line.split())
|
||||
)
|
||||
with open(positions_file, "r") as f:
|
||||
while True:
|
||||
line = f.readline()
|
||||
if not line.startswith(" "):
|
||||
break
|
||||
|
||||
environment = DiceEnvironment(
|
||||
number_of_sites=int(line.strip()),
|
||||
thickness=[float(n) for n in f.readline().split()[-3:]],
|
||||
items=[],
|
||||
)
|
||||
|
||||
# Skip the comment line
|
||||
|
||||
environment.items.extend(
|
||||
[
|
||||
DiceEnvironmentItemAdapter.validate_python(
|
||||
{"atom": site[0], "x": site[1], "y": site[2], "z": site[3]}
|
||||
)
|
||||
for atom in islice(f, environment.number_of_sites)
|
||||
if (site := atom.strip().split()) and len(site) == 4
|
||||
]
|
||||
)
|
||||
|
||||
results.append(environment)
|
||||
|
||||
return results
|
||||
|
||||
Reference in New Issue
Block a user