@@ -766,3 +766,110 @@ def bytes_to_human_readable(size):
766766 # If the value is larger than the largest unit, fall back to TB with
767767 # the current value (already divided accordingly).
768768 return "%3.1f %s" % (size , "TB" )
769+
770+
771+ def _is_password_style (item ): # pragma: no cover (jython)
772+ """Check if a script-parameter item is declared with `style="password"`.
773+
774+ Parameters
775+ ----------
776+ item : org.scijava.module.ModuleItem
777+ The module item to check, obtained e.g. by calling `inputs()` on an
778+ instance of `org.scijava.script.ScriptInfo`.
779+
780+ Returns
781+ -------
782+ bool
783+ """
784+ return WidgetStyle .isStyle (item , TextWidget .PASSWORD_STYLE )
785+
786+
787+ def save_script_parameters (
788+ script_globals , destination , save_file_name = "script_parameters.txt"
789+ ):
790+ """Save all Fiji script parameters to a text file.
791+
792+ Record all input parameters defined in the Fiji script header (e.g.
793+ `#@ String`) to a text file such that they can be stored e.g. next to the
794+ input data and the analysis results in order to document how a specific
795+ processing run was executed.
796+
797+ The following parameters are excluded:
798+
799+ - Parameters explicitly declared with `style="password"`.
800+ - Runtime keys (case insensitive):
801+ - `USERNAME`
802+ - `SJLOG` (SciJava LogService)
803+ - `COMMAND` (SciJava CommandService)
804+ - `RM` (RoiManager)
805+
806+ Parameters
807+ ----------
808+ script_globals : dict
809+ The globals dictionary from the running Fiji instance. Must be passed
810+ explicitly as `globals()` by the calling code.
811+ destination : str
812+ Directory where the script parameters file will be saved.
813+ save_file_name : str, optional
814+ Name of the script parameters file, by default "script_parameters.txt".
815+
816+ Examples
817+ --------
818+ In a Fiji script, you can call this function as follows to save the parameters:
819+
820+ >>> save_script_parameters(script_globals=globals(), destination="/data")
821+ Saved script parameters to: /data/script_parameters.txt
822+ """
823+ try :
824+ module = script_globals .get ("org.scijava.script.ScriptModule" )
825+ # Access script metadata and inputs
826+ script_info = module .getInfo ()
827+ inputs = module .getInputs ()
828+ except :
829+ timed_log ("ScriptModule inspection failed - skipping saving of parameters." )
830+ return
831+
832+ # NOTE: the two parameters are intentionally kept separate for (1) consistency
833+ # reasons with other scripts and (b) as this allows for easier modification of just
834+ # the output file e.g. in subsequent runs.
835+ destination = str (destination )
836+ out_path = os .path .join (destination , save_file_name )
837+
838+ # Keys to skip explicitly
839+ skip_keys = ["USERNAME" , "SJLOG" , "COMMAND" , "RM" ]
840+
841+ saved = skipped = passwords = 0
842+ with open (out_path , "w" ) as f :
843+ for item in script_info .inputs ():
844+ key = item .getName ()
845+
846+ # Skip if any keys are in the skip list
847+ if any (skip in key .upper () for skip in skip_keys ):
848+ log .info ("Skipping parameter from skip-list: %s" , key )
849+ skipped += 1
850+ continue
851+
852+ # Skip if parameter is declared with password style
853+ if _is_password_style (item ):
854+ log .info ("Skipping password-style parameter: %s" , key )
855+ passwords += 1
856+ continue
857+
858+ # TODO: discuss if this approach is fine within Fiji/Jython
859+ try :
860+ val = inputs .get (key )
861+ if val is None : # required for testing in CPython
862+ raise KeyError ("failure looking up value for '%s'" % key )
863+ f .write ("%s: %s\n " % (key , str (val )))
864+ saved += 1
865+ except :
866+ log .warning ("Unable to fetch value for parameter: %s" , key )
867+ pass
868+
869+ log .info (
870+ "Saved %i parameters (skipped %i password-style and %i others)." ,
871+ saved ,
872+ passwords ,
873+ skipped ,
874+ )
875+ timed_log ("Saved %i script parameters to: %s" % (saved , out_path ))
0 commit comments