Changeset 2375


Ignore:
Timestamp:
03/02/07 08:53:20 (13 years ago)
Author:
melissa
Message:

Merged Andor and Fluoview readers (since they are the same format).
Also cleaned up dimension order detection in new Fluoview reader, and finished
populating MetadataStore fields.

Location:
trunk/loci/formats
Files:
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/formats/in/FluoviewReader.java

    r2313 r2375  
    2626 
    2727import java.io.*; 
    28 import java.util.Hashtable; 
    29 import java.util.Vector; 
     28import java.util.*; 
    3029import loci.formats.*; 
    3130 
    3231/** 
    3332 * FluoviewReader is the file format reader for 
    34  * Olympus Fluoview TIFF files. 
     33 * Olympus Fluoview TIFF files AND Andor Bio-imaging Division (ABD) TIFF files. 
    3534 * 
    3635 * @author Eric Kjellman egkjellman at wisc.edu 
     
    4847  private static final String FLUOVIEW_MAGIC_STRING = "FLUOVIEW"; 
    4948 
    50   /** Fluoview TIFF private tags */ 
     49  /** Private TIFF tags */ 
    5150  private static final int MMHEADER = 34361; 
    52  
     51  private static final int MMSTAMP = 34362; 
     52 
     53  // -- Fields -- 
     54 
     55  /** Flag indicating this is a Fluoview file. */ 
     56  private boolean isFluoview; 
     57 
     58  /** Pixel dimensions for this file. */ 
     59  private float voxelX = 0f, voxelY = 0f, voxelZ = 0f, voxelC = 0f, voxelT = 0f; 
     60   
    5361  // -- Constructor -- 
    5462 
    5563  /** Constructs a new Fluoview TIFF reader. */ 
    5664  public FluoviewReader() { 
    57     super("Olympus Fluoview TIFF", new String[] {"tif", "tiff"}); 
     65    super("Olympus Fluoview/Andor Bio-imaging TIFF",  
     66      new String[] {"tif", "tiff"}); 
    5867  } 
    5968 
     
    6473    if (!TiffTools.isValidHeader(block)) return false; 
    6574 
    66     // if this file is a Fluoview TIFF file, it should have 42 
    67     // for the 3rd byte, and contain the text "FLUOVIEW" 
     75    if (block.length < 3) return false; 
     76    if (block.length < 8) return true; 
     77 
    6878    String test = new String(block); 
    69     return test.indexOf(FLUOVIEW_MAGIC_STRING) != -1; 
     79    if (test.indexOf(FLUOVIEW_MAGIC_STRING) != -1) { 
     80      isFluoview = true; 
     81      return true; 
     82    } 
     83 
     84    int ifdlocation = DataTools.bytesToInt(block, 4, true); 
     85    if (ifdlocation < 0 || ifdlocation + 1 > block.length) return false; 
     86    else { 
     87      int ifdnumber = DataTools.bytesToInt(block, ifdlocation, 2, true); 
     88      for (int i=0; i<ifdnumber; i++) { 
     89        if (ifdlocation + 3 + (i*12) > block.length) return false; 
     90        else { 
     91          int ifdtag = DataTools.bytesToInt(block, ifdlocation + 2 + (i*12), 
     92            2, true); 
     93          if (ifdtag == MMHEADER || ifdtag == MMSTAMP) return true; 
     94        } 
     95      } 
     96    } 
     97    return false; 
    7098  } 
    7199 
     
    75103  { 
    76104    if (!id.equals(currentId)) initFile(id); 
    77     String s = (String) getMeta("Map Ch" + theC + ": Range"); 
     105    String s = (String) getMeta("Map min"); 
    78106    if (s == null) return null; 
    79     s = s.substring(0, s.indexOf("to") - 1).trim(); 
    80     return new Double(Integer.parseInt(s)); 
     107    return new Double(s); 
    81108  } 
    82109 
     
    86113  { 
    87114    if (!id.equals(currentId)) initFile(id); 
    88     String s = (String) getMeta("Map Ch" + theC + ": Range"); 
     115    String s = (String) getMeta("Map max"); 
    89116    if (s == null) return null; 
    90     s = s.substring(s.indexOf("to") + 2).trim(); 
    91     return new Double(Integer.parseInt(s)); 
     117    return new Double(s); 
    92118  } 
    93119 
     
    96122    throws FormatException, IOException 
    97123  { 
    98     return true; 
     124    if (!id.equals(currentId)) initFile(id); 
     125    return getMeta("Min value") != null && getMeta("Max value") != null; 
    99126  } 
    100127 
     
    118145 
    119146  /* @see loci.formats.BaseTiffReader#initStandardMetadata() */ 
    120   protected void initStandardMetadata() throws FormatException { 
     147  protected void initStandardMetadata() throws FormatException, IOException { 
    121148    super.initStandardMetadata(); 
    122149 
    123     sizeZ[0] = 1; 
    124     sizeC[0] = 1; 
    125     sizeT[0] = 1; 
    126  
     150    // First, we want to determine whether this file is a Fluoview TIFF. 
     151    // Originally, Andor TIFF had its own reader; however, the two formats are 
     152    // very similar, so it made more sense to merge the two formats into one 
     153    // reader. 
     154   
     155    byte[] buf = new byte[BLOCK_CHECK_LEN]; 
     156    in.seek(0); 
     157    in.read(buf); 
     158    isFluoview = new String(buf).indexOf(FLUOVIEW_MAGIC_STRING) != -1; 
     159 
     160    short[] s = TiffTools.getIFDShortArray(ifds[0], MMHEADER, true); 
     161    byte[] mmheader = new byte[s.length]; 
     162    for (int i=0; i<mmheader.length; i++) { 
     163      mmheader[i] = (byte) s[i]; 
     164      if (mmheader[i] < 0) mmheader[i]++; 
     165    } 
     166   
     167    RandomAccessStream ras = new RandomAccessStream(mmheader); 
     168    ras.order(isLittleEndian(currentId)); 
     169 
     170    put("Header Flag", ras.readShort()); 
     171    put("Image Type", (char) ras.read()); 
     172     
     173    byte[] nameBytes = new byte[257]; 
     174    ras.read(nameBytes); 
     175    put("Image name", new String(nameBytes)); 
     176 
     177    ras.skipBytes(4); // skip pointer to data field 
     178 
     179    put("Number of colors", ras.readInt()); 
     180    ras.skipBytes(4); // skip pointer to palette field 
     181    ras.skipBytes(4); // skip pointer to other palette field 
     182     
     183    put("Comment size", ras.readInt()); 
     184    ras.skipBytes(4); // skip pointer to comment field 
     185 
     186    // read dimension information 
     187    byte[] dimNameBytes = new byte[16]; 
     188    byte[] dimCalibrationUnits = new byte[64]; 
     189    for (int i=0; i<10; i++) { 
     190      ras.read(dimNameBytes); 
     191      int size = ras.readInt(); 
     192      double origin = ras.readDouble(); 
     193      double resolution = ras.readDouble(); 
     194      ras.read(dimCalibrationUnits); 
     195     
     196      put("Dimension " + (i+1) + " Name", new String(dimNameBytes)); 
     197      put("Dimension " + (i+1) + " Size", size); 
     198      put("Dimension " + (i+1) + " Origin", origin); 
     199      put("Dimension " + (i+1) + " Resolution", resolution); 
     200      put("Dimension " + (i+1) + " Units", new String(dimCalibrationUnits)); 
     201    } 
     202 
     203    ras.skipBytes(4); // skip pointer to spatial position data 
     204 
     205    put("Map type", ras.readShort()); 
     206    put("Map min", ras.readDouble()); 
     207    put("Map max", ras.readDouble()); 
     208    put("Min value", ras.readDouble()); 
     209    put("Max value", ras.readDouble()); 
     210 
     211    ras.skipBytes(4); // skip pointer to map data 
     212 
     213    put("Gamma", ras.readDouble()); 
     214    put("Offset", ras.readDouble()); 
     215 
     216    // read gray channel data 
     217    ras.read(dimNameBytes); 
     218    put("Gray Channel Name", new String(dimNameBytes)); 
     219    put("Gray Channel Size", ras.readInt()); 
     220    put("Gray Channel Origin", ras.readDouble()); 
     221    put("Gray Channel Resolution", ras.readDouble()); 
     222    ras.read(dimCalibrationUnits); 
     223    put("Gray Channel Units", new String(dimCalibrationUnits)); 
     224 
     225    ras.skipBytes(4); // skip pointer to thumbnail data 
     226 
     227    put("Voice field", ras.readInt()); 
     228    ras.skipBytes(4); // skip pointer to voice field 
     229   
     230    // now we need to read the MMSTAMP data to determine dimension order 
     231     
     232    double[][] stamps = new double[8][ifds.length]; 
     233    for (int i=0; i<ifds.length; i++) { 
     234      s = TiffTools.getIFDShortArray(ifds[i], MMSTAMP, true); 
     235      byte[] stamp = new byte[s.length]; 
     236      for (int j=0; j<s.length; j++) { 
     237        stamp[j] = (byte) s[j]; 
     238        if (stamp[j] < 0) stamp[j]++; 
     239      } 
     240      ras = new RandomAccessStream(stamp); 
     241 
     242      // each stamp is 8 doubles, representing the position on dimensions 3-10 
     243      for (int j=0; j<8; j++) { 
     244        stamps[j][i] = ras.readDouble();  
     245      } 
     246    } 
     247 
     248    // calculate the dimension order and axis sizes 
     249     
     250    sizeZ[0] = sizeC[0] = sizeT[0] = 1; 
     251    currentOrder[0] = "XY"; 
     252 
     253    for (int i=0; i<10; i++) { 
     254      String name = (String) getMeta("Dimension " + (i+1) + " Name"); 
     255      Integer size = (Integer) getMeta("Dimension " + (i+1) + " Size"); 
     256      Double voxel = (Double) getMeta("Dimension " + (i+1) + " Resolution");  
     257      if (name == null || size == null || size.intValue() == 0) continue; 
     258      name = name.toLowerCase().trim(); 
     259       
     260      if (name.equals("x")) { 
     261        sizeX[0] = size.intValue(); 
     262        if (voxel != null) voxelX = voxel.floatValue();  
     263      }  
     264      else if (name.equals("y")) { 
     265        sizeY[0] = size.intValue(); 
     266        if (voxel != null) voxelY = voxel.floatValue();  
     267      }  
     268      else if (name.equals("z") || name.equals("event")) { 
     269        sizeZ[0] *= size.intValue(); 
     270        if (currentOrder[0].indexOf("Z") == -1) currentOrder[0] += "Z"; 
     271        if (voxel != null) voxelZ = voxel.floatValue();  
     272      } 
     273      else if (name.equals("ch") || name.equals("wavelength")) { 
     274        sizeC[0] *= size.intValue(); 
     275        if (currentOrder[0].indexOf("C") == -1) currentOrder[0] += "C"; 
     276        if (voxel != null) voxelC = voxel.floatValue();  
     277      } 
     278      else { 
     279        sizeT[0] *= size.intValue(); 
     280        if (currentOrder[0].indexOf("T") == -1) currentOrder[0] += "T"; 
     281        if (voxel != null) voxelT = voxel.floatValue();  
     282      } 
     283    } 
     284 
     285    if (currentOrder[0].indexOf("Z") == -1) currentOrder[0] += "Z"; 
     286    if (currentOrder[0].indexOf("T") == -1) currentOrder[0] += "T"; 
     287    if (currentOrder[0].indexOf("C") == -1) currentOrder[0] += "C"; 
     288     
     289    numImages = ifds.length; 
     290   
     291    // cut up the comment, if necessary  
     292    String comment = (String) getMeta("Comment");  
     293     
     294    if (comment != null && comment.startsWith("[")) { 
     295      int start = comment.indexOf("[Acquisition Parameters]"); 
     296      int end = comment.indexOf("[Acquisition Parameters End]"); 
     297      if (start != -1 && end != -1 && end > start) { 
     298        String parms = comment.substring(start + 24, end).trim(); 
     299         
     300        // this is an INI-style comment, with one key/value pair per line 
     301 
     302        StringTokenizer st = new StringTokenizer(parms, "\n"); 
     303        while (st.hasMoreTokens()) { 
     304          String token = st.nextToken(); 
     305          int eq = token.indexOf("="); 
     306          if (eq != -1) { 
     307            String key = token.substring(0, eq); 
     308            String value = token.substring(eq + 1); 
     309            addMeta(key, value);  
     310          } 
     311        } 
     312      } 
     313    
     314      start = comment.indexOf("[Version Info]"); 
     315      end = comment.indexOf("[Version Info End]"); 
     316      if (start != -1 && end != -1 && end > start) { 
     317        comment = comment.substring(start + 14, end).trim(); 
     318        comment = comment.substring(comment.indexOf("=") + 1, 
     319          comment.indexOf("\n")).trim();  
     320      } 
     321      else comment = ""; 
     322    } 
     323    addMeta("Comment", comment); 
     324  } 
     325 
     326  protected void initMetadataStore() { 
     327    super.initMetadataStore();  
    127328    try { 
    128       Hashtable ifd = ifds[0]; 
    129  
    130       // determine byte order 
    131       boolean little = TiffTools.isLittleEndian(ifd); 
    132  
    133       in.order(little); 
    134  
    135       // set file pointer to start reading MM_HEAD metadata 
    136       short[] mmHead = TiffTools.getIFDShortArray(ifd, MMHEADER, false); 
    137       int p = 0; // pointer to next byte in mmHead 
    138  
    139       // -- Parse standard metadata -- 
    140  
    141       put("HeaderSize", DataTools.bytesToInt(mmHead, p, 2, little)); 
    142       p += 2; 
    143       put("Status", DataTools.bytesToString(mmHead, p, 1)); 
    144       p++; 
    145  
    146       // change from the specs: using 257 bytes instead of 256 
    147       String imageName = DataTools.bytesToString(mmHead, p, 257); 
    148       put("ImageName", imageName); 
    149       p += 257 + 4; // there are 4 bytes that we don't need 
    150  
    151       put("NumberOfColors", DataTools.bytesToLong(mmHead, p, 4, little)); 
    152       p += 4 + 8; // again, 8 bytes we don't need 
    153  
    154       // don't add commentSize and commentOffset to hashtable 
    155       // these will be used later to read in the Comments field 
    156       // and add it to the hashtable 
    157       long commentSize = DataTools.bytesToLong(mmHead, p, 4, little); 
    158       p += 4; 
    159       long commentOffset = DataTools.bytesToLong(mmHead, p, 4, little); 
    160       p += 4; 
    161  
    162       // dimensions info 
    163       // there are 10 blocks of dimension info to be read, 
    164       // each with the same structure 
    165       // in the hashtable, the same tags in different blocks 
    166       // are distinguished by appending the block number to the 
    167       // tag name 
    168       for (int j=0; j<10; j++) { 
    169         put("DimName" + j, DataTools.bytesToString(mmHead, p, 16)); 
    170         p += 16; 
    171         put("Size" + j, DataTools.bytesToLong(mmHead, p, 4, little)); 
    172         p += 4; 
    173         put("Origin" + j, Double.longBitsToDouble( 
    174           DataTools.bytesToLong(mmHead, p, little))); 
    175         p += 8; 
    176         put("Resolution" + j, Double.longBitsToDouble( 
    177           DataTools.bytesToLong(mmHead, p, little))); 
    178         p += 8; 
    179       } 
    180  
    181       put("MapType", DataTools.bytesToInt(mmHead, p, 2, little)); 
    182       p += 2 + 2; // 2 bytes we don't need 
    183       put("MapMin", Double.longBitsToDouble( 
    184         DataTools.bytesToLong(mmHead, p, little))); 
    185       p += 8; 
    186       put("MapMax", Double.longBitsToDouble( 
    187         DataTools.bytesToLong(mmHead, p, little))); 
    188       p += 8; 
    189       put("MinValue", Double.longBitsToDouble( 
    190         DataTools.bytesToLong(mmHead, p, little))); 
    191       p += 8; 
    192       put("MaxValue", Double.longBitsToDouble( 
    193         DataTools.bytesToLong(mmHead, p, little))); 
    194       p += 8 + 4; // skipping over 4 bytes 
    195       put("Gamma", Double.longBitsToDouble( 
    196         DataTools.bytesToLong(mmHead, p, little))); 
    197       p += 8; 
    198       put("Offset", Double.longBitsToDouble( 
    199         DataTools.bytesToLong(mmHead, p, little))); 
    200       p += 8; 
    201  
    202       // get Gray dimension info 
    203  
    204       put("DimName11", DataTools.bytesToString(mmHead, p, 16)); 
    205       p += 16; 
    206       put("Size11", DataTools.bytesToLong(mmHead, p, 4, little)); 
    207       p += 4; 
    208       put("Origin11", Double.longBitsToDouble( 
    209         DataTools.bytesToLong(mmHead, p, little))); 
    210       p += 8; 
    211       put("Resolution11", Double.longBitsToDouble( 
    212         DataTools.bytesToLong(mmHead, p, little))); 
    213  
    214       // read in comments field 
    215       if (commentSize > 0) { 
    216         in.seek((int) commentOffset); 
    217         byte[] comments = new byte[(int) commentSize]; 
    218         in.read(comments); 
    219         put("Comments", new String(comments)); 
    220       } 
    221  
    222       // -- Parse OME-XML metadata -- 
    223  
    224       Object off = (Object) ifd.get(new Integer(MMHEADER)); 
    225       float origin = 0; 
    226  
    227       float stageX = 0; 
    228       float stageY = 0; 
    229       float stageZ = 0; 
    230  
    231       if (off != null) { 
    232         // read the metadata 
    233         byte[] temp2 = new byte[279]; 
    234         in.read(temp2); 
    235         char[] dimName; 
    236         for (int j=0; j<10; j++) { 
    237           dimName = new char[16]; 
    238           for (int i=0; i<16; i++) { 
    239             dimName[i] = (char) in.read(); 
    240             in.read(); 
    241           } 
    242  
    243           in.skipBytes(4); 
    244           origin = (float) in.readDouble(); 
    245           if (j == 1) stageX = origin; 
    246           else if (j == 2) stageY = origin; 
    247           else if (j == 3) stageZ = origin; 
    248  
    249           in.readDouble(); // skip next double 
     329      MetadataStore store = getMetadataStore(currentId); 
     330      store.setDimensions(new Float(voxelX), new Float(voxelY),  
     331        new Float(voxelZ), new Float(voxelC), new Float(voxelT), null);  
     332       
     333      Double gamma = (Double) getMeta("Gamma"); 
     334      for (int i=0; i<sizeC[0]; i++) { 
     335        store.setDisplayChannel(new Integer(i), null, null,  
     336          gamma == null ? null : new Float(gamma.floatValue()), null);  
     337      
     338        String gain = (String) getMeta("Gain Ch" + (i+1)); 
     339        String voltage = (String) getMeta("PMT Voltage Ch" + (i+1)); 
     340        String offset = (String) getMeta("Offset Ch" + (i+1)); 
     341        
     342        if (gain != null || voltage != null || offset != null) { 
     343          store.setDetector((String) getMeta("System Configuration"), null, 
     344            null, null, gain == null ? null : new Float(gain), 
     345            voltage == null ? null : new Float(voltage), 
     346            offset == null ? null : new Float(offset), null, new Integer(i));  
    250347        } 
    251348      } 
    252  
    253       // The metadata store we're working with. 
    254       MetadataStore store = getMetadataStore(currentId); 
    255  
    256       store.setStageLabel(null, new Float(stageX), new Float(stageY), 
    257         new Float(stageZ), null); 
    258  
    259       for (int i=0; i<sizeC[0]; i++) { 
    260         store.setLogicalChannel(i, null, null, null, null, null, null, null); 
    261       } 
    262  
    263       String descr = (String) getMeta("Comment"); 
    264       metadata.remove("Comment"); 
    265       if (descr == null) descr = ""; 
    266  
    267       // strip LUT data from image description 
    268       int firstIndex = descr.indexOf("[LUT Ch"); 
    269       int lastIndex = descr.lastIndexOf("[LUT Ch") + 13; 
    270       if (firstIndex != -1 && lastIndex > firstIndex) { 
    271         descr = descr.substring(0, firstIndex) + descr.substring(lastIndex); 
    272       } 
    273  
    274       // now parse key-value pairs in the description field 
    275  
    276       // first thing is to remove anything of the form "[blah]" 
    277  
    278       String first; 
    279       String last; 
    280  
    281       int lbrack = descr.indexOf("["); 
    282       while (lbrack != -1) { 
    283         int nl = descr.indexOf("\n", lbrack); 
    284         if (nl < 0) nl = descr.length(); 
    285         first = descr.substring(0, lbrack); 
    286         last = descr.substring(nl); 
    287         descr = first + last; 
    288         lbrack = descr.indexOf("["); 
    289       } 
    290  
    291       // each remaining line in descr is a (key, value) pair, 
    292       // where '=' separates the key from the value 
    293  
    294       String key; 
    295       String value; 
    296       int eqIndex = descr.indexOf("="); 
    297  
    298       while (eqIndex != -1) { 
    299         key = descr.substring(0, eqIndex); 
    300         value = descr.substring(eqIndex+1, descr.indexOf("\n", eqIndex)); 
    301         addMeta(key.trim(), value.trim()); 
    302         descr = descr.substring(descr.indexOf("\n", eqIndex)); 
    303         eqIndex = descr.indexOf("="); 
    304       } 
    305  
    306       // finally, set descr to be the value of "FLUOVIEW Version" 
    307  
    308       descr = (String) getMeta("FLUOVIEW Version"); 
    309       if (descr == null) { 
    310         descr = (String) getMeta("File Version"); 
    311       } 
    312       store.setImage(imageName, null, descr, null); 
    313  
    314       String d = (String) TiffTools.getIFDValue(ifds[0], TiffTools.PAGE_NAME); 
    315       int strPos = d.indexOf("[Higher Dimensions]") + 19; 
    316       d = d.substring(strPos); 
    317  
    318       String names = d.substring(5, d.indexOf("Spatial Position")); 
    319       String positions = d.substring(d.indexOf("Number Of Positions") + 19); 
    320       names = names.trim(); 
    321       positions = positions.trim(); 
    322  
    323       // first parse the names 
    324       Vector n = new Vector(); 
    325       Vector chars = new Vector(); 
    326       for(int i=0; i<names.length(); i++) { 
    327         if (!Character.isWhitespace(names.charAt(i))) { 
    328           chars.add(new Character(names.charAt(i))); 
    329         } 
    330         else { 
    331           if (chars.size() > 0) { 
    332             char[] dim = new char[chars.size()]; 
    333             for(int j=0; j<chars.size(); j++) { 
    334               dim[j] = ((Character) chars.get(j)).charValue(); 
    335             } 
    336             n.add(new String(dim)); 
    337           } 
    338           chars.clear(); 
    339         } 
    340       } 
    341  
    342       if (chars.size() > 0) { 
    343         char[] dim = new char[chars.size()]; 
    344         for (int j=0; j<chars.size(); j++) { 
    345           dim[j] = ((Character) chars.get(j)).charValue(); 
    346         } 
    347         n.add(new String(dim)); 
    348       } 
    349  
    350       // now parse the number of positions for each dimension 
    351  
    352       Vector numPlanes = new Vector(); 
    353       chars = new Vector(); 
    354  
    355       for(int i=0; i< positions.length(); i++) { 
    356         if (!Character.isWhitespace(positions.charAt(i))) { 
    357           chars.add(new Character(positions.charAt(i))); 
    358         } 
    359         else { 
    360           if (chars.size() > 0) { 
    361             char[] dim = new char[chars.size()]; 
    362             for (int j=0; j<chars.size(); j++) { 
    363               dim[j] = ((Character) chars.get(j)).charValue(); 
    364             } 
    365             numPlanes.add(new String(dim)); 
    366           } 
    367           chars.clear(); 
    368         } 
    369       } 
    370  
    371       if (chars.size() > 0) { 
    372         char[] dim = new char[chars.size()]; 
    373         for (int j=0; j<chars.size(); j++) { 
    374           dim[j] = ((Character) chars.get(j)).charValue(); 
    375         } 
    376         numPlanes.add(new String(dim)); 
    377       } 
    378  
    379       // Populate the metadata store appropriately 
    380  
    381       // first we need to reset the dimensions 
    382  
    383       boolean setZ = false; 
    384       boolean setT = false; 
    385  
    386       for(int i=0; i<n.size(); i++) { 
    387         String name = (String) n.get(i); 
    388         String pos = (String) numPlanes.get(i); 
    389         int q = Integer.parseInt(pos); 
    390  
    391         if (name.equals("Ch")) { 
    392           sizeC[series] = q; 
    393         } 
    394         else if (name.equals("Animation") || name.equals("T")) { 
    395           sizeT[series] = q; 
    396           setT = true; 
    397         } 
    398         else if (name.equals("Z")) { 
    399           sizeZ[series] = q; 
    400           setZ = true; 
    401         } 
    402       } 
    403  
    404       // set the number of valid bits per pixel 
    405  
    406       String bits = (String) getMeta("Map Ch" + (sizeC[0] - 1) + ": Range"); 
    407       int[] validBits = null; 
    408       int vb = -1; 
    409       if (bits != null && bits.length() > 0) { 
    410         int start = Integer.parseInt(bits.substring(0, bits.indexOf(" to"))); 
    411         int end = Integer.parseInt(bits.substring(bits.indexOf("to") + 3)); 
    412         while (Math.pow(2, vb) < end) vb++; 
    413       } 
    414  
    415       if (vb > -1) { 
    416         validBits = new int[sizeC[0]]; 
    417         if (validBits.length == 2) validBits = new int[3]; 
    418         for (int i=0; i<validBits.length; i++) validBits[i] = vb; 
    419       } 
    420  
    421       if (validBits != null) { 
    422         for (int i=0; i<ifds.length; i++) { 
    423           ifds[i].put(new Integer(TiffTools.VALID_BITS), validBits); 
    424         } 
    425       } 
    426  
    427       if (setZ && !setT) sizeT[series] = 1; 
    428       if (setT && !setZ) sizeZ[series] = 1; 
    429  
    430       // set the dimension order 
    431  
    432       String order = "XY"; 
    433  
    434       int[] dims = new int[] {sizeZ[series], sizeC[series], sizeT[series]}; 
    435       int max = 0; 
    436       int median = 1; 
    437       int min = Integer.MAX_VALUE; 
    438  
    439       for (int i=0; i<dims.length; i++) { 
    440         if (dims[i] < min) min = dims[i]; 
    441         if (dims[i] > max) max = dims[i]; 
    442       } 
    443  
    444       for (int i=0; i<dims.length; i++) { 
    445         if (dims[i] != max && dims[i] != min) median = dims[i]; 
    446       } 
    447  
    448       int[] orderedDims = new int[] {max, median, min}; 
    449  
    450       for (int i=0; i<orderedDims.length; i++) { 
    451         if (orderedDims[i] == sizeZ[series] && order.indexOf("Z") == -1) { 
    452           order += "Z"; 
    453         } 
    454         else if (orderedDims[i] == sizeC[series] && order.indexOf("C") == -1) { 
    455           order += "C"; 
    456         } 
    457         else order += "T"; 
    458       } 
    459       currentOrder[series] = order; 
    460     } 
    461     catch (IOException e) { 
    462       throw new FormatException(e); 
     349    
     350      String mag = (String) getMeta("Magnification"); 
     351      if (mag != null && mag.toLowerCase().endsWith("x")) { 
     352        mag = mag.substring(0, mag.length() - 1); 
     353      } 
     354      else if (mag == null) mag = "1"; 
     355      store.setObjective((String) getMeta("Objective Lens"), null, null, null,  
     356        new Float(mag), null, null); 
     357     
     358    } 
     359    catch (FormatException fe) { 
     360      if (debug) fe.printStackTrace(); 
     361    } 
     362    catch (IOException ie) { 
     363      if (debug) ie.printStackTrace(); 
    463364    } 
    464365  } 
  • trunk/loci/formats/readers.txt

    r2319 r2375  
    7373loci.formats.in.NikonReader       # nef, tif [TIFF; slow isThisType] 
    7474loci.formats.in.FluoviewReader    # tif [TIFF; slow isThisType] 
    75 loci.formats.in.AndorReader       # tif [TIFF; slow isThisType] 
    7675loci.formats.in.PrairieReader     # xml, cfg, tif 
    7776 
Note: See TracChangeset for help on using the changeset viewer.