Plugin Development

The plugins system used by the program makes use of the Yet Another Plugin SYstem (Yapsy) module. The choice for this system was made because it allows for very basic, very simple plugin implementation into the program.

plugins are stored in the “Plug-Ins” folder in the main program directory or in external directories added by the user. The program automatically scans these folders looking for plugins and imports any that it finds. This is all written in such a way that the developer wanting to add code to the program does not have to make any changes to the main program. (Just add your plugin to a folder and be done)

Creating a Plugin

This section will walk you trough all the steps of creating your own plugin.

Categories

Plugins are stored in the plugins folder and every sub-directory of it resembles a category in the operations box of the main program. If you want to add a plugin to a pre-existing category, add it to the corresponding folder. Else create a new folder with the desired category name and work in there.

If you add a new category to the program you must also add a “CatClass.py” file to this directory with the following contents:

1
2
3
4
5
6
7
from yapsy.IPlugin import IPlugin

class PluginClassName(IPlugin):
        name = "PluginClassName"

def ReturnClass():
        return  PluginClassName

In this file PluginClassName should be replaced with a clear name of the class you use. (very often something like I[InsertCategory]Plugin is used) This class is a cast of IPlugin which is part of yapsy. This class casting is required because yapsy uses the class type used for plugins to determine to what category they belong.

Designing the plugin

When creating the plugin there is a very precise process you must follow.

The plugin that is created must be in a class that is cast using the appropriate category. Meaning that if you for example have a “Spectral Operations” plugin you must start the plugin as follows:

1
2
3
class HeatMapPlugin(CatClass.ISpectralPlugin):
        def Run(self,FilePath,FileName,CurrentProject,WorkFolder,UserPref,Operation):
                """YOURPLUGINCODE"""

The main plugin MUST have a definition called “Run” which takes the following inputs, in this order:

  1. self (Is required because it is a definition in a class, it’s not actually used)
  2. FilePath (This is a list with strings which are the filepaths of all the files the user selected)
  3. FileName (This is a list with strings which are the filenames of all the files the user selected)
  4. CurrentProject (This is a string which contains the path to the current project folder.
  5. WorkFolder (This is a string to the workfolder the user is using. Please use the “Temp” folder in the work folder for all your temporary files because this folder will be cleared when the program is exited) (This auto deletion is not implemented at the moment)
  6. UserPref (The directory to the user preference file)
  7. Operation (The name of the plugin, this can be found in the .yapsy-plugin file variable “Name”)

We put in as many variables here as possible to give possible developers as many variables as they want. In the future we plan to implement some basic functions which can convert these into arrays and dictionary’s. Right now the developer must use h5py and dask.array to open arrays for example.

Using support files in the plugin

When you have multiple support files in your plugin folder you can not simply import these as normal because when Python looks for modules to import it only looks in the directory associated to the launched main file, not any sub-directories. Normal python modules can still be imported normally. Below is an example of how these modules should be imported.

1
2
import imp
ModuleName = imp.load_source("ModuleName","./plugins/CategoryFolder/FileName.py")

plugin Information File

If you have created your plugin and are happy with the final result it is time to tell yapsy that your plugin exists. This is done by creating a plugin info file. The contents of this file will tell yapsy what the name of the plugin is and where it is located. The commonplace is to put this file next to the plugin file and give it the same name. (to avoid confusion) This file must have the file extension ”.yapsy-plugin”. (yapsy searches for these files)

An other purpose of the .yapsy-plugin file is to give the user information about the plugin. When the user clicks with the right mouse button on the operation tree a popup menu will be given with a info option. This generates a dialog with the information from the .yapsy-plugin file.

The structure of this file must be as follows:

[Core]
Name = "Plugin Name"
Module = "File where plugin is located WITHOUT .py extension"

[Documentation]
Description = "Plugin Description"
Author = "Plugin Author"
Version = "Plugin Version Number"
Website = "Plugin website if exists"

[File Input Settings]
Input Files = {"ImageType":[minimum,maximum,group],"ImageType":[minimum,maximum,group],...}
Range for Number of Files = [min,max]

[Right Mouse Button Options](optinal)
Supported Files for Display = ["ImageType","ImageType",...]

[Extra Plugin Info](optinal)
References = "Reference used for the plugin"

File Input Settings

The File Input Settings section contains the amount of input files that the plugin takes. (the program will check for this so make sure to fill it out properly) and the total number of files it can take.

Input Files

The input files is structured as a python dictionary where the KEY is the image type (extracted from the metadata of files put into the plugin). Adding it here means that the plugin supports this type of image. Then the VALUE is a list with min,max and group. The minimum and maximum will determine how many of this type the plugin can take and the group(int) will determine the uniqueness of the Imagetype. Uniqueness means that every group must be selected ones.

Minimum must be at least one and Maximum can be None, which represents infinity.

The last option is to use “All” as a KEY and the VALUE [0,None,0]. This means that everything will be excepted. However this is not recommened because this makes the input of files for the plugin completely random.

Range for Number of Files

This range determines how many files in total the plugin can take. Again min must be at least one and max can be None, which represents infinity.

Examples

The RCA plugin, which requires 1 normalised and at least 2 Ref files. This translates in the following code below as you can see two types of files are needed so there are two groups.

[File Input Settings]
Input Files = {"Normalized_HSI":[1,1,0],"Ref_HSI":[2,None,1]}
Range for Number of Files = [3,None]

The normalisation plugin, which requires 1 Grey or white, 1 Black and 1 HSI file. This translates in the following code below as you can see three types of files are needed so there are three groups. Grey and White are in the same group because you need one of them but not both.

[File Input Settings]
Input Files ={"Grey":[1,1,0],"White":[1,1,0],"Black":[1,1,1],"HSI":[1,1,2]}
Range for Number of Files = [3,3]

Right Mouse Button Options

This section contains information about if this plugin has influance on what the program must do when the right mouse button is pressed.

Supported Files for Display

This is a list with file types that is used when the right mouse button is pressed in the file list and the option display is choosen. If display is choosen the program will search for all the plugins that have the selected file type in there Supported Files for Display list and this plugin is then execuded. If more then one plugin is found the user gets the option to choose one of them. when no plugins are found an error message will be raised.

Extra Plugin Info

This section gives the option to add additional information about the plugin to the user. Reference is an example but everything is possible.

References

This can be used if a reference is used to build the plugin.