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

net.maizegenetics.analysis.modelfitter.StepwiseOLSModelFitterPlugin Maven / Gradle / Ivy

Go to download

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

There is a newer version: 5.2.94
Show newest version
package net.maizegenetics.analysis.modelfitter;

import com.google.common.collect.Range;

import net.maizegenetics.phenotype.GenotypePhenotype;
import net.maizegenetics.phenotype.Phenotype.ATTRIBUTE_TYPE;
import net.maizegenetics.plugindef.*;
import net.maizegenetics.util.TableReport;

import org.apache.log4j.Logger;

import javax.swing.*;

import java.awt.*;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Stepwise Ordinary Least Squares model fitter
 *
 * @author Alex Lipka
 * @author Peter Bradbury
 */
public class StepwiseOLSModelFitterPlugin extends AbstractPlugin {

    private List myFactorList;
    private GenotypePhenotype myGenoPheno;
    private String datasetName;
    private final String NONE = "None";

    private PluginParameter modelType =
            new PluginParameter.Builder<>("modelType", StepwiseOLSModelFitter.MODEL_TYPE.pvalue, StepwiseOLSModelFitter.MODEL_TYPE.class)
                    .range(StepwiseOLSModelFitter.MODEL_TYPE.values())
                    .guiName("Model type")
                    .description("The model selection criteria used to determine which terms enter the model and how many. Value must be one of pvalue, bic, mbic, or aic")
                    .build();
    private PluginParameter enterlimit =
            new PluginParameter.Builder<>("enter", 1e-6, Double.class)
                    .range(Range.closed(0.0, 1.0))
                    .guiName("Entry limit")
                    .description("The enter limit or maximum p-value for which a term can enter the model")
                    .build();
    private PluginParameter exitlimit =
            new PluginParameter.Builder<>("exit", 2e-6, Double.class)
                    .range(Range.closed(0.0, 1.0))
                    .guiName("Exit limit")
                    .description("A term exits the model on a backward step if its p-value is greater than this value")
                    .build();
    private PluginParameter maxNumberOfMarkers =
            new PluginParameter.Builder<>("maxMarkers", 100, Integer.class)
                    .range(Range.closed(0, 10000))
                    .guiName("Maximum markers")
                    .description("The maximum number of markers that will be fit, if the enter limit is not reached first")
                    .build();
    private PluginParameter nestMarkers =
            new PluginParameter.Builder<>("nestMarkers", false, Boolean.class)
                    .guiName("Nest markers")
                    .description("Should markers be nested within a model factor")
                    .build();
    private PluginParameter nestingFactor =
            new PluginParameter.Builder<>("nestFactor", null, String.class)
                    .guiName("Nesting factor")
                    .description("Nest markers within this factor.")
                    .dependentOnParameter(nestMarkers)
                    .objectListSingleSelect()
                    .build();
    private PluginParameter numberOfPermutations =
            new PluginParameter.Builder<>("nperm", 0, Integer.class)
                    .range(Range.closed(0, 100000))
                    .guiName("Number of permutations")
                    .description("Number of permutations for the model to determine an empirical alpha")
                    .build();
//    private PluginParameter chromosomeResiduals =
//            new PluginParameter.Builder<>("chrResidual", false, Boolean.class)
//                    .guiName("Output chromosome residuals")
//                    .description("Should a dataset of chromosome residuals be created for each phenotype? The output datasets will include all factors but no covariates from the original phenotype data.")
//                    .build();
//    private PluginParameter residualsAsFile =
//            new PluginParameter.Builder<>("resAsFile", false, Boolean.class)
//                    .guiName("Save residuals as file?")
//                    .description("Should the chromosome residuals to be saved to separate files rather than stored in memory?")
//                    .dependentOnParameter(chromosomeResiduals)
//                    .build();
//    private PluginParameter residualFilebase =
//            new PluginParameter.Builder<>("resFilename", null, String.class)
//                    .guiName("Residual file name")
//                    .description("The base name for the residual files. _chrname.txt will be appended to each file.")
//                    .dependentOnParameter(residualsAsFile)
//                    .outFile()
//                    .build();

    private static final Logger myLogger = Logger.getLogger(StepwiseOLSModelFitterPlugin.class);
    private double alpha = 0.05;

    //TODO need to change this to a list

    public StepwiseOLSModelFitterPlugin(Frame parentFrame, boolean isInteractive) {
        super(parentFrame, isInteractive);
    }

