Changeset 4024


Ignore:
Timestamp:
05/07/08 17:03:51 (12 years ago)
Author:
melissa
Message:

Rewrote support for renamed/missing files - closes #295. There are still problems with Z and T being swapped for some datasets.

File:
1 edited

Legend:

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

    r3919 r4024  
    132132  public byte[][] get8BitLookupTable() throws FormatException, IOException { 
    133133    FormatTools.assertId(currentId, true, 1); 
    134     tiff[0][0].setId((String) files[0].get(0)); 
    135     return tiff[0][0].get8BitLookupTable(); 
     134    tiff[series][0].setId((String) files[series].get(0)); 
     135    return tiff[series][0].get8BitLookupTable(); 
    136136  } 
    137137 
     
    139139  public short[][] get16BitLookupTable() throws FormatException, IOException { 
    140140    FormatTools.assertId(currentId, true, 1); 
    141     tiff[0][0].setId((String) files[0].get(0)); 
    142     return tiff[0][0].get16BitLookupTable(); 
     141    tiff[series][0].setId((String) files[series].get(0)); 
     142    return tiff[series][0].get16BitLookupTable(); 
    143143  } 
    144144 
     
    328328    core.littleEndian[0] = !core.littleEndian[0]; 
    329329 
     330    int seriesIndex = 0; 
     331    boolean[] valid = new boolean[numSeries]; 
    330332    for (int i=0; i<headerIFDs.length; i++) { 
     333      valid[i] = true; 
    331334      if (headerIFDs[i].get(new Integer(SERIES)) != null) { 
    332335        byte[] temp = (byte[]) headerIFDs[i].get(new Integer(SERIES)); 
     
    336339      Vector f = new Vector(); 
    337340      byte[] tempData = (byte[]) headerIFDs[i].get(new Integer(IMAGES)); 
    338       int tempImages = DataTools.bytesToInt(tempData, 0, 
    339         core.littleEndian[0]); 
     341      int tempImages = DataTools.bytesToInt(tempData, 0, core.littleEndian[0]); 
     342 
     343      if (((long) tempImages * nameLength) > tempData.length) { 
     344        tempImages = DataTools.bytesToInt(tempData, 0, !core.littleEndian[0]); 
     345      } 
    340346 
    341347      File dirFile = new File(id).getAbsoluteFile(); 
     
    359365        } 
    360366      } 
    361  
    362       listing = (String[]) list.toArray(new String[0]); 
    363367 
    364368      boolean tiffsExist = true; 
     
    372376        // test to make sure the path is valid 
    373377        Location test = new Location((String) f.get(f.size() - 1)); 
     378        if (test.exists()) list.remove(prefix); 
    374379        if (tiffsExist) tiffsExist = test.exists(); 
    375380      } 
     
    378383 
    379384      if (!tiffsExist) { 
     385        // Strategy for handling renamed files: 
     386        // 1) Assume that files for each series follow a pattern. 
     387        // 2) Assign each file group to the first series with the correct count. 
    380388        status("Handling renamed TIFF files"); 
    381389 
    382         // get original LEI name associate with each TIFF 
    383         // this lets us figure out which TIFFs we need for this dataset 
    384         Hashtable leiMapping = new Hashtable(); 
    385         int numLeis = 0; 
    386         for (int j=0; j<listing.length; j++) { 
    387           RandomAccessStream ras = new RandomAccessStream( 
    388             new Location(dirPrefix, listing[j]).getAbsolutePath()); 
    389           ifd = TiffTools.getFirstIFD(ras); 
    390           ras.close(); 
    391           String descr = TiffTools.getComment(ifd); 
    392           int ndx = descr.indexOf("=", descr.indexOf("Series Name")); 
    393           String leiFile = descr.substring(ndx + 1, descr.indexOf("\n", ndx)); 
    394           leiFile = leiFile.trim(); 
    395           if (!leiMapping.contains(leiFile)) numLeis++; 
    396           leiMapping.put(listing[j], leiFile); 
    397         } 
    398  
    399         // compare original TIFF prefix with original LEI prefix 
    400  
    401         f.clear(); 
    402         String[] keys = (String[]) leiMapping.keySet().toArray(new String[0]); 
    403         for (int j=0; j<keys.length; j++) { 
    404           String lei = (String) leiMapping.get(keys[j]); 
    405           if (DataTools.samePrefix(lei, prefix)) { 
    406             f.add(keys[j]); 
     390        listing = (String[]) list.toArray(new String[0]); 
     391 
     392        // grab the file patterns 
     393        Vector filePatterns = new Vector(); 
     394        for (int q=0; q<listing.length; q++) { 
     395          Location l = new Location(dirPrefix, listing[q]); 
     396          l = l.getAbsoluteFile(); 
     397          FilePattern pattern = new FilePattern(l); 
     398 
     399          AxisGuesser guess = new AxisGuesser(pattern, "XYZCT", 1, 1, 1, false); 
     400          String fp = pattern.getPattern(); 
     401 
     402          if (guess.getAxisCountS() >= 1) { 
     403            String pre = pattern.getPrefix(guess.getAxisCountS()); 
     404            Vector fileList = new Vector(); 
     405            for (int n=0; n<listing.length; n++) { 
     406              Location p = new Location(dirPrefix, listing[n]); 
     407              if (p.getAbsolutePath().startsWith(pre)) { 
     408                fileList.add(listing[n]); 
     409              } 
     410            } 
     411            fp = FilePattern.findPattern(l.getAbsolutePath(), dirPrefix, 
     412              (String[]) fileList.toArray(new String[0])); 
    407413          } 
    408         } 
    409  
    410         // now that we have our list of files, all that remains is to figure 
    411         // out how they should be ordered 
    412  
    413         // we'll try looking for a naming convention, using FilePattern 
    414         String[] usedFiles = null; 
    415         for (int j=0; j<f.size(); j++) { 
    416           if (usedFiles != null) { 
    417             for (int k=0; k<usedFiles.length; k++) { 
    418               if (usedFiles[k].equals((String) f.get(j)) || 
    419                 usedFile((String) f.get(j))) 
    420               { 
    421                 k = 0; 
    422                 j++; 
     414 
     415          if (fp != null && !filePatterns.contains(fp)) { 
     416            filePatterns.add(fp); 
     417          } 
     418        } 
     419 
     420        for (int q=0; q<filePatterns.size(); q++) { 
     421          String[] pattern = 
     422            new FilePattern((String) filePatterns.get(q)).getFiles(); 
     423          if (pattern.length == tempImages) { 
     424            // make sure that this pattern hasn't already been used 
     425 
     426            boolean validPattern = true; 
     427            for (int n=0; n<i; n++) { 
     428              if (files[n] == null) continue; 
     429              if (files[n].contains(pattern[0])) { 
     430                validPattern = false; 
     431                break; 
     432              } 
     433            } 
     434 
     435            if (validPattern) { 
     436              files[i] = new Vector(); 
     437              for (int n=0; n<pattern.length; n++) { 
     438                files[i].add(pattern[n]); 
    423439              } 
    424440            } 
    425441          } 
    426           if (j >= f.size()) break; 
    427  
    428           FilePattern fp = new FilePattern(new Location((String) f.get(j))); 
    429           if (fp != null) usedFiles = fp.getFiles(); 
    430           if (usedFiles != null && usedFiles.length == tempImages) { 
    431             files[i] = new Vector(); 
    432             for (int k=0; k<usedFiles.length; k++) { 
    433               files[i].add(new Location(usedFiles[k]).getAbsolutePath()); 
    434             } 
    435             break; 
    436           } 
    437         } 
    438  
    439         // failing that, we can check the datestamp in each TIFF file 
    440         // note that this is not guaranteed to work - some versions of 
    441         // the Leica software will write a blank datestamp 
    442         if (files[i] == null || files[i].size() == 0) { 
    443           files[i] = new Vector(); 
    444           Hashtable h = new Hashtable(); 
    445           for (int j=0; j<listing.length; j++) { 
    446             RandomAccessStream ras = new RandomAccessStream( 
    447               new Location(dirPrefix, listing[j]).getAbsolutePath()); 
    448             Hashtable fd = TiffTools.getFirstIFD(ras); 
    449             String stamp = 
    450               (String) TiffTools.getIFDValue(fd, TiffTools.DATE_TIME); 
    451             if (h.size() == tempImages) { 
    452               String[] ks = (String[]) h.keySet().toArray(new String[0]); 
    453               Arrays.sort(ks); 
    454               for (int k=0; k<ks.length; k++) { 
    455                 files[i].add(new Location(dirPrefix, 
    456                   (String) h.get(ks[k])).getAbsolutePath()); 
    457               } 
    458               h.clear(); 
    459               break; 
    460             } 
    461             else { 
    462               if (!h.contains(stamp)) h.put(stamp, listing[j]); 
    463               else { 
    464                 h.clear(); 
    465                 h.put(stamp, listing[j]); 
    466               } 
    467             } 
    468             ras.close(); 
    469           } 
    470           if (h.size() == tempImages) { 
    471             String[] ks = (String[]) h.keySet().toArray(new String[0]); 
    472             Arrays.sort(ks); 
    473             for (int k=0; k<ks.length; k++) { 
    474               files[i].add(new Location(dirPrefix, 
    475                 (String) h.get(ks[k])).getAbsolutePath()); 
    476             } 
    477           } 
    478         } 
    479  
    480         // Our final effort is to just sort the filenames lexicographically. 
    481         // This gives us a pretty good chance of getting the order right, 
    482         // but it's not perfect.  Basically covers the (hopefully) unlikely 
    483         // case where filenames are nonsensical, and datestamps are invalid. 
    484         if (files[i] == null || files[i].size() == 0) { 
    485           if (debug) debug("File ordering is not obvious."); 
    486           files[i] = new Vector(); 
    487           Arrays.sort(listing); 
    488           int ndx = 0; 
    489           for (int j=0; j<i; j++) ndx += files[j].size(); 
    490           for (int j=ndx; j<ndx+tempImages; j++) { 
    491             files[i].add(new Location(dirPrefix, 
    492               listing[j]).getAbsolutePath()); 
    493           } 
    494         } 
    495  
    496         // Ways to break the renaming heuristics: 
    497         // 
    498         // 1) Don't use a detectable naming convention, and remove datestamps 
    499         //    from TIFF files. 
    500         // 2) Use a naming convention such as plane 0 -> "5.tif", 
    501         //    plane 1 -> "4.tif", plane 2 -> "3.tif", etc. 
    502         // 3) Place two datasets in the same folder: 
    503         //      a) swap the two LEI file names 
    504         //      b) use the same naming convention for both sets of TIFF files 
    505         //      c) use the same naming convention AND make sure the datestamps 
    506         //         are the same between TIFF files 
     442        } 
    507443      } 
    508444      else files[i] = f; 
    509       core.imageCount[i] = files[i].size(); 
    510       if (core.imageCount[i] > maxPlanes) maxPlanes = core.imageCount[i]; 
     445      if (files[i] == null) valid[i] = false; 
     446      else { 
     447        core.imageCount[i] = files[i].size(); 
     448        if (core.imageCount[i] > maxPlanes) maxPlanes = core.imageCount[i]; 
     449      } 
     450    } 
     451 
     452    int invalidCount = 0; 
     453    for (int i=0; i<valid.length; i++) { 
     454      if (!valid[i]) invalidCount++; 
     455    } 
     456 
     457    numSeries -= invalidCount; 
     458 
     459    int[] count = core.imageCount; 
     460    Vector[] tempFiles = files; 
     461    Hashtable[] tempIFDs = headerIFDs; 
     462    core = new CoreMetadata(numSeries); 
     463    files = new Vector[numSeries]; 
     464    headerIFDs = new Hashtable[numSeries]; 
     465    int index = 0; 
     466 
     467    for (int i=0; i<numSeries; i++) { 
     468      while (!valid[index]) index++; 
     469      core.imageCount[i] = count[index]; 
     470      files[i] = tempFiles[index]; 
     471      headerIFDs[i] = tempIFDs[index]; 
     472      index++; 
    511473    } 
    512474 
     
    542504        addMeta("Length of filename", new Integer(fileLength)); 
    543505        Integer fileExtLen = new Integer(stream.readInt()); 
     506        if (fileExtLen.intValue() > fileLength) { 
     507          stream.seek(0); 
     508          core.littleEndian[0] = !core.littleEndian[0]; 
     509          stream.order(core.littleEndian[0]); 
     510          fileLength = stream.readInt(); 
     511          fileExtLen = new Integer(stream.readInt()); 
     512        } 
    544513        addMeta("Length of file extension", fileExtLen); 
    545514        addMeta("Image file extension", 
     
    843812        addMeta("ID of colored dimension", new Integer(stream.readInt())); 
    844813 
    845         if (nChannels > 4) nChannels = 3; 
     814        //if (nChannels > 4) nChannels = 3; 
    846815        core.sizeC[i] = nChannels; 
    847816 
     
    885854      for (int i=0; i<core.sizeC.length; i++) { 
    886855        setSeries(i); 
     856        if (core.sizeC[i] == 0) core.sizeC[i] = 1; 
    887857        core.sizeZ[i] /= core.sizeC[i]; 
    888858      } 
     
    896866    for (int i=0; i<numSeries; i++) { 
    897867      if (core.sizeC[i] == 0) core.sizeC[i] = 1; 
    898       if (core.rgb[i]) core.sizeC[i] *= 3; 
    899       core.sizeT[i] += 1; 
     868      core.sizeT[i]++; 
    900869      if (core.sizeZ[i] == 0) core.sizeZ[i] = 1; 
    901       if (!core.rgb[i] && core.imageCount[i] == 1) {  
    902         tiff[i][0].setId((String) files[i].get(0)); 
    903         core.rgb[i] = tiff[i][0].isRGB();  
    904         core.indexed[i] = tiff[i][0].isIndexed();  
    905         core.sizeC[i] = tiff[i][0].getSizeC();  
    906       } 
    907       core.currentOrder[i] = core.sizeC[i] == 1 ? "XYZTC" : "XYCZT"; 
     870      tiff[i][0].setId((String) files[i].get(0)); 
     871      core.sizeX[i] = tiff[i][0].getSizeX(); 
     872      core.sizeY[i] = tiff[i][0].getSizeY(); 
     873      core.rgb[i] = tiff[i][0].isRGB(); 
     874      core.indexed[i] = tiff[i][0].isIndexed(); 
     875      core.sizeC[i] *= tiff[i][0].getSizeC(); 
     876      core.currentOrder[i] = core.rgb[i] ? "XYCZT" : "XYZTC"; 
    908877 
    909878      if (i < timestamps.length && timestamps[i] != null) { 
Note: See TracChangeset for help on using the changeset viewer.