/* * Copyright (c) 2009 The Jackson Laboratory * * This software was developed by Gary Churchill's Lab at The Jackson * Laboratory (see http://research.jax.org/faculty/churchill). * * This is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software. If not, see <http://www.gnu.org/licenses/>. */ package org.jax.qtl.cross; import java.util.ArrayList; import java.util.List; import org.jax.qtl.cross.Cross.CrossSubType; import org.jax.r.RAssignmentCommand; import org.jax.r.RCommand; import org.jax.r.RCommandParameter; import org.jax.r.RMethodInvocationCommand; import org.jax.r.RUtilities; /** * Class for creating a simulate cross command * @author <A HREF="mailto:keith.sheppard@jax.org">Keith Sheppard</A> */ public class SimulateCrossCommandBuilder { /** * The map function enum */ public enum MapFunction { /** * haldane enum */ HALDANE { /** * {@inheritDoc} */ @Override public String toString() { return "Haldane"; } /** * {@inheritDoc} */ @Override public String getRString() { return "haldane"; } }, /** * kosambi enum */ KOSAMBI { /** * {@inheritDoc} */ @Override public String toString() { return "Kosambi"; } /** * {@inheritDoc} */ @Override public String getRString() { return "kosambi"; } }, /** * carter-falconer enum */ CARTER_FALCONER { /** * {@inheritDoc} */ @Override public String toString() { return "Carter-Falconer"; } /** * {@inheritDoc} */ @Override public String getRString() { return "c-f"; } }, /** * morgan enum */ MORGAN { /** * {@inheritDoc} */ @Override public String toString() { return "Morgan"; } /** * {@inheritDoc} */ @Override public String getRString() { return "morgan"; } }; /** * Get the string that should be used in an R command * @return * the r string */ public abstract String getRString(); } /** * Class representing a simulated QTL * @author <A HREF="mailto:keith.sheppard@jax.org">Keith Sheppard</A> */ public static class SimulatedQtl { private volatile int chromosomeNumber = 1; private volatile double positionInCentimorgans; private volatile double effectOne; private volatile double effectTwo; private volatile double effectThree; /** * Getter for the chromosome number * @return the chromosomeNumber */ public int getChromosomeNumber() { return this.chromosomeNumber; } /** * Setter for the chromosome number * @param chromosomeNumber the chromosomeNumber to set */ public void setChromosomeNumber(int chromosomeNumber) { this.chromosomeNumber = chromosomeNumber; } /** * Getter for the position in cM * @return the positionInCentimorgans */ public double getPositionInCentimorgans() { return this.positionInCentimorgans; } /** * Setter for the position in cM * @param positionInCentimorgans the positionInCentimorgans to set */ public void setPositionInCentimorgans(double positionInCentimorgans) { this.positionInCentimorgans = positionInCentimorgans; } /** * The 1st effect * @return the effectOne */ public double getEffectOne() { return this.effectOne; } /** * Setter for the 1st effect * @param effectOne the effectOne to set */ public void setEffectOne(double effectOne) { this.effectOne = effectOne; } /** * Getter for the 2nd effect * @return the effectTwo */ public double getEffectTwo() { return this.effectTwo; } /** * Setter for the 2nd effect * @param effectTwo the effectTwo to set */ public void setEffectTwo(double effectTwo) { this.effectTwo = effectTwo; } /** * Getter for the 3rd effect * @return the effectThree */ public double getEffectThree() { return this.effectThree; } /** * Setter for the 3rd effect * @param effectThree the effectThree to set */ public void setEffectThree(double effectThree) { this.effectThree = effectThree; } } private volatile String mapAccessorString; private volatile int numIndividuals = 100; private volatile CrossSubType crossType = CrossSubType.F2; private volatile MapFunction mapFunction = MapFunction.HALDANE; private volatile double genotypingErrorRate; private volatile double missingGenotypeRate; private volatile double partiallyInformativeRate; private volatile double probabilityOfNoInterference; private volatile double interferenceParameter; private volatile SimulatedQtl[] simulatedQtls = new SimulatedQtl[0]; private volatile String crossName; /** * Getter for the map accessor string * @return the mapAccessorString */ public String getMapAccessorString() { return this.mapAccessorString; } /** * Setter for the map accessor string * @param mapAccessorString the mapAccessorString to set */ public void setMapAccessorString(String mapAccessorString) { this.mapAccessorString = mapAccessorString; } /** * Getter for the number of individuals * @return the numIndividuals */ public int getNumIndividuals() { return this.numIndividuals; } /** * Setter for the number of individuals * @param numIndividuals the numIndividuals to set */ public void setNumIndividuals(int numIndividuals) { this.numIndividuals = numIndividuals; } /** * Getter for the cross type * @return the crossType */ public CrossSubType getCrossType() { return this.crossType; } /** * Setter for the cross type * @param crossType the crossType to set */ public void setCrossType(CrossSubType crossType) { this.crossType = crossType; } /** * Getter for the map function * @return the mapFunction */ public MapFunction getMapFunction() { return this.mapFunction; } /** * Setter for the map function * @param mapFunction the mapFunction to set */ public void setMapFunction(MapFunction mapFunction) { this.mapFunction = mapFunction; } /** * Getter for the genotyping error rate * @return the genotypingErrorRate */ public double getGenotypingErrorRate() { return this.genotypingErrorRate; } /** * Setter for the genotyping error rate * @param genotypingErrorRate the genotypingErrorRate to set */ public void setGenotypingErrorRate(double genotypingErrorRate) { this.genotypingErrorRate = genotypingErrorRate; } /** * Getter for the missing genotype rate * @return the missingGenotypeRate */ public double getMissingGenotypeRate() { return this.missingGenotypeRate; } /** * Setter for the missing genotype rate * @param missingGenotypeRate the missingGenotypeRate to set */ public void setMissingGenotypeRate(double missingGenotypeRate) { this.missingGenotypeRate = missingGenotypeRate; } /** * Getter for the partially informative rate * @return the partiallyInformativeRate */ public double getPartiallyInformativeRate() { return this.partiallyInformativeRate; } /** * Setter for the partially informative rate * @param partiallyInformativeRate the partiallyInformativeRate to set */ public void setPartiallyInformativeRate(double partiallyInformativeRate) { this.partiallyInformativeRate = partiallyInformativeRate; } /** * Getter for the probability of no interference * @return the probabilityOfNoInterference */ public double getProbabilityOfNoInterference() { return this.probabilityOfNoInterference; } /** * Setter for the probability of no interference * @param probabilityOfNoInterference the probabilityOfNoInterference to set */ public void setProbabilityOfNoInterference( double probabilityOfNoInterference) { this.probabilityOfNoInterference = probabilityOfNoInterference; } /** * Getter for the interference parameter * @return the interferenceParameter */ public double getInterferenceParameter() { return this.interferenceParameter; } /** * Setter for the interface parameter * @param interferenceParameter the interferenceParameter to set */ public void setInterferenceParameter(double interferenceParameter) { this.interferenceParameter = interferenceParameter; } /** * Getter for the simulated qtls * @return the simulatedQtls */ public SimulatedQtl[] getSimulatedQtls() { return this.simulatedQtls; } /** * Setter for the simulated qtls * @param simulatedQtls the simulatedQtls to set */ public void setSimulatedQtls(SimulatedQtl[] simulatedQtls) { this.simulatedQtls = simulatedQtls; } /** * Getter for the cross name * @return the crossName */ public String getCrossName() { return this.crossName; } /** * Setter for the cross name * @param crossName the crossName to set */ public void setCrossName(String crossName) { this.crossName = crossName; } /** * Getter for the simulate cross command * @return * the command */ public RCommand getCommand() { List<RCommandParameter> commandParameters = this.getCommandParameters(); RMethodInvocationCommand simCrossMethodCommand = new RMethodInvocationCommand( "sim.cross", commandParameters); String crossName = this.crossName; if(crossName == null || crossName.trim().length() == 0) { return simCrossMethodCommand; } else { return new RAssignmentCommand( crossName.trim(), simCrossMethodCommand.getCommandText()); } } /** * Getter for the command parameters * @return * the command parameters */ private List<RCommandParameter> getCommandParameters() { List<RCommandParameter> parameters = new ArrayList<RCommandParameter>(); String mapAccessorString = this.mapAccessorString; if(mapAccessorString != null && mapAccessorString.trim().length() != 0) { parameters.add(new RCommandParameter( mapAccessorString.trim())); } CrossSubType crossType = this.crossType; SimulatedQtl[] simulatedQtls = this.simulatedQtls; if(simulatedQtls != null && simulatedQtls.length > 0) { StringBuffer qtlsBuffer = new StringBuffer("rbind("); for(int qtlIndex = 0; qtlIndex < simulatedQtls.length; qtlIndex++) { if(qtlIndex >= 1) { qtlsBuffer.append(", "); } qtlsBuffer.append("c("); qtlsBuffer.append(RUtilities.javaIntToRInt( simulatedQtls[qtlIndex].getChromosomeNumber())); qtlsBuffer.append(", "); qtlsBuffer.append(RUtilities.javaDoubleToRDouble( simulatedQtls[qtlIndex].getPositionInCentimorgans())); qtlsBuffer.append(", "); qtlsBuffer.append(RUtilities.javaDoubleToRDouble( simulatedQtls[qtlIndex].getEffectOne())); if(crossType == CrossSubType.F2 || crossType == CrossSubType.FOUR_WAY) { qtlsBuffer.append(", "); qtlsBuffer.append(RUtilities.javaDoubleToRDouble( simulatedQtls[qtlIndex].getEffectTwo())); if(crossType == CrossSubType.FOUR_WAY) { qtlsBuffer.append(", "); qtlsBuffer.append(RUtilities.javaDoubleToRDouble( simulatedQtls[qtlIndex].getEffectThree())); } } qtlsBuffer.append(")"); } qtlsBuffer.append(")"); parameters.add(new RCommandParameter( "model", qtlsBuffer.toString())); } parameters.add(new RCommandParameter( "n.ind", RUtilities.javaIntToRInt(this.numIndividuals))); parameters.add(new RCommandParameter( "type", RUtilities.javaStringToRString(crossType.getTypeString()))); parameters.add(new RCommandParameter( "error.prob", RUtilities.javaDoubleToRDouble(this.genotypingErrorRate))); parameters.add(new RCommandParameter( "missing.prob", RUtilities.javaDoubleToRDouble(this.missingGenotypeRate))); parameters.add(new RCommandParameter( "partial.missing.prob", RUtilities.javaDoubleToRDouble(this.partiallyInformativeRate))); parameters.add(new RCommandParameter( "m", RUtilities.javaDoubleToRDouble(this.interferenceParameter))); parameters.add(new RCommandParameter( "p", RUtilities.javaDoubleToRDouble(this.probabilityOfNoInterference))); parameters.add(new RCommandParameter( "map.function", RUtilities.javaStringToRString(this.mapFunction.getRString()))); return parameters; } }