mev-4.0.01/source/org/tigr/microarray/mev/cluster/algorithm/impl/ease/EASE.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 /*
2 26 Feb 07 jari 2 Copyright @ 1999-2003, The Institute for Genomic Research (TIGR).
2 26 Feb 07 jari 3 All rights reserved.
2 26 Feb 07 jari 4  */
2 26 Feb 07 jari 5 /*
2 26 Feb 07 jari 6  * $RCSfile: EASE.java,v $
2 26 Feb 07 jari 7  * $Revision: 1.7 $
2 26 Feb 07 jari 8  * $Date: 2006/02/23 20:59:45 $
2 26 Feb 07 jari 9  * $Author: caliente $
2 26 Feb 07 jari 10  * $State: Exp $
2 26 Feb 07 jari 11  */
2 26 Feb 07 jari 12
2 26 Feb 07 jari 13 package org.tigr.microarray.mev.cluster.algorithm.impl.ease;
2 26 Feb 07 jari 14
2 26 Feb 07 jari 15 import java.io.BufferedReader;
2 26 Feb 07 jari 16 import java.io.File;
2 26 Feb 07 jari 17 import java.io.FileNotFoundException;
2 26 Feb 07 jari 18 import java.io.FileReader;
2 26 Feb 07 jari 19 import java.io.IOException;
2 26 Feb 07 jari 20 import java.text.DecimalFormat;
2 26 Feb 07 jari 21 import java.util.Hashtable;
2 26 Feb 07 jari 22 import java.util.Random;
2 26 Feb 07 jari 23 import java.util.StringTokenizer;
2 26 Feb 07 jari 24 import java.util.Vector;
2 26 Feb 07 jari 25
2 26 Feb 07 jari 26 import javax.swing.JFrame;
2 26 Feb 07 jari 27 import javax.swing.JOptionPane;
2 26 Feb 07 jari 28
2 26 Feb 07 jari 29 import org.tigr.microarray.mev.cluster.algorithm.AbstractAlgorithm;
2 26 Feb 07 jari 30 import org.tigr.microarray.mev.cluster.algorithm.AlgorithmData;
2 26 Feb 07 jari 31 import org.tigr.microarray.mev.cluster.algorithm.AlgorithmEvent;
2 26 Feb 07 jari 32 import org.tigr.microarray.mev.cluster.algorithm.AlgorithmException;
2 26 Feb 07 jari 33 import org.tigr.microarray.mev.cluster.algorithm.AlgorithmParameters;
2 26 Feb 07 jari 34 import org.tigr.util.FloatMatrix;
2 26 Feb 07 jari 35 import org.tigr.util.QSort;
2 26 Feb 07 jari 36
2 26 Feb 07 jari 37 /** Manages EASE analysis and raw result manipulation and return.
2 26 Feb 07 jari 38  * @author braisted
2 26 Feb 07 jari 39  */
2 26 Feb 07 jari 40
2 26 Feb 07 jari 41 public class EASE extends AbstractAlgorithm {
2 26 Feb 07 jari 42     
2 26 Feb 07 jari 43     private JEASEStatistics jstats;
2 26 Feb 07 jari 44     private Vector sampleVector;
2 26 Feb 07 jari 45     private Vector populationVector;
2 26 Feb 07 jari 46     
2 26 Feb 07 jari 47     private String [] annotationFileList;
2 26 Feb 07 jari 48     private String [][] result;
2 26 Feb 07 jari 49     private String [][] hitList;
2 26 Feb 07 jari 50     private String [] categoryNames;
2 26 Feb 07 jari 51     /** True if accession numbers are appended.
2 26 Feb 07 jari 52      */
2 26 Feb 07 jari 53     private boolean haveAccessionNumbers = false;
2 26 Feb 07 jari 54     private boolean reportEaseScore = false;
2 26 Feb 07 jari 55     private AlgorithmEvent event;
2 26 Feb 07 jari 56     private Vector headerNames;
2 26 Feb 07 jari 57     private DecimalFormat format;
2 26 Feb 07 jari 58     private FloatMatrix expData;
2 26 Feb 07 jari 59     
2 26 Feb 07 jari 60     private boolean stop = false;
2 26 Feb 07 jari 61     private boolean performClusterAnalysis;
2 26 Feb 07 jari 62     
2 26 Feb 07 jari 63     long start;
2 26 Feb 07 jari 64     /** Creates a new instance of ease (Default)
2 26 Feb 07 jari 65      */
2 26 Feb 07 jari 66     public EASE() {
2 26 Feb 07 jari 67     }
2 26 Feb 07 jari 68     
2 26 Feb 07 jari 69     public void abort() {
2 26 Feb 07 jari 70         stop = true;
2 26 Feb 07 jari 71     }
2 26 Feb 07 jari 72     
2 26 Feb 07 jari 73     /** Recieves parameters, executes algorithm and returns the result in the <CODE>AlgorithmData</CODE> object.
2 26 Feb 07 jari 74      * @param algorithmData Intput data and parameters
2 26 Feb 07 jari 75      * @throws AlgorithmException Reports errors or abort requests
2 26 Feb 07 jari 76      * @return Returns result in <CODE>AlgorithmData</CODE>
2 26 Feb 07 jari 77      */
2 26 Feb 07 jari 78     public AlgorithmData execute(AlgorithmData algorithmData) throws AlgorithmException {
2 26 Feb 07 jari 79         //start = System.currentTimeMillis();
2 26 Feb 07 jari 80         
2 26 Feb 07 jari 81         AlgorithmParameters params = algorithmData.getParams();
2 26 Feb 07 jari 82         performClusterAnalysis = params.getBoolean("perform-cluster-analysis", true);
2 26 Feb 07 jari 83         expData = algorithmData.getMatrix("expression");
2 26 Feb 07 jari 84         
2 26 Feb 07 jari 85         if(performClusterAnalysis)
2 26 Feb 07 jari 86             return performClusterAnnotationAnalysis(algorithmData);
2 26 Feb 07 jari 87         else{
2 26 Feb 07 jari 88             return performSlideAnnotationSurvey(algorithmData);
2 26 Feb 07 jari 89         }
2 26 Feb 07 jari 90     }
2 26 Feb 07 jari 91     
2 26 Feb 07 jari 92     /** Main method for cluster analysis.
2 26 Feb 07 jari 93      * @param algorithmData Input data and parameters.
2 26 Feb 07 jari 94      * @throws AlgorithmException
2 26 Feb 07 jari 95      * @return
2 26 Feb 07 jari 96      */
2 26 Feb 07 jari 97     private AlgorithmData performClusterAnnotationAnalysis(AlgorithmData algorithmData) throws AlgorithmException {
2 26 Feb 07 jari 98         AlgorithmParameters params = algorithmData.getParams();
2 26 Feb 07 jari 99         
2 26 Feb 07 jari 100         headerNames = new Vector();
2 26 Feb 07 jari 101         reportEaseScore = params.getBoolean("report-ease-score", false);
2 26 Feb 07 jari 102         intializeHeaderNames();
2 26 Feb 07 jari 103         
2 26 Feb 07 jari 104         format = new DecimalFormat("0.###E00");
2 26 Feb 07 jari 105         
2 26 Feb 07 jari 106         event = new AlgorithmEvent(this, AlgorithmEvent.MONITOR_VALUE, 0);
2 26 Feb 07 jari 107         event.setDescription("Start EASE Analyis\n");
2 26 Feb 07 jari 108         fireValueChanged(event);
2 26 Feb 07 jari 109         
2 26 Feb 07 jari 110         String converterFileName = params.getString("converter-file-name");
2 26 Feb 07 jari 111         int [] clusterIndices = algorithmData.getIntArray("sample-indices");
2 26 Feb 07 jari 112         String [] sampleList = algorithmData.getStringArray("sample-list");
2 26 Feb 07 jari 113         String [] populationList = algorithmData.getStringArray("population-list");
2 26 Feb 07 jari 114         annotationFileList = algorithmData.getStringArray("annotation-file-list");
2 26 Feb 07 jari 115         
2 26 Feb 07 jari 116         EaseElementList sampleElementList = new EaseElementList(clusterIndices, sampleList);
2 26 Feb 07 jari 117         EaseElementList populationElementList = new EaseElementList(populationList);
2 26 Feb 07 jari 118
2 26 Feb 07 jari 119         if(stop)
2 26 Feb 07 jari 120             return null;
2 26 Feb 07 jari 121         
2 26 Feb 07 jari 122         try{
2 26 Feb 07 jari 123             if(converterFileName != null){
2 26 Feb 07 jari 124                 event.setDescription("Loading Cluster Annotation List\n");
2 26 Feb 07 jari 125                 fireValueChanged(event);
2 26 Feb 07 jari 126                 
2 26 Feb 07 jari 127                 sampleElementList.loadValues(converterFileName);
2 26 Feb 07 jari 128                 
2 26 Feb 07 jari 129                 event.setDescription("Loading Population Annotation List\n");
2 26 Feb 07 jari 130                 fireValueChanged(event);
2 26 Feb 07 jari 131                 
2 26 Feb 07 jari 132                 populationElementList.loadValues(converterFileName);
2 26 Feb 07 jari 133             } else {
2 26 Feb 07 jari 134                 event.setDescription("Preparing Annotation Lists (no conversion file)\n");
2 26 Feb 07 jari 135                 sampleElementList.setDefaultValues();
2 26 Feb 07 jari 136                 populationElementList.setDefaultValues();
2 26 Feb 07 jari 137             }
2 26 Feb 07 jari 138         } catch (FileNotFoundException fnfe) {
2 26 Feb 07 jari 139             throw new AlgorithmException("Annotation Conversion File Not Found\n"+converterFileName+"\n"+fnfe.getMessage());
2 26 Feb 07 jari 140         } catch (IOException ioe) {
2 26 Feb 07 jari 141             throw new AlgorithmException("Error Reading File: "+converterFileName+"\n"+ioe.getMessage());
2 26 Feb 07 jari 142         }
2 26 Feb 07 jari 143         event.setDescription("Extracting Unique Cluster Annotation List\n");
2 26 Feb 07 jari 144         fireValueChanged(event);
2 26 Feb 07 jari 145         sampleVector = sampleElementList.getUniqueValueList();
2 26 Feb 07 jari 146         
2 26 Feb 07 jari 147         if(stop)
2 26 Feb 07 jari 148             return null;
2 26 Feb 07 jari 149         
2 26 Feb 07 jari 150         event.setDescription("Extracting Unique Population Annotation List\n");
2 26 Feb 07 jari 151         fireValueChanged(event);
2 26 Feb 07 jari 152         populationVector = populationElementList.getUniqueValueList();
2 26 Feb 07 jari 153         
2 26 Feb 07 jari 154         if(stop)
2 26 Feb 07 jari 155             return null;
2 26 Feb 07 jari 156         
2 26 Feb 07 jari 157         jstats = new JEASEStatistics(reportEaseScore);
2 26 Feb 07 jari 158         
2 26 Feb 07 jari 159         for(int i = 0; i < annotationFileList.length; i++){
2 26 Feb 07 jari 160             jstats.AddAnnotationFileName(annotationFileList[i]);
2 26 Feb 07 jari 161         }
2 26 Feb 07 jari 162         
2 26 Feb 07 jari 163         event.setDescription("Loading Annotation Category Files\n");
2 26 Feb 07 jari 164         fireValueChanged(event);
2 26 Feb 07 jari 165         
2 26 Feb 07 jari 166         //jstats.GetCategories();
2 26 Feb 07 jari 167         jstats.GetCategories(populationVector);
2 26 Feb 07 jari 168
2 26 Feb 07 jari 169         if(stop)
2 26 Feb 07 jari 170             return null;
2 26 Feb 07 jari 171         
2 26 Feb 07 jari 172         //alter to take the keys as args
2 26 Feb 07 jari 173         
2 26 Feb 07 jari 174         event.setDescription("Finding Sample Category Hits\n");
2 26 Feb 07 jari 175         fireValueChanged(event);
2 26 Feb 07 jari 176         jstats.GetListHitsByCategory(sampleVector);
2 26 Feb 07 jari 177         
2 26 Feb 07 jari 178         if(stop)
2 26 Feb 07 jari 179             return null;
2 26 Feb 07 jari 180         
2 26 Feb 07 jari 181         //alter to take keys as arguments
2 26 Feb 07 jari 182         event.setDescription("Finding Population Category Hits\n");
2 26 Feb 07 jari 183         fireValueChanged(event);
2 26 Feb 07 jari 184         jstats.GetPopulationHitsByCategory(populationVector);
2 26 Feb 07 jari 185         
2 26 Feb 07 jari 186         event.setDescription("Statistical Testing and Result Prep.\n");
2 26 Feb 07 jari 187         fireValueChanged(event);
2 26 Feb 07 jari 188         jstats.ConstructResults();
2 26 Feb 07 jari 189         
2 26 Feb 07 jari 190         result = jstats.getResults();
2 26 Feb 07 jari 191         
2 26 Feb 07 jari 192         //if the result set is empty, return.
2 26 Feb 07 jari 193         if(result.length < 1) {
2 26 Feb 07 jari 194             return algorithmData;
2 26 Feb 07 jari 195         }
2 26 Feb 07 jari 196         
2 26 Feb 07 jari 197         hitList = jstats.getListHitMatrix();
2 26 Feb 07 jari 198         categoryNames = jstats.getCategoryNames();
2 26 Feb 07 jari 199         
2 26 Feb 07 jari 200         event.setDescription("Sorting Result on p-value\n");
2 26 Feb 07 jari 201         fireValueChanged(event);
2 26 Feb 07 jari 202         sortResults();
2 26 Feb 07 jari 203         
2 26 Feb 07 jari 204         if(stop)
2 26 Feb 07 jari 205             return null;
2 26 Feb 07 jari 206         
2 26 Feb 07 jari 207         if(algorithmData.getParams().getBoolean("p-value-corrections", false)){
2 26 Feb 07 jari 208             event.setDescription("Applying p-value Multiplicity Corrections\n");
2 26 Feb 07 jari 209             fireValueChanged(event);
2 26 Feb 07 jari 210             pValueCorrections(algorithmData);
2 26 Feb 07 jari 211         }
2 26 Feb 07 jari 212         
2 26 Feb 07 jari 213         if(algorithmData.getParams().getBoolean("run-permutation-analysis", false)){
2 26 Feb 07 jari 214             event.setDescription("Resampling Analysis\n");
2 26 Feb 07 jari 215             fireValueChanged(event);
2 26 Feb 07 jari 216             permutationAnalysis(algorithmData.getParams().getInt("permutation-count", 1));
2 26 Feb 07 jari 217         }
2 26 Feb 07 jari 218         
2 26 Feb 07 jari 219         if(stop)
2 26 Feb 07 jari 220             return null;
2 26 Feb 07 jari 221         
2 26 Feb 07 jari 222         event.setDescription("Appending Accessions\n");
2 26 Feb 07 jari 223         fireValueChanged(event);
2 26 Feb 07 jari 224         result = appendAccessions(result, annotationFileList);
2 26 Feb 07 jari 225         algorithmData.addParam("have-accession-numbers", String.valueOf(haveAccessionNumbers));
2 26 Feb 07 jari 226         
2 26 Feb 07 jari 227         //apply trim options
2 26 Feb 07 jari 228         String trimOption = params.getString("trim-option");
2 26 Feb 07 jari 229         float trimValue;
2 26 Feb 07 jari 230         if(!(trimOption.equals("NO_TRIM"))){
2 26 Feb 07 jari 231             event.setDescription("Trim Result\n");
2 26 Feb 07 jari 232             fireValueChanged(event);
2 26 Feb 07 jari 233             trimValue = params.getFloat("trim-value");
2 26 Feb 07 jari 234             trimResult(trimOption, trimValue);
2 26 Feb 07 jari 235         }
2 26 Feb 07 jari 236         
2 26 Feb 07 jari 237         event.setDescription("Indexing Result\n");
2 26 Feb 07 jari 238         fireValueChanged(event);
2 26 Feb 07 jari 239         indexResult();
2 26 Feb 07 jari 240         
2 26 Feb 07 jari 241         algorithmData.addObjectMatrix("result-matrix", result);
2 26 Feb 07 jari 242         algorithmData.addObjectMatrix("hit-list-matrix", hitList);
2 26 Feb 07 jari 243         
2 26 Feb 07 jari 244         //get sorted clusters
2 26 Feb 07 jari 245         event.setDescription("Extracting Cluster Indices and Stats\n");
2 26 Feb 07 jari 246         fireValueChanged(event);
2 26 Feb 07 jari 247         int [][] clusters = getClusters(sampleElementList, hitList);
2 26 Feb 07 jari 248         
2 26 Feb 07 jari 249         algorithmData.addStringArray("category-names", categoryNames);
2 26 Feb 07 jari 250         algorithmData.addIntMatrix("cluster-matrix", clusters);
2 26 Feb 07 jari 251         
2 26 Feb 07 jari 252         algorithmData.addStringArray("header-names", getHeaderNames());
2 26 Feb 07 jari 253         
2 26 Feb 07 jari 254         FloatMatrix means = getMeans(expData, clusters);
2 26 Feb 07 jari 255         algorithmData.addMatrix("means", means);
2 26 Feb 07 jari 256         algorithmData.addMatrix("variances", getVariances(expData, means, clusters));
2 26 Feb 07 jari 257         
2 26 Feb 07 jari 258         if(stop)
2 26 Feb 07 jari 259             return null;
2 26 Feb 07 jari 260         
2 26 Feb 07 jari 261         //System.out.println("Duration: "+(System.currentTimeMillis()-start));        
2 26 Feb 07 jari 262         
2 26 Feb 07 jari 263         return algorithmData;
2 26 Feb 07 jari 264     }
2 26 Feb 07 jari 265     
2 26 Feb 07 jari 266     /** Alternative analysis mode (slide survey)
2 26 Feb 07 jari 267      * @param algorithmData
2 26 Feb 07 jari 268      * @throws AlgorithmException
2 26 Feb 07 jari 269      * @return  */
2 26 Feb 07 jari 270     private AlgorithmData performSlideAnnotationSurvey(AlgorithmData algorithmData) throws AlgorithmException {
2 26 Feb 07 jari 271         AlgorithmParameters params = algorithmData.getParams();
2 26 Feb 07 jari 272         
2 26 Feb 07 jari 273         headerNames = new Vector();
2 26 Feb 07 jari 274         intializeHeaderNames();
2 26 Feb 07 jari 275         format = new DecimalFormat("0.###E00");
2 26 Feb 07 jari 276         
2 26 Feb 07 jari 277         AlgorithmEvent event = new AlgorithmEvent(this, AlgorithmEvent.MONITOR_VALUE, 0);
2 26 Feb 07 jari 278         event.setDescription("Start Survey\n");
2 26 Feb 07 jari 279         fireValueChanged(event);
2 26 Feb 07 jari 280         
2 26 Feb 07 jari 281         
2 26 Feb 07 jari 282         String converterFileName = params.getString("converter-file-name");
2 26 Feb 07 jari 283         String [] populationList = algorithmData.getStringArray("population-list");
2 26 Feb 07 jari 284         String [] annotationFileList = algorithmData.getStringArray("annotation-file-list");
2 26 Feb 07 jari 285         EaseElementList populationElementList = new EaseElementList(populationList);
2 26 Feb 07 jari 286         
2 26 Feb 07 jari 287         try{
2 26 Feb 07 jari 288             if(converterFileName != null){
2 26 Feb 07 jari 289                 event.setDescription("Loading Population Annotation List\n");
2 26 Feb 07 jari 290                 fireValueChanged(event);
2 26 Feb 07 jari 291                 populationElementList.loadValues(converterFileName);
2 26 Feb 07 jari 292             } else {
2 26 Feb 07 jari 293                 event.setDescription("Preparing Annotation Lists (no conversion file)\n");
2 26 Feb 07 jari 294                 populationElementList.setDefaultValues();
2 26 Feb 07 jari 295             }
2 26 Feb 07 jari 296         } catch (FileNotFoundException fnfe) {
2 26 Feb 07 jari 297             throw new AlgorithmException("Annotation Conversion File Not Found\n"+converterFileName+"\n"+fnfe.getMessage());
2 26 Feb 07 jari 298         } catch (IOException ioe) {
2 26 Feb 07 jari 299             throw new AlgorithmException("Error Reading File: "+converterFileName+"\n"+ioe.getMessage());
2 26 Feb 07 jari 300         }
2 26 Feb 07 jari 301         
2 26 Feb 07 jari 302         event.setDescription("Extracting Unique Population Annotation List\n");
2 26 Feb 07 jari 303         fireValueChanged(event);
2 26 Feb 07 jari 304         populationVector = populationElementList.getUniqueValueList();
2 26 Feb 07 jari 305         
2 26 Feb 07 jari 306         jstats = new JEASEStatistics();
2 26 Feb 07 jari 307         
2 26 Feb 07 jari 308         for(int i = 0; i < annotationFileList.length; i++){
2 26 Feb 07 jari 309             jstats.AddAnnotationFileName(annotationFileList[i]);
2 26 Feb 07 jari 310         }
2 26 Feb 07 jari 311         
2 26 Feb 07 jari 312         event.setDescription("Reading Annotation Category Files into Memory\n");
2 26 Feb 07 jari 313         fireValueChanged(event);
2 26 Feb 07 jari 314         jstats.GetCategories();
2 26 Feb 07 jari 315         
2 26 Feb 07 jari 316         event.setDescription("Finding Population Category Hits\n");
2 26 Feb 07 jari 317         fireValueChanged(event);
2 26 Feb 07 jari 318         jstats.GetPopulationHitsByCategoryForSurvey(populationVector);
2 26 Feb 07 jari 319         
2 26 Feb 07 jari 320         event.setDescription("Result Prep.\n");
2 26 Feb 07 jari 321         fireValueChanged(event);
2 26 Feb 07 jari 322         jstats.ConstructSurveyResults();
2 26 Feb 07 jari 323         
2 26 Feb 07 jari 324         result = jstats.getSurveyResults();
2 26 Feb 07 jari 325         
2 26 Feb 07 jari 326         //if the result set is empty, return.
2 26 Feb 07 jari 327         if(result.length < 1)
2 26 Feb 07 jari 328             return algorithmData;
2 26 Feb 07 jari 329         
2 26 Feb 07 jari 330         hitList = jstats.getListHitMatrix();
2 26 Feb 07 jari 331         categoryNames = jstats.getCategoryNames();
2 26 Feb 07 jari 332         
2 26 Feb 07 jari 333         event.setDescription("Sorting Result on hit count\n");
2 26 Feb 07 jari 334         fireValueChanged(event);
2 26 Feb 07 jari 335         sortSurveyResults();
2 26 Feb 07 jari 336         
2 26 Feb 07 jari 337         event.setDescription("Appending Accessions\n");
2 26 Feb 07 jari 338         fireValueChanged(event);
2 26 Feb 07 jari 339         result = appendAccessions(result, annotationFileList);
2 26 Feb 07 jari 340         algorithmData.addParam("have-accession-numbers", String.valueOf(haveAccessionNumbers));
2 26 Feb 07 jari 341         algorithmData.addStringArray("header-names", getHeaderNames());
2 26 Feb 07 jari 342         
2 26 Feb 07 jari 343         //apply trim options
2 26 Feb 07 jari 344         String trimOption = params.getString("trim-option");
2 26 Feb 07 jari 345         float trimValue;
2 26 Feb 07 jari 346         if(!(trimOption.equals("NO_TRIM"))){
2 26 Feb 07 jari 347             event.setDescription("Trim Result\n");
2 26 Feb 07 jari 348             fireValueChanged(event);
2 26 Feb 07 jari 349             trimValue = params.getFloat("trim-value");
2 26 Feb 07 jari 350             trimResult(trimOption, trimValue);
2 26 Feb 07 jari 351         }
2 26 Feb 07 jari 352         
2 26 Feb 07 jari 353         event.setDescription("Indexing Result\n");
2 26 Feb 07 jari 354         fireValueChanged(event);
2 26 Feb 07 jari 355         indexResult();
2 26 Feb 07 jari 356         
2 26 Feb 07 jari 357         algorithmData.addObjectMatrix("result-matrix", result);
2 26 Feb 07 jari 358         algorithmData.addObjectMatrix("hit-list-matrix", hitList);
2 26 Feb 07 jari 359         
2 26 Feb 07 jari 360         //get sorted clusters
2 26 Feb 07 jari 361         event.setDescription("Extracting Cluster Indices and Stats\n");
2 26 Feb 07 jari 362         fireValueChanged(event);
2 26 Feb 07 jari 363         int [][] clusters = getClusters(populationElementList, hitList);
2 26 Feb 07 jari 364         
2 26 Feb 07 jari 365         algorithmData.addStringArray("category-names", categoryNames);
2 26 Feb 07 jari 366         algorithmData.addIntMatrix("cluster-matrix", clusters);
2 26 Feb 07 jari 367         
2 26 Feb 07 jari 368         FloatMatrix means = getMeans(expData, clusters);
2 26 Feb 07 jari 369         algorithmData.addMatrix("means", means);
2 26 Feb 07 jari 370         algorithmData.addMatrix("variances", getVariances(expData, means, clusters));
2 26 Feb 07 jari 371         
2 26 Feb 07 jari 372         return algorithmData;
2 26 Feb 07 jari 373     }
2 26 Feb 07 jari 374     
2 26 Feb 07 jari 375     /** Creates header names based on analysis mode.
2 26 Feb 07 jari 376      */
2 26 Feb 07 jari 377     private void intializeHeaderNames(){
2 26 Feb 07 jari 378         if(performClusterAnalysis){
2 26 Feb 07 jari 379             headerNames.add("Index");
2 26 Feb 07 jari 380             headerNames.add("File");
2 26 Feb 07 jari 381             headerNames.add("Term");
2 26 Feb 07 jari 382             headerNames.add("List Hits");
2 26 Feb 07 jari 383             headerNames.add("List Size");
2 26 Feb 07 jari 384             headerNames.add("Pop. Hits");
2 26 Feb 07 jari 385             headerNames.add("Pop. Size");
2 26 Feb 07 jari 386             if(reportEaseScore)
2 26 Feb 07 jari 387                 headerNames.add("EASE Score");
2 26 Feb 07 jari 388             else
2 26 Feb 07 jari 389                 headerNames.add("Fisher's Exact");
2 26 Feb 07 jari 390         } else {
2 26 Feb 07 jari 391             headerNames.add("Index");
2 26 Feb 07 jari 392             headerNames.add("File");
2 26 Feb 07 jari 393             headerNames.add("Term");
2 26 Feb 07 jari 394             headerNames.add("Pop. Hits");
2 26 Feb 07 jari 395             headerNames.add("Pop. Size");
2 26 Feb 07 jari 396         }
2 26 Feb 07 jari 397     }
2 26 Feb 07 jari 398     
2 26 Feb 07 jari 399     /** Returns cluster indices
2 26 Feb 07 jari 400      * @param clusterList list of cluster indices
2 26 Feb 07 jari 401      * @param hitList List of acc. in each category
2 26 Feb 07 jari 402      * @return
2 26 Feb 07 jari 403      */
2 26 Feb 07 jari 404     private int [][] getClusters(EaseElementList clusterList, String [][] hitList){
2 26 Feb 07 jari 405         int [][] clusters = new int[hitList.length][];
2 26 Feb 07 jari 406         for(int i = 0; i < hitList.length; i++){
2 26 Feb 07 jari 407             clusters[i] = clusterList.getIndices(hitList[i]);
2 26 Feb 07 jari 408         }
2 26 Feb 07 jari 409         return clusters;
2 26 Feb 07 jari 410     }
2 26 Feb 07 jari 411     
2 26 Feb 07 jari 412     
2 26 Feb 07 jari 413     /** Sorts analysis results on stat.
2 26 Feb 07 jari 414      */
2 26 Feb 07 jari 415     private void sortResults(){
2 26 Feb 07 jari 416         double [] stat = new double[result.length];
2 26 Feb 07 jari 417         int pValueIndex;
2 26 Feb 07 jari 418         if(reportEaseScore)
2 26 Feb 07 jari 419             pValueIndex =  headerNames.indexOf("EASE Score");
2 26 Feb 07 jari 420         else
2 26 Feb 07 jari 421             pValueIndex =  headerNames.indexOf("Fisher's Exact");
2 26 Feb 07 jari 422         
2 26 Feb 07 jari 423         pValueIndex--;  //subtract one since result is not indexed until after sort
2 26 Feb 07 jari 424         
2 26 Feb 07 jari 425         for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 426             stat[i] = Double.parseDouble(result[i][pValueIndex]);
2 26 Feb 07 jari 427         }
2 26 Feb 07 jari 428         QSort qsorter = new QSort(stat);
2 26 Feb 07 jari 429         stat = qsorter.getSortedDouble();
2 26 Feb 07 jari 430         
2 26 Feb 07 jari 431         int [] orderedIndices = qsorter.getOrigIndx();
2 26 Feb 07 jari 432         
2 26 Feb 07 jari 433         String [] holder;
2 26 Feb 07 jari 434         String nameHolder;
2 26 Feb 07 jari 435         
2 26 Feb 07 jari 436         String [] newCatNames = new String[categoryNames.length];
2 26 Feb 07 jari 437         String [][] newHitList = new String[hitList.length][];
2 26 Feb 07 jari 438         String [][] newResult = new String[result.length][];
2 26 Feb 07 jari 439         
2 26 Feb 07 jari 440         for(int i = 0; i < orderedIndices.length; i++){
2 26 Feb 07 jari 441             newCatNames[i] = categoryNames[orderedIndices[i]];
2 26 Feb 07 jari 442             newHitList[i] = hitList[orderedIndices[i]];
2 26 Feb 07 jari 443             newResult[i] = result[orderedIndices[i]];
2 26 Feb 07 jari 444         }
2 26 Feb 07 jari 445         
2 26 Feb 07 jari 446         //format the pvalues
2 26 Feb 07 jari 447         for(int i = 0; i < newResult.length; i++) {
2 26 Feb 07 jari 448           newResult[i][pValueIndex] = format.format(Double.parseDouble(newResult[i][pValueIndex]));
2 26 Feb 07 jari 449           
2 26 Feb 07 jari 450           //handles international conventions where comma denotes decimal
2 26 Feb 07 jari 451           newResult[i][pValueIndex] = newResult[i][pValueIndex].replace(',','.');
2 26 Feb 07 jari 452         }
2 26 Feb 07 jari 453         
2 26 Feb 07 jari 454         categoryNames = newCatNames;
2 26 Feb 07 jari 455         hitList = newHitList;
2 26 Feb 07 jari 456         result = newResult;
2 26 Feb 07 jari 457     }
2 26 Feb 07 jari 458     
2 26 Feb 07 jari 459     
2 26 Feb 07 jari 460     /** Sorts survey analysis results on population hits (high --> low)
2 26 Feb 07 jari 461      */
2 26 Feb 07 jari 462     private void sortSurveyResults(){
2 26 Feb 07 jari 463         double [] hitCounts = new double[result.length];
2 26 Feb 07 jari 464         int hitIndex = this.headerNames.indexOf("Pop. Hits");
2 26 Feb 07 jari 465         hitIndex--; //decrement since no indexes inserted yet.
2 26 Feb 07 jari 466         for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 467             hitCounts[i] = Double.parseDouble(result[i][hitIndex]);
2 26 Feb 07 jari 468         }
2 26 Feb 07 jari 469         QSort qsorter = new QSort(hitCounts);
2 26 Feb 07 jari 470         hitCounts = qsorter.getSortedDouble();
2 26 Feb 07 jari 471         
2 26 Feb 07 jari 472         int [] orderedIndices = qsorter.getOrigIndx();
2 26 Feb 07 jari 473         
2 26 Feb 07 jari 474         String [] holder;
2 26 Feb 07 jari 475         String nameHolder;
2 26 Feb 07 jari 476         
2 26 Feb 07 jari 477         String [] newCatNames = new String[categoryNames.length];
2 26 Feb 07 jari 478         String [][] newHitList = new String[hitList.length][];
2 26 Feb 07 jari 479         String [][] newResult = new String[result.length][];
2 26 Feb 07 jari 480         
2 26 Feb 07 jari 481         //order high to low
2 26 Feb 07 jari 482         int index = 0;
2 26 Feb 07 jari 483         for(int i = orderedIndices.length-1; i >= 0; i--){
2 26 Feb 07 jari 484             newCatNames[index] = categoryNames[orderedIndices[i]];
2 26 Feb 07 jari 485             newHitList[index] = hitList[orderedIndices[i]];
2 26 Feb 07 jari 486             newResult[index] = result[orderedIndices[i]];
2 26 Feb 07 jari 487             index++;
2 26 Feb 07 jari 488         }
2 26 Feb 07 jari 489         
2 26 Feb 07 jari 490         categoryNames = newCatNames;
2 26 Feb 07 jari 491         hitList = newHitList;
2 26 Feb 07 jari 492         result = newResult;
2 26 Feb 07 jari 493     }
2 26 Feb 07 jari 494     
2 26 Feb 07 jari 495     
2 26 Feb 07 jari 496     /** Appends accessions
2 26 Feb 07 jari 497      * @param resultMatrix Result matrix input.
2 26 Feb 07 jari 498      * @param fileNames File names.
2 26 Feb 07 jari 499      * @return
2 26 Feb 07 jari 500      */
2 26 Feb 07 jari 501     private String [][] appendAccessions(String [][] resultMatrix, String [] fileNames){
2 26 Feb 07 jari 502         
2 26 Feb 07 jari 503         if(resultMatrix == null || resultMatrix.length < 1)
2 26 Feb 07 jari 504             return resultMatrix;
2 26 Feb 07 jari 505         
2 26 Feb 07 jari 506         String [][] newResult = null;
2 26 Feb 07 jari 507         File file = null;
2 26 Feb 07 jari 508         haveAccessionNumbers = false;
2 26 Feb 07 jari 509         try{
2 26 Feb 07 jari 510             for(int i = 0; i < fileNames.length; i++){
2 26 Feb 07 jari 511                 file = getAccessionFile(fileNames[i]);
2 26 Feb 07 jari 512                 
2 26 Feb 07 jari 513                 if(file.isFile()){
2 26 Feb 07 jari 514                     if(!haveAccessionNumbers){
2 26 Feb 07 jari 515                         newResult = new String[resultMatrix.length][resultMatrix[0].length+1];
2 26 Feb 07 jari 516                         initializeNewResult(newResult, resultMatrix);
2 26 Feb 07 jari 517                         headerNames.insertElementAt("Acc.", 2);  //add header name
2 26 Feb 07 jari 518                     }
2 26 Feb 07 jari 519                     insertAccessions(file, newResult);
2 26 Feb 07 jari 520                     haveAccessionNumbers = true;
2 26 Feb 07 jari 521                     resultMatrix = newResult;  // added to handle multiple files
2 26 Feb 07 jari 522                 }
2 26 Feb 07 jari 523             }
2 26 Feb 07 jari 524         }  catch (IOException ioe){
2 26 Feb 07 jari 525             JOptionPane.showMessageDialog(new JFrame(), "Error in collecting accessions following analysis" +
2 26 Feb 07 jari 526             " from file: "+file.getName()+"\n Results will not have accessions.  Please check file location"+
2 26 Feb 07 jari 527             " and format", "File Error", JOptionPane.WARNING_MESSAGE);
2 26 Feb 07 jari 528             return result;  // return original result
2 26 Feb 07 jari 529         }
2 26 Feb 07 jari 530         if(haveAccessionNumbers)
2 26 Feb 07 jari 531             return newResult;
2 26 Feb 07 jari 532         else
2 26 Feb 07 jari 533             return resultMatrix;
2 26 Feb 07 jari 534     }
2 26 Feb 07 jari 535     
2 26 Feb 07 jari 536     /** Builds a result copy
2 26 Feb 07 jari 537      */
2 26 Feb 07 jari 538     private void initializeNewResult(String [][] newResult, String [][] oldResult){
2 26 Feb 07 jari 539         for(int i = 0; i < newResult.length; i++){
2 26 Feb 07 jari 540             for(int j = 0; j < oldResult[0].length; j++){
2 26 Feb 07 jari 541                 if(j < 1)
2 26 Feb 07 jari 542                     newResult[i][j] = oldResult[i][j];
2 26 Feb 07 jari 543                 else
2 26 Feb 07 jari 544                     newResult[i][j+1] = oldResult[i][j];
2 26 Feb 07 jari 545             }
2 26 Feb 07 jari 546         }
2 26 Feb 07 jari 547         //initialize the acc column
2 26 Feb 07 jari 548         for(int i = 0; i < newResult.length; i++)
2 26 Feb 07 jari 549             newResult[i][1] = " ";
2 26 Feb 07 jari 550     }
2 26 Feb 07 jari 551     
2 26 Feb 07 jari 552     
2 26 Feb 07 jari 553     /** Inserts an index for each record in the result after sorting
2 26 Feb 07 jari 554      */
2 26 Feb 07 jari 555     private void indexResult(){
2 26 Feb 07 jari 556         if(result == null || result.length < 1)
2 26 Feb 07 jari 557             return;
2 26 Feb 07 jari 558         String [][] newResult = new String[result.length][result[0].length+1];
2 26 Feb 07 jari 559         for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 560             newResult[i][0] = String.valueOf(i+1);
2 26 Feb 07 jari 561             for(int j = 1; j < newResult[0].length; j++){
2 26 Feb 07 jari 562                 newResult[i][j] = result[i][j-1];
2 26 Feb 07 jari 563             }
2 26 Feb 07 jari 564         }
2 26 Feb 07 jari 565         result = newResult;
2 26 Feb 07 jari 566     }
2 26 Feb 07 jari 567     
2 26 Feb 07 jari 568     
2 26 Feb 07 jari 569     /** Insert accession numbers if they exist.
2 26 Feb 07 jari 570      * @param file file object
2 26 Feb 07 jari 571      * @param result Result data
2 26 Feb 07 jari 572      * @throws IOException
2 26 Feb 07 jari 573      */
2 26 Feb 07 jari 574     private void insertAccessions(File file, String [][] result) throws IOException {
2 26 Feb 07 jari 575         if(file == null)
2 26 Feb 07 jari 576             return;
2 26 Feb 07 jari 577         
2 26 Feb 07 jari 578         BufferedReader fr = new BufferedReader(new FileReader(file));
2 26 Feb 07 jari 579         String line;
2 26 Feb 07 jari 580         Hashtable accHash = new Hashtable();
2 26 Feb 07 jari 581         StringTokenizer stok;
2 26 Feb 07 jari 582         while( (line = fr.readLine()) != null){
2 26 Feb 07 jari 583             stok = new StringTokenizer(line, "\t");
2 26 Feb 07 jari 584             accHash.put(stok.nextToken(), stok.nextToken());
2 26 Feb 07 jari 585         }
2 26 Feb 07 jari 586         String acc;
2 26 Feb 07 jari 587         
2 26 Feb 07 jari 588         for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 589             acc = (String)accHash.get(result[i][2]);
2 26 Feb 07 jari 590             if(acc != null)
2 26 Feb 07 jari 591                 result[i][1] = acc;
2 26 Feb 07 jari 592         }
2 26 Feb 07 jari 593         
2 26 Feb 07 jari 594     }
2 26 Feb 07 jari 595     
2 26 Feb 07 jari 596     /** Creates the <CODE>File</CODE> object containing the
2 26 Feb 07 jari 597      * accessions (or indices)
2 26 Feb 07 jari 598      * @param fileName File name String
2 26 Feb 07 jari 599      * @return
2 26 Feb 07 jari 600      */
2 26 Feb 07 jari 601     private File getAccessionFile(String fileName){
2 26 Feb 07 jari 602         String sep = System.getProperty("file.separator");
2 26 Feb 07 jari 603         File file = new File(fileName);
2 26 Feb 07 jari 604         String accFileName = file.getName();
2 26 Feb 07 jari 605         file = file.getParentFile();
2 26 Feb 07 jari 606         file = new File(file.getPath()+sep+"URL data"+sep+"Tags"+sep+accFileName);
2 26 Feb 07 jari 607         return file;
2 26 Feb 07 jari 608     }
2 26 Feb 07 jari 609     
2 26 Feb 07 jari 610     /** Returns header names based on criteria of the analysis mode and
2 26 Feb 07 jari 611      * depending on if accessions are found.
2 26 Feb 07 jari 612      * @return  */
2 26 Feb 07 jari 613     private String [] getHeaderNames(){
2 26 Feb 07 jari 614         String [] headerNamesArray = new String[headerNames.size()];
2 26 Feb 07 jari 615         for(int i = 0; i < headerNamesArray.length; i++){
2 26 Feb 07 jari 616             headerNamesArray[i] = (String)(headerNames.elementAt(i));
2 26 Feb 07 jari 617         }
2 26 Feb 07 jari 618         return headerNamesArray;
2 26 Feb 07 jari 619     }
2 26 Feb 07 jari 620     
2 26 Feb 07 jari 621     /**
2 26 Feb 07 jari 622      *  Calculates means for the clusters
2 26 Feb 07 jari 623      */
2 26 Feb 07 jari 624     private FloatMatrix getMeans(FloatMatrix data, int [][] clusters){
2 26 Feb 07 jari 625         FloatMatrix means = new FloatMatrix(clusters.length, data.getColumnDimension());
2 26 Feb 07 jari 626         for(int i = 0; i < clusters.length; i++){
2 26 Feb 07 jari 627             means.A[i] = getMeans(data, clusters[i]);
2 26 Feb 07 jari 628         }
2 26 Feb 07 jari 629         return means;
2 26 Feb 07 jari 630     }
2 26 Feb 07 jari 631     
2 26 Feb 07 jari 632     /**
2 26 Feb 07 jari 633      *  Returns a set of means for an element
2 26 Feb 07 jari 634      */
2 26 Feb 07 jari 635     private float [] getMeans(FloatMatrix data, int [] indices){
2 26 Feb 07 jari 636         int nSamples = data.getColumnDimension();
2 26 Feb 07 jari 637         float [] means = new float[nSamples];
2 26 Feb 07 jari 638         float sum = 0;
2 26 Feb 07 jari 639         float n = 0;
2 26 Feb 07 jari 640         float value;
2 26 Feb 07 jari 641         for(int i = 0; i < nSamples; i++){
2 26 Feb 07 jari 642             n = 0;
2 26 Feb 07 jari 643             sum = 0;
2 26 Feb 07 jari 644             for(int j = 0; j < indices.length; j++){
2 26 Feb 07 jari 645                 value = data.get(indices[j],i);
2 26 Feb 07 jari 646                 if(!Float.isNaN(value)){
2 26 Feb 07 jari 647                     sum += value;
2 26 Feb 07 jari 648                     n++;
2 26 Feb 07 jari 649                 }
2 26 Feb 07 jari 650             }
2 26 Feb 07 jari 651             if(n > 0)
2 26 Feb 07 jari 652                 means[i] = sum/n;
2 26 Feb 07 jari 653             else
2 26 Feb 07 jari 654                 means[i] = Float.NaN;
2 26 Feb 07 jari 655         }
2 26 Feb 07 jari 656         return means;
2 26 Feb 07 jari 657     }
2 26 Feb 07 jari 658     
2 26 Feb 07 jari 659     /** Returns a matrix of standard deviations grouped by cluster and element
2 26 Feb 07 jari 660      * @param data Expression data
2 26 Feb 07 jari 661      * @param means calculated means
2 26 Feb 07 jari 662      * @param clusters cluster indices
2 26 Feb 07 jari 663      * @return
2 26 Feb 07 jari 664      */
2 26 Feb 07 jari 665     private FloatMatrix getVariances(FloatMatrix data, FloatMatrix means, int [][] clusters){
2 26 Feb 07 jari 666         int nSamples = data.getColumnDimension();
2 26 Feb 07 jari 667         FloatMatrix variances = new FloatMatrix(clusters.length, nSamples);
2 26 Feb 07 jari 668         for(int i = 0; i < clusters.length; i++){
2 26 Feb 07 jari 669             variances.A[i] = getVariances(data, means, clusters[i], i);
2 26 Feb 07 jari 670         }
2 26 Feb 07 jari 671         return variances;
2 26 Feb 07 jari 672     }
2 26 Feb 07 jari 673     
2 26 Feb 07 jari 674     /** Calculates the standard deviation for a set of genes.  One SD for each experiment point
2 26 Feb 07 jari 675      * in the expression vectors.
2 26 Feb 07 jari 676      * @param data Expression data
2 26 Feb 07 jari 677      * @param means previously calculated means
2 26 Feb 07 jari 678      * @param indices gene indices for cluster members
2 26 Feb 07 jari 679      * @param clusterIndex the index for the cluster to work upon
2 26 Feb 07 jari 680      * @return
2 26 Feb 07 jari 681      */
2 26 Feb 07 jari 682     private float [] getVariances(FloatMatrix data, FloatMatrix means, int [] indices, int clusterIndex){
2 26 Feb 07 jari 683         int nSamples = data.getColumnDimension();
2 26 Feb 07 jari 684         float [] variances = new float[nSamples];
2 26 Feb 07 jari 685         float sse = 0;
2 26 Feb 07 jari 686         float mean;
2 26 Feb 07 jari 687         float value;
2 26 Feb 07 jari 688         int n = 0;
2 26 Feb 07 jari 689         for(int i = 0; i < nSamples; i++){
2 26 Feb 07 jari 690             mean = means.get(clusterIndex, i);
2 26 Feb 07 jari 691             n = 0;
2 26 Feb 07 jari 692             sse = 0;
2 26 Feb 07 jari 693             for(int j = 0; j < indices.length; j++){
2 26 Feb 07 jari 694                 value = data.get(indices[j], i);
2 26 Feb 07 jari 695                 if(!Float.isNaN(value)){
2 26 Feb 07 jari 696                     sse += (float)Math.pow((value - mean),2);
2 26 Feb 07 jari 697                     n++;
2 26 Feb 07 jari 698                 }
2 26 Feb 07 jari 699             }
2 26 Feb 07 jari 700             if(n > 1)
2 26 Feb 07 jari 701                 variances[i] = (float)Math.sqrt(sse/(n-1));
2 26 Feb 07 jari 702             else
2 26 Feb 07 jari 703                 variances[i] = 0.0f;
2 26 Feb 07 jari 704         }
2 26 Feb 07 jari 705         return variances;
2 26 Feb 07 jari 706     }
2 26 Feb 07 jari 707     
2 26 Feb 07 jari 708     /** Appends a result onto the main result
2 26 Feb 07 jari 709      * @param resultVector data to append
2 26 Feb 07 jari 710      */
2 26 Feb 07 jari 711     private void appendResult(Vector resultVector){
2 26 Feb 07 jari 712         int numCorr = resultVector.size();
2 26 Feb 07 jari 713         double [] currentArray;
2 26 Feb 07 jari 714         int rawPIndex = result[0].length;
2 26 Feb 07 jari 715         int resultColumns = rawPIndex+numCorr;
2 26 Feb 07 jari 716         String [][] newResult = new String[result.length][resultColumns];
2 26 Feb 07 jari 717         
2 26 Feb 07 jari 718         
2 26 Feb 07 jari 719         for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 720             for(int j = 0; j < result[0].length; j++){
2 26 Feb 07 jari 721                 newResult[i][j] = result[i][j];
2 26 Feb 07 jari 722             }
2 26 Feb 07 jari 723         }
2 26 Feb 07 jari 724         int resultCol;
2 26 Feb 07 jari 725         for(int col = 0; col < numCorr; col++){
2 26 Feb 07 jari 726             currentArray = (double [])resultVector.elementAt(col);
2 26 Feb 07 jari 727             resultCol = col + rawPIndex;
2 26 Feb 07 jari 728             for(int row = 0; row < newResult.length; row++){
2 26 Feb 07 jari 729                 
2 26 Feb 07 jari 730                 newResult[row][resultCol] = format.format(currentArray[row]);
2 26 Feb 07 jari 731      
2 26 Feb 07 jari 732                 //handles international conventions where comma denotes decimal
2 26 Feb 07 jari 733                 newResult[row][resultCol] = newResult[row][resultCol].replace(',','.');
2 26 Feb 07 jari 734      
2 26 Feb 07 jari 735             }
2 26 Feb 07 jari 736         }
2 26 Feb 07 jari 737         result = newResult;
2 26 Feb 07 jari 738     }
2 26 Feb 07 jari 739     
2 26 Feb 07 jari 740     
2 26 Feb 07 jari 741     /** Selects and makes calles to various multiplicity corrections.
2 26 Feb 07 jari 742      */
2 26 Feb 07 jari 743     private void pValueCorrections(AlgorithmData inputData){
2 26 Feb 07 jari 744         int k = this.result.length;
2 26 Feb 07 jari 745         double [] pValues = new double[k];
2 26 Feb 07 jari 746         double [] correctedP = new double[k];
2 26 Feb 07 jari 747         
2 26 Feb 07 jari 748         int pIndex;
2 26 Feb 07 jari 749         if(reportEaseScore)
2 26 Feb 07 jari 750             pIndex =  headerNames.indexOf("EASE Score");
2 26 Feb 07 jari 751         else
2 26 Feb 07 jari 752             pIndex =  headerNames.indexOf("Fisher's Exact");
2 26 Feb 07 jari 753         
2 26 Feb 07 jari 754         pIndex--;  //subtract one since result is not indexed until after sort
2 26 Feb 07 jari 755         
2 26 Feb 07 jari 756         Vector pValueCorrectionVector = new Vector();
2 26 Feb 07 jari 757         for(int i = 0; i < k; i++){
2 26 Feb 07 jari 758             pValues[i] = Double.parseDouble(result[i][pIndex]);
2 26 Feb 07 jari 759         }
2 26 Feb 07 jari 760         AlgorithmParameters params = inputData.getParams();
2 26 Feb 07 jari 761         
2 26 Feb 07 jari 762         if(params.getBoolean("bonferroni-correction", false)){
2 26 Feb 07 jari 763             pValueCorrectionVector.add(bonferroniCorrection(pValues));
2 26 Feb 07 jari 764             headerNames.add("Bonf. Corr.");
2 26 Feb 07 jari 765         }
2 26 Feb 07 jari 766         
2 26 Feb 07 jari 767         if(params.getBoolean("bonferroni-step-down-correction", false)){
2 26 Feb 07 jari 768             pValueCorrectionVector.add(stepDownBonferroniCorrection(pValues));
2 26 Feb 07 jari 769             headerNames.add("Bonf. S.D. Corr.");
2 26 Feb 07 jari 770         }
2 26 Feb 07 jari 771         
2 26 Feb 07 jari 772         if(params.getBoolean("sidak-correction", false)){
2 26 Feb 07 jari 773             pValueCorrectionVector.add(sidakCorrection(pValues));
2 26 Feb 07 jari 774             headerNames.add("Sidak Corr.");
2 26 Feb 07 jari 775         }
2 26 Feb 07 jari 776         appendResult(pValueCorrectionVector);
2 26 Feb 07 jari 777     }
2 26 Feb 07 jari 778     
2 26 Feb 07 jari 779     /** Performs the standard Bonferroni correction.
2 26 Feb 07 jari 780      * @param pValues Raw values
2 26 Feb 07 jari 781      * @return Returns corrected values.
2 26 Feb 07 jari 782      */
2 26 Feb 07 jari 783     private double [] bonferroniCorrection(double [] pValues){
2 26 Feb 07 jari 784         int k = pValues.length;
2 26 Feb 07 jari 785         double [] correctedP = new double[k];
2 26 Feb 07 jari 786         for(int i = 0; i < k; i++){
2 26 Feb 07 jari 787             correctedP[i] = pValues[i]*(double)k;
2 26 Feb 07 jari 788             if(correctedP[i] > 1.0d)
2 26 Feb 07 jari 789                 correctedP[i] = 1.0d;
2 26 Feb 07 jari 790         }
2 26 Feb 07 jari 791         return correctedP;
2 26 Feb 07 jari 792     }
2 26 Feb 07 jari 793     
2 26 Feb 07 jari 794     /** Performs the step down Bonferroni correction.
2 26 Feb 07 jari 795      * @param pValues input values
2 26 Feb 07 jari 796      * @return returns corrected values
2 26 Feb 07 jari 797      */
2 26 Feb 07 jari 798     private double [] stepDownBonferroniCorrection(double [] pValues){
2 26 Feb 07 jari 799         int k = pValues.length;
2 26 Feb 07 jari 800         double [] correctedP = new double[k];
2 26 Feb 07 jari 801         int m = 0;
2 26 Feb 07 jari 802         
2 26 Feb 07 jari 803         //base case
2 26 Feb 07 jari 804         correctedP[0] = pValues[0]*(double)k;
2 26 Feb 07 jari 805         
2 26 Feb 07 jari 806         for(int i = 1; i < k; i++){
2 26 Feb 07 jari 807             if(pValues[i] > pValues[i-1])
2 26 Feb 07 jari 808                 m = i;
2 26 Feb 07 jari 809             correctedP[i] = pValues[i]*(double)(k-m);
2 26 Feb 07 jari 810             if(correctedP[i] > 1.0d)
2 26 Feb 07 jari 811                 correctedP[i] = 1.0d;
2 26 Feb 07 jari 812         }
2 26 Feb 07 jari 813         return correctedP;
2 26 Feb 07 jari 814     }
2 26 Feb 07 jari 815     
2 26 Feb 07 jari 816     /** Perform Sidak method.
2 26 Feb 07 jari 817      * @param pValues input
2 26 Feb 07 jari 818      * @return corrected output
2 26 Feb 07 jari 819      */
2 26 Feb 07 jari 820     private double [] sidakCorrection(double [] pValues){
2 26 Feb 07 jari 821         int k = pValues.length;
2 26 Feb 07 jari 822         double [] correctedP = new double[k];
2 26 Feb 07 jari 823         for(int i = 0; i < k; i++){
2 26 Feb 07 jari 824             correctedP[i] = 1.0d-Math.pow( (1.0d-pValues[i]), (double)k );
2 26 Feb 07 jari 825             if(correctedP[i] > 1.0d)
2 26 Feb 07 jari 826                 correctedP[i] = 1.0d;
2 26 Feb 07 jari 827         }
2 26 Feb 07 jari 828         return correctedP;
2 26 Feb 07 jari 829     }
2 26 Feb 07 jari 830     
2 26 Feb 07 jari 831     /** performs permutation analysis, bootstrapping selection of random samples from
2 26 Feb 07 jari 832      * the population.
2 26 Feb 07 jari 833      * @param p number of permutations
2 26 Feb 07 jari 834      */
2 26 Feb 07 jari 835     private void permutationAnalysis(int p){
2 26 Feb 07 jari 836         //Get a list of categories, have a corresponding accumulator array
2 26 Feb 07 jari 837         //Have a population Vector of strings
2 26 Feb 07 jari 838         //take k elements from here to construct a new sample list
2 26 Feb 07 jari 839         //then from jstats getList HitsByCategory() and Construct results
2 26 Feb 07 jari 840         
2 26 Feb 07 jari 841         //increment counters indicating the times times when a terms p value falls below
2 26 Feb 07 jari 842         //the minimum p value for a resampling iteration.
2 26 Feb 07 jari 843         
2 26 Feb 07 jari 844         AlgorithmEvent permEvent = new AlgorithmEvent(this, AlgorithmEvent.PROGRESS_VALUE, p);
2 26 Feb 07 jari 845         permEvent.setDescription("SET_UNITS");
2 26 Feb 07 jari 846         permEvent.setIntValue(p);
2 26 Feb 07 jari 847         fireValueChanged(permEvent);
2 26 Feb 07 jari 848         permEvent.setDescription("SET_VALUE");
2 26 Feb 07 jari 849         
2 26 Feb 07 jari 850         long start = System.currentTimeMillis();
2 26 Feb 07 jari 851         
2 26 Feb 07 jari 852         int k = result.length;
2 26 Feb 07 jari 853         int sampleSize = this.sampleVector.size();
2 26 Feb 07 jari 854         int populationSize = this.populationVector.size();
2 26 Feb 07 jari 855         int [] accumulator = new int[this.result.length];
2 26 Feb 07 jari 856         
2 26 Feb 07 jari 857         for(int i = 0; i < accumulator.length; i++)
2 26 Feb 07 jari 858             accumulator[0]=0;
2 26 Feb 07 jari 859         
2 26 Feb 07 jari 860         int [] hitNumberAcc = new int[sampleSize];
2 26 Feb 07 jari 861         
2 26 Feb 07 jari 862         Random rand = new Random(System.currentTimeMillis());
2 26 Feb 07 jari 863         String [][] testResult;
2 26 Feb 07 jari 864         
2 26 Feb 07 jari 865         long sampleTime = 0;
2 26 Feb 07 jari 866         long startsamp;
2 26 Feb 07 jari 867         
2 26 Feb 07 jari 868         for(int i = 0; i < p; i++){
2 26 Feb 07 jari 869             
2 26 Feb 07 jari 870             permEvent.setIntValue(i+1);
2 26 Feb 07 jari 871             fireValueChanged(permEvent);
2 26 Feb 07 jari 872
2 26 Feb 07 jari 873             sampleVector = getRandomSampleVector(sampleSize, rand);
2 26 Feb 07 jari 874
2 26 Feb 07 jari 875             jstats.resetForNewList();
2 26 Feb 07 jari 876
2 26 Feb 07 jari 877             jstats.GetListHitsByCategory(sampleVector);
2 26 Feb 07 jari 878     
2 26 Feb 07 jari 879             jstats.ConstructResults();
2 26 Feb 07 jari 880  
2 26 Feb 07 jari 881             testResult = jstats.getResults();
2 26 Feb 07 jari 882             
2 26 Feb 07 jari 883             accumulateBinHits(testResult, accumulator);
2 26 Feb 07 jari 884         }
2 26 Feb 07 jari 885         
2 26 Feb 07 jari 886         double [] prob = new double[k];
2 26 Feb 07 jari 887         for(int i = 0; i < k; i++){
2 26 Feb 07 jari 888             prob[i] = (double)accumulator[i]/(double)p;
2 26 Feb 07 jari 889             if(prob[i] == 0d)
2 26 Feb 07 jari 890                 prob[i] = 1d/(double)p;
2 26 Feb 07 jari 891         }
2 26 Feb 07 jari 892         
2 26 Feb 07 jari 893         permEvent.setDescription("DISPOSE");  //get rid of progress bar
2 26 Feb 07 jari 894         fireValueChanged(permEvent);
2 26 Feb 07 jari 895
2 26 Feb 07 jari 896         Vector probVector = new Vector();
2 26 Feb 07 jari 897         probVector.add(prob);
2 26 Feb 07 jari 898         appendResult(probVector);
2 26 Feb 07 jari 899         
2 26 Feb 07 jari 900         headerNames.add("Prob. Anal.");
2 26 Feb 07 jari 901     }
2 26 Feb 07 jari 902     
2 26 Feb 07 jari 903     /** Returns the maximum number of population hits for any category.
2 26 Feb 07 jari 904      */
2 26 Feb 07 jari 905     private int getMaxPopHits(String [][] result){
2 26 Feb 07 jari 906         int max = Integer.MIN_VALUE;
2 26 Feb 07 jari 907         for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 908             max = Math.max(max, Integer.parseInt(result[i][4]));
2 26 Feb 07 jari 909         }
2 26 Feb 07 jari 910         return max;
2 26 Feb 07 jari 911     }
2 26 Feb 07 jari 912     
2 26 Feb 07 jari 913     /** Returns a random sample vector of indices.
2 26 Feb 07 jari 914      */
2 26 Feb 07 jari 915     private Vector getRandomSampleVector(int sampleSize, Random rand){
2 26 Feb 07 jari 916         Vector sampleVector = new Vector(sampleSize);
2 26 Feb 07 jari 917         Vector dummyPopVector = (Vector)populationVector.clone();
2 26 Feb 07 jari 918         
2 26 Feb 07 jari 919         int popSize = populationVector.size();
2 26 Feb 07 jari 920         
2 26 Feb 07 jari 921         int index = 0;
2 26 Feb 07 jari 922         
2 26 Feb 07 jari 923         for(int i = 0; i < sampleSize; i++){
2 26 Feb 07 jari 924             index = (int)(dummyPopVector.size()*rand.nextFloat());
2 26 Feb 07 jari 925             sampleVector.add(dummyPopVector.remove(index));  //enforce w/o replacement
2 26 Feb 07 jari 926         }
2 26 Feb 07 jari 927         
2 26 Feb 07 jari 928         return sampleVector;
2 26 Feb 07 jari 929     }
2 26 Feb 07 jari 930     
2 26 Feb 07 jari 931     /** accumulates list hits results from permutations
2 26 Feb 07 jari 932      * @param result
2 26 Feb 07 jari 933      * @param keys
2 26 Feb 07 jari 934      * @param accumulator  */
2 26 Feb 07 jari 935     private void accumulateHits(String [][] result, String [] keys, int [] accumulator){
2 26 Feb 07 jari 936         for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 937             for(int j = 0; j < keys.length; j++){
2 26 Feb 07 jari 938                 if((result[i][1]).equals(keys[j])){
2 26 Feb 07 jari 939                     if(Integer.parseInt(result[i][2]) > Integer.parseInt(this.result[j][2]))
2 26 Feb 07 jari 940                         accumulator[j]++;
2 26 Feb 07 jari 941                     break;
2 26 Feb 07 jari 942                 }
2 26 Feb 07 jari 943             }
2 26 Feb 07 jari 944         }
2 26 Feb 07 jari 945     }
2 26 Feb 07 jari 946     
2 26 Feb 07 jari 947     /** Accumulates results from permutations.
2 26 Feb 07 jari 948      */
2 26 Feb 07 jari 949     private void accumulateBinHits(String [][] newResult, int [] accumulator){
2 26 Feb 07 jari 950         
2 26 Feb 07 jari 951         double minP;
2 26 Feb 07 jari 952         
2 26 Feb 07 jari 953         for(int cat = 0; cat < annotationFileList.length; cat++){
2 26 Feb 07 jari 954             
2 26 Feb 07 jari 955             minP = Double.POSITIVE_INFINITY;
2 26 Feb 07 jari 956
2 26 Feb 07 jari 957             for(int i = 0; i < newResult.length; i++){
2 26 Feb 07 jari 958                 if(this.annotationFileList[cat].indexOf(newResult[i][0]) >= 0)
2 26 Feb 07 jari 959                     minP = Math.min(minP, Double.parseDouble(newResult[i][6]));
2 26 Feb 07 jari 960             }
2 26 Feb 07 jari 961
2 26 Feb 07 jari 962             for(int j = 0; j < result.length; j++){
2 26 Feb 07 jari 963                 if((this.annotationFileList[cat].indexOf(result[j][0]) >= 0) && (minP < Double.parseDouble(result[j][6]))){
2 26 Feb 07 jari 964                     accumulator[j]++;
2 26 Feb 07 jari 965                 }
2 26 Feb 07 jari 966             }
2 26 Feb 07 jari 967         }
2 26 Feb 07 jari 968     }
2 26 Feb 07 jari 969     
2 26 Feb 07 jari 970     
2 26 Feb 07 jari 971     /** Orders the bootstrap probabilities based on raw probability order.
2 26 Feb 07 jari 972      */
2 26 Feb 07 jari 973     private double [] orderBootStrappedProb(double [] prob){
2 26 Feb 07 jari 974         double [] orderedProb = new double[result.length];
2 26 Feb 07 jari 975         for(int i = 0; i < this.result.length; i++){
2 26 Feb 07 jari 976             orderedProb[i] = prob[Integer.parseInt(this.result[i][2])];
2 26 Feb 07 jari 977         }
2 26 Feb 07 jari 978         return orderedProb;
2 26 Feb 07 jari 979     }
2 26 Feb 07 jari 980     
2 26 Feb 07 jari 981     
2 26 Feb 07 jari 982     /** Trims the results according to specified criteria.
2 26 Feb 07 jari 983      * @param trimOption Defines trim mode, "NO_TRIM", "N_TRIM", or "PERCENT_TRIM"
2 26 Feb 07 jari 984      * @param trimValue Trim parameter.
2 26 Feb 07 jari 985      */
2 26 Feb 07 jari 986     private void trimResult(String trimOption, float trimValue){
2 26 Feb 07 jari 987         
2 26 Feb 07 jari 988         boolean [] flagged = new boolean[result.length];
2 26 Feb 07 jari 989         int hitIndex;
2 26 Feb 07 jari 990         
2 26 Feb 07 jari 991         if(this.performClusterAnalysis){
2 26 Feb 07 jari 992             hitIndex = this.headerNames.indexOf("List Hits");
2 26 Feb 07 jari 993         } else {
2 26 Feb 07 jari 994             hitIndex = this.headerNames.indexOf("Pop. Hits");
2 26 Feb 07 jari 995         }
2 26 Feb 07 jari 996         
2 26 Feb 07 jari 997         hitIndex--;  //decrement since we don't have index inserted yet.
2 26 Feb 07 jari 998         
2 26 Feb 07 jari 999         int keeperCount = this.result.length;
2 26 Feb 07 jari 1000         if(trimOption.equals("N_TRIM")){
2 26 Feb 07 jari 1001             for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 1002                 if(Integer.parseInt(result[i][hitIndex]) < trimValue){
2 26 Feb 07 jari 1003                     flagged[i] = true;
2 26 Feb 07 jari 1004                     keeperCount--;
2 26 Feb 07 jari 1005                 }
2 26 Feb 07 jari 1006             }
2 26 Feb 07 jari 1007         } else { //Percent trim option
2 26 Feb 07 jari 1008             trimValue /= (float)100;
2 26 Feb 07 jari 1009             for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 1010                 if(Double.parseDouble(result[i][hitIndex])/Double.parseDouble(result[i][hitIndex+1]) < trimValue){
2 26 Feb 07 jari 1011                     flagged[i] = true;
2 26 Feb 07 jari 1012                     keeperCount--;
2 26 Feb 07 jari 1013                 }
2 26 Feb 07 jari 1014             }
2 26 Feb 07 jari 1015         }
2 26 Feb 07 jari 1016         
2 26 Feb 07 jari 1017         String [][] newResult = new String[keeperCount][];
2 26 Feb 07 jari 1018         String [][] newHitList = new String[keeperCount][];
2 26 Feb 07 jari 1019         String [] newCategoryNames = new String[keeperCount];
2 26 Feb 07 jari 1020         int keeperIndex = 0;
2 26 Feb 07 jari 1021         
2 26 Feb 07 jari 1022         for(int i = 0; i < result.length; i++){
2 26 Feb 07 jari 1023             if(!flagged[i]){
2 26 Feb 07 jari 1024                 newResult[keeperIndex] = result[i];
2 26 Feb 07 jari 1025                 newHitList[keeperIndex] = hitList[i];
2 26 Feb 07 jari 1026                 newCategoryNames[keeperIndex] = categoryNames[i];
2 26 Feb 07 jari 1027                 keeperIndex++;
2 26 Feb 07 jari 1028             }
2 26 Feb 07 jari 1029         }
2 26 Feb 07 jari 1030         this.result = newResult;
2 26 Feb 07 jari 1031         this.hitList = newHitList;
2 26 Feb 07 jari 1032         this.categoryNames = newCategoryNames;
2 26 Feb 07 jari 1033     }
2 26 Feb 07 jari 1034     
2 26 Feb 07 jari 1035 }
2 26 Feb 07 jari 1036