    public StepwiseOLSModelFitterPlugin() {
        super(null, false);
    }

    @Override
    protected void preProcessParameters(DataSet input) {
        List datasets = input.getDataOfType(new Class[] { GenotypePhenotype.class });
        if (datasets.size() < 1) {
            String msg = "Error in performFunction: No appropriate dataset selected.";
            throw new IllegalArgumentException(msg);
        }

        //only analyze one dataset
        if (datasets.size() > 1) {
            String msg = "Multiple datasets selected. Only one dataset is allowed.";
            throw new IllegalArgumentException(msg);
        }

        myGenoPheno = (GenotypePhenotype) datasets.get(0).getData();
        datasetName = datasets.get(0).getName();
        myFactorList = myGenoPheno.phenotype().attributeListOfType(ATTRIBUTE_TYPE.factor).stream()
                .map(pa -> pa.name())
                .collect(Collectors.toList());

        if (myFactorList.isEmpty()) {
            List noneList = Arrays.asList(NONE);
            nestingFactor = new PluginParameter(nestingFactor, noneList);
        } else {
            nestingFactor = new PluginParameter(nestingFactor, myFactorList);
        }
    }

    @Override
    protected void postProcessParameters() {
        if (nestMarkers.value() && nestingFactor.value().isEmpty()) {
            if (myFactorList.size() == 1) {
                nestingFactor(myFactorList.get(0));
            } else if (myFactorList.size() > 1) {
                throw new IllegalArgumentException("Nest markers was checked (set to true), but a single factor was not selected to nest markers within. This must be corrected before the analysis will run.");
            }
        }
    }

    @Override
    public DataSet processData(DataSet input) {
        StepwiseOLSModelFitter modelFitter = new StepwiseOLSModelFitter(myGenoPheno, datasetName);
        modelFitter.setEnterlimit(enterlimit.value());
        modelFitter.setExitlimit(exitlimit.value());
        modelFitter.setMaxNumberOfMarkers(maxNumberOfMarkers.value());
        modelFitter.setNested(nestMarkers.value());
        if (nestMarkers.value()) {
            int ndx = myGenoPheno.phenotype().attributeIndexForName(nestingFactor.value());
            if (ndx < 0)
                modelFitter.setNested(false);
            else
                modelFitter.setNestingEffectIndex(ndx);
        }

        modelFitter.setModelType(modelType.value());
        modelFitter.setNumberOfPermutations(numberOfPermutations.value());
        modelFitter.setAlpha(alpha);

        modelFitter.runAnalysis();

        TableReport trResults = modelFitter.getAnovaReport();
        TableReport trEffects = modelFitter.getMarkerEffectReport();
        TableReport trResultsAfterCIScan = modelFitter.getAnovaReportWithCI();
        TableReport trEffectsAfterCIScan = modelFitter.getMarkerEffectReportWithCI();
        TableReport trPermPvalues = modelFitter.getPermutationReport();

        LinkedList datumList = new LinkedList();
        if (trResults != null)
            datumList.add(new Datum("ANOVA_stepwise_" + datasetName, trResults, "comments"));
        if (trEffects != null)
            datumList.add(new Datum("Marker_estimates_" + datasetName, trEffects, "comments"));
        if (trResultsAfterCIScan != null)
            datumList.add(new Datum("ANOVA_stepwise_After_CI_Scan" + datasetName, trResultsAfterCIScan, "comments"));
        if (trEffectsAfterCIScan != null)
            datumList.add(new Datum("Marker_estimates_After_CI_Scan" + datasetName, trEffectsAfterCIScan, "comments"));
        if (trPermPvalues != null)
            datumList.add(new Datum("Permuted_Pvalues" + datasetName, trPermPvalues, "comments"));

        DataSet myResult = new DataSet(datumList, this);
        fireDataSetReturned(myResult);

        return myResult;
    }

    @Override
    public ImageIcon getIcon() {
        URL imageURL = StepwiseOLSModelFitterPlugin.class.getResource("stepwise.gif");
        if (imageURL == null) {
            return null;
        } else {
            return new ImageIcon(imageURL);
        }
    }

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

    @Override
    public String getToolTipText() {
        return "Fit multiple markers in a single model (experimental).";
    }

    public String getCitation() {
        String citation = "Written in 2013 by Peter Bradbury and Alex Lipka";
        return citation;
    }

