Skip to content

Commit 708451e

Browse files
committed
merge
2 parents da2e979 + ba38ceb commit 708451e

File tree

10 files changed

+308
-46
lines changed

10 files changed

+308
-46
lines changed

.github/workflows/CI.yaml

-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ on:
77
pull_request:
88
branches:
99
- "main"
10-
schedule:
11-
# Run on master by default Sunday morning at 3:30:
12-
# Scheduled workflows run on the latest commit on the default or base branch.
13-
# (from https://help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule)
14-
- cron: "30 3 * * 0"
1510

1611
jobs:
1712
ci:

.github/workflows/Release.yaml

+12
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,15 @@ jobs:
1313
with:
1414
src : packmol_step
1515
secrets: inherit
16+
17+
docker:
18+
name: Docker
19+
needs: release
20+
uses: molssi-seamm/devops/.github/workflows/Docker.yaml@main
21+
with:
22+
image : molssi-seamm/seamm-packmol
23+
description: A Packmol executable packaged for use with SEAMM or standalone
24+
# Can limit platforms, e.g., linux/amd64, linux/arm64
25+
platforms: linux/amd64
26+
secrets: inherit
27+

HISTORY.rst

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ History
55
* Using RDKit for SMILES since we found some issues with OpenBabel, and also the
66
atom typing uses RDKit, so this is more compatible.
77

8+
2024.3.19 -- Updated installer for new scheme
9+
* packmol-step-installer now uses the new scheme, which supports both Conda and
10+
Docker installation.
11+
* Added seamm-packmol Docker image
12+
813
2024.1.16 -- Adding support for containers
914
* Added the ability to work in Docker containers.
1015

devtools/docker/Dockerfile

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM molssi/mamba141
2+
3+
COPY ./environment.yml /root/environment.yml
4+
5+
RUN mamba env update -f /root/environment.yml
6+
7+
WORKDIR /home
8+
ENTRYPOINT ["packmol"]

devtools/docker/environment.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: base
2+
channels:
3+
- conda-forge
4+
- defaults
5+
dependencies:
6+
- python
7+
# Executables, etc.
8+
- packmol==20.2.2
9+

packmol_step/data/configuration.txt

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
11
[packmol-step]
2-
# Information about where/how the executables are installed
3-
# installation may be 'user', 'conda' or 'module'. If a module is
4-
# specified it will be loaded and those executables used. In this
5-
# case, any path specified using -path will be ignored.
62

7-
installation =
8-
conda-environment =
9-
modules =
3+
# The level of logging for the Packmol Step
104

11-
# The path to the executable. Can be empty or not present, in which
12-
# case the default PATH is used. If a path is given, packmol
13-
# from this location will be used.
14-
#
15-
# Ignored if a module is used. The default is to use the PATH
16-
# environment variable.
17-
18-
packmol-path =
5+
# log-level WARNING
196

