Population Plugin Example

package com.plugins;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import com.treestar.flowjo.engine.utility.ClusterPrompter;
import com.treestar.lib.PluginHelper;
import com.treestar.lib.core.ExportFileTypes;
import com.treestar.lib.core.ExternalAlgorithmResults;
import com.treestar.lib.core.PopulationPluginInterface;
import com.treestar.lib.fjml.FJML;
import com.treestar.lib.fjml.types.FileTypes;
import com.treestar.lib.xml.SElement;

 * This test class illustrates the implementation of the External Population Algorithm plugin.
 * It doesn't do anything useful, but attempts to show all the different types of return values
 * that can be used by ExternalAlgorithmResults.
public class ExternalAlgorithmTest implements PopulationPluginInterface 
    private List<String> fParameters = new ArrayList<String>(); // the list of $PnN parameter 
                                                                // names to be used
    private SElement fOptions; //an XML element that can hold any additional options used 
                               //by the algorithm

    public String getName() {    return "ExternalAlgorithmTest";    }

     * Return an XML element that fully describes the algorithm object and can be used to
     * reconstitute the state of the object.
    public SElement getElement() {
        SElement result = new SElement(getClass().getSimpleName());
        if (fOptions != null)
            result.addContent(new SElement(fOptions)); // create a copy of the XML element     
        // construct an XML element for each parameter name
        for (String pName : fParameters)
            SElement pElem = new SElement(FJML.Parameter);
            pElem.setString(FJML.name, pName);
        return result;

     * Use the input XML element to set the state of the algorithm object
    public void setElement(SElement elem) {
        fOptions = elem.getChild("Option"); // could be null
        // clear the parameter list and re-create from the XML element
        for (SElement child : elem.getChildren(FJML.Parameter))

    public List<String> getParameters() {
        return fParameters;

    public Icon getIcon() {
        return null;

     * This method uses class ClusterPrompter to prompt the user for a list of parameters 
     * and number of clusters.
    public boolean promptForOptions(SElement fcmlQueryElement, List<String> parameterNames)
        SElement algorithmElement = getElement();
        // pass the XML element to the cluster prompter
        ClusterPrompter prompter = new ClusterPrompter(algorithmElement);
        if (!prompter.promptForOptions(null, parameterNames, true))
            return false;
        algorithmElement = prompter.getElement();
        return true;

     * This method shows how to return different kinds of values using the 
     * ExternalAlgorithmResults object.
    public ExternalAlgorithmResults invokeAlgorithm(SElement fcmlElem, File sampleFile, File   
    outputFolder) {
     ExternalAlgorithmResults result = new ExternalAlgorithmResults();

        // 1. Create a CSV file that contains random cluster numbers
        // (CSV file is created in the given output folder)
        File outFile = new File(outputFolder, "Random." + sampleFile.getName() + FileTypes.CSV_SUFFIX);
        Writer output;
        // get the number of clusters from the options XML element
        int numClusters = fOptions == null ? 2 : fOptions.getInt("cluster");
        try {
            // get the number of total events in the sample file, using a a plugin helper method
            int num = PluginHelper.getNumExportedEvents(fcmlElem);
            if (num <= 0)
                return null;
            // now write CSV file with the correct number of rows,
            // each row containing a random cluster number
            output = new BufferedWriter(new FileWriter(outFile));
            for (int i = 0; i < num; i++) {
                int rand = (int)(Math.random() * 100);
                int cluster = rand % numClusters;
                output.write("" + cluster);
        } catch (IOException e) {
        // 2. Set the CSV file to be used by FlowJo to create a derived parameter that is then auto-gated

        // 3. Set the number of clusters, displayed in the workspace //window as the stat value

        // 4. Set the workspace description string, displayed in the workspace window
        result.setWorkspaceString("" + numClusters + " clusters");

        // 5. Create a 2-dimensional table of values, with a header row
        double[][] table = new double[numClusters][numClusters];
        String[] headers = new String[numClusters];
        for (int i = 0; i < numClusters; i++)
            headers[i] = "Column " + i;
            for (int j = 0; j < numClusters; j++)
                table[i][j] = (i+1) * (j+1);
        // 6. Set the table header and the table values in the result object

        // 7. Create a new formula that describes a derived parameter
        if (fParameters.size() > 1)
            // the formula is the first parameter's value divided by the second parameter's value
            String formula = fParameters.get(0) + " / " + fParameters.get(1);
            // add the formula to the result object (can add more than one)
            result.addDerivedParameterFormula(fParameters.get(0) + fParameters.get(1) + "Ratio", formula);

        // 8. Create a URL to an image and set the image URL in the result
        try {
            URL url = new URL("http://www.flowjo.com/wp-content/uploads/2015/09/Enterprise-for-web.png");
        } catch (MalformedURLException e) {

        // 9. Create a Gating-ML XML element that describes a gate
        // create the XML elements for a 1-D range gate
        SElement gate = new SElement("gating:Gating-ML");
        SElement rectGateElem = new SElement("gating:RectangleGate");
        rectGateElem.setString("gating:id", "TestGate");
        // create the dimension XML element
        SElement dimElem = new SElement("gating:dimension");
        dimElem.setInt("gating:min", 50000);
        dimElem.setInt("gating:max", 100000);
        // create the parameter name XML element
        SElement fcsDimElem = new SElement("data-type:fcs-dimension");
        fcsDimElem.setString("data-type:name", fParameters.get(0));

        // 10. Set the Gating-ML element in the result
        return result;

     * This method allows the algorithm to specify if the input file should be a CSV file (CSV_SCALE OR 
     * CSV_CHANNEL), or an FCS file based on algorithm's requirements.
     * @return ExportFileTypes One of three values (ExportFileTypes.FCS, ExportFileTypes.CSV_SCALE, 
     * ExportFileTypes.CSV_CHANNEL) will be returned according to algorithm's requirement.
    public ExportFileTypes useExportFileType() {
        return ExportFileTypes.CSV_SCALE;

    public String getVersion() {
        return "1.0";    


results matching ""

    No results matching ""