Developer documentation

Creating a node

Please keep this in mind

Extensions can register multiple nodes and data types, so you can greatly simplify your projects by merging multiple functions into a single extension.

As users will need to activate extensions in the extension manager, just creating one extension service will greatly simplify the user experience

Nodes usually are based on one of three types:

  1. JIPipeSimpleIteratingAlgorithm: A node with zero or one input(s)
  2. 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.
  3. 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.

Please keep this in mind

Extensions can register multiple nodes and data types, so you can greatly simplify your projects by merging multiple functions into a single extension.

As users will need to activate extensions in the extension manager, just creating one extension service will greatly simplify the user experience

@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"));
    }

}