packmol_step/data/packmol.ini

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Configuration options for how to run Packmol
2+
3+
[docker]
4+
# The code to use. This may maybe more than just the name of the code, and variables in
5+
# braces {} will be expanded. For example:
6+
# code = mpiexec -np {NTASKS} lmp_mpi
7+
# would expand {NTASKS} to the number of tasks and run the command
8+
9+
code = packmol
10+
11+
# The name and location of the Docker container to use, optionally with the version
12+
13+
container = ghcr.io/molssi-seamm/seamm-packmol:{version}
14+
15+
# In addition, you can specify the platform to use. This is useful on e.g. Macs with
16+
# app silicon (M1, M3...) where the default platform is linux/arm64 but some containers
17+
# are only available for linux/amd64.
18+
19+
platform = linux/amd64
20+
21+
[local]
22+
# The type of local installation to use. Options are:
23+
# conda: Use a conda environment
24+
# modules: Use the modules system
25+
# local: Use a local installation
26+
# docker: Use a Docker container
27+
# By default SEAMM installs Packmol using conda.
28+
29+
installation = conda
30+
31+
# The command line to use, which should start with the executable followed by any options.
32+
# Variables in braces {} will be expanded. For example:
33+
#
34+
# code = mpiexec -np {NTASKS} lmp_mpi
35+
#
36+
# would expand {NTASKS} to the number of tasks and run the command.
37+
# For a 'local' installation, the command line should include the full path to the
38+
# executable or it should be in the path.
39+
40+
code = packmol
41+
42+
######################### conda section ############################
43+
# The full path to the conda executable:
44+
45+
# conda =
46+
47+
# The Conda environment to use. This is either the name or full path.
48+
49+
# conda-environment = seamm-packmol
50+
51+
######################### modules section ############################
52+
# The modules to load to run Packmol, as a list of strings.
53+
# For example, to load the modules packmol and openmpi, you would use:
54+
# modules = packmol openmpi
55+
56+
# modules =
57+
58+
######################### local section ############################
59+
# The full path to the Packmol executable should be in the 'code' option.
60+
61+
######################### docker section ############################
62+
# The name and location of the Docker container to use, optionally with the version.
63+
# {version} will be expanded to the version of the plug-in.
64+
65+
# container = ghcr.io/molssi-seamm/seamm-packmol:{version}
66+
67+
# In addition, you can specify the platform to use. This is useful on e.g. Macs with
68+
# app silicon (M1, M3...) where the default platform is linux/arm64 but some containers
69+
# are only available for linux/amd64.
70+
71+
platform = linux/amd64

packmol_step/installer.py

+155-12
Original file line numberDiff line numberDiff line change
@@ -54,40 +54,183 @@ def __init__(self, logger=logger):
5454
logger.debug("Initializing the PACKMOL installer object.")
5555

5656
self.section = "packmol-step"
57-
self.path_name = "packmol-path"
5857
self.executables = ["packmol"]
5958
self.resource_path = Path(pkg_resources.resource_filename(__name__, "data/"))
59+
60+
# The environment.yaml file for Conda installations.
61+
logger.debug(f"data directory: {self.resource_path}")
62+
self.environment_file = self.resource_path / "seamm-packmol.yml"
63+
64+
def check(self):
65+
"""Check the status of the Packmol installation."""
66+
print("Checking the Packmol installation.")
67+
6068
# What Conda environment is the default?
61-
data = self.configuration.get_values(self.section)
69+
path = self.configuration.path.parent / "packmol.ini"
70+
if not path.exists():
71+
text = (self.resource_path / "packmol.ini").read_text()
72+
path.write_text(text)
73+
print(f" The packmol.ini file did not exist. Created {path}")
74+
75+
self.exe_config.path = path
76+
77+
# Get the current values
78+
data = self.exe_config.get_values("local")
79+
6280
if "conda-environment" in data and data["conda-environment"] != "":
6381
self.environment = data["conda-environment"]
6482
else:
6583
self.environment = "seamm-packmol"
6684

67-
# The environment.yaml file for Conda installations.
68-
path = Path(pkg_resources.resource_filename(__name__, "data/"))
69-
logger.debug(f"data directory: {path}")
70-
self.environment_file = path / "seamm-packmol.yml"
85+
super().check()
86+
87+
def install(self):
88+
"""Install Packmol in a conda environment."""
89+
print("Installing Packmol.")
90+
91+
# What Conda environment is the default?
92+
path = self.configuration.path.parent / "packmol.ini"
93+
if not path.exists():
94+
text = (self.resource_path / "packmol.ini").read_text()
95+
path.write_text(text)
96+
print(f" The packmol.ini file did not exist. Created {path}")
97+
98+
self.exe_config.path = path
99+
100+
# Get the current values
101+
data = self.exe_config.get_values("local")
102+
103+
if "conda-environment" in data and data["conda-environment"] != "":
104+
self.environment = data["conda-environment"]
105+
else:
106+
self.environment = "seamm-packmol"
107+
108+
super().install()
109+
110+
def show(self):
111+
"""Show the status of the Packmol installation."""
112+
print("Showing the Packmol installation.")
113+
114+
# What Conda environment is the default?
115+
path = self.configuration.path.parent / "packmol.ini"
116+
if not path.exists():
117+
text = (self.resource_path / "packmol.ini").read_text()
118+
path.write_text(text)
119+
print(f" The packmol.ini file does not exist at {path}")
120+
print(" The 'check' command will create it if Packmol is installed.")
121+
print(" Otherwise 'install' will install Packmol.")
122+
return
123+
124+
self.exe_config.path = path
125+
126+
if not self.exe_config.section_exists("local"):
127+
print(
128+
" Packmol is not configured: there is no 'local' section in "
129+
f" {path}."
130+
)
131+
return
132+
133+
# Get the current values
134+
data = self.exe_config.get_values("local")
135+
136+
if "conda-environment" in data and data["conda-environment"] != "":
137+
self.environment = data["conda-environment"]
138+
else:
139+
self.environment = "seamm-packmol"
71140

