All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.maizegenetics.analysis.distance.MultiDimensionalScalingPlugin Maven / Gradle / Ivy

Go to download

TASSEL is a software package to evaluate traits associations, evolutionary patterns, and linkage disequilibrium.

The newest version!
package net.maizegenetics.analysis.distance;

import java.awt.Frame;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;

import net.maizegenetics.analysis.association.AssociationUtils;
import net.maizegenetics.phenotype.NumericAttribute;
import net.maizegenetics.phenotype.Phenotype;
import net.maizegenetics.phenotype.PhenotypeBuilder;
import net.maizegenetics.phenotype.TaxaAttribute;
import net.maizegenetics.phenotype.Phenotype.ATTRIBUTE_TYPE;
import net.maizegenetics.phenotype.PhenotypeAttribute;
import net.maizegenetics.plugindef.AbstractPlugin;
import net.maizegenetics.plugindef.DataSet;
import net.maizegenetics.plugindef.Datum;
import net.maizegenetics.plugindef.PluginParameter;
import net.maizegenetics.stats.PCA.ClassicMds;
import net.maizegenetics.taxa.distance.DistanceMatrix;
import net.maizegenetics.util.OpenBitSet;
import net.maizegenetics.util.TableReportBuilder;

public class MultiDimensionalScalingPlugin extends AbstractPlugin {

    private PluginParameter numberOfAxes = new PluginParameter.Builder<>("axes", 5, Integer.class)
            .description("The number of axes or dimensions and associated eigenvalues to be returned by the analysis.")
            .guiName("Number of Axes")
            .build();

    private PluginParameter removeNaN = new PluginParameter.Builder<>("removeNaN", true, Boolean.class)
            .description("Remove NaNs from matrix before performing MDS")
            .guiName("Remove NaNs")
            .build();

    public MultiDimensionalScalingPlugin(Frame parent, boolean interactive) {
        super(parent, interactive);
    }

    @Override
    public DataSet processData(DataSet input) {
        List resultList = new ArrayList<>();
        List myDatumList = input.getDataOfType(DistanceMatrix.class);
        if (myDatumList.size() < 1) {
            throw new RuntimeException("MDS requires a Distance Matrix as input.");
        }
        int ndata = myDatumList.size();

        fireProgress(10);
        int counter = 0;
        for (Datum myDatum : myDatumList) {
            DistanceMatrix myDistanceMatrix = (DistanceMatrix) myDatum.getData();
            if (removeNaN()) {
                myDistanceMatrix = RemoveNaNFromDistanceMatrixPlugin.runPlugin(myDistanceMatrix);
            }
            ClassicMds myMDS = new ClassicMds(myDistanceMatrix);
            int numberOfAxesToReport = numberOfAxes.value();

            //get requested number of axes and package as a Phenotype (covariates)
            List attrList = new ArrayList<>();
            List typeList = new ArrayList<>();
            attrList.add(new TaxaAttribute(myDistanceMatrix.getTaxaList()));
            typeList.add(ATTRIBUTE_TYPE.taxa);
            int ntaxa = myDistanceMatrix.getSize();
            for (int i = 0; i < numberOfAxesToReport; i++) {
                typeList.add(ATTRIBUTE_TYPE.covariate);
                float[] floatValues = AssociationUtils.convertDoubleArrayToFloat(myMDS.getPrincipalCoordinate(i));
                NumericAttribute pcAttr = new NumericAttribute("PC" + (i + 1), floatValues, new OpenBitSet(ntaxa));
                attrList.add(pcAttr);
            }
            Phenotype myPhenotype = new PhenotypeBuilder().fromAttributeList(attrList, typeList).build().get(0);
            String name = "MDS_PCs_" + myDatum.getName();
            String comment = "Principal Coordinates from MDS analysis of " + myDatum.getName();
            resultList.add(new Datum(name, myPhenotype, comment));

            //get requested number of eigenvalues and package as a TableReport
            String[] colnames = new String[]{"PC", "eigenvalue"};
            TableReportBuilder reportBuilder = TableReportBuilder.getInstance("", colnames);
            for (int i = 0; i < numberOfAxesToReport; i++) {
                reportBuilder.add(new Object[]{new Integer(i + 1), new Double(myMDS.getEigenvalue(i))});
            }
            name = "MDS_Eigenvalues_" + myDatum.getName();
            comment = "Eigenvalues from MDS analysis of " + myDatum.getName();
            resultList.add(new Datum(name, reportBuilder.build(), comment));

            counter++;
            fireProgress(Math.min(99, counter * 100 / ndata));
        }

        return new DataSet(resultList, this);
    }

    @Override
    public ImageIcon getIcon() {
        URL imageURL = MultiDimensionalScalingPlugin.class.getResource("/net/maizegenetics/analysis/images/pca.gif");
        if (imageURL == null) {
            return null;
        } else {
            return new ImageIcon(imageURL);
        }
    }

    @Override
    public String getButtonName() {
        return "MDS";
    }

    @Override
    public String getToolTipText() {
        return "Perform classic multidimensional scaling (principal coordinate analysis)";
    }

    @Override
    public String pluginDescription() {
        return "MultiDimensionalScalingPlugin takes a DistanceMatrix as input and performs classic multidimensional scaling, which is also know as principal coordinate analysis (PCO).";
    }
    
    @Override
    public String pluginUserManualURL() {
        return "https://bitbucket.org/tasseladmin/tassel-5-source/wiki/UserManual/MDS/MDS";
    }

    /**
     * The number of axes or dimensions and associated eigenvalues to be
     * returned by the analysis.
     *
     * @return Number of Axes
     */
    public Integer numberOfAxes() {
        return numberOfAxes.value();
    }

    /**
     * Set Number of Axes. The number of axes or dimensions and associated
     * eigenvalues to be returned by the analysis.
     *
     * @param value Number of Axes
     *
     * @return this plugin
     */
    public MultiDimensionalScalingPlugin numberOfAxes(Integer value) {
        numberOfAxes = new PluginParameter<>(numberOfAxes, value);
        return this;
    }

    /**
     * Remove NaNs from matrix before performing MDS
     *
     * @return Remove NaNs
     */
    public Boolean removeNaN() {
        return removeNaN.value();
    }

    /**
     * Set Remove NaNs. Remove NaNs from matrix before performing MDS
     *
     * @param value Remove NaNs
     *
     * @return this plugin
     */
    public MultiDimensionalScalingPlugin removeNaN(Boolean value) {
        removeNaN = new PluginParameter<>(removeNaN, value);
        return this;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy