{"action":"created","comment":{"url":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/comments/225168867","pull_request_review_id":164709120,"id":225168867,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyNTE2ODg2Nw==","diff_hunk":"@@ -0,0 +1,900 @@\n+/*\n+ * #%L\n+ * OME Bio-Formats package for reading and converting biological file formats.\n+ * %%\n+ * Copyright (C) 2005 - 2015 Open Microscopy Environment:\n+ *   - Board of Regents of the University of Wisconsin-Madison\n+ *   - Glencoe Software, Inc.\n+ *   - University of Dundee\n+ * %%\n+ * This program is free software: you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License as\n+ * published by the Free Software Foundation, either version 2 of the \n+ * License, or (at your option) any later version.\n+ * \n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ * GNU General Public License for more details.\n+ * \n+ * You should have received a copy of the GNU General Public \n+ * License along with this program.  If not, see\n+ * <http://www.gnu.org/licenses/gpl-2.0.html>.\n+ * #L%\n+ */\n+\n+package loci.formats.in;\n+\n+import java.io.IOException;\n+import java.util.ArrayList;\n+import java.util.Arrays;\n+import java.util.HashMap;\n+import java.util.HashSet;\n+import java.util.List;\n+import java.util.Map;\n+\n+import loci.common.DataTools;\n+import loci.common.Location;\n+import loci.common.RandomAccessInputStream;\n+import loci.common.xml.BaseHandler;\n+import loci.common.xml.XMLTools;\n+import loci.formats.CoreMetadata;\n+import loci.formats.FormatException;\n+import loci.formats.FormatReader;\n+import loci.formats.FormatTools;\n+import loci.formats.MetadataTools;\n+import loci.formats.meta.MetadataStore;\n+import loci.formats.tiff.IFD;\n+import loci.formats.tiff.TiffParser;\n+\n+import ome.units.UNITS;\n+import ome.units.quantity.Length;\n+import ome.units.quantity.Power;\n+import ome.units.quantity.Time;\n+import ome.xml.model.primitives.Color;\n+import ome.xml.model.primitives.NonNegativeInteger;\n+import ome.xml.model.primitives.PositiveFloat;\n+import ome.xml.model.primitives.PositiveInteger;\n+import ome.xml.model.primitives.Timestamp;\n+\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+import org.xml.sax.Attributes;\n+\n+/**\n+ *\n+ * @author Melissa Linkert melissa at glencoesoftware.com\n+ */\n+public class CV7000Reader extends FormatReader {\n+\n+  // -- Constants --\n+\n+  private static final Logger LOGGER = LoggerFactory.getLogger(CV7000Reader.class);\n+\n+  private static final String MEASUREMENT_FILE = \"MeasurementData.mlf\";\n+  private static final String MEASUREMENT_DETAIL = \"MeasurementDetail.mrf\";\n+  private static final String POST_PROCESS = \"PostProcess.ppf\";\n+\n+  // -- Fields --\n+\n+  private String[] allFiles;\n+  private Location parent;\n+  private MinimalTiffReader reader;\n+  private String wppPath;\n+  private String detailPath;\n+  private String measurementPath;\n+  private String settingsPath;\n+  private ArrayList<Plane> planeData;\n+  private int[][] reversePlaneLookup;\n+  private ArrayList<LightSource> lightSources;\n+  private ArrayList<Channel> channels;\n+  private int fields;\n+  private String startTime, endTime;\n+  private ArrayList<String> extraFiles;\n+\n+  // -- Constructor --\n+\n+  /** Constructs a new Yokogawa CV7000 reader. */\n+  public CV7000Reader() {\n+    super(\"Yokogawa CV7000\", new String[] {\"wpi\"});\n+    hasCompanionFiles = true;\n+    domains = new String[] {FormatTools.HCS_DOMAIN};\n+    datasetDescription = \"Directory with XML files and one .tif/.tiff file per plane\";\n+  }\n+\n+  // -- IFormatReader API methods --\n+\n+  /* @see loci.formats.IFormatReader#getRequiredDirectories(String[]) */\n+  @Override\n+  public int getRequiredDirectories(String[] files)\n+    throws FormatException, IOException\n+  {\n+    return 1;\n+  }\n+\n+  /* @see loci.formats.IFormatReader#isSingleFile(String) */\n+  @Override\n+  public boolean isSingleFile(String id) throws FormatException, IOException {\n+    return false;\n+  }\n+\n+  /* @see loci.formats.IFormatReader#fileGroupOption(String) */\n+  @Override\n+  public int fileGroupOption(String id) throws FormatException, IOException {\n+    return FormatTools.MUST_GROUP;\n+  }\n+\n+  /* @see loci.formats.IFormatReader#getUsedFiles(boolean) */\n+  @Override\n+  public String[] getUsedFiles(boolean noPixels) {\n+    ArrayList<String> files = new ArrayList<String>();\n+    files.add(new Location(currentId).getAbsolutePath());\n+    for (String file : allFiles) {\n+      if (!files.contains(file) && (!noPixels || !checkSuffix(file, \"tif\"))) {\n+        files.add(file);\n+      }\n+    }\n+    return files.toArray(new String[files.size()]);\n+  }\n+\n+  /* @see loci.formats.IFormatReader#getSeriesUsedFiles(boolean) */\n+  @Override\n+  public String[] getSeriesUsedFiles(boolean noPixels) {\n+    FormatTools.assertId(currentId, true, 1);\n+\n+    HashSet<String> files = new HashSet<String>();\n+    files.add(new Location(currentId).getAbsolutePath());\n+    files.add(measurementPath);\n+    if (detailPath != null) {\n+      files.add(detailPath);\n+    }\n+    if (settingsPath != null) {\n+      files.add(settingsPath);\n+    }\n+    if (wppPath != null) {\n+      files.add(wppPath);\n+    }\n+    if (!noPixels && planeData != null) {\n+      for (int index : reversePlaneLookup[getSeries()]) {\n+        if (index < 0) {\n+          continue;\n+        }\n+        Plane p = planeData.get(index);\n+        if (p != null && p.file != null) {\n+          files.add(p.file);\n+        }\n+      }\n+    }\n+    if (!noPixels && channels != null) {\n+      for (Channel c : channels) {\n+        if (c != null && c.correctionFile != null &&\n+          new Location(c.correctionFile).exists())\n+        {\n+          files.add(c.correctionFile);\n+        }\n+      }\n+    }\n+    files.addAll(extraFiles);\n+    for (String file : allFiles) {\n+      if (!checkSuffix(file, \"tif\") && !(new Location(file).isDirectory())) {\n+        files.add(file);\n+      }\n+    }\n+    String[] allFiles = files.toArray(new String[files.size()]);\n+    Arrays.sort(allFiles);\n+    return allFiles;\n+  }\n+\n+  /* @see loci.formats.IFormatReader#close(boolean) */\n+  @Override\n+  public void close(boolean fileOnly) throws IOException {\n+    super.close(fileOnly);\n+    if (!fileOnly) {\n+      if (reader != null) {\n+        reader.close();\n+      }\n+      reader = null;\n+      measurementPath = null;\n+      detailPath = null;\n+      wppPath = null;\n+      settingsPath = null;\n+      planeData = null;\n+      fields = 0;\n+      lightSources = null;\n+      channels = null;\n+      startTime = null;\n+      endTime = null;\n+      reversePlaneLookup = null;\n+      extraFiles = null;\n+    }\n+  }\n+\n+  /**\n+   * @see loci.formats.IFormatReader#openBytes(int, byte[], int, int, int, int)\n+   */\n+  @Override\n+  public byte[] openBytes(int no, byte[] buf, int x, int y, int w, int h)\n+    throws FormatException, IOException\n+  {\n+    FormatTools.checkPlaneParameters(this, no, buf.length, x, y, w, h);\n+\n+    Arrays.fill(buf, (byte) 0);\n+    Plane p = lookupPlane(getSeries(), no);\n+    LOGGER.trace(\"series = {}, no = {}, file = {}\", series, no, p == null ? null : p.file);\n+    if (p != null && p.file != null) {\n+      reader.setId(p.file);\n+      return reader.openBytes(0, buf, x, y, w, h);\n+    }\n+    return buf;\n+  }\n+\n+  // -- Internal FormatReader API methods --\n+\n+  /* @see loci.formats.FormatReader#initFile(String) */\n+  @Override\n+  protected void initFile(String id) throws FormatException, IOException {\n+    super.initFile(id);\n+    WPIHandler plate = new WPIHandler();\n+    String wpiXML = readSanitizedXML(id);\n+    XMLTools.parseXML(wpiXML, plate);\n+\n+    parent = new Location(id).getAbsoluteFile().getParentFile();\n+    allFiles = parent.list(true);\n+    Arrays.sort(allFiles);\n+    for (int i=0; i<allFiles.length; i++) {\n+      allFiles[i] = new Location(parent, allFiles[i]).getAbsolutePath();\n+    }\n+    Location measurementData = new Location(parent, MEASUREMENT_FILE);\n+\n+    if (!measurementData.exists()) {\n+      throw new FormatException(\"Missing \" + MEASUREMENT_FILE + \" file\");\n+    }\n+\n+    measurementPath = measurementData.getAbsolutePath();\n+    MeasurementDataHandler measurementHandler = new MeasurementDataHandler(parent.getAbsolutePath());\n+    XMLTools.parseXML(readSanitizedXML(measurementPath), measurementHandler);\n+\n+    planeData = measurementHandler.getPlanes();\n+\n+    Location measurementDetail = new Location(parent, MEASUREMENT_DETAIL);\n+    if (!measurementDetail.exists()) {\n+      LOGGER.warn(\"Missing \" + MEASUREMENT_DETAIL + \" file\");\n+    }\n+    else {\n+      channels = new ArrayList<Channel>();\n+      detailPath = measurementDetail.getAbsolutePath();\n+      MeasurementDetailHandler detailHandler = new MeasurementDetailHandler();\n+      XMLTools.parseXML(readSanitizedXML(detailPath), detailHandler);\n+      if (wppPath != null) {\n+        wppPath = new Location(parent, wppPath).getAbsolutePath();\n+      }\n+      if (settingsPath != null) {\n+        settingsPath = new Location(parent, settingsPath).getAbsolutePath();\n+      }\n+    }\n+\n+    if (settingsPath != null && new Location(settingsPath).exists()) {\n+      lightSources = new ArrayList<LightSource>();\n+      MeasurementSettingsHandler settingsHandler = new MeasurementSettingsHandler();\n+      String xml = readSanitizedXML(settingsPath);\n+      if (xml.length() > 0) {\n+        XMLTools.parseXML(xml, settingsHandler);\n+      }\n+    }\n+\n+    for (Channel ch : channels) {\n+      if (ch.correctionFile != null) {\n+        ch.correctionFile = new Location(parent, ch.correctionFile).getAbsolutePath();\n+      }\n+    }\n+\n+    String firstFile = null;\n+    int minSizeZ = Integer.MAX_VALUE, maxSizeZ = 0;\n+    int minSizeC = Integer.MAX_VALUE, maxSizeC = 0;\n+    int minSizeT = Integer.MAX_VALUE, maxSizeT = 0;\n+    fields = 0;\n+    HashSet<Integer> uniqueWells = new HashSet<Integer>();\n+\n+    for (Plane p : planeData) {\n+      if (p != null) {\n+        if (p.file != null && firstFile == null) {\n+          firstFile = p.file;\n+        }\n+\n+        if (p.timepoint > maxSizeT) {\n+          maxSizeT = p.timepoint;\n+        }\n+        if (p.timepoint < minSizeT) {\n+          minSizeT = p.timepoint;\n+        }\n+        if (p.z > maxSizeZ) {\n+          maxSizeZ = p.z;\n+        }\n+        if (p.z < minSizeZ) {\n+          minSizeZ = p.z;\n+        }\n+        if (p.channel > maxSizeC) {\n+          maxSizeC = p.channel;\n+        }\n+        if (p.channel < minSizeC) {\n+          minSizeC = p.channel;\n+        }\n+\n+        if (p.field >= fields) {\n+          fields = p.field + 1;\n+        }\n+        uniqueWells.add(p.row * plate.getPlateColumns() + p.column);\n+      }\n+    }\n+\n+    reader = new MinimalTiffReader();\n+    reader.setId(firstFile);\n+    core.clear();\n+    core.add(new CoreMetadata(reader.getCoreMetadataList().get(0)));\n+\n+    core.get(0).dimensionOrder = \"XYCZT\";\n+    core.get(0).sizeZ = (maxSizeZ - minSizeZ) + 1;\n+    core.get(0).sizeT = (maxSizeT - minSizeT) + 1;\n+    core.get(0).sizeC *= (maxSizeC - minSizeC) + 1;\n+    core.get(0).imageCount = getSizeZ() * getSizeT() * (getSizeC() / reader.getSizeC());\n+\n+    int realWells = uniqueWells.size();\n+    Integer[] wells = uniqueWells.toArray(new Integer[realWells]);\n+    Arrays.sort(wells);\n+\n+    for (int i=1; i<realWells * fields; i++) {\n+      core.add(new CoreMetadata(core.get(0)));\n+    }\n+\n+    int[] seriesLengths = new int[] {fields, realWells};\n+    int[] planeLengths = new int[] {getSizeC(), getSizeZ(), getSizeT()};\n+    reversePlaneLookup = new int[getSeriesCount()][getImageCount()];\n+    for (int i=0; i<reversePlaneLookup.length; i++) {\n+      // do this so that the index does not default to 0 for ERR planes\n+      Arrays.fill(reversePlaneLookup[i], -1);\n+    }\n+    extraFiles = new ArrayList<String>();\n+    for (int i=0; i<planeData.size(); i++) {\n+      Plane p = planeData.get(i);\n+      int wellIndex = Arrays.binarySearch(wells, p.row * plate.getPlateColumns() + p.column);\n+      p.series = FormatTools.positionToRaster(seriesLengths,\n+        new int[] {p.field, wellIndex});\n+      p.no = FormatTools.positionToRaster(planeLengths,\n+        new int[] {p.channel - minSizeC, p.z - minSizeZ, p.timepoint - minSizeT});\n+      if (reversePlaneLookup[p.series][p.no] < 0) {\n+        reversePlaneLookup[p.series][p.no] = i;\n+      }\n+      else {\n+        LOGGER.warn(\"Ignoring file {}\", p.file);\n+        extraFiles.add(p.file);\n+      }\n+    }\n+\n+    // populate the MetadataStore\n+\n+    MetadataStore store = makeFilterMetadata();\n+    MetadataTools.populatePixels(store, this, true);\n+\n+    store.setPlateID(MetadataTools.createLSID(\"Plate\", 0), 0);\n+    store.setPlateName(plate.getPlateName(), 0);\n+    store.setPlateDescription(plate.getPlateDescription(), 0);\n+    store.setPlateExternalIdentifier(plate.getPlateID(), 0);\n+    store.setPlateRows(new PositiveInteger(plate.getPlateRows()), 0);\n+    store.setPlateColumns(new PositiveInteger(plate.getPlateColumns()), 0);\n+\n+    String plateAcqID = MetadataTools.createLSID(\"PlateAcquisition\", 0, 0);\n+    store.setPlateAcquisitionID(plateAcqID, 0, 0);\n+\n+    PositiveInteger fieldCount = FormatTools.getMaxFieldCount(fields);\n+    if (fieldCount != null) {\n+      store.setPlateAcquisitionMaximumFieldCount(fieldCount, 0, 0);\n+    }\n+\n+    if (startTime != null) {\n+      store.setPlateAcquisitionStartTime(new Timestamp(startTime), 0, 0);\n+    }\n+    if (endTime != null) {\n+      store.setPlateAcquisitionEndTime(new Timestamp(endTime), 0, 0);\n+    }\n+\n+    int nextWell = 0;\n+    int nextImage = 0;\n+    for (int row=0; row<plate.getPlateRows(); row++) {\n+      for (int col=0; col<plate.getPlateColumns(); col++) {\n+        store.setWellID(MetadataTools.createLSID(\"Well\", 0, nextWell), 0, nextWell);\n+        store.setWellRow(new NonNegativeInteger(row), 0, nextWell);\n+        store.setWellColumn(new NonNegativeInteger(col), 0, nextWell);\n+\n+        if (!isWellAcquired(row, col)) {\n+          nextWell++;\n+          continue;\n+        }\n+\n+        for (int field=0; field<fields; field++) {\n+          String wellSampleID =\n+            MetadataTools.createLSID(\"WellSample\", 0, nextWell, field);\n+          store.setWellSampleID(wellSampleID, 0, nextWell, field);\n+          store.setWellSampleIndex(\n+            new NonNegativeInteger(nextImage), 0, nextWell, field);\n+          String imageID = MetadataTools.createLSID(\"Image\", nextImage);\n+          store.setImageID(imageID, nextImage);\n+          store.setWellSampleImageRef(imageID, 0, nextWell, field);\n+\n+          String name = \"Well \" + ((char) ('A' + row)) + (col + 1) + \", Field \" + (field + 1);\n+          store.setImageName(name, nextImage);\n+          store.setPlateAcquisitionWellSampleRef(wellSampleID, 0, 0, nextImage);\n+          nextImage++;\n+        }\n+        nextWell++;\n+      }\n+    }\n+\n+    if (getMetadataOptions().getMetadataLevel() != MetadataLevel.MINIMUM) {\n+      store.setPlateName(plate.getPlateName(), 0);\n+      store.setPlateDescription(plate.getPlateDescription(), 0);\n+      store.setPlateExternalIdentifier(plate.getPlateID(), 0);\n+\n+      String instrument = null;\n+      List<String> usedObjectiveIDs = new ArrayList<String>();\n+      if (lightSources.size() > 0) {\n+        instrument = MetadataTools.createLSID(\"Instrument\", 0);\n+\n+        store.setInstrumentID(instrument, 0);\n+\n+        int nextLightSource = 0;\n+        for (LightSource l : lightSources) {\n+          if (\"Laser\".equals(l.type)) {\n+            String laserID = MetadataTools.createLSID(\"LightSource\", 0, nextLightSource);\n+            store.setLaserID(laserID, 0, nextLightSource);\n+            store.setLaserWavelength(\n+              new Length(l.wavelength, UNITS.NM), 0, nextLightSource);\n+            store.setLaserPower(new Power(l.power, UNITS.MW), 0, nextLightSource);\n+            nextLightSource++;\n+          }\n+        }\n+\n+        for (Channel c : channels) {\n+          if (c.objectiveID != null && !usedObjectiveIDs.contains(c.objectiveID)) {\n+            int index = usedObjectiveIDs.size();\n+            String objectiveID = MetadataTools.createLSID(\"Objective\", 0, index);\n+            store.setObjectiveID(objectiveID, 0, index);\n+            store.setObjectiveModel(c.objective, 0, index);\n+            usedObjectiveIDs.add(c.objectiveID);\n+          }\n+        }\n+      }\n+\n+      for (int i=0; i<getSeriesCount(); i++) {\n+        if (channels != null) {\n+          for (int c=0; c<getSizeC(); c++) {\n+            Plane p = lookupPlane(i, c);\n+            if (p == null) {\n+              // There was likely an error during acquisition for this\n+              // particular plane.  Skip it.\n+              continue;\n+            }\n+            Channel channel = null;\n+            for (Channel ch : channels) {\n+              if (ch.index == p.channel) {\n+                channel = ch;\n+                break;\n+              }\n+            }\n+            if (channel == null) {\n+              continue;\n+            }\n+\n+            if (c == 0) {\n+              store.setPixelsPhysicalSizeX(FormatTools.getPhysicalSizeX(channel.xSize), i);\n+              store.setPixelsPhysicalSizeY(FormatTools.getPhysicalSizeY(channel.xSize), i);\n+            }\n+\n+            int objective = -1;\n+            if (channel.objectiveID != null) {\n+              objective = usedObjectiveIDs.indexOf(channel.objectiveID);\n+            }\n+\n+            if (channel.magnification != null && objective >= 0) {\n+              store.setObjectiveNominalMagnification(channel.magnification, 0, objective);\n+            }\n+            if (objective >= 0) {\n+              String objectiveID = MetadataTools.createLSID(\"Objective\", 0, objective);\n+              store.setObjectiveSettingsID(objectiveID, i);\n+            }\n+\n+            store.setChannelName(\"Channel #\" + (channel.index + 1) + \", Camera #\" + channel.cameraNumber, i, c);\n+\n+            if (channel.color != null) {\n+              store.setChannelColor(channel.color, i, c);\n+            }\n+\n+            if (channel.excitation != null && channel.lightSourceRefs != null) {\n+              int index = -1;\n+              for (int ref=0; ref<channel.lightSourceRefs.size(); ref++) {\n+                int lightSource = channel.lightSourceRefs.get(ref);\n+                if (\"Laser\".equals(lightSources.get(lightSource).type) &&\n+                  lightSources.get(lightSource).wavelength < channel.excitation)\n+                {\n+                  index = lightSource;\n+                }\n+              }\n+              if (index >= 0) {\n+                store.setChannelLightSourceSettingsID(\n+                  MetadataTools.createLSID(\"LightSource\", 0, index), i, c);\n+                store.setChannelExcitationWavelength(\n+                  new Length(channel.excitation, UNITS.NM), i, c);\n+              }\n+            }\n+\n+            if (channel.exposureTime != null) {\n+              Time exposure = new Time(channel.exposureTime, UNITS.MS);\n+              for (int z=0; z<getSizeZ(); z++) {\n+                for (int t=0; t<getSizeT(); t++) {\n+                  int plane = getIndex(z, c, t);\n+                  store.setPlaneExposureTime(exposure, i, plane);\n+                }\n+              }\n+            }\n+          }\n+        }\n+\n+        for (int p=0; p<getImageCount(); p++) {\n+          Plane plane = lookupPlane(i, p);\n+          if (plane == null) {\n+            continue;\n+          }\n+          store.setPlanePositionX(FormatTools.createLength(plane.xpos, UNITS.REFERENCEFRAME), i, p);","path":"components/formats-gpl/src/loci/formats/in/CV7000Reader.java","position":546,"original_position":546,"commit_id":"a49b94b8cab5b135f1fe23f41bb1f6c0b65dbf6a","original_commit_id":"b8960d0063db4acf758846f4f8c7d239d68fb18b","user":{"login":"melissalinkert","id":109998,"node_id":"MDQ6VXNlcjEwOTk5OA==","avatar_url":"https://avatars0.githubusercontent.com/u/109998?v=4","gravatar_id":"","url":"https://api.github.com/users/melissalinkert","html_url":"https://github.com/melissalinkert","followers_url":"https://api.github.com/users/melissalinkert/followers","following_url":"https://api.github.com/users/melissalinkert/following{/other_user}","gists_url":"https://api.github.com/users/melissalinkert/gists{/gist_id}","starred_url":"https://api.github.com/users/melissalinkert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/melissalinkert/subscriptions","organizations_url":"https://api.github.com/users/melissalinkert/orgs","repos_url":"https://api.github.com/users/melissalinkert/repos","events_url":"https://api.github.com/users/melissalinkert/events{/privacy}","received_events_url":"https://api.github.com/users/melissalinkert/received_events","type":"User","site_admin":false},"body":"Noted for follow-up PR: https://trello.com/c/b0nFSUzZ/49-cv7000#comment-5bc498c81ae2b885ae77c111","created_at":"2018-10-15T13:40:38Z","updated_at":"2018-10-15T13:40:39Z","html_url":"https://github.com/openmicroscopy/bioformats/pull/3224#discussion_r225168867","pull_request_url":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/3224","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/comments/225168867"},"html":{"href":"https://github.com/openmicroscopy/bioformats/pull/3224#discussion_r225168867"},"pull_request":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/3224"}},"in_reply_to_id":224841439},"pull_request":{"url":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/3224","id":216057355,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE2MDU3MzU1","html_url":"https://github.com/openmicroscopy/bioformats/pull/3224","diff_url":"https://github.com/openmicroscopy/bioformats/pull/3224.diff","patch_url":"https://github.com/openmicroscopy/bioformats/pull/3224.patch","issue_url":"https://api.github.com/repos/openmicroscopy/bioformats/issues/3224","number":3224,"state":"open","locked":false,"title":"Initial CV7000 reader","user":{"login":"melissalinkert","id":109998,"node_id":"MDQ6VXNlcjEwOTk5OA==","avatar_url":"https://avatars0.githubusercontent.com/u/109998?v=4","gravatar_id":"","url":"https://api.github.com/users/melissalinkert","html_url":"https://github.com/melissalinkert","followers_url":"https://api.github.com/users/melissalinkert/followers","following_url":"https://api.github.com/users/melissalinkert/following{/other_user}","gists_url":"https://api.github.com/users/melissalinkert/gists{/gist_id}","starred_url":"https://api.github.com/users/melissalinkert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/melissalinkert/subscriptions","organizations_url":"https://api.github.com/users/melissalinkert/orgs","repos_url":"https://api.github.com/users/melissalinkert/repos","events_url":"https://api.github.com/users/melissalinkert/events{/privacy}","received_events_url":"https://api.github.com/users/melissalinkert/received_events","type":"User","site_admin":false},"body":"Backported from a bunch of private PRs.  See https://trello.com/c/b0nFSUzZ/238-cv7000\r\n\r\nTo test, use 3 plates in ```/uod/idr/repos/curated/cv7000/glencoe/```.  For each, the ```.wpi``` file is the one to initialize (this is the main metadata file).  The ```DW 0001``` plate has 370 wells - standard 16x24 with D07, E12, H14, H21, I14, I24, J09, J18, K18, L17, L18, M02, P10, and P20 missing.  ```DW 0002``` is a single row (22 wells, H13 and H14 missing) and ```DW 0003``` is a single column (16 wells).  All three are single field, single T, single Z, and 4 channels (```DAPI, 488, 594, mitotracker```).  There are many more plates that cover a wider range of dimensions which could be transferred to ```data_repo```, but this requires coordination due to https://trello.com/c/AJf3bdxa/83-the-slow-death-of-ome-datarepo\r\n\r\nFor each, confirm that ```showinf -nopix -omexml``` shows dimensions that match the description above.  It should be possible to open each series (well), either via ```showinf``` or ImageJ.  The images are 16 bit, and not particularly biologically interesting (all were acquired specifically for testing).\r\n\r\nMemo files will be impacted; may conflict with #3219 and/or #3151.","created_at":"2018-09-17T17:28:48Z","updated_at":"2018-10-15T13:40:39Z","closed_at":null,"merged_at":null,"merge_commit_sha":"952951303a45612d620b38a4b50cdf5c5c9fce55","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":763010002,"node_id":"MDU6TGFiZWw3NjMwMTAwMDI=","url":"https://api.github.com/repos/openmicroscopy/bioformats/labels/reader:new","name":"reader:new","color":"ededed","default":false}],"milestone":{"url":"https://api.github.com/repos/openmicroscopy/bioformats/milestones/64","html_url":"https://github.com/openmicroscopy/bioformats/milestone/64","labels_url":"https://api.github.com/repos/openmicroscopy/bioformats/milestones/64/labels","id":3469491,"node_id":"MDk6TWlsZXN0b25lMzQ2OTQ5MQ==","number":64,"title":"6.0.0","description":"","creator":{"login":"sbesson","id":1355463,"node_id":"MDQ6VXNlcjEzNTU0NjM=","avatar_url":"https://avatars1.githubusercontent.com/u/1355463?v=4","gravatar_id":"","url":"https://api.github.com/users/sbesson","html_url":"https://github.com/sbesson","followers_url":"https://api.github.com/users/sbesson/followers","following_url":"https://api.github.com/users/sbesson/following{/other_user}","gists_url":"https://api.github.com/users/sbesson/gists{/gist_id}","starred_url":"https://api.github.com/users/sbesson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sbesson/subscriptions","organizations_url":"https://api.github.com/users/sbesson/orgs","repos_url":"https://api.github.com/users/sbesson/repos","events_url":"https://api.github.com/users/sbesson/events{/privacy}","received_events_url":"https://api.github.com/users/sbesson/received_events","type":"User","site_admin":false},"open_issues":6,"closed_issues":21,"state":"open","created_at":"2018-07-03T08:31:08Z","updated_at":"2018-10-12T10:46:53Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/3224/commits","review_comments_url":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/3224/comments","review_comment_url":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openmicroscopy/bioformats/issues/3224/comments","statuses_url":"https://api.github.com/repos/openmicroscopy/bioformats/statuses/a49b94b8cab5b135f1fe23f41bb1f6c0b65dbf6a","head":{"label":"melissalinkert:cv7000-develop","ref":"cv7000-develop","sha":"a49b94b8cab5b135f1fe23f41bb1f6c0b65dbf6a","user":{"login":"melissalinkert","id":109998,"node_id":"MDQ6VXNlcjEwOTk5OA==","avatar_url":"https://avatars0.githubusercontent.com/u/109998?v=4","gravatar_id":"","url":"https://api.github.com/users/melissalinkert","html_url":"https://github.com/melissalinkert","followers_url":"https://api.github.com/users/melissalinkert/followers","following_url":"https://api.github.com/users/melissalinkert/following{/other_user}","gists_url":"https://api.github.com/users/melissalinkert/gists{/gist_id}","starred_url":"https://api.github.com/users/melissalinkert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/melissalinkert/subscriptions","organizations_url":"https://api.github.com/users/melissalinkert/orgs","repos_url":"https://api.github.com/users/melissalinkert/repos","events_url":"https://api.github.com/users/melissalinkert/events{/privacy}","received_events_url":"https://api.github.com/users/melissalinkert/received_events","type":"User","site_admin":false},"repo":{"id":2703894,"node_id":"MDEwOlJlcG9zaXRvcnkyNzAzODk0","name":"bioformats","full_name":"melissalinkert/bioformats","private":false,"owner":{"login":"melissalinkert","id":109998,"node_id":"MDQ6VXNlcjEwOTk5OA==","avatar_url":"https://avatars0.githubusercontent.com/u/109998?v=4","gravatar_id":"","url":"https://api.github.com/users/melissalinkert","html_url":"https://github.com/melissalinkert","followers_url":"https://api.github.com/users/melissalinkert/followers","following_url":"https://api.github.com/users/melissalinkert/following{/other_user}","gists_url":"https://api.github.com/users/melissalinkert/gists{/gist_id}","starred_url":"https://api.github.com/users/melissalinkert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/melissalinkert/subscriptions","organizations_url":"https://api.github.com/users/melissalinkert/orgs","repos_url":"https://api.github.com/users/melissalinkert/repos","events_url":"https://api.github.com/users/melissalinkert/events{/privacy}","received_events_url":"https://api.github.com/users/melissalinkert/received_events","type":"User","site_admin":false},"html_url":"https://github.com/melissalinkert/bioformats","description":"Bio-Formats is a Java library for reading and writing data in life sciences image file formats. It is developed by the  Open Microscopy Environment (particularly  UW-Madison LOCI and  Glencoe Software). Bio-Formats is released under the  GNU General Public License (GPL); commercial licenses are available from  Glencoe Software. ","fork":true,"url":"https://api.github.com/repos/melissalinkert/bioformats","forks_url":"https://api.github.com/repos/melissalinkert/bioformats/forks","keys_url":"https://api.github.com/repos/melissalinkert/bioformats/keys{/key_id}","collaborators_url":"https://api.github.com/repos/melissalinkert/bioformats/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/melissalinkert/bioformats/teams","hooks_url":"https://api.github.com/repos/melissalinkert/bioformats/hooks","issue_events_url":"https://api.github.com/repos/melissalinkert/bioformats/issues/events{/number}","events_url":"https://api.github.com/repos/melissalinkert/bioformats/events","assignees_url":"https://api.github.com/repos/melissalinkert/bioformats/assignees{/user}","branches_url":"https://api.github.com/repos/melissalinkert/bioformats/branches{/branch}","tags_url":"https://api.github.com/repos/melissalinkert/bioformats/tags","blobs_url":"https://api.github.com/repos/melissalinkert/bioformats/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/melissalinkert/bioformats/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/melissalinkert/bioformats/git/refs{/sha}","trees_url":"https://api.github.com/repos/melissalinkert/bioformats/git/trees{/sha}","statuses_url":"https://api.github.com/repos/melissalinkert/bioformats/statuses/{sha}","languages_url":"https://api.github.com/repos/melissalinkert/bioformats/languages","stargazers_url":"https://api.github.com/repos/melissalinkert/bioformats/stargazers","contributors_url":"https://api.github.com/repos/melissalinkert/bioformats/contributors","subscribers_url":"https://api.github.com/repos/melissalinkert/bioformats/subscribers","subscription_url":"https://api.github.com/repos/melissalinkert/bioformats/subscription","commits_url":"https://api.github.com/repos/melissalinkert/bioformats/commits{/sha}","git_commits_url":"https://api.github.com/repos/melissalinkert/bioformats/git/commits{/sha}","comments_url":"https://api.github.com/repos/melissalinkert/bioformats/comments{/number}","issue_comment_url":"https://api.github.com/repos/melissalinkert/bioformats/issues/comments{/number}","contents_url":"https://api.github.com/repos/melissalinkert/bioformats/contents/{+path}","compare_url":"https://api.github.com/repos/melissalinkert/bioformats/compare/{base}...{head}","merges_url":"https://api.github.com/repos/melissalinkert/bioformats/merges","archive_url":"https://api.github.com/repos/melissalinkert/bioformats/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/melissalinkert/bioformats/downloads","issues_url":"https://api.github.com/repos/melissalinkert/bioformats/issues{/number}","pulls_url":"https://api.github.com/repos/melissalinkert/bioformats/pulls{/number}","milestones_url":"https://api.github.com/repos/melissalinkert/bioformats/milestones{/number}","notifications_url":"https://api.github.com/repos/melissalinkert/bioformats/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/melissalinkert/bioformats/labels{/name}","releases_url":"https://api.github.com/repos/melissalinkert/bioformats/releases{/id}","deployments_url":"https://api.github.com/repos/melissalinkert/bioformats/deployments","created_at":"2011-11-03T17:54:44Z","updated_at":"2018-07-11T15:47:03Z","pushed_at":"2018-10-15T13:37:30Z","git_url":"git://github.com/melissalinkert/bioformats.git","ssh_url":"git@github.com:melissalinkert/bioformats.git","clone_url":"https://github.com/melissalinkert/bioformats.git","svn_url":"https://github.com/melissalinkert/bioformats","homepage":"http://www.openmicroscopy.org/site/products/bio-formats","size":273475,"stargazers_count":3,"watchers_count":3,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"gpl-2.0","name":"GNU General Public License v2.0","spdx_id":"GPL-2.0","url":"https://api.github.com/licenses/gpl-2.0","node_id":"MDc6TGljZW5zZTg="},"forks":1,"open_issues":0,"watchers":3,"default_branch":"develop"}},"base":{"label":"openmicroscopy:develop","ref":"develop","sha":"ea3383e996b30b16232e4d863ebb66dcea9ee7b0","user":{"login":"openmicroscopy","id":975861,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk3NTg2MQ==","avatar_url":"https://avatars2.githubusercontent.com/u/975861?v=4","gravatar_id":"","url":"https://api.github.com/users/openmicroscopy","html_url":"https://github.com/openmicroscopy","followers_url":"https://api.github.com/users/openmicroscopy/followers","following_url":"https://api.github.com/users/openmicroscopy/following{/other_user}","gists_url":"https://api.github.com/users/openmicroscopy/gists{/gist_id}","starred_url":"https://api.github.com/users/openmicroscopy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openmicroscopy/subscriptions","organizations_url":"https://api.github.com/users/openmicroscopy/orgs","repos_url":"https://api.github.com/users/openmicroscopy/repos","events_url":"https://api.github.com/users/openmicroscopy/events{/privacy}","received_events_url":"https://api.github.com/users/openmicroscopy/received_events","type":"Organization","site_admin":false},"repo":{"id":2510503,"node_id":"MDEwOlJlcG9zaXRvcnkyNTEwNTAz","name":"bioformats","full_name":"openmicroscopy/bioformats","private":false,"owner":{"login":"openmicroscopy","id":975861,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk3NTg2MQ==","avatar_url":"https://avatars2.githubusercontent.com/u/975861?v=4","gravatar_id":"","url":"https://api.github.com/users/openmicroscopy","html_url":"https://github.com/openmicroscopy","followers_url":"https://api.github.com/users/openmicroscopy/followers","following_url":"https://api.github.com/users/openmicroscopy/following{/other_user}","gists_url":"https://api.github.com/users/openmicroscopy/gists{/gist_id}","starred_url":"https://api.github.com/users/openmicroscopy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openmicroscopy/subscriptions","organizations_url":"https://api.github.com/users/openmicroscopy/orgs","repos_url":"https://api.github.com/users/openmicroscopy/repos","events_url":"https://api.github.com/users/openmicroscopy/events{/privacy}","received_events_url":"https://api.github.com/users/openmicroscopy/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/openmicroscopy/bioformats","description":"Bio-Formats is a Java library for reading and writing data in life sciences image file formats. It is developed by the  Open Microscopy Environment. Bio-Formats is released under the  GNU General Public License (GPL); commercial licenses are available from  Glencoe Software. ","fork":false,"url":"https://api.github.com/repos/openmicroscopy/bioformats","forks_url":"https://api.github.com/repos/openmicroscopy/bioformats/forks","keys_url":"https://api.github.com/repos/openmicroscopy/bioformats/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openmicroscopy/bioformats/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openmicroscopy/bioformats/teams","hooks_url":"https://api.github.com/repos/openmicroscopy/bioformats/hooks","issue_events_url":"https://api.github.com/repos/openmicroscopy/bioformats/issues/events{/number}","events_url":"https://api.github.com/repos/openmicroscopy/bioformats/events","assignees_url":"https://api.github.com/repos/openmicroscopy/bioformats/assignees{/user}","branches_url":"https://api.github.com/repos/openmicroscopy/bioformats/branches{/branch}","tags_url":"https://api.github.com/repos/openmicroscopy/bioformats/tags","blobs_url":"https://api.github.com/repos/openmicroscopy/bioformats/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openmicroscopy/bioformats/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openmicroscopy/bioformats/git/refs{/sha}","trees_url":"https://api.github.com/repos/openmicroscopy/bioformats/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openmicroscopy/bioformats/statuses/{sha}","languages_url":"https://api.github.com/repos/openmicroscopy/bioformats/languages","stargazers_url":"https://api.github.com/repos/openmicroscopy/bioformats/stargazers","contributors_url":"https://api.github.com/repos/openmicroscopy/bioformats/contributors","subscribers_url":"https://api.github.com/repos/openmicroscopy/bioformats/subscribers","subscription_url":"https://api.github.com/repos/openmicroscopy/bioformats/subscription","commits_url":"https://api.github.com/repos/openmicroscopy/bioformats/commits{/sha}","git_commits_url":"https://api.github.com/repos/openmicroscopy/bioformats/git/commits{/sha}","comments_url":"https://api.github.com/repos/openmicroscopy/bioformats/comments{/number}","issue_comment_url":"https://api.github.com/repos/openmicroscopy/bioformats/issues/comments{/number}","contents_url":"https://api.github.com/repos/openmicroscopy/bioformats/contents/{+path}","compare_url":"https://api.github.com/repos/openmicroscopy/bioformats/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openmicroscopy/bioformats/merges","archive_url":"https://api.github.com/repos/openmicroscopy/bioformats/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openmicroscopy/bioformats/downloads","issues_url":"https://api.github.com/repos/openmicroscopy/bioformats/issues{/number}","pulls_url":"https://api.github.com/repos/openmicroscopy/bioformats/pulls{/number}","milestones_url":"https://api.github.com/repos/openmicroscopy/bioformats/milestones{/number}","notifications_url":"https://api.github.com/repos/openmicroscopy/bioformats/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openmicroscopy/bioformats/labels{/name}","releases_url":"https://api.github.com/repos/openmicroscopy/bioformats/releases{/id}","deployments_url":"https://api.github.com/repos/openmicroscopy/bioformats/deployments","created_at":"2011-10-04T08:06:14Z","updated_at":"2018-10-12T10:46:58Z","pushed_at":"2018-10-15T13:37:32Z","git_url":"git://github.com/openmicroscopy/bioformats.git","ssh_url":"git@github.com:openmicroscopy/bioformats.git","clone_url":"https://github.com/openmicroscopy/bioformats.git","svn_url":"https://github.com/openmicroscopy/bioformats","homepage":"https://www.openmicroscopy.org/bio-formats","size":269839,"stargazers_count":161,"watchers_count":161,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":173,"mirror_url":null,"archived":false,"open_issues_count":50,"license":{"key":"gpl-2.0","name":"GNU General Public License v2.0","spdx_id":"GPL-2.0","url":"https://api.github.com/licenses/gpl-2.0","node_id":"MDc6TGljZW5zZTg="},"forks":173,"open_issues":50,"watchers":161,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/3224"},"html":{"href":"https://github.com/openmicroscopy/bioformats/pull/3224"},"issue":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/issues/3224"},"comments":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/issues/3224/comments"},"review_comments":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/3224/comments"},"review_comment":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/pulls/3224/commits"},"statuses":{"href":"https://api.github.com/repos/openmicroscopy/bioformats/statuses/a49b94b8cab5b135f1fe23f41bb1f6c0b65dbf6a"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"melissalinkert"}}