package org.seqcode.projects.seed.stats; import java.util.List; import org.seqcode.projects.seed.features.Feature; import cern.jet.random.Binomial; import cern.jet.random.engine.DRand; public class FeatureStatistics { protected Binomial binomial; public FeatureStatistics(){ binomial = new Binomial(100,.5, new DRand()); } /** * Binomial CDF assuming scaled control. Uses COLT binomial test. * Tests equality of signal & scaled control counts. * @param k = scaled control * @param n = scaled control+signal * @param minFoldChange = minimun fold difference between signal & control * @return */ public double binomialPValue(double k, double n, double minFoldChange){ double pval=1; synchronized(binomial){ binomial.setNandP((int)Math.ceil(n), 1.0 / (minFoldChange + 1.0)); pval = binomial.cdf((int) Math.ceil(k)); } return(pval); } /** * In-place FDR-based multiple testing correction by computing q-values. * Benjamini-Hochberg procedure, enforcing monotonicity of p-value increases as defined in: * Storey JD. A direct approach to false discovery rates. Journal of the Royal Statistical Society. 2002;64:479-498 * */ public void benjaminiHochbergCorrection(List<Feature> features){ if(features.size()>0 && features.get(0).scoreIsAPValue){ double total = (double)features.size(); double rank = (double)features.size(); //Correct the lowest ranked item first double q = Math.min(features.get(features.size()-1).getScore()*(total/rank), 1); features.get(features.size()-1).setScore(q); //Iterate backwards for(int i=features.size()-2; i>=0; i--){ Feature fi = features.get(i); rank--; //Set q-value based q = Math.min(fi.getScore()*(total/rank), features.get(i+1).getScore()); fi.setScore(q); } } } //TODO: IDR method }