/*
* Copyright (c) 2003-2012 Fred Hutchinson Cancer Research Center
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.fhcrc.cpl.viewer.align;
import org.apache.log4j.Logger;
import org.fhcrc.cpl.toolbox.ApplicationContext;
import org.fhcrc.cpl.toolbox.datastructure.Pair;
import org.fhcrc.cpl.toolbox.statistics.RegressionUtilities;
import org.fhcrc.cpl.viewer.amt.AmtDatabaseMatcher;
import java.io.*;
/**
* Aligner using quantile regression
*/
public class QuantileRegressionAligner extends Aligner
{
private static Logger _log = Logger.getLogger(QuantileRegressionAligner.class);
protected int nonlinearMappingPolynomialDegree =
AmtDatabaseMatcher.DEFAULT_NONLINEAR_MAPPING_DEGREE;
protected double[] modalRegressionCoefficients = null;
public QuantileRegressionAligner()
{
}
/**
* Cover method. In the absence of filename information, use a filename that's
* likely to be unique
* @param pairs
* @param maxValueToWarp
* @return
*/
public double[] alignPairs(Pair<Double,Double>[] pairs, int maxValueToWarp)
{
return alignPairs(pairs, maxValueToWarp, "length" + pairs.length);
}
/**
* Generic method for creating a warping based on pairs of values.
* Create temp files with names based on tempFileNameStart, in case the user
* wants to peruse them
* @param pairs
* @param maxValueToWarp
* @return
*/
public double[] alignPairs(Pair<Double,Double>[] pairs, double maxValueToWarp,
String tempFileNameStart)
{
PrintWriter pw = null;
double[] result = null;
if (pairs.length < 4)
throw new RuntimeException("QuantileRegressionAligner.alignPairs: at least 4 pairs are necessary for " +
"alignment, only " + pairs.length + " were provided");
_log.debug("alignPairs, #pairs=" + pairs.length);
try
{
double[] baseTimes = new double[pairs.length];
double[] toAlignTimes = new double[pairs.length];
for (int j=0; j<pairs.length; j++)
{
Pair<Double,Double> matchedPair = pairs[j];
baseTimes[j] = matchedPair.first;
toAlignTimes[j] = matchedPair.second;
}
try
{
modalRegressionCoefficients = RegressionUtilities.modalRegression(baseTimes,
toAlignTimes, nonlinearMappingPolynomialDegree);
_log.debug("Regression complete");
result = new double[(int) (maxValueToWarp+1)];
for (int j=0; j<=maxValueToWarp; j++)
{
result[j] =
RegressionUtilities.mapValueUsingCoefficients(modalRegressionCoefficients, j);
}
}
catch (IOException e)
{
e.printStackTrace(System.err);
//if we failed, it could be because of timeout, or because of a missing
//quantreg package, or...?
//todo: move text to bundle
throw new RuntimeException("Failure calling R for modal regression. R may have timed out.\n" +
"This may also be because the required \"quantreg\" package is not installed.\n"+
" To install this package, run the following lines in R:\n" +
"source(\"http://bioconductor.org/biocLite.R\")\n" +
"biocLite(c(\"quantreg\"))");
}
}
catch (Exception x)
{
ApplicationContext.errorMessage("Failed alignment: " + x.getMessage(), x);
return null;
}
finally
{
if (pw != null)
pw.close();
}
return result;
}
public double[] getModalRegressionCoefficients()
{
return modalRegressionCoefficients;
}
public int getNonlinearMappingPolynomialDegree()
{
return nonlinearMappingPolynomialDegree;
}
public void setNonlinearMappingPolynomialDegree(int nonlinearMappingPolynomialDegree)
{
this.nonlinearMappingPolynomialDegree = nonlinearMappingPolynomialDegree;
}
}