@Override
 public void writeDisplaySettings() {
   for (MultipageTiffReader r : new HashSet<MultipageTiffReader>(tiffReadersByLabel_.values())) {
     try {
       r.rewriteDisplaySettings(displayAndComments_.getJSONArray("Channels"));
       r.rewriteComments(displayAndComments_.getJSONObject("Comments"));
     } catch (JSONException ex) {
       ReportingUtils.logError("Error writing display settings");
     } catch (IOException ex) {
       ReportingUtils.logError(ex);
     }
   }
 }
  @Override
  public void putImage(TaggedImage taggedImage) throws MMException {
    if (!newDataSet_) {
      throw new MMException("This ImageFileManager is read-only.");
    }
    int fileSetIndex = 0;
    if (splitByXYPosition_) {
      try {
        fileSetIndex = MDUtils.getPositionIndex(taggedImage.tags);
      } catch (JSONException ex) {
        ReportingUtils.logError(ex);
      }
    }
    String label = MDUtils.getLabel(taggedImage.tags);
    if (fileSets_ == null) {
      try {
        fileSets_ = new HashMap<Integer, FileSet>();
        createDirectory(directory_);
      } catch (Exception ex) {
        ReportingUtils.logError(ex);
      }
    }

    if (omeTiff_) {
      if (omeMetadata_ == null) {
        omeMetadata_ = new OMEMetadata(this);
      }
    }

    if (fileSets_.get(fileSetIndex) == null) {
      fileSets_.put(fileSetIndex, new FileSet(taggedImage.tags, this));
    }
    FileSet set = fileSets_.get(fileSetIndex);
    try {
      set.writeImage(taggedImage);
    } catch (IOException ex) {
      ReportingUtils.showError("problem writing image to file");
    }
    tiffReadersByLabel_.put(label, set.getCurrentReader());

    int frame;
    try {
      frame = MDUtils.getFrameIndex(taggedImage.tags);
    } catch (JSONException ex) {
      frame = 0;
    }
    lastFrameOpenedDataSet_ = Math.max(frame, lastFrameOpenedDataSet_);
    cached_.add(taggedImage, label);
  }
 /** Disposes of the tagged images in the imagestorage */
 @Override
 public void close() {
   shutdownHook_.run();
   Runtime.getRuntime().removeShutdownHook(shutdownHook_);
   for (MultipageTiffReader r : new HashSet<MultipageTiffReader>(tiffReadersByLabel_.values())) {
     try {
       r.close();
     } catch (IOException ex) {
       ReportingUtils.logError(ex);
     }
   }
 }
 // <editor-fold defaultstate="collapsed" desc=" Metadata ">
 //
 private void processSummaryMD() {
   // TODO      displayAndComments_ =
   // VirtualAcquisitionDisplay.getDisplaySettingsFromSummary(summaryMetadata_);
   try {
     numPositions_ = MDUtils.getNumPositions(summaryMetadata_);
     if (numPositions_ <= 0) {
       numPositions_ = 1;
     }
   } catch (JSONException ex) {
     ReportingUtils.logError(ex);
     numPositions_ = 1;
   }
   try {
     // Estimate of max number of image planes
     numChannels_ = MDUtils.getNumChannels(summaryMetadata_);
     numSlices_ = MDUtils.getNumSlices(summaryMetadata_);
     totalNumImagePlanes_ =
         numChannels_ * MDUtils.getNumFrames(summaryMetadata_) * numPositions_ * numSlices_;
   } catch (Exception ex) {
     ReportingUtils.logError("Error estimating total number of image planes");
     totalNumImagePlanes_ = 1;
   }
 }
 @Override
 public void setSummaryMetadata(JSONObject md) {
   summaryMetadata_ = md;
   if (summaryMetadata_ != null) {
     try {
       boolean slicesFirst = summaryMetadata_.getBoolean("SlicesFirst");
       boolean timeFirst = summaryMetadata_.getBoolean("TimeFirst");
       TreeMap<String, MultipageTiffReader> oldImageMap = tiffReadersByLabel_;
       tiffReadersByLabel_ =
           new TreeMap<String, MultipageTiffReader>(
               new ImageLabelComparator(slicesFirst, timeFirst));
       tiffReadersByLabel_.putAll(oldImageMap);
     } catch (JSONException ex) {
       ReportingUtils.logError("Couldn't find SlicesFirst or TimeFirst in summary metadata");
     }
     if (summaryMetadata_ != null && summaryMetadata_.length() > 0) {
       processSummaryMD();
     }
   }
 }
 /**
  * Call this function when no more images are expected Finishes writing the metadata file and
  * closes it. After calling this function, the imagestorage is read-only
  */
 @Override
 public synchronized void finished() {
   if (finished_) {
     return;
   }
   newDataSet_ = false;
   try {
     if (fileSets_ != null) {
       for (FileSet p : fileSets_.values()) {
         p.finishAbortedAcqIfNeeded();
       }
       for (FileSet p : fileSets_.values()) {
         p.finished();
       }
     }
   } catch (IOException ex) {
     ReportingUtils.logError(ex);
   }
   finished_ = true;
 }
 private void openExistingDataSet() throws IOException {
   // Need to throw error if file not found
   MultipageTiffReader reader = null;
   File dir = new File(directory_);
   for (File f : dir.listFiles()) {
     if (f.getName().endsWith(".tif") || f.getName().endsWith(".TIF")) {
       reader = new MultipageTiffReader(f);
       Set<String> labels = reader.getIndexKeys();
       for (String label : labels) {
         tiffReadersByLabel_.put(label, reader);
         int frameIndex = Integer.parseInt(label.split("_")[2]);
         lastFrameOpenedDataSet_ = Math.max(frameIndex, lastFrameOpenedDataSet_);
       }
     }
   }
   try {
     setSummaryMetadata(reader.getSummaryMetadata());
     numPositions_ = MDUtils.getNumPositions(summaryMetadata_);
     displayAndComments_ = reader.getDisplayAndComments();
   } catch (JSONException ex) {
     ReportingUtils.logError(ex);
   }
 }