Changeset 4782


Ignore:
Timestamp:
02/05/09 15:27:12 (11 years ago)
Author:
melissa
Message:

Fixed a bunch of dimension detection problems, and improved metadata support. Closes #351.

File:
1 edited

Legend:

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

    r4774 r4782  
    4747  // -- Fields -- 
    4848 
    49   private Vector tiffs; 
     49  private Image[][][] imageFiles; 
    5050  private MinimalTiffReader tiffReader; 
    5151  private int seriesCount; 
    5252  private Vector emWaves, exWaves; 
    53   private Vector timings; 
    5453  private int totalImages; 
    5554  private String creationDate; 
    5655  private int startRow, startCol; 
    57   private int fieldCount, zCount; 
     56  private int fieldCount; 
    5857 
    5958  private int wellRows, wellCols; 
    60   private Vector wellCoordinates; 
     59  private Hashtable wellCoordinates; 
     60  private Vector posX, posY; 
     61 
     62  private int firstRow, firstCol; 
     63  private int lastCol; 
    6164 
    6265  // -- Constructor -- 
     
    98101    FormatTools.checkPlaneNumber(this, no); 
    99102    FormatTools.checkBufferSize(this, buf.length, w, h); 
    100     tiffReader.setId((String) tiffs.get(series * getImageCount() + no)); 
     103 
     104    int well = getWellFromSeries(getSeries()); 
     105    int field = getFieldFromSeries(getSeries()); 
     106    tiffReader.setId(imageFiles[well][field][no].filename); 
    101107    return tiffReader.openBytes(0, buf, x, y, w, h); 
    102108  } 
     
    105111  public String[] getUsedFiles() { 
    106112    FormatTools.assertId(currentId, true, 1); 
    107     Vector v = new Vector(); 
    108     v.add(currentId); 
    109     for (int i=0; i<tiffs.size(); i++) { 
    110       v.add(tiffs.get(i)); 
    111     } 
    112     return (String[]) v.toArray(new String[0]); 
     113    String[] files = new String[getSeriesCount() * getImageCount() + 1]; 
     114    int nextFile = 0; 
     115    if (imageFiles != null) { 
     116      for (int series=0; series<getSeriesCount(); series++) { 
     117        int well = getWellFromSeries(series); 
     118        int field = getFieldFromSeries(series); 
     119        for (int plane=0; plane<getImageCount(); plane++) { 
     120          files[nextFile++] = imageFiles[well][field][plane].filename; 
     121        } 
     122      } 
     123    } 
     124    files[files.length - 1] = currentId; 
     125    return files; 
    113126  } 
    114127 
     
    118131  public void close() throws IOException { 
    119132    super.close(); 
    120     tiffs = null; 
     133    imageFiles = null; 
    121134    if (tiffReader != null) tiffReader.close(); 
    122135    tiffReader = null; 
     
    126139    emWaves = exWaves = null; 
    127140    wellCoordinates = null; 
    128     timings = null; 
     141    posX = null; 
     142    posY = null; 
    129143    creationDate = null; 
    130144    wellRows = wellCols = 0; 
    131145    startRow = startCol = 0; 
    132     fieldCount = zCount = 0; 
     146    fieldCount = 0; 
    133147  } 
    134148 
     
    141155    in = new RandomAccessStream(id); 
    142156 
    143     tiffs = new Vector(); 
     157    firstRow = Integer.MAX_VALUE; 
     158    firstCol = Integer.MAX_VALUE; 
     159    lastCol = Integer.MIN_VALUE; 
     160 
    144161    emWaves = new Vector(); 
    145162    exWaves = new Vector(); 
    146     timings = new Vector(); 
    147  
    148     wellCoordinates = new Vector(); 
     163 
     164    wellCoordinates = new Hashtable(); 
     165    posX = new Vector(); 
     166    posY = new Vector(); 
    149167 
    150168    byte[] b = new byte[(int) in.length()]; 
    151169    in.read(b); 
     170 
     171    core[0].dimensionOrder = "XYZCT"; 
    152172 
    153173    MetadataStore store = 
     
    156176    DataTools.parseXML(b, handler); 
    157177 
    158     core[0].sizeZ = fieldCount * zCount; 
     178    if (getSizeZ() == 0) core[0].sizeZ = 1; 
     179    if (getSizeC() == 0) core[0].sizeC = 1; 
     180    if (getSizeT() == 0) core[0].sizeT = 1; 
    159181 
    160182    seriesCount = totalImages / (getSizeZ() * getSizeC() * getSizeT()); 
     
    175197 
    176198    tiffReader = new MinimalTiffReader(); 
     199    tiffReader.setId( 
     200      imageFiles[getWellFromSeries(0)][getFieldFromSeries(0)][0].filename); 
    177201 
    178202    int nextTiming = 0; 
    179203    for (int i=0; i<seriesCount; i++) { 
    180       tiffReader.setId((String) tiffs.get(i * (tiffs.size() / seriesCount))); 
    181204      core[i].sizeX = tiffReader.getSizeX(); 
    182205      core[i].sizeY = tiffReader.getSizeY(); 
     
    199222 
    200223    for (int i=0; i<seriesCount; i++) { 
    201       store.setImageName("", i); 
     224      int well = getWellFromSeries(i); 
     225      int field = getFieldFromSeries(i); 
     226      store.setImageName("Well #" + well + ", Field #" + field, i); 
    202227      store.setImageCreationDate(creationDate, i); 
    203228    } 
     
    206231 
    207232    for (int i=0; i<seriesCount; i++) { 
     233      int well = getWellFromSeries(i); 
     234      int field = getFieldFromSeries(i); 
    208235      for (int q=0; q<core[i].imageCount; q++) { 
    209         store.setPlaneTimingDeltaT((Float) timings.get(nextTiming++), i, 0, q); 
    210         //store.setPlaneTimingExposureTime(new Float(0), i, 0, q); 
     236        Image img = imageFiles[well][field][q]; 
     237        store.setPlaneTimingDeltaT(img.deltaT, i, 0, q); 
     238        store.setPlaneTimingExposureTime(img.exposure, i, 0, q); 
    211239      } 
    212240    } 
     
    223251    // populate Well data 
    224252 
     253    int[][] plate = new int[wellRows][wellCols]; 
     254 
    225255    for (int i=0; i<seriesCount; i++) { 
    226       int row = (int) ((Point) wellCoordinates.get(i)).x - startRow; 
    227       int col = (int) ((Point) wellCoordinates.get(i)).y - startCol; 
    228       store.setWellSampleIndex(new Integer(i), 0, row*wellCols + col, 0); 
    229       store.setWellSampleImageRef("Image:" + i, 0, row * wellCols + col, 0); 
    230     } 
     256      int well = getWellFromSeries(i); 
     257      int field = getFieldFromSeries(i); 
     258 
     259      store.setWellSampleIndex(new Integer(i), 0, well, field); 
     260      store.setWellSampleImageRef("Image:" + i, 0, well, field); 
     261      store.setWellSamplePosX((Float) posX.get(field), 0, well, field); 
     262      store.setWellSamplePosY((Float) posY.get(field), 0, well, field); 
     263    } 
     264  } 
     265 
     266  // -- Helper methods -- 
     267 
     268  private int getFieldFromSeries(int series) { 
     269    return series % fieldCount; 
     270  } 
     271 
     272  private int getWellFromSeries(int series) { 
     273    int well = series / fieldCount; 
     274    int wellRow = well / (lastCol - firstCol + 1); 
     275    int wellCol = well % (lastCol - firstCol + 1); 
     276    return (wellRow + firstRow) * wellCols + wellCol + firstCol; 
    231277  } 
    232278 
     
    234280 
    235281  class MinimalInCellHandler extends DefaultHandler { 
     282    private String currentImageFile; 
     283    private int wellRow, wellCol; 
     284 
     285    public void endElement(String uri, String localName, String qName) { 
     286      if (qName.equals("PlateMap")) { 
     287        int imageCount = getSizeZ() * getSizeC() * getSizeT(); 
     288        imageFiles = new Image[wellRows * wellCols][fieldCount][imageCount]; 
     289      } 
     290    } 
     291 
    236292    public void startElement(String uri, String localName, String qName, 
    237293      Attributes attributes) 
    238294    { 
    239       if (qName.equals("Images")) { 
     295      if (qName.equals("Plate")) { 
     296        wellRows = Integer.parseInt(attributes.getValue("rows")); 
     297        wellCols = Integer.parseInt(attributes.getValue("columns")); 
     298      } 
     299      else if (qName.equals("Images")) { 
    240300        totalImages = Integer.parseInt(attributes.getValue("number")); 
    241301      } 
     
    245305        Location current = new Location(currentId).getAbsoluteFile(); 
    246306 
    247         if (new Location(current.getParentFile(), file).exists()) { 
    248           tiffs.add( 
    249             new Location(current.getParentFile(), file).getAbsolutePath()); 
    250         } 
    251         else tiffs.add(file); 
     307        Location imageFile = new Location(current.getParentFile(), file); 
     308        if (imageFile.exists()) { 
     309          currentImageFile = imageFile.getAbsolutePath(); 
     310        } 
     311        else currentImageFile = file; 
    252312      } 
    253313      else if (qName.equals("Identifier")) { 
    254         int field = Integer.parseInt(attributes.getValue("field_index")) + 1; 
    255         int z = Integer.parseInt(attributes.getValue("z_index")) + 1; 
    256         int c = Integer.parseInt(attributes.getValue("wave_index")) + 1; 
    257         int t = Integer.parseInt(attributes.getValue("time_index")) + 1; 
    258         fieldCount = (int) Math.max(fieldCount, field); 
    259         zCount = (int) Math.max(zCount, z); 
    260         core[0].sizeC = (int) Math.max(getSizeC(), c); 
    261         core[0].sizeT = (int) Math.max(getSizeT(), t); 
     314        int field = Integer.parseInt(attributes.getValue("field_index")); 
     315        int z = Integer.parseInt(attributes.getValue("z_index")); 
     316        int c = Integer.parseInt(attributes.getValue("wave_index")); 
     317        int t = Integer.parseInt(attributes.getValue("time_index")); 
     318        core[0].imageCount = getSizeZ() * getSizeC() * getSizeT(); 
     319        int index = getIndex(z, c, t); 
     320 
     321        Image img = new Image(); 
     322        img.filename = currentImageFile; 
     323        imageFiles[wellRow * wellCols + wellCol][field][index] = img; 
     324      } 
     325      else if (qName.equals("offset_point")) { 
     326        fieldCount++; 
     327      } 
     328      else if (qName.equals("TimePoint")) { 
     329        core[0].sizeT++; 
     330      } 
     331      else if (qName.equals("Wavelength")) { 
     332        core[0].sizeC++; 
     333      } 
     334      else if (qName.equals("ZDimensionParameters")) { 
     335        String nz = attributes.getValue("number_of_slices"); 
     336        if (nz != null) { 
     337          core[0].sizeZ = Integer.parseInt(nz); 
     338        } 
     339        else core[0].sizeZ = 1; 
     340      } 
     341      else if (qName.equals("Row")) { 
     342        wellRow = Integer.parseInt(attributes.getValue("number")) - 1; 
     343        firstRow = (int) Math.min(firstRow, wellRow); 
     344      } 
     345      else if (qName.equals("Column")) { 
     346        wellCol = Integer.parseInt(attributes.getValue("number")) - 1; 
     347        firstCol = (int) Math.min(firstCol, wellCol); 
     348        lastCol = (int) Math.max(lastCol, wellCol); 
    262349      } 
    263350    } 
     
    267354  class InCellHandler extends DefaultHandler { 
    268355    private String currentQName; 
     356    private boolean openImage; 
    269357    private int nextEmWave = 0; 
    270358    private int nextExWave = 0; 
     
    272360    private int nextPlate = 0; 
    273361    private int currentRow = -1, currentCol = -1; 
     362    private int currentField = 0; 
     363    private int currentImage; 
     364    private Float timestamp, exposure; 
    274365 
    275366    public InCellHandler(MetadataStore store) { 
     
    287378      if (qName.equals("Image")) { 
    288379        Point p = new Point(currentRow, currentCol); 
    289         if (!wellCoordinates.contains(p)) wellCoordinates.add(p); 
     380        wellCoordinates.put(new Integer(currentField), p); 
     381        openImage = false; 
     382 
     383        int well = currentRow * wellCols + currentCol; 
     384        imageFiles[well][currentField][currentImage].deltaT = timestamp; 
     385        imageFiles[well][currentField][currentImage].exposure = exposure; 
    290386      } 
    291387    } 
     
    300396 
    301397      if (qName.equals("Image")) { 
    302         float timestamp = 
     398        openImage = true; 
     399        float time = 
    303400          Float.parseFloat(attributes.getValue("acquisition_time_ms")); 
    304         timings.add(new Float(timestamp / 1000)); 
     401        timestamp = new Float(time / 1000); 
     402      } 
     403      else if (qName.equals("Identifier")) { 
     404        currentField = Integer.parseInt(attributes.getValue("field_index")); 
     405        int z = Integer.parseInt(attributes.getValue("z_index")); 
     406        int c = Integer.parseInt(attributes.getValue("wave_index")); 
     407        int t = Integer.parseInt(attributes.getValue("time_index")); 
     408        currentImage = getIndex(z, c, t); 
    305409      } 
    306410      else if (qName.equals("Creation")) { 
     
    310414      } 
    311415      else if (qName.equals("ObjectiveCalibration")) { 
    312         store.setObjectiveCalibratedMagnification( 
    313           new Float(attributes.getValue("magnification")), 0, 0); 
     416        store.setObjectiveNominalMagnification(new Integer( 
     417          (int) Float.parseFloat(attributes.getValue("magnification"))), 0, 0); 
    314418        store.setObjectiveModel(attributes.getValue("objective_name"), 0, 0); 
    315419        store.setObjectiveLensNA(new Float( 
     
    318422        store.setObjectiveImmersion("Unknown", 0, 0); 
    319423 
     424        Float pixelSizeX = new Float(attributes.getValue("pixel_width")); 
     425        Float pixelSizeY = new Float(attributes.getValue("pixel_height")); 
     426        Float refractive = new Float(attributes.getValue("refractive_index")); 
     427 
    320428        // link Objective to Image 
    321429        store.setObjectiveID("Objective:0", 0, 0); 
    322         store.setObjectiveSettingsObjective("Objective:0", 0); 
     430        for (int i=0; i<getSeriesCount(); i++) { 
     431          store.setObjectiveSettingsObjective("Objective:0", i); 
     432          store.setObjectiveSettingsRefractiveIndex(refractive, i); 
     433          store.setDimensionsPhysicalSizeX(pixelSizeX, i, 0); 
     434          store.setDimensionsPhysicalSizeY(pixelSizeY, i, 0); 
     435        } 
    323436      } 
    324437      else if (qName.equals("ExcitationFilter")) { 
     
    330443        if (wave != null) emWaves.add(new Integer(wave)); 
    331444      } 
     445      else if (qName.equals("Camera")) { 
     446        store.setDetectorModel(attributes.getValue("name"), 0, 0); 
     447        store.setDetectorType("Unknown", 0, 0); 
     448        store.setDetectorID("Detector:0", 0, 0); 
     449        for (int i=0; i<getSeriesCount(); i++) { 
     450          for (int q=0; q<getSizeC(); q++) { 
     451            store.setDetectorSettingsDetector("Detector:0", i, q); 
     452          } 
     453        } 
     454      } 
     455      else if (qName.equals("Binning")) { 
     456        String binning = attributes.getValue("value"); 
     457        for (int i=0; i<getSeriesCount(); i++) { 
     458          for (int q=0; q<getSizeC(); q++) { 
     459            store.setDetectorSettingsBinning(binning, i, q); 
     460          } 
     461        } 
     462      } 
     463      else if (qName.equals("Gain")) { 
     464        Float gain = new Float(attributes.getValue("value")); 
     465        for (int i=0; i<getSeriesCount(); i++) { 
     466          for (int q=0; q<getSizeC(); q++) { 
     467            store.setDetectorSettingsGain(gain, i, q); 
     468          } 
     469        } 
     470      } 
     471      else if (qName.equals("PlateTemperature")) { 
     472        Float temperature = new Float(attributes.getValue("value")); 
     473        for (int i=0; i<getSeriesCount(); i++) { 
     474          store.setImagingEnvironmentTemperature(temperature, i); 
     475        } 
     476      } 
    332477      else if (qName.equals("Plate")) { 
    333478        store.setPlateName(new Location(getCurrentFile()).getName(), nextPlate); 
    334         wellRows = Integer.parseInt(attributes.getValue("rows")); 
    335         wellCols = Integer.parseInt(attributes.getValue("columns")); 
    336479 
    337480        for (int r=0; r<wellRows; r++) { 
     
    344487      } 
    345488      else if (qName.equals("Row")) { 
    346         currentRow = Integer.parseInt(attributes.getValue("number")); 
     489        currentRow = Integer.parseInt(attributes.getValue("number")) - 1; 
    347490      } 
    348491      else if (qName.equals("Column")) { 
    349         currentCol = Integer.parseInt(attributes.getValue("number")); 
     492        currentCol = Integer.parseInt(attributes.getValue("number")) - 1; 
     493      } 
     494      else if (qName.equals("Exposure") && openImage) { 
     495        float exp = Float.parseFloat(attributes.getValue("time")); 
     496        exposure = new Float(exp / 1000); 
    350497      } 
    351498      else if (qName.equals("NamingRows")) { 
     
    367514        } 
    368515      } 
    369     } 
     516      else if (qName.equals("offset_point")) { 
     517        posX.add(new Float(attributes.getValue("x"))); 
     518        posY.add(new Float(attributes.getValue("y"))); 
     519      } 
     520    } 
     521  } 
     522 
     523  class Image { 
     524    public String filename; 
     525    public Float deltaT, exposure; 
    370526  } 
    371527 
Note: See TracChangeset for help on using the changeset viewer.