Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 7 additions & 57 deletions src/opi/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from typing import Any, cast

from opi.execution.core import Runner
from opi.input.arbitrary_string import ArbitraryStringPos
from opi.input.blocks.block_output import BlockOutput
from opi.input.core import Input
from opi.input.structures.structure import Structure
Expand Down Expand Up @@ -215,55 +214,15 @@ def write_input(self, force: bool = True) -> bool:

try:
input_param = self.input
simple_keywords = input_param.simple_keywords
blocks = input_param.blocks.values() if input_param.blocks else ()
arbitrary_strings = input_param.arbitrary_strings

assert self.inpfile is not None
with self.inpfile.open("w") as inp:
with open(self._inpfile, "w") as inp:
# ---------------------------------
# > Arbitrary Strings: top
# > Before coords block
# ---------------------------------
if arbitrary_strings:
for item in arbitrary_strings:
if item.pos is ArbitraryStringPos.TOP:
inp.write(f"{item.format_orca()}\n")
input_string_before_coords = input_param.format_before_coords(self.working_dir)

# ---------------------------------
# > Simple Keywords
# ---------------------------------
if simple_keywords:
for keyword in simple_keywords:
if isinstance(keyword, str):
inp.write(f"!{keyword}\n")
else:
inp.write(f"!{keyword.format_orca()}\n")

# ---------------------------------
# > Special Strings
# ---------------------------------
if (memory := input_param.memory) is not None:
inp.write(f"%maxcore {memory:d}\n")
if (ncores := input_param.ncores) is not None:
inp.write(f"%pal\n nprocs {ncores:d}\nend\n")
if (moinp := input_param.moinp) is not None:
inp.write(f'%moinp "{moinp.relative_to(self.working_dir)}"\n')

# ---------------------------------
# > Block Options: Before coords
# ---------------------------------
if blocks:
for block in blocks:
if not block.aftercoord:
inp.write(f"\n{block.format_orca()}\n")

# ---------------------------------
# > Arbitrary Strings: Before Coords
# ---------------------------------
if arbitrary_strings:
for item in arbitrary_strings:
if item.pos is ArbitraryStringPos.BEFORE_COORDS:
inp.write(f"\n{item}\n")
inp.write(input_string_before_coords)

# ---------------------------------
# > Coords block
Expand All @@ -275,20 +234,11 @@ def write_input(self, force: bool = True) -> bool:
inp.write(f"\n{self.structure.format_orca()}\n")

# ---------------------------------
# > Block options: After coords
# > After coords block
# ---------------------------------
if blocks:
for block in blocks:
if block.aftercoord:
inp.write(f"\n{block.format_orca()}\n")
input_string_after_coords = input_param.format_after_coords()

# ---------------------------------
# > Arbitrary Strings: Bottom
# ---------------------------------
if arbitrary_strings:
for item in arbitrary_strings:
if item.pos is ArbitraryStringPos.BOTTOM:
inp.write(f"\n{item}\n")
inp.write(input_string_after_coords)

return input_overwritten

Expand Down
114 changes: 114 additions & 0 deletions src/opi/input/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,120 @@ def moinp(self, value: Path | str | os.PathLike[str] | None) -> None:
# > METHODS
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

def format_before_coords(self, working_directory: Path) -> str:
"""
Function to format input data that appears before the coordinate block in the ORCA .inp file.

Parameters
----------
working_directory: Path
working directory of the ORCA calculation.

Raises
------
ValueError
If the working directory is empty
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comment to the line where the Exception might be raised.


Returns
-------
str
Formatted string of input data
"""
input_before_coords = ""
try:
simple_keywords = self.simple_keywords
blocks = self.blocks.values() if self.blocks else ()
arbitrary_strings = self.arbitrary_strings

# ---------------------------------
# > Arbitrary Strings: top
# ---------------------------------
if arbitrary_strings:
for item in arbitrary_strings:
if item.pos is ArbitraryStringPos.TOP:
input_before_coords += f"{item.format_orca()}\n"

# ---------------------------------
# > Simple Keywords
# ---------------------------------
if simple_keywords:
for keyword in simple_keywords:
if isinstance(keyword, str):
input_before_coords += f"!{keyword}\n"
else:
input_before_coords += f"!{keyword.format_orca()}\n"

# ---------------------------------
# > Special Strings
# ---------------------------------
if (memory := self.memory) is not None:
input_before_coords += f"%maxcore {memory:d}\n"
if (ncores := self.ncores) is not None:
input_before_coords += f"%pal\n nprocs {ncores:d}\nend\n"
if (moinp := self.moinp) is not None:
input_before_coords += f'%moinp "{moinp.relative_to(working_directory)}"\n'

# ---------------------------------
# > Block Options: Before coords
# ---------------------------------
if blocks:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add more details. When is this raised?
Can this be raised at every point in the function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify this point a bit more?

Copy link
Contributor

@timmyte timmyte Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry.
Looks like I placed the comment on the wrong line.
It's meant to apply to this part here:

        Raises
        ------
        ValueError
            If the working directory is empty

for block in blocks:
if not block.aftercoord:
input_before_coords += f"\n{block.format_orca()}\n"

# ---------------------------------
# > Arbitrary Strings: Before Coords
# ---------------------------------
if arbitrary_strings:
for item in arbitrary_strings:
if item.pos is ArbitraryStringPos.BEFORE_COORDS:
input_before_coords += f"\n{item}\n"

return input_before_coords

except ValueError as err:
raise ValueError(f"Error formatting Input: {err}") from err

def format_after_coords(self) -> str:
"""
Function to format input data that appears after the coordinate block in the ORCA .inp file.

Raises
------
ValueError
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add more details. When is this raised?
Can this be raised at every point in the function?



Returns
-------
str
Formatted string of input data

"""
input_after_coords = ""
try:
blocks = self.blocks.values() if self.blocks else ()
arbitrary_strings = self.arbitrary_strings
# ---------------------------------
# > Block options: After coords
# ---------------------------------
if blocks:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if can be omitted, as blocks is an empty list, so the for-loop does nothing.

for block in blocks:
if block.aftercoord:
input_after_coords += f"\n{block.format_orca()}\n"

# ---------------------------------
# > Arbitrary Strings: Bottom
# ---------------------------------
if arbitrary_strings:
for item in arbitrary_strings:
if item.pos is ArbitraryStringPos.BOTTOM:
input_after_coords += f"\n{item}\n"

return input_after_coords

except ValueError as err:
raise ValueError(f"Error formatting Input: {err}") from err

# ----------------------------------------------------------------------
# > SIMPLE KEYWORDS
# ----------------------------------------------------------------------
Expand Down