    // The following getters and setters were auto-generated.
    // Please use this method to re-generate.
    //
    // public static void main(String[] args) {
    //     GeneratePluginCode.generate(StepwiseOLSModelFitterPlugin.class);
    // }

    /**
     * Convenience method to run plugin with one return object.
     */
    // TODO: Replace  with specific type.
    public TableReport runPlugin(DataSet input) {
        return (TableReport) performFunction(input).getData(0).getData();
    }

    /**
     * The model selection criteria used to determine which
     * terms enter the model and how many. Value must be one
     * of pvalue, bic, mbic, or aic
     *
     * @return Model type
     */
    public StepwiseOLSModelFitter.MODEL_TYPE modelType() {
        return modelType.value();
    }

    /**
     * Set Model type. The model selection criteria used to
     * determine which terms enter the model and how many.
     * Value must be one of pvalue, bic, mbic, or aic
     *
     * @param value Model type
     *
     * @return this plugin
     */
    public StepwiseOLSModelFitterPlugin modelType(StepwiseOLSModelFitter.MODEL_TYPE value) {
        modelType = new PluginParameter<>(modelType, value);
        return this;
    }

    /**
     * The enter limit or maximum p-value for which a term
     * can enter the model
     *
     * @return Entry limit
     */
    public Double enterlimit() {
        return enterlimit.value();
    }

    /**
     * Set Entry limit. The enter limit or maximum p-value
     * for which a term can enter the model
     *
     * @param value Entry limit
     *
     * @return this plugin
     */
    public StepwiseOLSModelFitterPlugin enterlimit(Double value) {
        enterlimit = new PluginParameter<>(enterlimit, value);
        return this;
    }

    /**
     * A term exits the model on a backward step if its p-value
     * is greater than this value
     *
     * @return Exit limit
     */
    public Double exitlimit() {
        return exitlimit.value();
    }

    /**
     * Set Exit limit. A term exits the model on a backward
     * step if its p-value is greater than this value
     *
     * @param value Exit limit
     *
     * @return this plugin
     */
    public StepwiseOLSModelFitterPlugin exitlimit(Double value) {
        exitlimit = new PluginParameter<>(exitlimit, value);
        return this;
    }

    /**
     * The maximum number of markers that will be fit, if
     * the enter limit is not reached first
     *
     * @return Maximum markers
     */
    public Integer maxNumberOfMarkers() {
        return maxNumberOfMarkers.value();
    }

    /**
     * Set Maximum markers. The maximum number of markers
     * that will be fit, if the enter limit is not reached
     * first
     *
     * @param value Maximum markers
     *
     * @return this plugin
     */
    public StepwiseOLSModelFitterPlugin maxNumberOfMarkers(Integer value) {
        maxNumberOfMarkers = new PluginParameter<>(maxNumberOfMarkers, value);
        return this;
    }

    /**
     * Should markers be nested within a model factor
     *
     * @return Nest markers
     */
    public Boolean nestMarkers() {
        return nestMarkers.value();
    }

    /**
     * Set Nest markers. Should markers be nested within a
     * model factor
     *
     * @param value Nest markers
     *
     * @return this plugin
     */
    public StepwiseOLSModelFitterPlugin nestMarkers(Boolean value) {
        nestMarkers = new PluginParameter<>(nestMarkers, value);
        return this;
    }

    /**
     * Nest markers within this factor.
     *
     * @return Nesting factor
     */
    public String nestingFactor() {
        return nestingFactor.value();
    }

    /**
     * Set Nesting factor. Nest markers within this factor.
     *
     * @param value Nesting factor
     *
     * @return this plugin
     */
    public StepwiseOLSModelFitterPlugin nestingFactor(String value) {
        nestingFactor = new PluginParameter<>(nestingFactor, value);
        return this;
    }

    /**
     * Number of permutations for the model to determine an
     * empirical alpha
     *
     * @return Number of permutations
     */
    public Integer numberOfPermutations() {
        return numberOfPermutations.value();
    }

    /**
     * Set Number of permutations. Number of permutations
     * for the model to determine an empirical alpha
     *
     * @param value Number of permutations
     *
     * @return this plugin
     */
    public StepwiseOLSModelFitterPlugin numberOfPermutations(Integer value) {
        numberOfPermutations = new PluginParameter<>(numberOfPermutations, value);
        return this;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy