-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Utilities to simplify the integration of command-line tools in TrackMate modules #299
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Only used in the GUI.
For instance, in cellpose we have the --pretrained_model arg that can accept either a string from a pretrained model list, or a path to a custom model. This corresponds to two different types of Argument<?> : a list and a path. To make it possible to choose between one OR the other in a GUI, there is a SelectableArguments that lets the user specifies that one argument can be active OR another one, but not bother at the same time. // State that we can set one or the other. cli.addSelectableArguments() .add( ptm ) .add( cm ) .select( ptm ); This is supported in the GUI (but what a mess) and the args that are in a selectable group appear with a radio button. Selecting one properly sets the CLI. The arguments in a selectable groups do not have to be following in the arg list, but it is prettier that way.
TODO: also make it in the TrackMate settings map bridge.
- restrict visibility once the CLI config is built. - shorten the class using abstract classes more.
Sometimes we need to change the output of an argument so that it 'looks good' in TrackMate GUI but still translates into something the executable can understand. For instance in cellpose we want to display for the optional channel 2: - 0 (don't use) - 1 (red) - 2 (green) - 3 (blue) into the accepted values by the CLI: - 0 - 1 - 2 - 3 This mechanism offers the possibility to do so.
Typically, a TrackMate detector or tracker has more parameters than the CLI of the tool it will call. For instance to simplify contours after a detection step. This commit allows passing these extra parameters to the UI builder and to the map serializer so that a TrackMate module that calls a command line tool can be handled by the CLI framework.
…mage. Required to support Trackastra.
Do not use Elements. Instead just gives the possibity of adding extra arguments, making them visible in the GUI, but not used in the command. For this, add a method arg.inCLI(boolean) that specified whether this arg is to be used in the CLI. This allows using the same system to generate a command line, a GUI, and manage all of this via TrackMate settings. Also add javadocs and fix some typos.
For many tools we want to integrate are Python tools that can be run from a specific conda environment. If the implementing CLI config knows already what is the Python command, the user should just have to specify in what conda env it is installed. It is more convenient than to browse to a Python executable and less prone to error.
Right now, the conda CLI config only works on windows.
- Offer a utility to let the user sets the path to the conda executable on their system. Stores it in a SciJava Prefs. - Make a method with defaults, from known installation of conda flavor. - Use it the conda exec to build a map from conda env name to the path of the python executable they are using. - Rework the conda env list command.
We CANNOT change the conda environment with the Java ProcessBuilder. At least after me trying very hard. So we have to defer on this platform to calling the Python tool as a module, from the python executable. It is very sad. And it limits what we can run this way to tools that works as a module ('python -m blablabla'). I see no other way yey. To do so: - Make a special command for the arg that allows selecting a conda environment: CondaEnvironmentCommand. Use it in the GUI and in the command builder. - Its translator turns it into either a 'conda activate' thing on Windows, or in a 'python -m blablabla' on Mac.
when trying to create a GUI with a CLI config that has some arguments that miss a value.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR ships a series of classes meant to simplify and accelerate the integration of command-lines in TrackMate modules. Typically such tools are Python tools that can be installed in a conda environment, can be called and configured from the command line, and yield results as files that can be imported in TrackMate. Good examples are Python scientific tools like cellpose or Trackastra.
These tools are in the
fiji.plugin.trackmate.util.cli
package.An example implementation is in https://github.com/trackmate-sc/TrackMate-Trackastra/tree/main/src/main/java/fiji/plugin/trackmate/tracking/trackastra
A simple example is included in
src/test/java/fiji/plugin/trackmate/util/cli/ExampleCommandCLI.java
Simple example.
Each tool is represented by one class, inheriting from
CLIConfigurator
. If the tool you want to run corresponds to an executable on disk, subclassCommandCLIConfigurator
. If it based on a Python tool installed in a conda environment, subclassCondaCLIConfigurator
.Creating a CLI config.
For instance, a tool that depends on an executable with 3 arguments, 2 optional, 1 required, would look like this:
executable
is the executable that will be called by the TrackMate module.CLI configs that inherit from 'CommandCLIConfigurator' are all based on an actual executable, that is a file with exec rights somewhere on the user computer. They need to set it themselves, so the config part only specifies the name, the help and the key of this command. The help and name will be used in the UI.
name()
sets a user-friendly name to use in UIs and messages.help()
is a text help that is shown in the tooltip of the UIs.key()
is used to serialize the config to aMap< String, Object >
, for TrackMate integration.In this example we will assume that the tool we want to run accepts a few arguments.
The first one is the
--nThreads
argument, that accept integer larger than 1 and smaller than 24.The 'argument()' part must be something the tool can understand. This is what is passed to it before the value.
This example argument is not required, but has a default value of 1. The default value is used only in the command line. If an argument is not required, is not set, but has a default value, then the argument will appear in the command line with this default value.
Adding arguments is done via 'adder' methods, that are only visible in inhering classes. The
get()
method of the adder returns the created argument. It also adds it to the inner parts of the mother class, so that it is handled automatically when creating a GUI or a command line. But it is a good idea to expose it in this concrete class so that you can expose it to the user and let them set it.The second argument is a double. It is required, which means that an error will be thrown when making a command line from this config if the user forgot to set a value. It also has a unit, which is only used in the UI.
Because it does not specify a min or a max, any numerical value can be entered in the GUI. The implementation will have to add an extra check to verify consistency of values.
The third argument is a a double argument that has a min and a max will generate another widget in the UI: a slider.
Using a CLI config to yield a command line.
Here is how this CLI config could be used to generate a command line. The class
CommandBuilder
contains a static method that generates a command line as a list of tokens, so that they can be used directly by JavaProcessBuilder
.The following will generate an error because 'diameter' is required and not set.
The argument 'nThreads' is not set either, but it has a default value and is not required -> no error, the command line will use the default value.
The argument 'time' is not set either, does not have a default, but it is not required -> no error, the command line will just miss the 'time' argument.
This prints:
We can fix this by actually setting the diameter:
This prints:
Generating a UI from a CLI config.
A CLI object can also be used to generate a UI that will configure it. This is done with the
CliGuiBuilder
class. There is one important point: the UI builder requires all arguments and commands to have a value set:This prints:
To fix this we can set a value for all arguments:
And it yields this:
The UI directly modifies the values of the arguments. When pressing the
echo
button we get this: