From 4dc75a25d53d16df9e9688c182bbe7b779306766 Mon Sep 17 00:00:00 2001 From: Rohan Girish Date: Wed, 16 Sep 2026 17:16:28 +0200 Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=9A=AE=20Remove=20TODO=20as=20the=20b?= =?UTF-8?q?lock=20was=20tested=20in=20Fiji?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imcflibs/imagej/misc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/imcflibs/imagej/misc.py b/src/imcflibs/imagej/misc.py index 045301db..131e0297 100644 --- a/src/imcflibs/imagej/misc.py +++ b/src/imcflibs/imagej/misc.py @@ -855,7 +855,6 @@ def save_script_parameters( passwords += 1 continue - # TODO: discuss if this approach is fine within Fiji/Jython try: val = inputs.get(key) if val is None: # required for testing in CPython From 08bcc7f10da459b05c93dd51478dd8a61acf5f42 Mon Sep 17 00:00:00 2001 From: Rohan Girish Date: Wed, 16 Sep 2026 17:17:26 +0200 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=93=9D=20Rewrite=20to=20numbered=20li?= =?UTF-8?q?sting=20for=20consistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/imcflibs/imagej/misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imcflibs/imagej/misc.py b/src/imcflibs/imagej/misc.py index 131e0297..92d7f0e1 100644 --- a/src/imcflibs/imagej/misc.py +++ b/src/imcflibs/imagej/misc.py @@ -830,7 +830,7 @@ def save_script_parameters( return # NOTE: the two parameters are intentionally kept separate for (1) consistency - # reasons with other scripts and (b) as this allows for easier modification of just + # reasons with other scripts and (2) as this allows for easier modification of just # the output file e.g. in subsequent runs. destination = str(destination) out_path = os.path.join(destination, save_file_name) From 93cdb3023bdf46735c439111358d3c0397484fd6 Mon Sep 17 00:00:00 2001 From: Rohan Girish Date: Thu, 17 Sep 2026 11:58:03 +0200 Subject: [PATCH 3/7] =?UTF-8?q?=E2=9C=A8=20Implement=20auto-generated=20fi?= =?UTF-8?q?lename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The parameters file is now timestamped and has the name of the script as a prefix. An additional overwrite option is also present, so that the same file can be overwritten while testing. --- src/imcflibs/imagej/misc.py | 44 +++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/imcflibs/imagej/misc.py b/src/imcflibs/imagej/misc.py index 92d7f0e1..36e1a0a6 100644 --- a/src/imcflibs/imagej/misc.py +++ b/src/imcflibs/imagej/misc.py @@ -784,9 +784,7 @@ def _is_password_style(item): # pragma: no cover (jython) return WidgetStyle.isStyle(item, TextWidget.PASSWORD_STYLE) -def save_script_parameters( - script_globals, destination, save_file_name="script_parameters.txt" -): +def save_script_parameters(script_globals, destination="", overwrite=False): """Save all Fiji script parameters to a text file. Record all input parameters defined in the Fiji script header (e.g. @@ -794,6 +792,9 @@ def save_script_parameters( input data and the analysis results in order to document how a specific processing run was executed. + The file name is generated automatically following the pattern + ``_run-_params.txt``. + The following parameters are excluded: - Parameters explicitly declared with `style="password"`. @@ -808,30 +809,49 @@ def save_script_parameters( script_globals : dict The globals dictionary from the running Fiji instance. Must be passed explicitly as `globals()` by the calling code. - destination : str - Directory where the script parameters file will be saved. - save_file_name : str, optional - Name of the script parameters file, by default "script_parameters.txt". + destination : str, optional + Directory where the script parameters file will be saved. If empty + (the default), parameter saving is skipped. + overwrite : bool, optional + If True, use a fixed filename ``_params.txt`` that gets + overwritten on each run. If False (the default), a timestamp is + included in the filename to preserve parameters from each run. Examples -------- In a Fiji script, you can call this function as follows to save the parameters: >>> save_script_parameters(script_globals=globals(), destination="/data") - Saved script parameters to: /data/script_parameters.txt + Saved 2 script parameters to: /data/example1_run-2026-04-10--10-41_params.txt """ + if destination == "": + timed_log("No destination provided for saving script parameters - skipping.") + return + try: module = script_globals.get("org.scijava.script.ScriptModule") - # Access script metadata and inputs script_info = module.getInfo() inputs = module.getInputs() except: timed_log("ScriptModule inspection failed - skipping saving of parameters.") return - # NOTE: the two parameters are intentionally kept separate for (1) consistency - # reasons with other scripts and (2) as this allows for easier modification of just - # the output file e.g. in subsequent runs. + script_location = script_info.getLocation() + if script_location: + # getLocation() returns "file:/path/to/script.py" + # strip the "file:" prefix to get the actual path + if script_location.startswith("file:"): + script_location = script_location[5:] + script_name = os.path.splitext(os.path.basename(script_location))[0] + else: + script_name = "script" + + if overwrite: + save_file_name = "%s_params.txt" % script_name + else: + timestamp = time.strftime("%Y-%m-%d--%H-%M") + save_file_name = "%s_run-%s_params.txt" % (script_name, timestamp) + destination = str(destination) out_path = os.path.join(destination, save_file_name) From 7e29b942f7a7185e36ea9783e80ad9b43880e559 Mon Sep 17 00:00:00 2001 From: Rohan Girish Date: Wed, 30 Sep 2026 14:12:06 +0200 Subject: [PATCH 4/7] =?UTF-8?q?=E2=9C=85=20Update=20save=5Fscript=5Fparame?= =?UTF-8?q?ters=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Destination is now optimal, so the test has to reflect this --- tests/test_misc.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_misc.py b/tests/test_misc.py index 9f137cb7..7645a0aa 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -13,11 +13,19 @@ PASSWORD_ITEMS = ["OMERO_PASSWD"] -def test_save_script_parameters_fail(caplog): +def test_save_script_parameters_no_destination(caplog): + """Tests save_script_parameters skips saving without a destination.""" + caplog.clear() + + save_script_parameters(script_globals=None) + assert "No destination provided" in caplog.messages[0] + + +def test_save_script_parameters_fail(tmp_path, caplog): """Tests save_script_parameters with an invalid script_globals object.""" caplog.clear() - save_script_parameters(script_globals=None, destination="") + save_script_parameters(script_globals=None, destination=tmp_path) assert "ScriptModule inspection failed" in caplog.messages[0] From 1f53a6633271d77cfb21c7f241158ff9a00e8e70 Mon Sep 17 00:00:00 2001 From: Rohan Girish Date: Wed, 30 Sep 2026 14:17:32 +0200 Subject: [PATCH 5/7] =?UTF-8?q?=E2=9C=85=20Adapt=20save=5Fscript=5Fparamet?= =?UTF-8?q?ers=20test=20to=20generated=20filename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_misc.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_misc.py b/tests/test_misc.py index 7645a0aa..c1aa4f37 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -45,16 +45,17 @@ def _is_password_style(item): script_module = ScriptModule( input_names=["AAA", "BBB", "OMERO_PASSWD", "SJLOG", "NOT_THERE"], inputs={"AAA": "aaa", "BBB": "bbb", "OMERO_PASSWD": "ultra-secret"}, + location="file:/some/path/example1.py", ) script_globals = {"org.scijava.script.ScriptModule": script_module} - save_script_parameters(script_globals, destination=base) + save_script_parameters(script_globals, destination=base, overwrite=True) assert "Skipping parameter from skip-list" in caplog.text assert "Skipping password-style parameter" in caplog.text assert "Unable to fetch value for parameter: NOT_THERE" in caplog.text assert "Saved 2 parameters (skipped 1 password-style and 1 others)." in caplog.text assert "Saved 2 script parameters to" in caplog.text - with open(str(base) + "/script_parameters.txt", "r") as f: + with open(str(base) + "/example1_params.txt", "r") as f: contents = f.read() assert contents == "AAA: aaa\nBBB: bbb\n" From 9b5dfff8072a3bf092f5e83eb5fae00749d1afe2 Mon Sep 17 00:00:00 2001 From: Rohan Girish Date: Thu, 15 Oct 2026 09:13:01 +0200 Subject: [PATCH 6/7] =?UTF-8?q?=E2=9C=85=20Set=20script=20location=20via?= =?UTF-8?q?=20ScriptInfo=20mock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_misc.py b/tests/test_misc.py index c1aa4f37..2f2686a8 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -45,8 +45,8 @@ def _is_password_style(item): script_module = ScriptModule( input_names=["AAA", "BBB", "OMERO_PASSWD", "SJLOG", "NOT_THERE"], inputs={"AAA": "aaa", "BBB": "bbb", "OMERO_PASSWD": "ultra-secret"}, - location="file:/some/path/example1.py", ) + script_module.getInfo().location = "file:/some/path/example1.py" script_globals = {"org.scijava.script.ScriptModule": script_module} save_script_parameters(script_globals, destination=base, overwrite=True) assert "Skipping parameter from skip-list" in caplog.text From 28f1c32d8363d2d52528979f5566904ba52c793f Mon Sep 17 00:00:00 2001 From: Rohan Girish Date: Thu, 15 Oct 2026 09:41:30 +0200 Subject: [PATCH 7/7] =?UTF-8?q?=E2=9C=85=20Add=20test=20for=20timestamped?= =?UTF-8?q?=20filename?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_misc.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/test_misc.py b/tests/test_misc.py index 2f2686a8..81266bf0 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -1,6 +1,7 @@ """Tests for `imcflibs.imagej.misc` utility functions.""" import logging +import os from org.scijava.script import ScriptInfo, ScriptModule @@ -9,7 +10,6 @@ from imcflibs.imagej.misc import bytes_to_human_readable from imcflibs.imagej.misc import save_script_parameters - PASSWORD_ITEMS = ["OMERO_PASSWD"] @@ -60,6 +60,31 @@ def _is_password_style(item): assert contents == "AAA: aaa\nBBB: bbb\n" +def test_save_script_parameters_timestamped(tmp_path, monkeypatch): + """Tests save_script_parameters default naming without a script location.""" + + def _is_password_style(item): + return False + + monkeypatch.setattr(imcflibs.imagej.misc, "_is_password_style", _is_password_style) + + script_module = ScriptModule(input_names=["AAA"], inputs={"AAA": "aaa"}) + script_globals = {"org.scijava.script.ScriptModule": script_module} + save_script_parameters(script_globals, destination=tmp_path) + + # the folder should now contain exactly one file + files = os.listdir(str(tmp_path)) + assert len(files) == 1 + + # its name is "script_run-_params.txt" + file_name = files[0] + assert file_name.startswith("script_run-") + assert file_name.endswith("_params.txt") + + with open(os.path.join(str(tmp_path), file_name), "r") as f: + assert f.read() == "AAA: aaa\n" + + def test_bytes_to_human_readable_simple(): """Ensure common sizes are formatted into human-readable strings.""" assert bytes_to_human_readable(500) == "500.0 bytes"