Changeset 5745


Ignore:
Timestamp:
12/16/09 15:07:42 (10 years ago)
Author:
melissa
Message:

Allow file grouping across multiple directories.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/components/bio-formats/src/loci/formats/in/DicomReader.java

    r5743 r5745  
    3333import loci.common.Location; 
    3434import loci.common.RandomAccessInputStream; 
     35import loci.formats.CoreMetadata; 
    3536import loci.formats.FilePattern; 
    3637import loci.formats.FormatException; 
     
    125126  private String pixelSizeX, pixelSizeY; 
    126127 
    127   private Vector<String> fileList; 
     128  private Hashtable<Integer, Vector<String>> fileList; 
    128129  private int imagesPerFile; 
    129130 
    130131  private String originalDate, originalTime, originalInstance; 
     132  private int originalSeries; 
    131133 
    132134  private DicomReader helper; 
     
    196198  public String[] getSeriesUsedFiles(boolean noPixels) { 
    197199    FormatTools.assertId(currentId, true, 1); 
    198     return noPixels || fileList == null ? null : 
    199       fileList.toArray(new String[fileList.size()]); 
     200    if (noPixels || fileList == null) return null; 
     201    Integer[] keys = fileList.keySet().toArray(new Integer[0]); 
     202    Arrays.sort(keys); 
     203    Vector<String> files = fileList.get(keys[getSeries()]); 
     204    return files == null ? null : files.toArray(new String[files.size()]); 
    200205  } 
    201206 
     
    213218    FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h); 
    214219 
    215     if (fileList.size() > 1) { 
     220    Integer[] keys = fileList.keySet().toArray(new Integer[0]); 
     221    Arrays.sort(keys); 
     222    if (fileList.get(keys[getSeries()]).size() > 1) { 
    216223      int fileNumber = no / imagesPerFile; 
    217224      no = no % imagesPerFile; 
    218       initFile(fileList.get(fileNumber)); 
     225      String file = fileList.get(keys[getSeries()]).get(fileNumber); 
     226      helper.setId(file); 
     227      return helper.openBytes(no, buf, x, y, w, h); 
    219228    } 
    220229 
     
    382391      date = time = imageType = null; 
    383392      originalDate = originalTime = originalInstance = null; 
     393      originalSeries = 0; 
    384394      helper = null; 
    385395    } 
     
    394404    in = new RandomAccessInputStream(id); 
    395405    in.order(true); 
     406 
     407    helper = new DicomReader(); 
     408    helper.setGroupFiles(false); 
    396409 
    397410    core[0].littleEndian = true; 
     
    417430      // header exists, so we'll read it 
    418431      in.seek(0); 
    419       addGlobalMeta("Header information", in.readString(128)); 
     432      addSeriesMeta("Header information", in.readString(128)); 
    420433      in.skipBytes(4); 
    421434      location = 128; 
     
    639652      originalTime != null && isGroupFiles()) 
    640653    { 
    641       fileList = new Vector<String>(); 
     654      currentId = new Location(currentId).getAbsolutePath(); 
     655      fileList = new Hashtable<Integer, Vector<String>>(); 
     656      Integer s = new Integer(originalSeries); 
     657      fileList.put(s, new Vector<String>()); 
    642658 
    643659      int instanceNumber = Integer.parseInt(originalInstance) - 1; 
    644       if (instanceNumber == 0) fileList.add(currentId); 
     660      if (instanceNumber == 0) fileList.get(s).add(currentId); 
    645661      else { 
    646         while (instanceNumber > fileList.size()) fileList.add(null); 
    647         fileList.add(currentId); 
    648       } 
    649       int timestamp = 0; 
    650       try { 
    651         timestamp = Integer.parseInt(originalTime); 
    652       } 
    653       catch (NumberFormatException e) { } 
    654  
     662        while (instanceNumber > fileList.get(s).size()) fileList.get(s).add(null); 
     663        fileList.get(s).add(currentId); 
     664      } 
     665 
     666      // look for matching files in the current directory 
    655667      Location currentFile = new Location(currentId).getAbsoluteFile(); 
    656668      Location directory = currentFile.getParentFile(); 
    657       FilePattern pattern = 
    658         new FilePattern(currentFile.getName(), directory.getAbsolutePath()); 
    659       String[] patternFiles = pattern.getFiles(); 
    660       if (patternFiles == null) patternFiles = new String[0]; 
    661       Arrays.sort(patternFiles); 
    662       String[] files = directory.list(true); 
    663       Arrays.sort(files); 
    664       for (int i=0; i<files.length; i++) { 
    665         String file = new Location(directory, files[i]).getAbsolutePath(); 
    666         debug("Checking file " + file); 
    667         if (!files[i].equals(currentId) && !file.equals(currentId) && 
    668           isThisType(files[i]) && Arrays.binarySearch(patternFiles, file) >= 0) 
    669         { 
    670           RandomAccessInputStream stream = new RandomAccessInputStream(file); 
    671           if (!isThisType(stream)) continue; 
    672           stream.order(true); 
    673  
    674           stream.seek(128); 
    675           if (!stream.readString(4).equals("DICM")) stream.seek(0); 
    676  
    677           String date = null, time = null, instance = null; 
    678           while (date == null || time == null || instance == null) { 
    679             long fp = stream.getFilePointer(); 
    680             if (fp + 4 >= stream.length() || fp < 0) break; 
    681             int tag = getNextTag(stream); 
    682             String key = TYPES.get(new Integer(tag)); 
    683             if ("Instance Number".equals(key)) { 
    684               instance = stream.readString(elementLength).trim(); 
    685               if (instance.length() == 0) instance = null; 
    686             } 
    687             else if ("Acquisition Time".equals(key)) { 
    688               time = stream.readString(elementLength); 
    689             } 
    690             else if ("Acquisition Date".equals(key)) { 
    691               date = stream.readString(elementLength); 
    692             } 
    693             else stream.skipBytes(elementLength); 
     669      scanDirectory(directory, false); 
     670 
     671      // move up a directory and look for other directories that 
     672      // could contain matching files 
     673 
     674      directory = directory.getParentFile(); 
     675      String[] subdirs = directory.list(true); 
     676      for (String subdir : subdirs) { 
     677        Location f = new Location(directory, subdir).getAbsoluteFile(); 
     678        if (!f.isDirectory()) continue; 
     679        scanDirectory(f, true); 
     680      } 
     681 
     682      Integer[] keys = fileList.keySet().toArray(new Integer[0]); 
     683      Arrays.sort(keys); 
     684      for (Integer key : keys) { 
     685        for (int j=0; j<fileList.get(key).size(); j++) { 
     686          if (fileList.get(key).get(j) == null) { 
     687            fileList.get(key).remove(j); 
     688            j--; 
    694689          } 
    695           stream.close(); 
    696  
    697           if (date == null || time == null || instance == null) continue; 
    698  
    699           int stamp = 0; 
    700           try { 
    701             stamp = Integer.parseInt(time); 
    702           } 
    703           catch (NumberFormatException e) { } 
    704  
    705           if (date.equals(originalDate) && (Math.abs(stamp - timestamp) < 100)) 
    706           { 
    707             int position = Integer.parseInt(instance) - 1; 
    708             if (position < 0) position = 0; 
    709             if (position < fileList.size()) { 
    710               while (position < fileList.size() && 
    711                 fileList.get(position) != null) 
    712               { 
    713                 position++; 
    714               } 
    715               if (position < fileList.size()) { 
    716                 fileList.setElementAt(file, position); 
    717               } 
    718               else fileList.add(file); 
    719             } 
    720             else { 
    721               while (position > fileList.size()) { 
    722                 fileList.add(null); 
    723               } 
    724               fileList.add(file); 
    725             } 
    726           } 
    727         } 
    728       } 
    729  
    730       files = fileList.toArray(new String[0]); 
    731       fileList.clear(); 
    732       for (int i=0; i<files.length; i++) { 
    733         if (files[i] != null) fileList.add(files[i]); 
    734       } 
    735       if (fileList.size() == 0) fileList.add(currentId); 
     690        } 
     691      } 
    736692    } 
    737693    else if (fileList == null) { 
    738       fileList = new Vector<String>(); 
    739       fileList.add(currentId); 
     694      fileList = new Hashtable<Integer, Vector<String>>(); 
     695      fileList.put(new Integer(0), new Vector<String>()); 
     696      fileList.get(0).add(currentId); 
    740697    } 
    741698 
    742699    status("Populating metadata"); 
    743700 
    744     core[0].sizeZ = imagesPerFile * fileList.size(); 
    745     core[0].imageCount = getSizeZ(); 
    746     if (getSizeC() == 0) core[0].sizeC = 1; 
    747     core[0].rgb = getSizeC() > 1; 
    748     core[0].sizeT = 1; 
    749     core[0].dimensionOrder = "XYCZT"; 
    750     core[0].metadataComplete = true; 
    751     core[0].falseColor = false; 
    752     if (isRLE) core[0].interleaved = false; 
     701    if (fileList.size() > 1) { 
     702      core = new CoreMetadata[fileList.size()]; 
     703    } 
     704 
     705    Integer[] keys = fileList.keySet().toArray(new Integer[0]); 
     706    Arrays.sort(keys); 
     707 
     708    for (int i=0; i<core.length; i++) { 
     709      if (core.length == 1) { 
     710        core[i].sizeZ = imagesPerFile * fileList.get(keys[i]).size(); 
     711        if (core[i].sizeC == 0) core[i].sizeC = 1; 
     712        core[i].rgb = core[i].sizeC > 1; 
     713        core[i].sizeT = 1; 
     714        core[i].dimensionOrder = "XYCZT"; 
     715        core[i].metadataComplete = true; 
     716        core[i].falseColor = false; 
     717        if (isRLE) core[i].interleaved = false; 
     718      } 
     719      else { 
     720        helper.setId(fileList.get(keys[i]).get(0)); 
     721        core[i] = helper.getCoreMetadata()[0]; 
     722        core[i].sizeZ *= fileList.get(keys[i]).size(); 
     723      } 
     724      core[i].imageCount = core[i].sizeZ; 
     725    } 
    753726 
    754727    // The metadata store we're working with. 
     
    766739    if (stamp == null || stamp.trim().equals("")) stamp = null; 
    767740 
    768     if (stamp != null) store.setImageCreationDate(stamp, 0); 
    769     else MetadataTools.setDefaultCreationDate(store, id, 0); 
    770     store.setImageDescription(imageType, 0); 
    771  
    772     if (pixelSizeX != null) { 
    773       store.setDimensionsPhysicalSizeX(new Double(pixelSizeX), 0, 0); 
    774     } 
    775     if (pixelSizeY != null) { 
    776       store.setDimensionsPhysicalSizeY(new Double(pixelSizeY), 0, 0); 
     741    for (int i=0; i<core.length; i++) { 
     742      if (stamp != null) store.setImageCreationDate(stamp, i); 
     743      else MetadataTools.setDefaultCreationDate(store, id, i); 
     744      store.setImageDescription(imageType, i); 
     745      store.setImageName("Series " + i, i); 
     746 
     747      if (pixelSizeX != null) { 
     748        store.setDimensionsPhysicalSizeX(new Double(pixelSizeX), i, 0); 
     749      } 
     750      if (pixelSizeY != null) { 
     751        store.setDimensionsPhysicalSizeY(new Double(pixelSizeY), i, 0); 
     752      } 
    777753    } 
    778754 
     
    820796          originalInstance = info; 
    821797        } 
     798      } 
     799      else if (key.equals("Series Number")) { 
     800        try { 
     801          originalSeries = Integer.parseInt(info); 
     802        } 
     803        catch (NumberFormatException e) { } 
    822804      } 
    823805      else if (key.indexOf("Palette Color LUT Data") != -1) { 
     
    853835          Object v = getMetadataValue(key); 
    854836          metadata.remove(key); 
    855           addGlobalMeta(key + " #1", v); 
    856           addGlobalMeta(key + " #2", info); 
     837          addSeriesMeta(key + " #1", v); 
     838          addSeriesMeta(key + " #2", info); 
    857839        } 
    858840        else if (metadata.containsKey(key + " #1")) { 
    859841          int index = 2; 
    860842          while (metadata.containsKey(key + " #" + index)) index++; 
    861           addGlobalMeta(key + " #" + index, info); 
    862         } 
    863         else addGlobalMeta(key, info); 
     843          addSeriesMeta(key + " #" + index, info); 
     844        } 
     845        else addSeriesMeta(key, info); 
    864846      } 
    865847    } 
     
    10751057 
    10761058  // -- Utility methods -- 
     1059 
     1060  /** 
     1061   * Scan the given directory for files that belong to this dataset. 
     1062   */ 
     1063  private void scanDirectory(Location dir, boolean checkSeries) 
     1064    throws FormatException, IOException 
     1065  { 
     1066    Location currentFile = new Location(currentId).getAbsoluteFile(); 
     1067    FilePattern pattern = 
     1068      new FilePattern(currentFile.getName(), dir.getAbsolutePath()); 
     1069    String[] patternFiles = pattern.getFiles(); 
     1070    if (patternFiles == null) patternFiles = new String[0]; 
     1071    Arrays.sort(patternFiles); 
     1072    String[] files = dir.list(true); 
     1073    Arrays.sort(files); 
     1074    for (int i=0; i<files.length; i++) { 
     1075      String file = new Location(dir, files[i]).getAbsolutePath(); 
     1076      debug("Checking file " + file); 
     1077      if (!files[i].equals(currentId) && !file.equals(currentId) && 
     1078        isThisType(file) && Arrays.binarySearch(patternFiles, file) >= 0) 
     1079      { 
     1080        addFileToList(file, checkSeries); 
     1081      } 
     1082    } 
     1083  } 
     1084 
     1085  /** 
     1086   * Determine if the given file belongs in the same dataset as this file. 
     1087   */ 
     1088  private void addFileToList(String file, boolean checkSeries) 
     1089    throws FormatException, IOException 
     1090  { 
     1091    RandomAccessInputStream stream = new RandomAccessInputStream(file); 
     1092    if (!isThisType(stream)) return; 
     1093    stream.order(true); 
     1094 
     1095    stream.seek(128); 
     1096    if (!stream.readString(4).equals("DICM")) stream.seek(0); 
     1097 
     1098    int fileSeries = -1; 
     1099 
     1100    String date = null, time = null, instance = null; 
     1101    while (date == null || time == null || instance == null || 
     1102      (checkSeries && fileSeries < 0)) 
     1103    { 
     1104      long fp = stream.getFilePointer(); 
     1105      if (fp + 4 >= stream.length() || fp < 0) break; 
     1106      int tag = getNextTag(stream); 
     1107      String key = TYPES.get(new Integer(tag)); 
     1108      if ("Instance Number".equals(key)) { 
     1109        instance = stream.readString(elementLength).trim(); 
     1110        if (instance.length() == 0) instance = null; 
     1111      } 
     1112      else if ("Acquisition Time".equals(key)) { 
     1113        time = stream.readString(elementLength); 
     1114      } 
     1115      else if ("Acquisition Date".equals(key)) { 
     1116        date = stream.readString(elementLength); 
     1117      } 
     1118      else if ("Series Number".equals(key)) { 
     1119        fileSeries = Integer.parseInt(stream.readString(elementLength).trim()); 
     1120      } 
     1121      else stream.skipBytes(elementLength); 
     1122    } 
     1123    stream.close(); 
     1124 
     1125    if (date == null || time == null || instance == null || 
     1126      (checkSeries && fileSeries == originalSeries)) 
     1127    { 
     1128      return; 
     1129    } 
     1130 
     1131    int stamp = 0; 
     1132    try { 
     1133      stamp = Integer.parseInt(time); 
     1134    } 
     1135    catch (NumberFormatException e) { } 
     1136 
     1137    int timestamp = 0; 
     1138    try { 
     1139      timestamp = Integer.parseInt(originalTime); 
     1140    } 
     1141    catch (NumberFormatException e) { } 
     1142 
     1143    if (date.equals(originalDate) && (Math.abs(stamp - timestamp) < 150)) 
     1144    { 
     1145      int position = Integer.parseInt(instance) - 1; 
     1146      if (position < 0) position = 0; 
     1147      if (fileList.get(fileSeries) == null) { 
     1148        fileList.put(new Integer(fileSeries), new Vector<String>()); 
     1149      } 
     1150      if (position < fileList.get(fileSeries).size()) { 
     1151        while (position < fileList.get(fileSeries).size() && 
     1152          fileList.get(fileSeries).get(position) != null) 
     1153        { 
     1154          position++; 
     1155        } 
     1156        if (position < fileList.get(fileSeries).size()) { 
     1157          fileList.get(fileSeries).setElementAt(file, position); 
     1158        } 
     1159        else fileList.get(fileSeries).add(file); 
     1160      } 
     1161      else { 
     1162        while (position > fileList.get(fileSeries).size()) { 
     1163          fileList.get(fileSeries).add(null); 
     1164        } 
     1165        fileList.get(fileSeries).add(file); 
     1166      } 
     1167    } 
     1168  } 
    10771169 
    10781170  /** 
Note: See TracChangeset for help on using the changeset viewer.