Changeset 2126


Ignore:
Timestamp:
01/19/07 11:49:36 (13 years ago)
Author:
melissa
Message:

Improved support for renamed LEI and TIFF files.

File:
1 edited

Legend:

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

    r2117 r2126  
    118118  /** Determines the number of images in the given Leica file. */ 
    119119  public int getImageCount(String id) throws FormatException, IOException { 
    120     if (!id.equals(currentId) && !DataTools.samePrefix(id, currentId)) { 
    121       initFile(id); 
    122     } 
     120    if (!id.equals(currentId) && !usedFile(id)) initFile(id); 
    123121    return numPlanes[series]; 
    124122  } 
     
    126124  /** Return the number of series in the given Leica file. */ 
    127125  public int getSeriesCount(String id) throws FormatException, IOException { 
    128     if (!id.equals(currentId) && !DataTools.samePrefix(id, currentId)) { 
    129       initFile(id); 
    130     } 
     126    if (!id.equals(currentId) && !usedFile(id)) initFile(id); 
    131127    return numSeries; 
    132128  } 
     
    134130  /** Checks if the images in the file are RGB. */ 
    135131  public boolean isRGB(String id) throws FormatException, IOException { 
    136     if (!id.equals(currentId) && !DataTools.samePrefix(id, currentId)) { 
    137       initFile(id); 
    138     } 
     132    if (!id.equals(currentId) && !usedFile(id)) initFile(id); 
    139133    tiff[series][0].setColorTableIgnored(isColorTableIgnored()); 
    140134    return tiff[series][0].isRGB((String) files[series].get(0)); 
     
    143137  /** Return true if the data is in little-endian format. */ 
    144138  public boolean isLittleEndian(String id) throws FormatException, IOException { 
    145     if (!id.equals(currentId)) initFile(id); 
     139    if (!id.equals(currentId) && !usedFile(id)) initFile(id); 
    146140    return littleEndian; 
    147141  } 
     
    156150    throws FormatException, IOException 
    157151  { 
    158     if (!id.equals(currentId) && !DataTools.samePrefix(id, currentId)) { 
    159       initFile(id); 
    160     } 
     152    if (!id.equals(currentId) && !usedFile(id)) initFile(id); 
    161153 
    162154    if (no < 0 || no >= getImageCount(id)) { 
     
    173165    throws FormatException, IOException 
    174166  { 
    175     if (!id.equals(currentId) && !DataTools.samePrefix(id, currentId)) { 
    176       initFile(id); 
    177     } 
     167    if (!id.equals(currentId) && !usedFile(id)) initFile(id); 
    178168 
    179169    if (no < 0 || no >= getImageCount(id)) { 
     
    193183  /* @see IFormatReader#getUsedFiles(String) */ 
    194184  public String[] getUsedFiles(String id) throws FormatException, IOException { 
    195     if (!id.equals(currentId)) initFile(id); 
     185    if (!id.equals(currentId) && !usedFile(id)) initFile(id); 
    196186    Vector v = new Vector(); 
    197187    v.add(id); 
     
    295285 
    296286      // now open the LEI file 
    297       initFile(lei); 
    298       //super.initMetadata(); 
     287 
     288      Location l = new Location(lei); 
     289      if (l.getAbsoluteFile().exists()) initFile(lei); 
     290      else { 
     291        l = l.getAbsoluteFile().getParentFile(); 
     292        String[] list = l.list(); 
     293        for (int i=0; i<list.length; i++) { 
     294          if (list[i].toLowerCase().endsWith("lei")) { 
     295            initFile(list[i]); 
     296            return; 
     297          } 
     298        } 
     299      } 
    299300    } 
    300301    else { 
     
    379380          new Location(id).getAbsoluteFile().getParent(); 
    380381        dirPrefix = dirPrefix == null ? "" : (dirPrefix + File.separator); 
     382         
     383        String[] listing = (new Location(dirPrefix)).list(); 
     384        Vector list = new Vector(); 
     385 
     386        for (int k=0; k<listing.length; k++) { 
     387          if (listing[k].toLowerCase().endsWith(".tif") || 
     388            listing[k].toLowerCase().endsWith(".tiff")) 
     389          { 
     390            list.add(listing[k]); 
     391          } 
     392        } 
     393 
     394        listing = (String[]) list.toArray(new String[0]); 
     395 
     396        boolean tiffsExist = true; 
     397 
     398        String prefix = ""; 
    381399        for (int j=0; j<tempImages; j++) { 
    382400          // read in each filename 
    383           f.add(dirPrefix + DataTools.stripString( 
    384             new String(tempData, 20 + 2*(j*nameLength), 2*nameLength))); 
     401          prefix = DataTools.stripString(new String(tempData,  
     402            20 + 2*(j*nameLength), 2*nameLength)); 
     403          f.add(dirPrefix + prefix);  
    385404          // test to make sure the path is valid 
    386405          Location test = new Location((String) f.get(f.size() - 1)); 
    387           if (!test.exists()) { 
    388             // TIFF files were renamed 
    389  
    390             Location[] dirListing = (new Location(dirPrefix)).listFiles(); 
    391  
    392             int pos = 0; 
    393             int maxChars = 0; 
    394             for (int k=0; k<dirListing.length; k++) { 
    395               int pt = 0; 
    396               int chars = 0; 
    397               String path = dirListing[k].getAbsolutePath(); 
    398               if (path.toLowerCase().endsWith("tif") || 
    399                 path.toLowerCase().endsWith("tiff")) 
    400               { 
    401                 while (path.charAt(pt) == test.getAbsolutePath().charAt(pt)) { 
    402                   pt++; 
    403                   chars++; 
    404                 } 
    405                 int newPt = path.length() - 1; 
    406                 int oldPt = test.getAbsolutePath().length() - 1; 
    407                 while (path.charAt(newPt) == 
    408                   test.getAbsolutePath().charAt(oldPt)) 
     406          if (tiffsExist) tiffsExist = test.exists(); 
     407        } 
     408 
     409        // at least one of the TIFF files was renamed 
     410         
     411        if (!tiffsExist) { 
     412          // first thing is to get original LEI name associate with each TIFF 
     413          // this lets us figure out which TIFFs we need for this dataset 
     414          Hashtable leiMapping = new Hashtable(); 
     415          int numLeis = 0; 
     416          for (int j=0; j<listing.length; j++) { 
     417            RandomAccessStream ras =  
     418              new RandomAccessStream((String) listing[j]); 
     419            Hashtable ifd = TiffTools.getFirstIFD(ras); 
     420            ras.close(); 
     421            String descr =  
     422              (String) ifd.get(new Integer(TiffTools.IMAGE_DESCRIPTION)); 
     423            int ndx = descr.indexOf("=", descr.indexOf("Series Name")); 
     424            String leiFile = descr.substring(ndx + 1, descr.indexOf("\n", ndx)); 
     425            leiFile = leiFile.trim(); 
     426            if (!leiMapping.contains(leiFile)) numLeis++; 
     427            leiMapping.put(listing[j], leiFile); 
     428          } 
     429        
     430          // compare original TIFF prefix with original LEI prefix 
     431         
     432          f.clear(); 
     433          String[] keys = (String[]) leiMapping.keySet().toArray(new String[0]); 
     434          for (int j=0; j<keys.length; j++) { 
     435            String lei = (String) leiMapping.get(keys[j]); 
     436            if (DataTools.samePrefix(lei, prefix)) { 
     437              f.add(keys[j]); 
     438            } 
     439          } 
     440         
     441          // now that we have our list of files, all that remains is to figure 
     442          // out how they should be ordered 
     443 
     444          // we'll try looking for a naming convention, using FilePattern 
     445          String[] usedFiles = null; 
     446          for (int j=0; j<f.size(); j++) { 
     447            if (usedFiles != null) { 
     448              for (int k=0; k<usedFiles.length; k++) { 
     449                if (usedFiles[k].equals((String) f.get(j)) ||  
     450                  usedFile((String) f.get(j)))  
    409451                { 
    410                   newPt--; 
    411                   oldPt--; 
    412                   chars++; 
    413                 } 
    414                 if (chars > maxChars) { 
    415                   maxChars = chars; 
    416                   pos = k; 
     452                  k = 0; 
     453                  j++; 
    417454                } 
    418455              } 
    419456            } 
    420  
    421             f.set(f.size() - 1, dirListing[pos].getAbsolutePath()); 
    422           } 
    423         } 
    424  
    425         files[i] = f; 
    426         numPlanes[i] = f.size(); 
     457            if (j >= f.size()) break; 
     458             
     459            FilePattern fp = new FilePattern(new Location((String) f.get(j))); 
     460            if (fp != null) usedFiles = fp.getFiles(); 
     461            if (usedFiles != null && usedFiles.length == tempImages) { 
     462              files[i] = new Vector(); 
     463              for (int k=0; k<usedFiles.length; k++) { 
     464                files[i].add(usedFiles[k]); 
     465              } 
     466              break; 
     467            } 
     468          } 
     469 
     470          // failing that, we can check the datestamp in each TIFF file 
     471          // note that this is not guaranteed to work - some versions of 
     472          // the Leica software will write a blank datestamp 
     473          if (files[i] == null || files[i].size() == 0) { 
     474            files[i] = new Vector(); 
     475            Hashtable h = new Hashtable(); 
     476            for (int j=0; j<listing.length; j++) { 
     477              RandomAccessStream ras = new RandomAccessStream(listing[j]); 
     478              Hashtable fd = TiffTools.getFirstIFD(ras); 
     479              String stamp =  
     480                (String) TiffTools.getIFDValue(fd, TiffTools.DATE_TIME); 
     481              if (h.size() == tempImages) { 
     482                String[] ks = (String[]) h.keySet().toArray(new String[0]); 
     483                Arrays.sort(ks); 
     484                for (int k=0; k<ks.length; k++) { 
     485                  files[i].add(h.get(ks[k])); 
     486                } 
     487                h.clear(); 
     488                break; 
     489              } 
     490              else { 
     491                if (!h.contains(stamp)) h.put(stamp, listing[j]); 
     492                else { 
     493                  h.clear(); 
     494                  h.put(stamp, listing[j]); 
     495                } 
     496              } 
     497            } 
     498            if (h.size() == tempImages) { 
     499              String[] ks = (String[]) h.keySet().toArray(new String[0]); 
     500              Arrays.sort(ks); 
     501              for (int k=0; k<ks.length; k++) { 
     502                files[i].add(h.get(ks[k])); 
     503                /* debug */ System.out.println("adding " + h.get(ks[k]) +  
     504                  " to series " + i); 
     505              } 
     506            } 
     507          } 
     508 
     509          // Our final effort is to just sort the filenames lexicographically. 
     510          // This gives us a pretty good chance of getting the order right, 
     511          // but it's not perfect.  Basically covers the (hopefully) unlikely 
     512          // case where filenames are nonsensical, and datestamps are invalid. 
     513          if (files[i] == null || files[i].size() == 0) { 
     514            if (debug) debug("File ordering is not obvious."); 
     515            files[i] = new Vector(); 
     516            Arrays.sort(listing); 
     517            int ndx = 0; 
     518            for (int j=0; j<i; j++) ndx += files[j].size(); 
     519            for (int j=ndx; j<ndx+tempImages; j++) files[i].add(listing[j]); 
     520          } 
     521 
     522          // Ways to break the renaming heuristics: 
     523          // 
     524          // 1) Don't use a detectable naming convention, and remove datestamps 
     525          //    from TIFF files. 
     526          // 2) Use a naming convention such as plane 0 -> "5.tif",  
     527          //    plane 1 -> "4.tif", plane 2 -> "3.tif", etc. 
     528          // 3) Place two datasets in the same folder: 
     529          //      a) swap the two LEI file names 
     530          //      b) use the same naming convention for both sets of TIFF files 
     531          //      c) use the same naming convention AND make sure the datestamps 
     532          //         are the same between TIFF files 
     533        } 
     534        else files[i] = f; 
     535        numPlanes[i] = files[i].size(); 
    427536        if (numPlanes[i] > maxPlanes) maxPlanes = numPlanes[i]; 
    428537      } 
     
    471580      if (ndx == -1) return false; 
    472581 
    473       String lei = descr.substring(descr.indexOf("=", ndx) + 1); 
    474       lei = lei.substring(0, lei.indexOf("\n")); 
    475       lei = lei.trim(); 
    476  
    477       String dir = name.substring(0, name.lastIndexOf("/") + 1); 
    478       lei = dir + lei; 
    479  
    480       Location check = new Location(lei); 
    481       return check.exists(); 
     582      String dir = new Location(name).getAbsoluteFile().getParent();  
     583      String[] listing = new Location(dir).list(); 
     584      for (int i=0; i<listing.length; i++) { 
     585        if (listing[i].toLowerCase().endsWith(".lei")) return true; 
     586      } 
     587      return false; 
    482588    } 
    483589    catch (IOException exc) { } 
     
    9451051      catch (NullPointerException n) { } 
    9461052    } 
    947  
     1053  } 
     1054 
     1055  private boolean usedFile(String s) { 
     1056    for (int i=0; i<files.length; i++) { 
     1057      if (files[i] == null) continue; 
     1058      if (files[i].contains(s)) return true; 
     1059    } 
     1060    return false; 
    9481061  } 
    9491062 
Note: See TracChangeset for help on using the changeset viewer.