From 45cb9c14fcd0b71dc20f57b96178471622d6ccdd Mon Sep 17 00:00:00 2001 From: ssjunnebo Date: Mon, 19 Jan 2026 14:27:59 +0100 Subject: [PATCH 1/6] Add new MiSeqi100 --- dataflow_transfer/run_classes/__init__.py | 1 + dataflow_transfer/run_classes/illumina_runs.py | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/dataflow_transfer/run_classes/__init__.py b/dataflow_transfer/run_classes/__init__.py index 705c5c7..ffb1215 100644 --- a/dataflow_transfer/run_classes/__init__.py +++ b/dataflow_transfer/run_classes/__init__.py @@ -5,6 +5,7 @@ MiSeqRun, # noqa: F401 NextSeqRun, # noqa: F401 NovaSeqXPlusRun, # noqa: F401 + MiSeqi100Run, # noqa: F401 ) from dataflow_transfer.run_classes.ont_runs import MinIONRun, PromethIONRun # noqa: F401 diff --git a/dataflow_transfer/run_classes/illumina_runs.py b/dataflow_transfer/run_classes/illumina_runs.py index b74bb4c..686c88b 100644 --- a/dataflow_transfer/run_classes/illumina_runs.py +++ b/dataflow_transfer/run_classes/illumina_runs.py @@ -49,3 +49,16 @@ def __init__(self, run_dir, configuration): "^\d{6}_[A-Z0-9]+_\d{4}_[A-Z0-9\-]+$" # 251015_M01548_0646_000000000-M6D7K ) super().__init__(run_dir, configuration) + + +@register_run_class +class MiSeqi100Run(IlluminaRun): + """Defines a MiSeqi100 sequencing run""" + + run_type = "MiSeqi100" + + def __init__(self, run_dir, configuration): + self.run_id_format = ( + "^\d{6}_[A-Z0-9]+_\d{4}_[A-Z0-9\-]+$" # TODO: Need to update this + ) + super().__init__(run_dir, configuration) From a2320ddbbfaf817ab2e8e3fa15474892298249b3 Mon Sep 17 00:00:00 2001 From: ssjunnebo Date: Mon, 19 Jan 2026 14:29:30 +0100 Subject: [PATCH 2/6] Make regex patterns raw strings to avoid deprecation warnings --- dataflow_transfer/run_classes/element_runs.py | 2 +- dataflow_transfer/run_classes/illumina_runs.py | 8 ++++---- dataflow_transfer/run_classes/ont_runs.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dataflow_transfer/run_classes/element_runs.py b/dataflow_transfer/run_classes/element_runs.py index 97f448e..a3ea109 100644 --- a/dataflow_transfer/run_classes/element_runs.py +++ b/dataflow_transfer/run_classes/element_runs.py @@ -22,6 +22,6 @@ class AVITIRun(ElementRun): def __init__(self, run_dir, configuration): self.run_id_format = ( - "^\d{8}_AV\d{6}_(A|BP)\d{10}$" # 20251007_AV242106_A2507535225 + r"^\d{8}_AV\d{6}_(A|BP)\d{10}$" # 20251007_AV242106_A2507535225 ) super().__init__(run_dir, configuration) diff --git a/dataflow_transfer/run_classes/illumina_runs.py b/dataflow_transfer/run_classes/illumina_runs.py index 686c88b..397a0a5 100644 --- a/dataflow_transfer/run_classes/illumina_runs.py +++ b/dataflow_transfer/run_classes/illumina_runs.py @@ -20,7 +20,7 @@ class NovaSeqXPlusRun(IlluminaRun): def __init__(self, run_dir, configuration): self.run_id_format = ( - "^\d{8}_[A-Z0-9]+_\d{4}_[A-Z0-9]+$" # 20251010_LH00202_0284_B22CVHTLT1 + r"^\d{8}_[A-Z0-9]+_\d{4}_[A-Z0-9]+$" # 20251010_LH00202_0284_B22CVHTLT1 ) super().__init__(run_dir, configuration) @@ -33,7 +33,7 @@ class NextSeqRun(IlluminaRun): def __init__(self, run_dir, configuration): self.run_id_format = ( - "^\d{6}_[A-Z0-9]+_\d{3}_[A-Z0-9]+$" # 251015_VH00203_572_AAHFHCCM5 + r"^\d{6}_[A-Z0-9]+_\d{3}_[A-Z0-9]+$" # 251015_VH00203_572_AAHFHCCM5 ) super().__init__(run_dir, configuration) @@ -46,7 +46,7 @@ class MiSeqRun(IlluminaRun): def __init__(self, run_dir, configuration): self.run_id_format = ( - "^\d{6}_[A-Z0-9]+_\d{4}_[A-Z0-9\-]+$" # 251015_M01548_0646_000000000-M6D7K + r"^\d{6}_[A-Z0-9]+_\d{4}_[A-Z0-9\-]+$" # 251015_M01548_0646_000000000-M6D7K ) super().__init__(run_dir, configuration) @@ -59,6 +59,6 @@ class MiSeqi100Run(IlluminaRun): def __init__(self, run_dir, configuration): self.run_id_format = ( - "^\d{6}_[A-Z0-9]+_\d{4}_[A-Z0-9\-]+$" # TODO: Need to update this + r"^\d{6}_[A-Z0-9]+_\d{4}_[A-Z0-9\-]+$" # TODO: Need to update this ) super().__init__(run_dir, configuration) diff --git a/dataflow_transfer/run_classes/ont_runs.py b/dataflow_transfer/run_classes/ont_runs.py index dfd11d7..243b685 100644 --- a/dataflow_transfer/run_classes/ont_runs.py +++ b/dataflow_transfer/run_classes/ont_runs.py @@ -19,7 +19,7 @@ class PromethIONRun(ONTRun): run_type = "PromethION" def __init__(self, run_dir, configuration): - self.run_id_format = "^\d{8}_\d{4}_[A-Z0-9]{2}_P[A-Z0-9]+_[a-f0-9]{8}$" # 20251015_1051_3B_PBG60686_0af3a2e0 + self.run_id_format = r"^\d{8}_\d{4}_[A-Z0-9]{2}_P[A-Z0-9]+_[a-f0-9]{8}$" # 20251015_1051_3B_PBG60686_0af3a2e0 super().__init__(run_dir, configuration) @@ -30,5 +30,5 @@ class MinIONRun(ONTRun): run_type = "MinION" def __init__(self, run_dir, configuration): - self.run_id_format = "^\d{8}_\d{4}_MN[A-Z0-9]+_[A-Z0-9]+_[a-f0-9]{8}$" # 20240229_1404_MN19414_ASH657_7a74bf8f + self.run_id_format = r"^\d{8}_\d{4}_MN[A-Z0-9]+_[A-Z0-9]+_[a-f0-9]{8}$" # 20240229_1404_MN19414_ASH657_7a74bf8f super().__init__(run_dir, configuration) From 34b5e315a6e2203940daff98ed4537ba4277f7e3 Mon Sep 17 00:00:00 2001 From: ssjunnebo Date: Mon, 2 Feb 2026 15:42:21 +0100 Subject: [PATCH 3/6] Make a regex for MiSeqi100 --- dataflow_transfer/run_classes/illumina_runs.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dataflow_transfer/run_classes/illumina_runs.py b/dataflow_transfer/run_classes/illumina_runs.py index 397a0a5..21468fa 100644 --- a/dataflow_transfer/run_classes/illumina_runs.py +++ b/dataflow_transfer/run_classes/illumina_runs.py @@ -58,7 +58,5 @@ class MiSeqi100Run(IlluminaRun): run_type = "MiSeqi100" def __init__(self, run_dir, configuration): - self.run_id_format = ( - r"^\d{6}_[A-Z0-9]+_\d{4}_[A-Z0-9\-]+$" # TODO: Need to update this - ) + self.run_id_format = r"^\d{8}_[A-Z0-9]+_\d{4}_[A-Z0-9]+-[A-Z0-9]+$" # 20260128_SH01140_0002_ASC2150561-SC3 super().__init__(run_dir, configuration) From 7d774761e009ccce89aa496d51df4134a0207476 Mon Sep 17 00:00:00 2001 From: ssjunnebo Date: Tue, 3 Feb 2026 09:41:45 +0100 Subject: [PATCH 4/6] Add tests for MiSeqi100 --- dataflow_transfer/tests/test_run_classes.py | 56 +++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/dataflow_transfer/tests/test_run_classes.py b/dataflow_transfer/tests/test_run_classes.py index 8f46a92..09457fe 100644 --- a/dataflow_transfer/tests/test_run_classes.py +++ b/dataflow_transfer/tests/test_run_classes.py @@ -85,6 +85,32 @@ def miseqseq_testobj(tmp_path): return illumina_runs.MiSeqRun(str(run_dir), config) +@pytest.fixture +def miseqseqi100_testobj(tmp_path): + config = { + "log": {"file": "test.log"}, + "transfer_details": {"user": "testuser", "host": "testhost"}, + "statusdb": { + "username": "dbuser", + "password": "dbpass", + "url:": "dburl", + "database": "dbname", + }, + "sequencers": { + "MiSeqi100": { + "miarka_destination": "/data/MiSeqi100", + "metadata_for_statusdb": ["RunInfo.xml", "RunParameters.xml"], + "ignore_folders": ["nosync"], + "rsync_options": ["--chmod=Dg+s,g+rw"], + } + }, + } + run_id = "20260128_SH01140_0002_ASC2150561-SC3" + run_dir = tmp_path / run_id + run_dir.mkdir() + return illumina_runs.MiSeqi100Run(str(run_dir), config) + + @pytest.fixture(autouse=True) def mock_statusdbsession(monkeypatch): class MockStatusdbSession: @@ -106,6 +132,7 @@ def update_db_doc(self, doc): ("novaseqxplus_testobj", "NovaSeqXPlus"), ("nextseq_testobj", "NextSeq"), ("miseqseq_testobj", "MiSeq"), + ("miseqseqi100_testobj", "MiSeqi100"), ], ) def test_confirm_run_type(run_fixture, expected_run_type, request): @@ -124,6 +151,7 @@ def test_confirm_run_type(run_fixture, expected_run_type, request): "novaseqxplus_testobj", "nextseq_testobj", "miseqseq_testobj", + "miseqseqi100_testobj", ], ) def test_sequencing_ongoing(run_fixture, request): @@ -146,6 +174,8 @@ def test_sequencing_ongoing(run_fixture, request): ("nextseq_testobj", True), ("miseqseq_testobj", False), ("miseqseq_testobj", True), + ("miseqseqi100_testobj", False), + ("miseqseqi100_testobj", True), ], ) def test_generate_rsync_command(run_fixture, final_sync, request): @@ -174,6 +204,10 @@ def test_generate_rsync_command(run_fixture, final_sync, request): ("miseqseq_testobj", True, False), ("miseqseq_testobj", False, True), ("miseqseq_testobj", True, True), + ("miseqseqi100_testobj", False, False), + ("miseqseqi100_testobj", True, False), + ("miseqseqi100_testobj", False, True), + ("miseqseqi100_testobj", True, True), ], ) def test_start_transfer(run_fixture, rsync_running, final, request, monkeypatch): @@ -219,6 +253,8 @@ def mock_update_statusdb(status, additional_info=None): ("nextseq_testobj", False), ("miseqseq_testobj", True), ("miseqseq_testobj", False), + ("miseqseqi100_testobj", True), + ("miseqseqi100_testobj", False), ], ) def test_final_sync_successful(run_fixture, sync_successful, request): @@ -249,6 +285,10 @@ def test_final_sync_successful(run_fixture, sync_successful, request): ("miseqseq_testobj", "sequencing_started", True), ("miseqseq_testobj", "sequencing_finished", False), ("miseqseq_testobj", "sequencing_finished", True), + ("miseqseqi100_testobj", "sequencing_started", False), + ("miseqseqi100_testobj", "sequencing_started", True), + ("miseqseqi100_testobj", "sequencing_finished", False), + ("miseqseqi100_testobj", "sequencing_finished", True), ], ) def test_has_status(run_fixture, status_to_check, expected_result, request): @@ -268,6 +308,12 @@ def get_events(self, run_id): @pytest.mark.parametrize( "run_fixture, existing_statuses, status_to_update", [ + ("novaseqxplus_testobj", [], "sequencing_started"), + ( + "novaseqxplus_testobj", + [{"event_type": "sequencing_started"}], + "transfer_started", + ), ( "nextseq_testobj", [], @@ -288,6 +334,16 @@ def get_events(self, run_id): [{"event_type": "sequencing_started"}], "transfer_started", ), + ( + "miseqseqi100_testobj", + [], + "sequencing_started", + ), + ( + "miseqseqi100_testobj", + [{"event_type": "sequencing_started"}], + "transfer_started", + ), ], ) def test_update_statusdb( From 93feabc7c60977a41141921844b1edbb1137d383 Mon Sep 17 00:00:00 2001 From: ssjunnebo Date: Tue, 3 Feb 2026 09:42:22 +0100 Subject: [PATCH 5/6] Bump version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 88ed6df..e8b5d7b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ ignore = [ [project] name = "dataflow_transfer" -version = "1.0.4" +version = "1.0.5" description = "Script for transferring sequencing data from sequencers to storage" authors = [ { name = "Sara Sjunnebo", email = "sara.sjunnebo@scilifelab.se" }, From 13e553a27afa65818b052807d62d3e0885012c4e Mon Sep 17 00:00:00 2001 From: ssjunnebo Date: Tue, 3 Feb 2026 16:40:55 +0100 Subject: [PATCH 6/6] Update MiSeqi100 run ID format --- dataflow_transfer/run_classes/illumina_runs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataflow_transfer/run_classes/illumina_runs.py b/dataflow_transfer/run_classes/illumina_runs.py index 21468fa..3e35acb 100644 --- a/dataflow_transfer/run_classes/illumina_runs.py +++ b/dataflow_transfer/run_classes/illumina_runs.py @@ -58,5 +58,5 @@ class MiSeqi100Run(IlluminaRun): run_type = "MiSeqi100" def __init__(self, run_dir, configuration): - self.run_id_format = r"^\d{8}_[A-Z0-9]+_\d{4}_[A-Z0-9]+-[A-Z0-9]+$" # 20260128_SH01140_0002_ASC2150561-SC3 + self.run_id_format = r"^\d{8}_[A-Z0-9]+_\d{4}_[A-Z0-9]{10}-SC3$" # 20260128_SH01140_0002_ASC2150561-SC3 super().__init__(run_dir, configuration)