72-
def exe_version(self, path):
141+
super().show()
142+
143+
def uninstall(self):
144+
"""Uninstall the Packmol installation."""
145+
print("Uninstall the Packmol installation.")
146+
147+
# What Conda environment is the default?
148+
path = self.configuration.path.parent / "packmol.ini"
149+
if not path.exists():
150+
text = (self.resource_path / "packmol.ini").read_text()
151+
path.write_text(text)
152+
print(
153+
f"""" The packmol.ini file does not exist at {path}
154+
Perhaps Packmol is not installed, but if it is the 'check' command may locate it
155+
and create the ini file, after which 'uninstall' will remove it."""
156+
)
157+
return
158+
159+
self.exe_config.path = path
160+
161+
if not self.exe_config.section_exists("local"):
162+
print(
163+
f"""" The packmol.ini file at {path} does not have local section.
164+
Perhaps Packmol is not installed, but if it is the 'check' command may locate it
165+
and update the ini file, after which 'uninstall' will remove it."""
166+
)
167+
return
168+
169+
# Get the current values
170+
data = self.exe_config.get_values("local")
171+
172+
if "conda-environment" in data and data["conda-environment"] != "":
173+
self.environment = data["conda-environment"]
174+
else:
175+
self.environment = "seamm-packmol"
176+
177+
super().uninstall()
178+
179+
def update(self):
180+
"""Updates the Packmol installation."""
181+
print("Updating the Packmol installation.")
182+
183+
# What Conda environment is the default?
184+
path = self.configuration.path.parent / "packmol.ini"
185+
if not path.exists():
186+
text = (self.resource_path / "packmol.ini").read_text()
187+
path.write_text(text)
188+
print(f" The packmol.ini file did not exist. Created {path}")
189+
190+
self.exe_config.path = path
191+
192+
# Get the current values
193+
data = self.exe_config.get_values("local")
194+
195+
if "conda-environment" in data and data["conda-environment"] != "":
196+
self.environment = data["conda-environment"]
197+
else:
198+
self.environment = "seamm-packmol"
199+
200+
super().update()
201+
202+
def exe_version(self, config):
73203
"""Get the version of the PACKMOL executable.
74204
75205
Parameters
76206
----------
77-
path : pathlib.Path
78-
Path to the executable.
207+
config : dict
208+
Dictionary of options for running Packmol
79209
80210
Returns
81211
-------
82-
str
212+
"Packmol", str
83213
The version reported by the executable, or 'unknown'.
84214
"""
215+
environment = config["conda-environment"]
216+
conda = config["conda"]
217+
if environment[0] == "~":
218+
environment = str(Path(environment).expanduser())
219+
command = f"'{conda}' run --live-stream -p '{environment}'"
220+
elif Path(environment).is_absolute():
221+
command = f"'{conda}' run --live-stream -p '{environment}'"
222+
else:
223+
command = f"'{conda}' run --live-stream -n '{environment}'"
224+
command += " packmol -log none"
225+
226+
logger.debug(f" Running {command}")
85227
try:
86228
result = subprocess.run(
87-
[str(path), "-log", "none"],
229+
command,
88230
stdin=subprocess.DEVNULL,
89231
capture_output=True,
90232
text=True,
233+
shell=True,
91234
)
92235
except Exception:
93236
version = "unknown"
@@ -103,4 +246,4 @@ def exe_version(self, path):
103246
version = value
104247
break
105248

106-
return version
249+
return "Packmol", version

0 commit comments

Comments
 (0)