refactor: restructure dice environment handling and update Python version requirement
Some checks failed
build and upload / test (3.10) (push) Failing after 1m45s
build and upload / pypi-upload (push) Has been skipped

This commit is contained in:
2026-03-29 17:38:44 -03:00
parent 7e66c98f26
commit 2802f10013
9 changed files with 314 additions and 352 deletions

View File

@@ -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