net.maizegenetics.analysis.modelfitter.StepwiseOLSModelFitterPlugin Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tassel Show documentation
Show all versions of tassel Show documentation
TASSEL is a software package to evaluate traits associations, evolutionary patterns, and linkage
disequilibrium.
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