Skip to content

Commit a7600b4

Browse files
authored
Merge pull request #27 from xsuite/release/v0.4.3
Release 0.4.3
2 parents 60b6aff + d4daf53 commit a7600b4

File tree

8 files changed

+62
-27
lines changed

8 files changed

+62
-27
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ When the jobs are completed, the Xboinc server will store the results in your al
114114
```python
115115
import xboinc as xb
116116

117-
for job_name, result_particles in xb.JobRetriever.iterate("mycernshortname", "a_relevant_study_name", dev_server=True):
117+
for job_name, job_metadata, result_particles in xb.JobRetriever.iterate("mycernshortname", "a_relevant_study_name", dev_server=True):
118118
print(f"Job {job_name} completed with particles: {result_particles.to_dict()}")
119+
print(f"Job metadata: {job_metadata}")
119120

120121
```
121122

examples/results.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
list_of_succeeded_jobs = []
99
user='sixtadm'
1010
study_name='example_study'
11-
for jobname, new_particles in xb.JobRetriever(user=user, study_name=study_name, dev_server=True):
11+
for jobname, metadata, new_particles in xb.JobRetriever(user=user, study_name=study_name, dev_server=True):
1212
print(jobname)
13+
print(metadata)
1314
print(f"Particles: {new_particles.at_turn}")

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
[tool.poetry]
77
name = "xboinc"
8-
version = "0.4.2"
8+
version = "0.4.3"
99
description = "Xsuite BOINC interface"
1010
homepage = "https://github.com/xsuite/xboinc"
1111
repository = "https://github.com/xsuite/xboinc"

tests/test_03_submission_and_retrieval.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ def test_retrieval(registered_user):
358358
shutil.copy(tar_file, output_dir)
359359

360360
# Iterate through jobs and validate results
361-
for _, result_particles in xb.JobRetriever.iterate(
361+
for _, _, result_particles in xb.JobRetriever.iterate(
362362
"testuser", "example_study_fourth", dev_server=True
363363
):
364364
assert len(result_particles.x) == 100

tests/test_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
def test_version():
15-
assert __version__ == '0.4.2'
15+
assert __version__ == '0.4.3'
1616

1717

1818
def test_xb_ver():

xboinc/df_wu.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,23 +94,23 @@ def query_registered_work_units(
9494
return all_df
9595

9696

97-
def query_subscribed_users() -> list[str]:
97+
def query_subscribed_users() -> list[tuple[str, str]]:
9898
"""
99-
Get a list of all users subscribed to the work unit database.
99+
Get a list of all users subscribed to the work unit database with their status.
100100
101101
Returns
102102
-------
103-
list[str]
104-
List of usernames subscribed to the work unit database.
103+
list[tuple[str, str]]
104+
List of tuples containing (username, status) for users subscribed to the work unit database.
105105
"""
106106
with _get_read_only_user_db_connection() as conn:
107107
cursor = conn.cursor()
108-
cursor.execute("SELECT user FROM users")
109-
users = [row[0] for row in cursor.fetchall()]
108+
cursor.execute("SELECT user, status FROM users")
109+
users = [(row[0], row[1]) for row in cursor.fetchall()]
110110
return users
111111

112112

113-
def check_user_subscription(user: str) -> bool:
113+
def check_user_subscription(user: str) -> str:
114114
"""
115115
Check if a user is subscribed to the work unit database.
116116
@@ -121,7 +121,12 @@ def check_user_subscription(user: str) -> bool:
121121
122122
Returns
123123
-------
124-
bool
125-
True if the user is subscribed, False otherwise.
124+
str
125+
The status of the user if subscribed, "not_subscribed" otherwise,
126+
"broken" if the user's directory is invalid.
126127
"""
127-
return user in query_subscribed_users()
128+
users = query_subscribed_users()
129+
for u, status in users:
130+
if u == user:
131+
return status
132+
return "not_subscribed"

xboinc/general.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# Do not change
1313
# ==============================================================================
1414

15-
__version__ = '0.4.2'
15+
__version__ = '0.4.3'
1616

1717
# These are the xsuite modules that are used by boinc and the versions they are
1818
# tied to. This will be automatically updated from the active environment when

xboinc/retrieve.py

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,22 @@ def _index_results(self, path: FsPath, silent: bool = False) -> pd.DataFrame:
104104
job_name = parts[2]
105105
wu_name = bin_file.name.replace(".bin", "")
106106
# append to the DataFrame
107-
new_row = pd.DataFrame([{
108-
"user": user,
109-
"study_name": study_name,
110-
"job_name": job_name,
111-
"wu_name": wu_name,
112-
"bin_file": bin_file,
113-
}])
107+
new_row = pd.DataFrame(
108+
[
109+
{
110+
"user": user,
111+
"study_name": study_name,
112+
"job_name": job_name,
113+
"wu_name": wu_name,
114+
"bin_file": bin_file,
115+
"json_file": bin_file.with_name(
116+
bin_file.name.replace(
117+
"__file_xboinc_state_out.bin", ".json"
118+
)
119+
),
120+
}
121+
]
122+
)
114123
df = pd.concat([df, new_row], ignore_index=True)
115124
return df
116125

@@ -299,8 +308,8 @@ def iterate_results(self, study_name):
299308
300309
Yields
301310
------
302-
tuple of (str, xpart.Particles)
303-
Job name and corresponding particles object for each result
311+
tuple of (str, dict, xpart.Particles)
312+
Job name, corresponding metadata, and particles object for each result
304313
305314
Raises
306315
------
@@ -324,6 +333,7 @@ def iterate_results(self, study_name):
324333
for row in self._df[self._df["study_name"] == study_name].itertuples():
325334
job_name = row.job_name
326335
bin_file = row.bin_file
336+
json_file = row.json_file
327337
result = XbState.from_binary(bin_file, raise_version_error=False)
328338
if result is None:
329339
warn(
@@ -332,7 +342,22 @@ def iterate_results(self, study_name):
332342
UserWarning,
333343
)
334344
continue
335-
yield job_name, result.particles
345+
try:
346+
with open(json_file, "r") as f:
347+
metadata = json.load(f)
348+
# is metadata an empty dict?
349+
if not metadata:
350+
warn(
351+
f"Warning: The JSON file {json_file} is empty.",
352+
UserWarning,
353+
)
354+
except FileNotFoundError:
355+
warn(
356+
f"Warning: The JSON file {json_file} was not found.",
357+
UserWarning,
358+
)
359+
metadata = {}
360+
yield job_name, metadata, result.particles
336361

337362
def clean(self, study_name):
338363
"""
@@ -362,6 +387,9 @@ def clean(self, study_name):
362387
bin_file = row.bin_file
363388
if bin_file.exists():
364389
bin_file.unlink()
390+
json_file = row.json_file
391+
if json_file.exists():
392+
json_file.unlink()
365393
# Remove empty directories
366394
for folder in self._directory.glob("*/"):
367395
if not any(folder.iterdir()):
@@ -487,4 +515,4 @@ def study_list(cls, user, dev_server=False, silent=False):
487515
>>> print(studies)
488516
"""
489517
instance = cls(user, dev_server=dev_server, silent=silent)
490-
return instance.get_study_list()
518+
return instance.get_study_list()

0 commit comments

Comments
 (0)