From 1e402f1aaecf1b3c6de04e7c9e67ff53f70ab9df Mon Sep 17 00:00:00 2001 From: Tom Close Date: Thu, 17 Oct 2024 12:36:01 +1100 Subject: [PATCH 1/3] added type annotation --- xnat_ingest/store.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xnat_ingest/store.py b/xnat_ingest/store.py index 288afe7..5972dad 100644 --- a/xnat_ingest/store.py +++ b/xnat_ingest/store.py @@ -91,7 +91,7 @@ def create_data_tree( id: str, leaves: ty.List[ty.Tuple[str, ...]], hierarchy: ty.List[str], - axes: type, + axes: ty.Type[Axes], **kwargs: ty.Any, ) -> DataTree: raise NotImplementedError From c0ecb7ebeee13e8ce161e13487963eb0339c4591 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Thu, 17 Oct 2024 12:36:01 +1100 Subject: [PATCH 2/3] check for loop is not none --- xnat_ingest/cli/stage.py | 2 +- xnat_ingest/cli/upload.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xnat_ingest/cli/stage.py b/xnat_ingest/cli/stage.py index ce11f53..08ee319 100644 --- a/xnat_ingest/cli/stage.py +++ b/xnat_ingest/cli/stage.py @@ -383,7 +383,7 @@ def do_stage() -> None: else: raise - if loop: + if loop is not None: while True: start_time = datetime.datetime.now() do_stage() diff --git a/xnat_ingest/cli/upload.py b/xnat_ingest/cli/upload.py index 7526b2f..12cbceb 100644 --- a/xnat_ingest/cli/upload.py +++ b/xnat_ingest/cli/upload.py @@ -416,7 +416,7 @@ def do_upload() -> None: else: assert False - if loop: + if loop is not None: while True: start_time = datetime.datetime.now() do_upload() From 376d774f46ec6d043d6421418468b4ff955c5227 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Tue, 22 Oct 2024 17:18:43 +1100 Subject: [PATCH 3/3] added run uid to session to disambiguate from sessions from different runs --- xnat_ingest/session.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/xnat_ingest/session.py b/xnat_ingest/session.py index 2953237..ebc3bfc 100644 --- a/xnat_ingest/session.py +++ b/xnat_ingest/session.py @@ -4,6 +4,8 @@ import logging from functools import cached_property import random +import hashlib +from datetime import datetime import string from itertools import chain from collections import defaultdict, Counter @@ -44,6 +46,7 @@ class ImagingSession: converter=scans_converter, validator=attrs.validators.instance_of(dict), ) + run_uid: ty.Optional[str] = attrs.field(default=None) def __attrs_post_init__(self) -> None: for scan in self.scans.values(): @@ -296,6 +299,16 @@ def from_paths( else: fspaths = [Path(p) for p in glob(files_path, recursive=True)] + # Create a UID out of the paths that session was created from and the + # timestamp + crypto = hashlib.sha256() + for fspath in fspaths: + crypto.update(str(fspath.absolute()).encode()) + run_uid: str = crypto.hexdigest()[:6] + datetime.strftime( + datetime.now(), + "%Y%m%d%H%M%S", + ) + from_paths_kwargs = {} if datatypes is DicomSeries: from_paths_kwargs["specific_tags"] = [ @@ -387,6 +400,7 @@ def get_id(field_type: str, field_name: str) -> str: project_id=project_id, subject_id=subject_id, visit_id=visit_id, + run_uid=run_uid, ) sessions[session_uid] = session else: @@ -594,11 +608,17 @@ def load( ImagingSession the loaded session """ - project_id, subject_id, visit_id = session_dir.name.split("-") + parts = session_dir.name.split("-") + if len(parts) == 4: + project_id, subject_id, visit_id, run_uid = parts + else: + project_id, subject_id, visit_id = parts + run_uid = None session = cls( project_id=project_id, subject_id=subject_id, visit_id=visit_id, + run_uid=run_uid, ) for scan_dir in session_dir.iterdir(): if scan_dir.is_dir(): @@ -661,7 +681,10 @@ def save( project_id = self.project_id else: project_id = "INVALID_UNRECOGNISED_" + self.project_id - session_dir = dest_dir / "-".join((project_id, self.subject_id, self.visit_id)) + session_dirname = "-".join((project_id, self.subject_id, self.visit_id)) + if self.run_uid: + session_dirname += f"-{self.run_uid}" + session_dir = dest_dir / session_dirname session_dir.mkdir(parents=True, exist_ok=True) for scan in tqdm(self.scans.values(), f"Staging sessions to {session_dir}"): saved_scan = scan.save(session_dir, copy_mode=copy_mode)