Nodes usually are based on one of three types:
- JIPipeSimpleIteratingAlgorithm: A node with zero or one input(s)
- JIPipeIteratingAlgorithm: A node with inputs that are not merged. For each input slot, there is exactly data item that is passed into the workload function. Zero inputs are allowed.
- JIPipeMergingAlgorithm: A node with inputs that are merged. For each input slot, multiple data items might be passed into the workload function. Zero inputs are allowed.
There are also additional node types that can be reviewed in the JIPipeAlgorithm JavaDoc.
To develop a node, inherit from one of these classes. Annotations are used to provide essential metadata.
- @JIPipeDocumentation provides the node with a name and documentation (displayed to users on selecting the node)
- @JIPipeNode sets the category of the node and also allows to set the menu location. This annotation is essential to make nodes visible to users
- @JIPipeInputSlot adds an input slot to the node. Please note that by default, this has only documentation-related purposes. Set
autoCreate=true
to automatically create an input slot according to the specifications of the annotation. - @JIPipeOutputSlot adds an output slot to the node. Please note that by default, this has only documentation-related purposes. Set
autoCreate=true
to automatically create an input slot according to the specifications of the annotation. - @JIPipeCitation (optional) allows to cite external work directly within the node. The information will be displayed in the node documentation
Example code: simple iterating node
// Annotates documentation to the algorithm @JIPipeDocumentation(name = "My Algorithm", description = "Does something") // Sets the algorithm category (here: put into the "Miscellaneous" menu) @JIPipeNode(nodeTypeCategory = MiscellaneousNodeTypeCategory.class) // Input and output slots autoCreate automatically creates the slots if set to true and no slot configuration was provided @JIPipeInputSlot(value = ImagePlusData.class, slotName = "Input", description="The input", autoCreate = true) @JIPipeOutputSlot(value = ImagePlusData.class, slotName = "Output", description="The output", autoCreate = true) // You can add multiple JIPipeCitation annotations to provide citations for this node only // Citations are optional @JIPipeCitation("Additional citation") public class MyAlgorithm extends JIPipeSimpleIteratingAlgorithm { // A simple iterating algorithm is easier to use compared to JIPipeIteratingAlgorithm (but it requires that that is at most 1 input) /* This is the main constructor of the algorithm. It contains a reference to the algorithm info that contains some important metadata */ public MyAlgorithm(JIPipeNodeInfo info) { super(info); // Info: There is also an alternative constructor allows to pass a slot configuration object (annotations are ignored in this case) } /* A deep copy constructor. It is required. Please do not forget to deep-copy all important fields */ public MyAlgorithm(MyAlgorithm original) { super(original); // Deep-copy additional fields here } /* The workload is run in this functon. You can also have the ability to inform the user about the current algorithm status for more complex algorithms. You can also query if the user requested cancellation */ @Override protected void runIteration(JIPipeDataBatch dataBatch, JIPipeProgressInfo progressInfo) { // Run your workload here // Read inputs / write outputs via the dataBatch object // We read the image from the "Input" slot ImagePlusData inputData = dataBatch.getInputData("Input", ImagePlusData.class, progressInfo); // TODO: Operations on the image (do not forget to duplicate the image) // We pass the image directly into the output slot dataBatch.addOutputData("Output", inputData, progressInfo); } }
Registering the node
JIPipe will not automatically register nodes into extensions. To do this, you have to call the registerNodeType
function inside your extension service.
@Plugin(type = JIPipeJavaExtension.class) public class MyExtension extends JIPipeDefaultJavaExtension { // ... See previous tutorial for other methods @Override public void register(JIPipe jiPipe, Context context, JIPipeProgressInfo progressInfo) { // Registers our algorithm with a unique ID and an icon registerNodeType("my-algorithm", MyAlgorithm.class, UIUtils.getIconURLFromResources("actions/viewimage.png")); } }