affyfusion-109/src/affymetrix/gcos/cdf/CDFFileData.java

Code
Comments
Other
Rev Date Author Line
11 13 Sep 07 nicklas 1 /////////////////////////////////////////////////////////////////
11 13 Sep 07 nicklas 2 //
11 13 Sep 07 nicklas 3 // Copyright (C) 2005 Affymetrix, Inc.
11 13 Sep 07 nicklas 4 //
11 13 Sep 07 nicklas 5 // This library is free software; you can redistribute it and/or modify
11 13 Sep 07 nicklas 6 // it under the terms of the GNU Lesser General Public License as published
11 13 Sep 07 nicklas 7 // by the Free Software Foundation; either version 2.1 of the License,
11 13 Sep 07 nicklas 8 // or (at your option) any later version.
11 13 Sep 07 nicklas 9 //
11 13 Sep 07 nicklas 10 // This library is distributed in the hope that it will be useful, but
11 13 Sep 07 nicklas 11 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 13 Sep 07 nicklas 12 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 13 Sep 07 nicklas 13 // for more details.
11 13 Sep 07 nicklas 14 //
11 13 Sep 07 nicklas 15 // You should have received a copy of the GNU Lesser General Public License
11 13 Sep 07 nicklas 16 // along with this library; if not, write to the Free Software Foundation, Inc.,
11 13 Sep 07 nicklas 17 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
11 13 Sep 07 nicklas 18 //
11 13 Sep 07 nicklas 19 /////////////////////////////////////////////////////////////////
11 13 Sep 07 nicklas 20
11 13 Sep 07 nicklas 21 package affymetrix.gcos.cdf;
11 13 Sep 07 nicklas 22
11 13 Sep 07 nicklas 23 import affymetrix.gcos.*;
11 13 Sep 07 nicklas 24 import affymetrix.portability.*;
11 13 Sep 07 nicklas 25 import java.util.*;
11 13 Sep 07 nicklas 26 import java.io.*;
11 13 Sep 07 nicklas 27 import java.nio.channels.*;
11 13 Sep 07 nicklas 28 import java.nio.channels.FileChannel.*;
11 13 Sep 07 nicklas 29 import java.nio.*;
11 13 Sep 07 nicklas 30
11 13 Sep 07 nicklas 31 /** This class provides reading and storage capabilities for the CDF file. */
11 13 Sep 07 nicklas 32 public class CDFFileData {
11 13 Sep 07 nicklas 33     
11 13 Sep 07 nicklas 34     /** The magic number for an XDA CDF file. */
11 13 Sep 07 nicklas 35     private static final int CDF_FILE_MAGIC_NUMBER = 67;
11 13 Sep 07 nicklas 36     
11 13 Sep 07 nicklas 37     /** The version number for an XDA CDF file. */
11 13 Sep 07 nicklas 38     private static final int CDF_FILE_VERSION_NUMBER = 1;
11 13 Sep 07 nicklas 39     
11 13 Sep 07 nicklas 40     /** The file header object. */
11 13 Sep 07 nicklas 41     private CDFFileHeader header;
11 13 Sep 07 nicklas 42
11 13 Sep 07 nicklas 43     /** Gets the header. */
11 13 Sep 07 nicklas 44     public CDFFileHeader getHeader() { return header; }
11 13 Sep 07 nicklas 45     
11 13 Sep 07 nicklas 46     /** The list of probe set names. */
11 13 Sep 07 nicklas 47     private CDFProbeSetNames probeSetNames;
11 13 Sep 07 nicklas 48
11 13 Sep 07 nicklas 49     /** An array of probe sets. */
13 14 Sep 07 nicklas 50     private List<CDFProbeSetInformation> probeSets;
11 13 Sep 07 nicklas 51
11 13 Sep 07 nicklas 52     /** An array of QC probe sets. */
13 14 Sep 07 nicklas 53     private List<CDFQCProbeSetInformation> qcProbeSets;
11 13 Sep 07 nicklas 54
11 13 Sep 07 nicklas 55     /** The CDF file name (full path). */
11 13 Sep 07 nicklas 56     private String fileName;
11 13 Sep 07 nicklas 57     
13 14 Sep 07 nicklas 58     /** 
13 14 Sep 07 nicklas 59      * Store result from {@link #isXDACompatibleFile()} since we 
13 14 Sep 07 nicklas 60      * can't call it twice if using an input stream
13 14 Sep 07 nicklas 61      */
13 14 Sep 07 nicklas 62     private Boolean isXDACompatible = null;
13 14 Sep 07 nicklas 63     
13 14 Sep 07 nicklas 64     /**
13 14 Sep 07 nicklas 65      * To keep track if headers have been read or not, since we can't do that twice
13 14 Sep 07 nicklas 66      * if using an input stream.
13 14 Sep 07 nicklas 67      */
13 14 Sep 07 nicklas 68     private boolean hasReadHeaders = false;
13 14 Sep 07 nicklas 69     
13 14 Sep 07 nicklas 70     /**
13 14 Sep 07 nicklas 71      * If reading the headers was successful (true) or not (false)
13 14 Sep 07 nicklas 72      */
13 14 Sep 07 nicklas 73     private boolean headerResult;
13 14 Sep 07 nicklas 74     
13 14 Sep 07 nicklas 75     /**
13 14 Sep 07 nicklas 76      * To keep track if data have been read or not, since we can't do that twice
13 14 Sep 07 nicklas 77      * if using an input stream.
13 14 Sep 07 nicklas 78      */
13 14 Sep 07 nicklas 79      private boolean hasReadData = false;
13 14 Sep 07 nicklas 80
13 14 Sep 07 nicklas 81      /**
13 14 Sep 07 nicklas 82       * If reading the data was successful (true) or not (false)
13 14 Sep 07 nicklas 83       */
13 14 Sep 07 nicklas 84      private boolean dataResult;
13 14 Sep 07 nicklas 85      
13 14 Sep 07 nicklas 86     /** 
13 14 Sep 07 nicklas 87      * If set, we will read data from this input stream instead of 
13 14 Sep 07 nicklas 88      * from the file specified by fileName 
13 14 Sep 07 nicklas 89      */
13 14 Sep 07 nicklas 90     private InputStream in;
19 15 Nov 07 nicklas 91
13 14 Sep 07 nicklas 92     /**
19 15 Nov 07 nicklas 93      * Temporary file in case we need to copy the entire InputStream
19 15 Nov 07 nicklas 94      */
19 15 Nov 07 nicklas 95     private File tempFile;
19 15 Nov 07 nicklas 96    
19 15 Nov 07 nicklas 97     /**
14 14 Sep 07 nicklas 98      * A reader wrapping the input stream when reading text CDF files.
13 14 Sep 07 nicklas 99      */
14 14 Sep 07 nicklas 100     private BufferedReader textReader;
13 14 Sep 07 nicklas 101     
14 14 Sep 07 nicklas 102     /**
14 14 Sep 07 nicklas 103      * A reader wrapping the input stream when reading binary CDF files.
14 14 Sep 07 nicklas 104      */
14 14 Sep 07 nicklas 105     private FileInputStream xdaReader;
14 14 Sep 07 nicklas 106     
11 13 Sep 07 nicklas 107     /** Gets the file name. */
11 13 Sep 07 nicklas 108     public String getFileName() { return fileName; }
11 13 Sep 07 nicklas 109
11 13 Sep 07 nicklas 110     /** Sets the file name. */
11 13 Sep 07 nicklas 111     public void setFileName(String value) { fileName = value; }
13 14 Sep 07 nicklas 112     
13 14 Sep 07 nicklas 113     /** 
13 14 Sep 07 nicklas 114      * Set the input stream to read from. If set
13 14 Sep 07 nicklas 115      * we use the stream instead of the file given by filename
13 14 Sep 07 nicklas 116      */
13 14 Sep 07 nicklas 117     public void setInputStream(InputStream in)
13 14 Sep 07 nicklas 118     {
13 14 Sep 07 nicklas 119         this.in = in;
13 14 Sep 07 nicklas 120     }
11 13 Sep 07 nicklas 121
11 13 Sep 07 nicklas 122     /** A string to hold an error message upon read failures. */
11 13 Sep 07 nicklas 123     private String strError;
11 13 Sep 07 nicklas 124     
11 13 Sep 07 nicklas 125     /** Gets the error message. */
11 13 Sep 07 nicklas 126     public String getError() { return strError; }
11 13 Sep 07 nicklas 127     
11 13 Sep 07 nicklas 128     /** Array of file positions for the probe set data. */
13 14 Sep 07 nicklas 129     private List<Integer> probeSetPositions;
11 13 Sep 07 nicklas 130
11 13 Sep 07 nicklas 131     /** Array of file positions for the QC probe set data. */
13 14 Sep 07 nicklas 132     private List<Integer> qcProbeSetPositions;
11 13 Sep 07 nicklas 133
11 13 Sep 07 nicklas 134     /** A mapped byte buffer for XDA files. */
11 13 Sep 07 nicklas 135     private MappedByteBuffer xdaBuffer;
11 13 Sep 07 nicklas 136         
11 13 Sep 07 nicklas 137     /** Opens the file for reading.
11 13 Sep 07 nicklas 138      * @param bReadHeaderOnly Flag indicating if only the header should be read.
11 13 Sep 07 nicklas 139      * @return True if successful.
11 13 Sep 07 nicklas 140      */
11 13 Sep 07 nicklas 141     private boolean open(boolean bReadHeaderOnly) {
11 13 Sep 07 nicklas 142         if (isXDACompatibleFile())
13 14 Sep 07 nicklas 143         {
13 14 Sep 07 nicklas 144            return readXDAFormat(bReadHeaderOnly);
13 14 Sep 07 nicklas 145         }
13 14 Sep 07 nicklas 146         else
13 14 Sep 07 nicklas 147         {
11 13 Sep 07 nicklas 148             return readTextFormat(bReadHeaderOnly);
13 14 Sep 07 nicklas 149         }
11 13 Sep 07 nicklas 150     }
11 13 Sep 07 nicklas 151
11 13 Sep 07 nicklas 152     /** Reads the header from a text CDF file.
11 13 Sep 07 nicklas 153      * @param b The file buffer reader.
11 13 Sep 07 nicklas 154      * @return True if successful.
11 13 Sep 07 nicklas 155      */
11 13 Sep 07 nicklas 156     private boolean readTextHeader(BufferedReader b) {
11 13 Sep 07 nicklas 157         String str;
11 13 Sep 07 nicklas 158         String[] sarray;
11 13 Sep 07 nicklas 159         final String CDFVERSION1 = "GC1.0";
11 13 Sep 07 nicklas 160         final String CDFVERSION2 = "GC2.0";
11 13 Sep 07 nicklas 161         final String CDFVERSION3 = "GC3.0";
11 13 Sep 07 nicklas 162
11 13 Sep 07 nicklas 163         // Get the CDF section.
11 13 Sep 07 nicklas 164         str = FileIO.ReadNextLine(b);
11 13 Sep 07 nicklas 165         if (str.startsWith("[CDF]") == false)
11 13 Sep 07 nicklas 166         {
11 13 Sep 07 nicklas 167             strError = "Unknown file format.";
11 13 Sep 07 nicklas 168             return false;
11 13 Sep 07 nicklas 169         }
11 13 Sep 07 nicklas 170
11 13 Sep 07 nicklas 171         // Get the version number.
11 13 Sep 07 nicklas 172         header = new CDFFileHeader();
11 13 Sep 07 nicklas 173         sarray = FileIO.ReadNextLine(b).split("=");
11 13 Sep 07 nicklas 174         if ( sarray[1].startsWith(CDFVERSION1) == true)
11 13 Sep 07 nicklas 175             header.setVersion(1);
11 13 Sep 07 nicklas 176         else if ( sarray[1].startsWith(CDFVERSION2) == true)
11 13 Sep 07 nicklas 177             header.setVersion(2);
11 13 Sep 07 nicklas 178         else if ( sarray[1].startsWith(CDFVERSION3) == true)
11 13 Sep 07 nicklas 179             header.setVersion(3);
11 13 Sep 07 nicklas 180
11 13 Sep 07 nicklas 181
11 13 Sep 07 nicklas 182         // Get the next section.
11 13 Sep 07 nicklas 183         str = FileIO.ReadNextLine(b); // [Chip]
11 13 Sep 07 nicklas 184         str = FileIO.ReadNextLine(b); // name
11 13 Sep 07 nicklas 185         sarray = FileIO.ReadNextLine(b).split("="); // rows
11 13 Sep 07 nicklas 186         header.setRows(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 187         sarray = FileIO.ReadNextLine(b).split("="); // cols
11 13 Sep 07 nicklas 188         header.setCols(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 189         sarray = FileIO.ReadNextLine(b).split("="); // #ProbeSets
11 13 Sep 07 nicklas 190         header.setNumProbeSets(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 191         str = FileIO.ReadNextLine(b); // max ProbeSet number
11 13 Sep 07 nicklas 192         header.setNumQCProbeSets(0);
11 13 Sep 07 nicklas 193         if (header.getVersion() > 1)
11 13 Sep 07 nicklas 194         {
11 13 Sep 07 nicklas 195                 sarray = FileIO.ReadNextLine(b).split("="); // #qc ProbeSets
11 13 Sep 07 nicklas 196                 header.setNumQCProbeSets(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 197                 sarray = FileIO.ReadNextLine(b).split("=");  // The reference string.
11 13 Sep 07 nicklas 198                 if (sarray.length == 2)
11 13 Sep 07 nicklas 199                     header.setReference(sarray[1]);
11 13 Sep 07 nicklas 200         }
11 13 Sep 07 nicklas 201         return true;
11 13 Sep 07 nicklas 202     }
11 13 Sep 07 nicklas 203
11 13 Sep 07 nicklas 204     /** Read the QC section from a text CDF file.
11 13 Sep 07 nicklas 205      * @param b The file buffer reader.
11 13 Sep 07 nicklas 206      */
11 13 Sep 07 nicklas 207     private void readTextQC(BufferedReader b) {
11 13 Sep 07 nicklas 208   String str;
11 13 Sep 07 nicklas 209         String[] sarray;
11 13 Sep 07 nicklas 210         
11 13 Sep 07 nicklas 211         // Allocate for the QCProbeSets.
13 14 Sep 07 nicklas 212         qcProbeSets = new ArrayList<CDFQCProbeSetInformation>(header.getNumQCProbeSets());
11 13 Sep 07 nicklas 213
11 13 Sep 07 nicklas 214   // Read the QC probe sets
11 13 Sep 07 nicklas 215   for (int iQCProbeSet=0; iQCProbeSet<header.getNumQCProbeSets(); iQCProbeSet++)
11 13 Sep 07 nicklas 216   {
11 13 Sep 07 nicklas 217             CDFQCProbeSetInformation qcProbeSet = new CDFQCProbeSetInformation();
11 13 Sep 07 nicklas 218
11 13 Sep 07 nicklas 219             str = FileIO.ReadNextLine(b);  // label [QCUnit...]
11 13 Sep 07 nicklas 220             sarray = FileIO.ReadNextLine(b).split("=");  // type
11 13 Sep 07 nicklas 221             qcProbeSet.setQCProbeSetType(Short.parseShort(sarray[1].trim()));
11 13 Sep 07 nicklas 222             sarray = FileIO.ReadNextLine(b).split("=");  // #cells
11 13 Sep 07 nicklas 223             qcProbeSet.setNumCells(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 224             str = FileIO.ReadNextLine(b);  // cell header
11 13 Sep 07 nicklas 225
11 13 Sep 07 nicklas 226             // Read the QC cells.
11 13 Sep 07 nicklas 227             int xqc;
11 13 Sep 07 nicklas 228             int yqc;
11 13 Sep 07 nicklas 229             byte plenqc;
13 14 Sep 07 nicklas 230             List<CDFQCProbeInformation> qccells = new ArrayList<CDFQCProbeInformation>(qcProbeSet.getNumCells());
11 13 Sep 07 nicklas 231             for (int iqccell=0; iqccell<qcProbeSet.getNumCells(); iqccell++)
11 13 Sep 07 nicklas 232             {
11 13 Sep 07 nicklas 233                 CDFQCProbeInformation qcCell = new CDFQCProbeInformation();
11 13 Sep 07 nicklas 234
11 13 Sep 07 nicklas 235                 sarray = FileIO.ReadNextLine(b).split("=");
11 13 Sep 07 nicklas 236                 sarray = sarray[1].split("\t");
11 13 Sep 07 nicklas 237                 xqc = Integer.parseInt(sarray[0].trim());
11 13 Sep 07 nicklas 238                 yqc = Integer.parseInt(sarray[1].trim());
11 13 Sep 07 nicklas 239                 plenqc = Byte.parseByte(sarray[3].trim());
11 13 Sep 07 nicklas 240
11 13 Sep 07 nicklas 241                 qcCell.setX(xqc);
11 13 Sep 07 nicklas 242                 qcCell.setY(yqc);
11 13 Sep 07 nicklas 243                 qcCell.setProbeLength(plenqc);
11 13 Sep 07 nicklas 244                 qcCell.setBackground(false);
11 13 Sep 07 nicklas 245                 qcCell.setPMProbe(false);
11 13 Sep 07 nicklas 246
13 14 Sep 07 nicklas 247                 qccells.add(qcCell);
11 13 Sep 07 nicklas 248             }
11 13 Sep 07 nicklas 249             qcProbeSet.setCells(qccells);
13 14 Sep 07 nicklas 250             qcProbeSets.add(qcProbeSet);
11 13 Sep 07 nicklas 251   }
11 13 Sep 07 nicklas 252     }
11 13 Sep 07 nicklas 253     
11 13 Sep 07 nicklas 254     /** Reads a text format CDF file.
11 13 Sep 07 nicklas 255      * @param bReadHeaderOnly Flag indicating if only the header should be read.
11 13 Sep 07 nicklas 256      * @return True if successful.
11 13 Sep 07 nicklas 257      */
11 13 Sep 07 nicklas 258     private boolean readTextFormat(boolean bReadHeaderOnly) {
11 13 Sep 07 nicklas 259         try
11 13 Sep 07 nicklas 260         {
13 14 Sep 07 nicklas 261             if (in != null)
13 14 Sep 07 nicklas 262             {
14 14 Sep 07 nicklas 263                 if (textReader == null) 
13 14 Sep 07 nicklas 264                 {
14 14 Sep 07 nicklas 265                     textReader = new BufferedReader(new InputStreamReader(in));
13 14 Sep 07 nicklas 266                 }
13 14 Sep 07 nicklas 267             }
13 14 Sep 07 nicklas 268             else
13 14 Sep 07 nicklas 269             {
13 14 Sep 07 nicklas 270                 // Read from file
14 14 Sep 07 nicklas 271                 textReader = new BufferedReader(new FileReader(fileName));
13 14 Sep 07 nicklas 272             }
11 13 Sep 07 nicklas 273         }
11 13 Sep 07 nicklas 274         catch (Throwable t)
11 13 Sep 07 nicklas 275         {
11 13 Sep 07 nicklas 276             strError = t.getMessage();
11 13 Sep 07 nicklas 277             return false;
11 13 Sep 07 nicklas 278         }
11 13 Sep 07 nicklas 279         
11 13 Sep 07 nicklas 280         // Read the header
13 14 Sep 07 nicklas 281         if (!hasReadHeaders)
13 14 Sep 07 nicklas 282         {
13 14 Sep 07 nicklas 283             hasReadHeaders = true;
14 14 Sep 07 nicklas 284             headerResult = readTextHeader(textReader);
13 14 Sep 07 nicklas 285         }
13 14 Sep 07 nicklas 286         if (headerResult == false) return false;
11 13 Sep 07 nicklas 287         
13 14 Sep 07 nicklas 288       // Stop if just reading the header.
13 14 Sep 07 nicklas 289       if (bReadHeaderOnly) return true;
13 14 Sep 07 nicklas 290     
13 14 Sep 07 nicklas 291         if (!hasReadData)
13 14 Sep 07 nicklas 292         {
13 14 Sep 07 nicklas 293             hasReadData = true;
13 14 Sep 07 nicklas 294             dataResult = true;
13 14 Sep 07 nicklas 295     
13 14 Sep 07 nicklas 296             // Read the remaing sections.
14 14 Sep 07 nicklas 297             readTextQC(textReader);
14 14 Sep 07 nicklas 298             readTextProbeSets(textReader);
13 14 Sep 07 nicklas 299         }
13 14 Sep 07 nicklas 300         return dataResult;
11 13 Sep 07 nicklas 301     }
11 13 Sep 07 nicklas 302     
11 13 Sep 07 nicklas 303     /** Read the probe sets from the text CDF file.
11 13 Sep 07 nicklas 304      * @param b The file buffer reader.
11 13 Sep 07 nicklas 305      */
11 13 Sep 07 nicklas 306     private void readTextProbeSets(BufferedReader b) {
11 13 Sep 07 nicklas 307         String str;
11 13 Sep 07 nicklas 308         String[] sarray;
11 13 Sep 07 nicklas 309         
11 13 Sep 07 nicklas 310   // Allocate for the probe set names.
11 13 Sep 07 nicklas 311   probeSetNames = new CDFProbeSetNames();
11 13 Sep 07 nicklas 312         probeSetNames.setSize(header.getNumProbeSets());
11 13 Sep 07 nicklas 313         
11 13 Sep 07 nicklas 314   // Allocate for the ProbeSets.
11 13 Sep 07 nicklas 315   int iProbeSet=0;
13 14 Sep 07 nicklas 316   probeSets = new ArrayList<CDFProbeSetInformation>(header.getNumProbeSets());
11 13 Sep 07 nicklas 317
11 13 Sep 07 nicklas 318   // Skip until the ProbeSet section is found
11 13 Sep 07 nicklas 319         boolean nextProbeSet = true;
11 13 Sep 07 nicklas 320         while (nextProbeSet == true)
11 13 Sep 07 nicklas 321         {
11 13 Sep 07 nicklas 322             while (true)
11 13 Sep 07 nicklas 323             {
11 13 Sep 07 nicklas 324                     str = FileIO.ReadNextLine(b);
11 13 Sep 07 nicklas 325                     if (str == null)
11 13 Sep 07 nicklas 326                         return;
11 13 Sep 07 nicklas 327                     if (str.length() > 5 && str.startsWith("[Unit") == true && str.indexOf("Block") == -1)
11 13 Sep 07 nicklas 328                         break;
11 13 Sep 07 nicklas 329             }
11 13 Sep 07 nicklas 330
11 13 Sep 07 nicklas 331       boolean expectMisMatch = false;
11 13 Sep 07 nicklas 332             CDFProbeSetInformation probeSet = new CDFProbeSetInformation();
11 13 Sep 07 nicklas 333
11 13 Sep 07 nicklas 334             // ProbeSet info.
11 13 Sep 07 nicklas 335             probeSet.setIndex(iProbeSet);
11 13 Sep 07 nicklas 336             sarray = FileIO.ReadNextLine(b).split("="); // name
11 13 Sep 07 nicklas 337             probeSetNames.setName(iProbeSet, sarray[1]);
11 13 Sep 07 nicklas 338             sarray = FileIO.ReadNextLine(b).split("="); // direction
11 13 Sep 07 nicklas 339             probeSet.setDirection(Byte.parseByte(sarray[1].trim()));
11 13 Sep 07 nicklas 340             sarray = FileIO.ReadNextLine(b).split("="); // # Lists
11 13 Sep 07 nicklas 341             sarray = sarray[1].split("\t");
11 13 Sep 07 nicklas 342             probeSet.setNumCellsPerList((byte)0);
11 13 Sep 07 nicklas 343             probeSet.setNumLists(Integer.parseInt(sarray[0].trim()));
11 13 Sep 07 nicklas 344             if (sarray.length == 2)
11 13 Sep 07 nicklas 345                 probeSet.setNumCellsPerList(Byte.parseByte(sarray[1].trim()));
11 13 Sep 07 nicklas 346             sarray = FileIO.ReadNextLine(b).split("="); // # cells
11 13 Sep 07 nicklas 347             probeSet.setNumCells(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 348             sarray = FileIO.ReadNextLine(b).split("="); // ProbeSet number
11 13 Sep 07 nicklas 349             probeSet.setProbeSetNumber(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 350             sarray = FileIO.ReadNextLine(b).split("="); // type
11 13 Sep 07 nicklas 351             int ival = Integer.parseInt(sarray[1].trim());
11 13 Sep 07 nicklas 352
11 13 Sep 07 nicklas 353             final int UNKNOWN_TILE=0;
11 13 Sep 07 nicklas 354             final int STANDARD_TILE=1;
11 13 Sep 07 nicklas 355             final int BLOCK_TILE=2;
11 13 Sep 07 nicklas 356             final int GENE_EXPRESSION_TILE=3;
11 13 Sep 07 nicklas 357             final int CONTROL_TILE=4;
11 13 Sep 07 nicklas 358             final int STANDARD_ALTERNATE_TILE=5;
11 13 Sep 07 nicklas 359             final int STANDARD_VARIANT_TILE=6;
11 13 Sep 07 nicklas 360             final int UNIVERSAL_TILE=7;
11 13 Sep 07 nicklas 361             final int COPY_NUMBER_TILE = 8;
11 13 Sep 07 nicklas 362             final int GENOTYPE_CONTROL_TILE = 9;
11 13 Sep 07 nicklas 363             final int EXPRESSION_CONTROL_TILE = 10;
11 13 Sep 07 nicklas 364
11 13 Sep 07 nicklas 365             switch (ival)
11 13 Sep 07 nicklas 366             {
11 13 Sep 07 nicklas 367             case STANDARD_TILE:
11 13 Sep 07 nicklas 368             case STANDARD_ALTERNATE_TILE:
11 13 Sep 07 nicklas 369             case STANDARD_VARIANT_TILE:
11 13 Sep 07 nicklas 370                 probeSet.setProbeSetType(GeneChipProbeSetType.ResequencingProbeSetType);
11 13 Sep 07 nicklas 371                 break;
11 13 Sep 07 nicklas 372
11 13 Sep 07 nicklas 373             case BLOCK_TILE:
11 13 Sep 07 nicklas 374                 probeSet.setProbeSetType(GeneChipProbeSetType.GenotypingProbeSetType);
11 13 Sep 07 nicklas 375                 break;
11 13 Sep 07 nicklas 376
11 13 Sep 07 nicklas 377             case GENE_EXPRESSION_TILE:
11 13 Sep 07 nicklas 378                 probeSet.setProbeSetType(GeneChipProbeSetType.ExpressionProbeSetType);
11 13 Sep 07 nicklas 379                 break;
11 13 Sep 07 nicklas 380
11 13 Sep 07 nicklas 381             case UNIVERSAL_TILE:
11 13 Sep 07 nicklas 382                 probeSet.setProbeSetType(GeneChipProbeSetType.TagProbeSetType);
11 13 Sep 07 nicklas 383                 break;
11 13 Sep 07 nicklas 384               
11 13 Sep 07 nicklas 385             case COPY_NUMBER_TILE:
11 13 Sep 07 nicklas 386                 probeSet.setProbeSetType(GeneChipProbeSetType.CopyNumberProbeSetType);
11 13 Sep 07 nicklas 387                 break;
11 13 Sep 07 nicklas 388
11 13 Sep 07 nicklas 389             case GENOTYPE_CONTROL_TILE:
11 13 Sep 07 nicklas 390                 probeSet.setProbeSetType(GeneChipProbeSetType.GenotypeControlProbeSetType);
11 13 Sep 07 nicklas 391                 break;
11 13 Sep 07 nicklas 392
11 13 Sep 07 nicklas 393             case EXPRESSION_CONTROL_TILE:
11 13 Sep 07 nicklas 394                 probeSet.setProbeSetType(GeneChipProbeSetType.ExpressionControlProbeSetType);
11 13 Sep 07 nicklas 395                 break;
11 13 Sep 07 nicklas 396
11 13 Sep 07 nicklas 397             default:
11 13 Sep 07 nicklas 398                 probeSet.setProbeSetType(GeneChipProbeSetType.UnknownProbeSetType);
11 13 Sep 07 nicklas 399                 break;
11 13 Sep 07 nicklas 400             }
11 13 Sep 07 nicklas 401
11 13 Sep 07 nicklas 402             sarray = FileIO.ReadNextLine(b).split("="); // # blocks
11 13 Sep 07 nicklas 403             probeSet.setNumGroups(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 404
11 13 Sep 07 nicklas 405             // Determine the number of cells per List if not specified
11 13 Sep 07 nicklas 406             // in the CDF file.
11 13 Sep 07 nicklas 407             if (probeSet.getNumCellsPerList() == 0)
11 13 Sep 07 nicklas 408             {
11 13 Sep 07 nicklas 409                 if (probeSet.getProbeSetType() == GeneChipProbeSetType.GenotypingProbeSetType ||
11 13 Sep 07 nicklas 410                      probeSet.getProbeSetType() == GeneChipProbeSetType.ResequencingProbeSetType ||
11 13 Sep 07 nicklas 411                      probeSet.getProbeSetType() == GeneChipProbeSetType.TagProbeSetType ||
11 13 Sep 07 nicklas 412                      probeSet.getProbeSetType() == GeneChipProbeSetType.UnknownProbeSetType)
11 13 Sep 07 nicklas 413     {
11 13 Sep 07 nicklas 414                     probeSet.setNumCellsPerList((byte)4);
11 13 Sep 07 nicklas 415     }
11 13 Sep 07 nicklas 416                 else if (probeSet.getProbeSetType() == GeneChipProbeSetType.ExpressionProbeSetType ||
11 13 Sep 07 nicklas 417                         probeSet.getProbeSetType() == GeneChipProbeSetType.CopyNumberProbeSetType ||
11 13 Sep 07 nicklas 418                         probeSet.getProbeSetType() == GeneChipProbeSetType.GenotypeControlProbeSetType ||
11 13 Sep 07 nicklas 419                         probeSet.getProbeSetType() == GeneChipProbeSetType.ExpressionControlProbeSetType)
11 13 Sep 07 nicklas 420                 {
11 13 Sep 07 nicklas 421                         if (probeSet.getNumLists() != 0 && probeSet.getNumCells() / probeSet.getNumLists() < 255) 
11 13 Sep 07 nicklas 422                             probeSet.setNumCellsPerList((byte)(probeSet.getNumCells() / probeSet.getNumLists()));
11 13 Sep 07 nicklas 423                         else
11 13 Sep 07 nicklas 424                             probeSet.setNumCellsPerList((byte)1);
11 13 Sep 07 nicklas 425                 }
11 13 Sep 07 nicklas 426                 else
11 13 Sep 07 nicklas 427                         probeSet.setNumCellsPerList((byte)1);
11 13 Sep 07 nicklas 428             }
11 13 Sep 07 nicklas 429       
11 13 Sep 07 nicklas 430             // If this is an expression probe set and we have 2 cells per list set expectMisMatch flag.
11 13 Sep 07 nicklas 431             if(probeSet.getProbeSetType() == GeneChipProbeSetType.ExpressionProbeSetType &&
11 13 Sep 07 nicklas 432                probeSet.getNumCellsPerList() == 2) 
11 13 Sep 07 nicklas 433               expectMisMatch = true;
11 13 Sep 07 nicklas 434
11 13 Sep 07 nicklas 435             // Get the mutation type if block tile. ignore.
11 13 Sep 07 nicklas 436             if (probeSet.getProbeSetType() == GeneChipProbeSetType.GenotypingProbeSetType && header.getVersion() > 1)
11 13 Sep 07 nicklas 437                 str = FileIO.ReadNextLine(b);
11 13 Sep 07 nicklas 438
11 13 Sep 07 nicklas 439             // Read the blocks.
13 14 Sep 07 nicklas 440             List<CDFProbeGroupInformation> groups = new ArrayList<CDFProbeGroupInformation>(probeSet.getNumGroups());
11 13 Sep 07 nicklas 441             for (int iGroup=0; iGroup<probeSet.getNumGroups(); iGroup++)
11 13 Sep 07 nicklas 442             {
11 13 Sep 07 nicklas 443                 CDFProbeGroupInformation blk = new CDFProbeGroupInformation();
11 13 Sep 07 nicklas 444                 blk.setGroupIndex(iGroup);
11 13 Sep 07 nicklas 445                 blk.setProbeSetIndex(iProbeSet);
11 13 Sep 07 nicklas 446
11 13 Sep 07 nicklas 447                 str = FileIO.ReadNextLine(b); // section name - ignore
11 13 Sep 07 nicklas 448                 sarray = FileIO.ReadNextLine(b).split("="); // name
11 13 Sep 07 nicklas 449                 blk.setName(sarray[1]);
11 13 Sep 07 nicklas 450
11 13 Sep 07 nicklas 451                 if (probeSet.getProbeSetType() == GeneChipProbeSetType.ExpressionProbeSetType)
11 13 Sep 07 nicklas 452                     probeSetNames.setName(iProbeSet, sarray[1]);
11 13 Sep 07 nicklas 453
11 13 Sep 07 nicklas 454                 str = FileIO.ReadNextLine(b); // block number - ignore.
11 13 Sep 07 nicklas 455                 sarray = FileIO.ReadNextLine(b).split("="); // number of Lists.
11 13 Sep 07 nicklas 456                 blk.setNumLists(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 457                 sarray = FileIO.ReadNextLine(b).split("="); // number of cells
11 13 Sep 07 nicklas 458                 blk.setNumCells(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 459                 sarray = FileIO.ReadNextLine(b).split("="); // start position.
11 13 Sep 07 nicklas 460                 blk.setStart(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 461                 sarray = FileIO.ReadNextLine(b).split("="); // stop position
11 13 Sep 07 nicklas 462                 blk.setStop(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 463                 blk.setNumCellsPerList(probeSet.getNumCellsPerList());
11 13 Sep 07 nicklas 464                 if (probeSet.getProbeSetType() == GeneChipProbeSetType.GenotypingProbeSetType && header.getVersion() > 2)
11 13 Sep 07 nicklas 465                 {
11 13 Sep 07 nicklas 466                     sarray = FileIO.ReadNextLine(b).split("=");
11 13 Sep 07 nicklas 467                     blk.setDirection(Byte.parseByte(sarray[1].trim()));
11 13 Sep 07 nicklas 468                 }
11 13 Sep 07 nicklas 469                 else
11 13 Sep 07 nicklas 470                     blk.setDirection(probeSet.getDirection());
11 13 Sep 07 nicklas 471
11 13 Sep 07 nicklas 472                 // Read the cells.
11 13 Sep 07 nicklas 473                 str = FileIO.ReadNextLine(b); // header
13 14 Sep 07 nicklas 474                 List<CDFProbeInformation> cells = Arrays.asList(new CDFProbeInformation[blk.getNumCells()]);
11 13 Sep 07 nicklas 475                 int cellIndex=0;
11 13 Sep 07 nicklas 476                 for (int iCell=0; iCell<blk.getNumCells(); iCell++)
11 13 Sep 07 nicklas 477                 {
11 13 Sep 07 nicklas 478                     CDFProbeInformation cell = new CDFProbeInformation();
11 13 Sep 07 nicklas 479                     sarray = FileIO.ReadNextLine(b).split("=");
11 13 Sep 07 nicklas 480                     sarray = sarray[1].split("\t");
11 13 Sep 07 nicklas 481                     cell.setX(Integer.parseInt(sarray[0].trim()));
11 13 Sep 07 nicklas 482                     cell.setY(Integer.parseInt(sarray[1].trim()));
11 13 Sep 07 nicklas 483                     cell.setExpos(Integer.parseInt(sarray[5].trim()));
11 13 Sep 07 nicklas 484                     cell.setPBase(sarray[8].charAt(0));
11 13 Sep 07 nicklas 485                     cell.setTBase(sarray[9].charAt(0));
11 13 Sep 07 nicklas 486                     cell.setListIndex(Integer.parseInt(sarray[10].trim()));
11 13 Sep 07 nicklas 487
11 13 Sep 07 nicklas 488                     if (probeSet.getProbeSetType() == GeneChipProbeSetType.ExpressionProbeSetType)
11 13 Sep 07 nicklas 489                     {
11 13 Sep 07 nicklas 490                         cellIndex = (iCell / probeSet.getNumCellsPerList()) * probeSet.getNumCellsPerList();
11 13 Sep 07 nicklas 491                         if (expectMisMatch && cell.getPBase() == cell.getTBase())
11 13 Sep 07 nicklas 492                             ++cellIndex;
11 13 Sep 07 nicklas 493                     }
11 13 Sep 07 nicklas 494                     else
11 13 Sep 07 nicklas 495                     {
11 13 Sep 07 nicklas 496                         cellIndex = (iCell / probeSet.getNumCellsPerList()) * probeSet.getNumCellsPerList();
11 13 Sep 07 nicklas 497                         cellIndex += (probeSet.getNumCellsPerList() - (iCell % probeSet.getNumCellsPerList()) - 1);
11 13 Sep 07 nicklas 498                     }
11 13 Sep 07 nicklas 499
11 13 Sep 07 nicklas 500                     cells.set(cellIndex, cell);
11 13 Sep 07 nicklas 501                     
11 13 Sep 07 nicklas 502                     if (iCell==0)
11 13 Sep 07 nicklas 503                         blk.setStart(cell.getListIndex());
11 13 Sep 07 nicklas 504                     else if (iCell == blk.getNumCells()-1)
11 13 Sep 07 nicklas 505                         blk.setStop(cell.getListIndex());
11 13 Sep 07 nicklas 506                 }
11 13 Sep 07 nicklas 507                 blk.setCells(cells);
13 14 Sep 07 nicklas 508                 groups.add(blk);
11 13 Sep 07 nicklas 509             }
11 13 Sep 07 nicklas 510             probeSet.setGroups(groups);
13 14 Sep 07 nicklas 511             probeSets.add(probeSet);
11 13 Sep 07 nicklas 512             ++iProbeSet;
11 13 Sep 07 nicklas 513         }
11 13 Sep 07 nicklas 514         return;
11 13 Sep 07 nicklas 515     }
11 13 Sep 07 nicklas 516
11 13 Sep 07 nicklas 517     /** Reads an XDA format CDF file.
11 13 Sep 07 nicklas 518      * @param bReadHeaderOnly Flag indicating if only the header should be read.
11 13 Sep 07 nicklas 519      * @return True if successful.
11 13 Sep 07 nicklas 520      */
14 14 Sep 07 nicklas 521     private boolean readXDAFormat(boolean bReadHeaderOnly) 
14 14 Sep 07 nicklas 522     {
14 14 Sep 07 nicklas 523         // Read the header
14 14 Sep 07 nicklas 524         if (!hasReadHeaders)
14 14 Sep 07 nicklas 525         {
14 14 Sep 07 nicklas 526             hasReadHeaders = true;
14 14 Sep 07 nicklas 527             headerResult = false;
14 14 Sep 07 nicklas 528
14 14 Sep 07 nicklas 529             InputStream readHeaders = in;
14 14 Sep 07 nicklas 530             if (in == null)
14 14 Sep 07 nicklas 531             {
14 14 Sep 07 nicklas 532                 if (xdaReader == null)
14 14 Sep 07 nicklas 533                 {
14 14 Sep 07 nicklas 534                     try
14 14 Sep 07 nicklas 535                     {
14 14 Sep 07 nicklas 536                         xdaReader = new FileInputStream(fileName);
14 14 Sep 07 nicklas 537                         readHeaders = xdaReader;
14 14 Sep 07 nicklas 538                     }
14 14 Sep 07 nicklas 539                     catch (Throwable t)
14 14 Sep 07 nicklas 540                     {
14 14 Sep 07 nicklas 541                         strError = t.getMessage();
14 14 Sep 07 nicklas 542                         return false;
14 14 Sep 07 nicklas 543                     }
14 14 Sep 07 nicklas 544                 }
14 14 Sep 07 nicklas 545             }
14 14 Sep 07 nicklas 546             headerResult = readXDAHeader(readHeaders);
14 14 Sep 07 nicklas 547             
14 14 Sep 07 nicklas 548         }
14 14 Sep 07 nicklas 549         if (headerResult == false) return false;
11 13 Sep 07 nicklas 550         
14 14 Sep 07 nicklas 551         // Stop if just reading the header.
14 14 Sep 07 nicklas 552         if (bReadHeaderOnly) return true;
14 14 Sep 07 nicklas 553
14 14 Sep 07 nicklas 554         if (hasReadData) return dataResult;
14 14 Sep 07 nicklas 555
14 14 Sep 07 nicklas 556         hasReadData = true;
14 14 Sep 07 nicklas 557         dataResult = false;
14 14 Sep 07 nicklas 558
11 13 Sep 07 nicklas 559         // Open the file.
14 14 Sep 07 nicklas 560         FileChannel fc = null;
14 14 Sep 07 nicklas 561         int headerOffset = 0;
14 14 Sep 07 nicklas 562         if (in != null)
11 13 Sep 07 nicklas 563         {
14 14 Sep 07 nicklas 564             // We must copy data to a temporary file, before we can read them
14 14 Sep 07 nicklas 565             try
14 14 Sep 07 nicklas 566             {
19 15 Nov 07 nicklas 567                 tempFile = File.createTempFile(fileName, null);
14 14 Sep 07 nicklas 568                 OutputStream out = new BufferedOutputStream(new FileOutputStream(tempFile));
14 14 Sep 07 nicklas 569                 FileIO.copy(in, out);
14 14 Sep 07 nicklas 570                 out.close();
14 14 Sep 07 nicklas 571                 fc = new FileInputStream(tempFile).getChannel();
14 14 Sep 07 nicklas 572                 tempFile.deleteOnExit();
14 14 Sep 07 nicklas 573             }
14 14 Sep 07 nicklas 574             catch (Throwable t)
14 14 Sep 07 nicklas 575             {
14 14 Sep 07 nicklas 576                 strError = t.getMessage();
14 14 Sep 07 nicklas 577                 return false;
14 14 Sep 07 nicklas 578             }
11 13 Sep 07 nicklas 579         }
14 14 Sep 07 nicklas 580         else
11 13 Sep 07 nicklas 581         {
14 14 Sep 07 nicklas 582             // Read directly from file
14 14 Sep 07 nicklas 583             try
14 14 Sep 07 nicklas 584             {
14 14 Sep 07 nicklas 585                 fc = xdaReader.getChannel();
14 14 Sep 07 nicklas 586             }
14 14 Sep 07 nicklas 587             catch (Throwable t)
14 14 Sep 07 nicklas 588             {
14 14 Sep 07 nicklas 589                 strError = t.getMessage();
14 14 Sep 07 nicklas 590                 return false;
14 14 Sep 07 nicklas 591             }            
11 13 Sep 07 nicklas 592         }
11 13 Sep 07 nicklas 593
11 13 Sep 07 nicklas 594         // Get a pointer to the memory map.
11 13 Sep 07 nicklas 595         try
11 13 Sep 07 nicklas 596         {
11 13 Sep 07 nicklas 597             headerOffset = (int)fc.position();
11 13 Sep 07 nicklas 598             long fileSize = fc.size();
11 13 Sep 07 nicklas 599             xdaBuffer = fc.map(MapMode.READ_ONLY, headerOffset, fileSize-headerOffset);
11 13 Sep 07 nicklas 600             xdaBuffer.order(ByteOrder.LITTLE_ENDIAN);
11 13 Sep 07 nicklas 601         }
11 13 Sep 07 nicklas 602         catch(Throwable t)
11 13 Sep 07 nicklas 603         {
11 13 Sep 07 nicklas 604             strError = t.getMessage();
11 13 Sep 07 nicklas 605             return false;
11 13 Sep 07 nicklas 606         }
11 13 Sep 07 nicklas 607
11 13 Sep 07 nicklas 608   // Now that the file is mapped, set the file pointers of the members
11 13 Sep 07 nicklas 609         int dataOffset = 0;
11 13 Sep 07 nicklas 610         probeSetNames = new CDFProbeSetNames();
11 13 Sep 07 nicklas 611         probeSetNames.setMap(xdaBuffer, dataOffset);
11 13 Sep 07 nicklas 612
11 13 Sep 07 nicklas 613   // Skip over the probe set names
11 13 Sep 07 nicklas 614   dataOffset += (CDFProbeSetNames.MAX_PROBE_SET_NAME_LENGTH * header.getNumProbeSets());
11 13 Sep 07 nicklas 615
11 13 Sep 07 nicklas 616   // Read the qc probe set indicies
13 14 Sep 07 nicklas 617   qcProbeSetPositions = new ArrayList<Integer>(header.getNumQCProbeSets());
11 13 Sep 07 nicklas 618   for (int iqcset=0; iqcset<header.getNumQCProbeSets(); iqcset++)
11 13 Sep 07 nicklas 619   {
13 14 Sep 07 nicklas 620             qcProbeSetPositions.add(FileIO.MmGetInt32_I(xdaBuffer, dataOffset)-headerOffset);
11 13 Sep 07 nicklas 621             dataOffset += DataSizes.INT_SIZE;
11 13 Sep 07 nicklas 622   }
11 13 Sep 07 nicklas 623
11 13 Sep 07 nicklas 624   // Read the probe set indicies.
13 14 Sep 07 nicklas 625   probeSetPositions = new ArrayList<Integer>(header.getNumProbeSets());
11 13 Sep 07 nicklas 626   for (int iset=0; iset<header.getNumProbeSets(); iset++)
11 13 Sep 07 nicklas 627   {
13 14 Sep 07 nicklas 628             probeSetPositions.add(FileIO.MmGetInt32_I(xdaBuffer, dataOffset)-headerOffset);
11 13 Sep 07 nicklas 629             dataOffset += DataSizes.INT_SIZE;
11 13 Sep 07 nicklas 630   }
14 14 Sep 07 nicklas 631     dataResult = true;
11 13 Sep 07 nicklas 632   return true;
11 13 Sep 07 nicklas 633     }
11 13 Sep 07 nicklas 634             
11 13 Sep 07 nicklas 635     /** Reads the header of an XDA format CDF file.
11 13 Sep 07 nicklas 636      * @param instr The file stream object.
11 13 Sep 07 nicklas 637      * @return True if successful.
11 13 Sep 07 nicklas 638      */
13 14 Sep 07 nicklas 639     private boolean readXDAHeader(InputStream fis) {
11 13 Sep 07 nicklas 640         // Extact the magic and version numbers.
11 13 Sep 07 nicklas 641     header = new CDFFileHeader();
11 13 Sep 07 nicklas 642   header.setMagic(FileIO.ReadInt32_I(fis));
11 13 Sep 07 nicklas 643         header.setVersion(FileIO.ReadInt32_I(fis));
11 13 Sep 07 nicklas 644
11 13 Sep 07 nicklas 645   // Check the values for the right format file.
11 13 Sep 07 nicklas 646   if (header.getMagic() != CDF_FILE_MAGIC_NUMBER || header.getVersion() > CDF_FILE_VERSION_NUMBER)
11 13 Sep 07 nicklas 647   {
11 13 Sep 07 nicklas 648             strError = "The file does not appear to be the correct format.";
11 13 Sep 07 nicklas 649             return false;
11 13 Sep 07 nicklas 650   }
11 13 Sep 07 nicklas 651
11 13 Sep 07 nicklas 652   // Read the remaining header.
11 13 Sep 07 nicklas 653         header.setCols(FileIO.ReadInt16_I(fis));
11 13 Sep 07 nicklas 654         header.setRows(FileIO.ReadInt16_I(fis));
11 13 Sep 07 nicklas 655         header.setNumProbeSets(FileIO.ReadInt32_I(fis));
11 13 Sep 07 nicklas 656         header.setNumQCProbeSets(FileIO.ReadInt32_I(fis));
11 13 Sep 07 nicklas 657         header.setReference(FileIO.ReadString_I(fis));
11 13 Sep 07 nicklas 658
11 13 Sep 07 nicklas 659   return true;
11 13 Sep 07 nicklas 660     }
11 13 Sep 07 nicklas 661     
11 13 Sep 07 nicklas 662     /** Gets the name of a probe set.
11 13 Sep 07 nicklas 663      * @param index The index to the probe set name of interest.
11 13 Sep 07 nicklas 664      * @return The probe set name.
11 13 Sep 07 nicklas 665      */
11 13 Sep 07 nicklas 666     public String getProbeSetName(int index) { return probeSetNames.getName(index); }
11 13 Sep 07 nicklas 667
11 13 Sep 07 nicklas 668     /** Gets the chip type (probe array type) of the CDF file.
11 13 Sep 07 nicklas 669      * @return The chip type. This is just the name (without extension) of the CDF file.
11 13 Sep 07 nicklas 670      */
11 13 Sep 07 nicklas 671     public String getChipType() {
13 14 Sep 07 nicklas 672     if (fileName.length() > 0)
13 14 Sep 07 nicklas 673     {
11 13 Sep 07 nicklas 674             int start = fileName.lastIndexOf('\\');
11 13 Sep 07 nicklas 675             if (start == -1)
11 13 Sep 07 nicklas 676                 start = fileName.lastIndexOf('/');
11 13 Sep 07 nicklas 677             int end = fileName.lastIndexOf('.');
11 13 Sep 07 nicklas 678             return fileName.substring(start+1, end);
11 13 Sep 07 nicklas 679         }
13 14 Sep 07 nicklas 680     return "";
11 13 Sep 07 nicklas 681     }
11 13 Sep 07 nicklas 682
11 13 Sep 07 nicklas 683     /** Reads the entire file.
11 13 Sep 07 nicklas 684      * @return True if successful.
11 13 Sep 07 nicklas 685      */
11 13 Sep 07 nicklas 686     public boolean read() {
11 13 Sep 07 nicklas 687         if (open(false) == false)
11 13 Sep 07 nicklas 688   {
11 13 Sep 07 nicklas 689             clear();
11 13 Sep 07 nicklas 690             return false;
11 13 Sep 07 nicklas 691   }
11 13 Sep 07 nicklas 692   return true;
11 13 Sep 07 nicklas 693     }
11 13 Sep 07 nicklas 694
11 13 Sep 07 nicklas 695     /** Reads the header of the file only.
11 13 Sep 07 nicklas 696      * @return True if successful.
11 13 Sep 07 nicklas 697      */
11 13 Sep 07 nicklas 698     public boolean readHeader() {
13 14 Sep 07 nicklas 699        if (open(true) == false)
11 13 Sep 07 nicklas 700   {
11 13 Sep 07 nicklas 701             clear();
11 13 Sep 07 nicklas 702             return false;
11 13 Sep 07 nicklas 703   }
11 13 Sep 07 nicklas 704   return true;
11 13 Sep 07 nicklas 705     }
11 13 Sep 07 nicklas 706     
13 14 Sep 07 nicklas 707     /** 
13 14 Sep 07 nicklas 708      * Checks if the file exists or if an input stream has been specified.
11 13 Sep 07 nicklas 709      * @return True if the file exists.
11 13 Sep 07 nicklas 710      */
13 14 Sep 07 nicklas 711     public boolean exists() { 
13 14 Sep 07 nicklas 712         return in != null || new File(fileName).exists(); 
13 14 Sep 07 nicklas 713     }
11 13 Sep 07 nicklas 714
11 13 Sep 07 nicklas 715     /** Determines if a CDF file is of the XDA (binary) format.
11 13 Sep 07 nicklas 716      * @return True if XDA format.
11 13 Sep 07 nicklas 717      */
13 14 Sep 07 nicklas 718     public boolean isXDACompatibleFile() 
13 14 Sep 07 nicklas 719     {
13 14 Sep 07 nicklas 720         if (isXDACompatible == null)
11 13 Sep 07 nicklas 721         {
13 14 Sep 07 nicklas 722             try
13 14 Sep 07 nicklas 723             {
13 14 Sep 07 nicklas 724                 int magicNumber = 0;
13 14 Sep 07 nicklas 725                 if (in != null)
13 14 Sep 07 nicklas 726                 {
13 14 Sep 07 nicklas 727                     // Read data from input stream
13 14 Sep 07 nicklas 728                     PushbackInputStream pin = new PushbackInputStream(in, DataSizes.INT_SIZE);
13 14 Sep 07 nicklas 729                     magicNumber = FileIO.PeekInt32_I(pin);
13 14 Sep 07 nicklas 730                     in = pin;
13 14 Sep 07 nicklas 731                 }
13 14 Sep 07 nicklas 732                 else
13 14 Sep 07 nicklas 733                 {
13 14 Sep 07 nicklas 734                     // Read from file
13 14 Sep 07 nicklas 735                     FileInputStream fis = new FileInputStream(fileName);
13 14 Sep 07 nicklas 736                     
13 14 Sep 07 nicklas 737                     magicNumber = FileIO.ReadInt32_I(fis);
13 14 Sep 07 nicklas 738                     fis.close();
13 14 Sep 07 nicklas 739                 }
13 14 Sep 07 nicklas 740                 isXDACompatible = (magicNumber == CDFFileData.CDF_FILE_MAGIC_NUMBER);
13 14 Sep 07 nicklas 741             }
13 14 Sep 07 nicklas 742             catch (Throwable t)
13 14 Sep 07 nicklas 743             {
13 14 Sep 07 nicklas 744                 isXDACompatible = false;
13 14 Sep 07 nicklas 745             
13 14 Sep 07 nicklas 746             }
11 13 Sep 07 nicklas 747         }
13 14 Sep 07 nicklas 748          return isXDACompatible;
11 13 Sep 07 nicklas 749     }
11 13 Sep 07 nicklas 750
11 13 Sep 07 nicklas 751     /** Gets the probe set type for non-qc probe sets.
11 13 Sep 07 nicklas 752      * @param index The index to the probe set of interest.
11 13 Sep 07 nicklas 753      * @return The type of probe set.
11 13 Sep 07 nicklas 754      */
11 13 Sep 07 nicklas 755     public int getProbeSetType(int index) {
11 13 Sep 07 nicklas 756         if (probeSets != null)
13 14 Sep 07 nicklas 757             return probeSets.get(index).getProbeSetType();
11 13 Sep 07 nicklas 758   else if (xdaBuffer != null)
11 13 Sep 07 nicklas 759   {
11 13 Sep 07 nicklas 760             // The type is the first item in the probe set object.
13 14 Sep 07 nicklas 761             int offset = probeSetPositions.get(index);
11 13 Sep 07 nicklas 762             return FileIO.MmGetUInt16_I(xdaBuffer, offset);
11 13 Sep 07 nicklas 763   }
11 13 Sep 07 nicklas 764         return GeneChipProbeSetType.UnknownProbeSetType;
11 13 Sep 07 nicklas 765     }
11 13 Sep 07 nicklas 766
11 13 Sep 07 nicklas 767     /** Gets the probe set information.
11 13 Sep 07 nicklas 768      * @param index The index to the probe set of interest.
11 13 Sep 07 nicklas 769      * @return The probe set information.
11 13 Sep 07 nicklas 770      */
11 13 Sep 07 nicklas 771     public CDFProbeSetInformation getProbeSetInformation(int index) {
11 13 Sep 07 nicklas 772         if (probeSets != null)
13 14 Sep 07 nicklas 773             return probeSets.get(index);
11 13 Sep 07 nicklas 774   else if (xdaBuffer != null)
11 13 Sep 07 nicklas 775   {
11 13 Sep 07 nicklas 776             CDFProbeSetInformation probeSet = new CDFProbeSetInformation();
13 14 Sep 07 nicklas 777             long dataOffset = (long) probeSetPositions.get(index);
11 13 Sep 07 nicklas 778             probeSet.setMap(xdaBuffer, dataOffset, index);
11 13 Sep 07 nicklas 779             return probeSet;
11 13 Sep 07 nicklas 780         }
11 13 Sep 07 nicklas 781         return null;
11 13 Sep 07 nicklas 782     }
11 13 Sep 07 nicklas 783
11 13 Sep 07 nicklas 784     /** Gets the QC probe set information by index.
11 13 Sep 07 nicklas 785      * @param index The index to the QC probe set of interest.
11 13 Sep 07 nicklas 786      * @return The QC probe set information.
11 13 Sep 07 nicklas 787      */
11 13 Sep 07 nicklas 788     public CDFQCProbeSetInformation getQCProbeSetInformation(int index) {
11 13 Sep 07 nicklas 789         if (qcProbeSets != null)
13 14 Sep 07 nicklas 790             return qcProbeSets.get(index);
11 13 Sep 07 nicklas 791   else if (xdaBuffer != null)
11 13 Sep 07 nicklas 792   {
11 13 Sep 07 nicklas 793             CDFQCProbeSetInformation qcProbeSet = new CDFQCProbeSetInformation();
13 14 Sep 07 nicklas 794             long dataOffset = (long) qcProbeSetPositions.get(index);
11 13 Sep 07 nicklas 795             qcProbeSet.setMap(xdaBuffer, dataOffset);
11 13 Sep 07 nicklas 796             return qcProbeSet;
11 13 Sep 07 nicklas 797         }
11 13 Sep 07 nicklas 798         return null;
11 13 Sep 07 nicklas 799     }
11 13 Sep 07 nicklas 800
11 13 Sep 07 nicklas 801     /** Gets the QC probe set information by type.
11 13 Sep 07 nicklas 802      * @param qcType The type of QC probe set to retrieve.
11 13 Sep 07 nicklas 803      * @return The QC probe set information.
11 13 Sep 07 nicklas 804      */
11 13 Sep 07 nicklas 805     public CDFQCProbeSetInformation getQCProbeSetInformationByType(int qcType) {
11 13 Sep 07 nicklas 806       for (int i=0; i<header.getNumQCProbeSets(); i++)
11 13 Sep 07 nicklas 807   {
11 13 Sep 07 nicklas 808             CDFQCProbeSetInformation info = getQCProbeSetInformation(i);
11 13 Sep 07 nicklas 809             if (info.getQCProbeSetType() == qcType)
11 13 Sep 07 nicklas 810                 return info;
11 13 Sep 07 nicklas 811   }
11 13 Sep 07 nicklas 812         return null;
11 13 Sep 07 nicklas 813     }
11 13 Sep 07 nicklas 814     
11 13 Sep 07 nicklas 815     /** Creates a new instance of CDFFileData */
11 13 Sep 07 nicklas 816     public CDFFileData() {
11 13 Sep 07 nicklas 817         fileName = "";
11 13 Sep 07 nicklas 818         strError = "";
11 13 Sep 07 nicklas 819         clear();
11 13 Sep 07 nicklas 820     }
11 13 Sep 07 nicklas 821     
11 13 Sep 07 nicklas 822     /** Clears the members. */
11 13 Sep 07 nicklas 823     public void clear() {
13 14 Sep 07 nicklas 824         if (in == null)
13 14 Sep 07 nicklas 825         {
13 14 Sep 07 nicklas 826             xdaBuffer = null;
13 14 Sep 07 nicklas 827             probeSetPositions = null;
13 14 Sep 07 nicklas 828             qcProbeSetPositions = null;
13 14 Sep 07 nicklas 829             header = null;
13 14 Sep 07 nicklas 830             probeSetNames = null;
13 14 Sep 07 nicklas 831             probeSets = null;
13 14 Sep 07 nicklas 832             qcProbeSets = null;
13 14 Sep 07 nicklas 833             hasReadData = false;
13 14 Sep 07 nicklas 834             hasReadHeaders = false;
13 14 Sep 07 nicklas 835         }
11 13 Sep 07 nicklas 836     }
19 15 Nov 07 nicklas 837
19 15 Nov 07 nicklas 838     @Override
19 15 Nov 07 nicklas 839     protected void finalize()
19 15 Nov 07 nicklas 840         throws Throwable
19 15 Nov 07 nicklas 841     {
19 15 Nov 07 nicklas 842         super.finalize();
19 15 Nov 07 nicklas 843         if (tempFile != null && tempFile.exists())
19 15 Nov 07 nicklas 844         {
19 15 Nov 07 nicklas 845             tempFile.delete();
19 15 Nov 07 nicklas 846         }
19 15 Nov 07 nicklas 847     }    
11 13 Sep 07 nicklas 848     
11 13 Sep 07 nicklas 849 }