From 86375d3711eb8bc6360a712822e5bc50153c1b4c Mon Sep 17 00:00:00 2001
From: brinn <brinn>
Date: Thu, 3 Feb 2011 21:21:26 +0000
Subject: [PATCH] [LMS-2044] HCS: Change Data Set Types [LMS-2040] Screening:
 Provide Overlay data sets via the API

SVN: 19745
---
 .../v1/IScreeningOpenbisServiceFacade.java    |  18 ++-
 .../client/api/v1/ScreeningClientApiTest.java |   2 +-
 .../api/v1/ScreeningClientApiTester.java      |   2 +-
 .../api/v1/ScreeningOpenbisServiceFacade.java |  34 +++++-
 .../screening/server/ScreeningServer.java     |  12 ++
 .../server/ScreeningServerLogger.java         |  14 +++
 .../server/logic/ImageDatasetLoader.java      |  78 ++++++++++++-
 .../server/logic/ScreeningApiImpl.java        |  12 ++
 .../server/logic/ScreeningUtils.java          | 106 +++++++++++-------
 .../shared/api/v1/IScreeningApiServer.java    |  28 +++++
 .../api/v1/dto/ImageDatasetReference.java     |  30 ++++-
 .../shared/basic/dto/ScreeningConstants.java  |  14 ++-
 .../server/logic/ScreeningApiImplTest.java    | 104 +++++++++++++++++
 13 files changed, 404 insertions(+), 50 deletions(-)

diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java
index 603f95e69aa..2ad934bd649 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java
@@ -91,10 +91,26 @@ public interface IScreeningOpenbisServiceFacade
             List<? extends PlateIdentifier> plates);
 
     /**
-     * For a given set of plates provides the list of all connected data sets containing images.
+     * For a given set of plates provides the list of all connected data sets containing images
+     * which are not segmentation images.
+     * 
+     * @deprecated Use {@link #listRawImageDatasets(List)} instead.
      */
+    @Deprecated
     public List<ImageDatasetReference> listImageDatasets(List<? extends PlateIdentifier> plates);
 
+    /**
+     * For a given set of plates provides the list of all connected data sets containing raw images.
+     */
+    public List<ImageDatasetReference> listRawImageDatasets(List<? extends PlateIdentifier> plates);
+
+    /**
+     * For a given set of plates provides the list of all connected data sets containing
+     * segmentation images (overlays).
+     */
+    public List<ImageDatasetReference> listSegmentationImageDatasets(
+            List<? extends PlateIdentifier> plates);
+
     /**
      * For the given <var>experimentIdentifier</var> find all plate locations that are connected to
      * the specified <var>materialIdentifier</var>. If <code>findDatasets == true</code>, find also
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTest.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTest.java
index fab871c1ff6..2956248f31f 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTest.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTest.java
@@ -114,7 +114,7 @@ public class ScreeningClientApiTest
 
         List<Plate> plates = facade.listPlates();
         print("Plates: " + plates);
-        List<ImageDatasetReference> imageDatasets = facade.listImageDatasets(plates);
+        List<ImageDatasetReference> imageDatasets = facade.listRawImageDatasets(plates);
         Collections.sort(imageDatasets, new Comparator<ImageDatasetReference>()
             {
                 public int compare(ImageDatasetReference r1, ImageDatasetReference r2)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTester.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTester.java
index 6caade42116..135f28e0036 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTester.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTester.java
@@ -220,7 +220,7 @@ public class ScreeningClientApiTester
         private void loadImagesByDataSetCode()
         {
             Form form = new Form(this, "Parameters for Loading Images by Data Set");
-            List<ImageDatasetReference> dataSets = facade.listImageDatasets(facade.listPlates());
+            List<ImageDatasetReference> dataSets = facade.listRawImageDatasets(facade.listPlates());
             List<String> dataSetCodes = new ArrayList<String>();
             for (ImageDatasetReference imageDataset : dataSets)
             {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java
index 044fca2be1c..5c52dbac014 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java
@@ -8,6 +8,7 @@ import java.io.OutputStream;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -264,14 +265,45 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa
     }
 
     /**
-     * For a given set of plates provides the list of all connected data sets containing images.
+     * For a given set of plates provides the list of all connected data sets containing raw images.
+     * 
+     * @deprecated Use {@link #listRawImageDatasets(List)} instead.
      */
+    @Deprecated
     public List<ImageDatasetReference> listImageDatasets(List<? extends PlateIdentifier> plates)
     {
         checkASMinimalMinorVersion("listImageDatasets", List.class);
         return openbisScreeningServer.listImageDatasets(sessionToken, plates);
     }
 
+    /**
+     * For a given set of plates provides the list of all connected data sets containing raw images.
+     */
+    public List<ImageDatasetReference> listRawImageDatasets(List<? extends PlateIdentifier> plates)
+    {
+        if (hasASMethod("listRawImageDatasets", List.class))
+        {
+            return openbisScreeningServer.listRawImageDatasets(sessionToken, plates);
+        } else
+        {
+            checkASMinimalMinorVersion("listImageDatasets", List.class);
+            return openbisScreeningServer.listImageDatasets(sessionToken, plates);
+        }
+    }
+
+    /**
+     * For a given set of plates provides the list of all connected data sets containing images.
+     */
+    public List<ImageDatasetReference> listSegmentationImageDatasets(
+            List<? extends PlateIdentifier> plates)
+    {
+        if (hasASMethod("listSegmentationImageDatasets", List.class))
+        {
+            return openbisScreeningServer.listSegmentationImageDatasets(sessionToken, plates);
+        }
+        return Collections.emptyList();
+    }
+
     /**
      * For the given <var>experimentIdentifier</var> find all plate locations that are connected to
      * the specified <var>materialIdentifier</var>. If <code>findDatasets == true</code>, find also
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
index ccbc902c869..b29383c6c46 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
@@ -244,6 +244,18 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl
         return createScreeningApiImpl(sessionToken).listImageDatasets(plates);
     }
 
+    public List<ImageDatasetReference> listRawImageDatasets(String sessionToken,
+            List<? extends PlateIdentifier> plates)
+    {
+        return createScreeningApiImpl(sessionToken).listRawImageDatasets(plates);
+    }
+
+    public List<ImageDatasetReference> listSegmentationImageDatasets(String sessionToken,
+            List<? extends PlateIdentifier> plates)
+    {
+        return createScreeningApiImpl(sessionToken).listSegmentationImageDatasets(plates);
+    }
+
     public List<PlateWellReferenceWithDatasets> listPlateWells(
             String sessionToken,
             ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIdentifier experimentIdentifer,
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java
index 912bedb6f79..c52278ce06a 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java
@@ -180,6 +180,20 @@ final class ScreeningServerLogger extends AbstractServerLogger implements IScree
         return null;
     }
 
+    public List<ImageDatasetReference> listRawImageDatasets(String sessionToken,
+            List<? extends PlateIdentifier> plates) throws IllegalArgumentException
+    {
+        logAccess(sessionToken, "listRawImageDatasets", "#plates: %s", plates.size());
+        return null;
+    }
+
+    public List<ImageDatasetReference> listSegmentationImageDatasets(String sessionToken,
+            List<? extends PlateIdentifier> plates) throws IllegalArgumentException
+    {
+        logAccess(sessionToken, "listSegmentationImageDatasets", "#plates: %s", plates.size());
+        return null;
+    }
+
     public List<PlateWellReferenceWithDatasets> listPlateWells(
             String sessionToken,
             ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIdentifier experimentIdentifer,
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ImageDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ImageDatasetLoader.java
index 714fb8e8004..5dcd63527f0 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ImageDatasetLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ImageDatasetLoader.java
@@ -55,6 +55,24 @@ class ImageDatasetLoader extends PlateDatasetLoader
         return filterImageDatasets();
     }
 
+    /**
+     * Return the raw image datasets for the specified plates.
+     */
+    private List<ExternalData> getRawImageDatasets()
+    {
+        load();
+        return filterRawImageDatasets();
+    }
+
+    /**
+     * Return the segmentation image datasets (overlays) for the specified plates.
+     */
+    private List<ExternalData> getSegmentationImageDatasets()
+    {
+        load();
+        return filterSegmententationImageDatasets();
+    }
+
     /**
      * Return the image datasets references for the specified plates.
      */
@@ -63,6 +81,22 @@ class ImageDatasetLoader extends PlateDatasetLoader
         return asImageDatasetReferences(getImageDatasets());
     }
 
+    /**
+     * Return the raw image datasets references for the specified plates.
+     */
+    public List<ImageDatasetReference> getRawImageDatasetReferences()
+    {
+        return asImageDatasetReferences(getRawImageDatasets());
+    }
+
+    /**
+     * Return the segmentation image datasets references for the specified plates.
+     */
+    public List<ImageDatasetReference> getSegmentationImageDatasetReferences()
+    {
+        return asImageDatasetReferences(getSegmentationImageDatasets());
+    }
+
     private List<ExternalData> filterImageDatasets()
     {
         List<ExternalData> result = new ArrayList<ExternalData>();
@@ -76,6 +110,32 @@ class ImageDatasetLoader extends PlateDatasetLoader
         return result;
     }
 
+    private List<ExternalData> filterRawImageDatasets()
+    {
+        List<ExternalData> result = new ArrayList<ExternalData>();
+        for (ExternalData externalData : getDatasets())
+        {
+            if (ScreeningUtils.isRawHcsImageDataset(externalData))
+            {
+                result.add(externalData);
+            }
+        }
+        return result;
+    }
+
+    private List<ExternalData> filterSegmententationImageDatasets()
+    {
+        List<ExternalData> result = new ArrayList<ExternalData>();
+        for (ExternalData externalData : getDatasets())
+        {
+            if (ScreeningUtils.isSegmentationHcsImageDataset(externalData))
+            {
+                result.add(externalData);
+            }
+        }
+        return result;
+    }
+
     private List<ImageDatasetReference> asImageDatasetReferences(List<ExternalData> imageDatasets)
     {
         List<ImageDatasetReference> references = new ArrayList<ImageDatasetReference>();
@@ -86,12 +146,28 @@ class ImageDatasetLoader extends PlateDatasetLoader
         return references;
     }
 
+    private ExternalData tryGetParent(ExternalData externalData)
+    {
+        if (externalData.getParents() != null && externalData.getParents().size() == 1)
+        {
+            return externalData.getParents().iterator().next();
+        } else
+        {
+            return null;
+        }
+    }
+
     protected ImageDatasetReference asImageDataset(ExternalData externalData)
     {
+        if (externalData == null || ScreeningUtils.isHcsImageDataset(externalData) == false)
+        {
+            return null;
+        }
         DataStore dataStore = externalData.getDataStore();
         return new ImageDatasetReference(externalData.getCode(),
                 getDataStoreUrlFromDataStore(dataStore), createPlateIdentifier(externalData),
                 createExperimentIdentifier(externalData), extractPlateGeometry(externalData),
-                externalData.getRegistrationDate(), extractProperties(externalData));
+                externalData.getRegistrationDate(), extractProperties(externalData),
+                asImageDataset(tryGetParent(externalData)));
     }
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
index 6a14234f7b6..e6d6a54029b 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
@@ -125,6 +125,18 @@ public class ScreeningApiImpl
                 session.tryGetHomeGroupCode(), plates).getImageDatasetReferences();
     }
 
+    public List<ImageDatasetReference> listRawImageDatasets(List<? extends PlateIdentifier> plates)
+    {
+        return new ImageDatasetLoader(session, businessObjectFactory,
+                session.tryGetHomeGroupCode(), plates).getRawImageDatasetReferences();
+    }
+
+    public List<ImageDatasetReference> listSegmentationImageDatasets(List<? extends PlateIdentifier> plates)
+    {
+        return new ImageDatasetLoader(session, businessObjectFactory,
+                session.tryGetHomeGroupCode(), plates).getSegmentationImageDatasetReferences();
+    }
+
     public List<Plate> listPlates()
     {
         final ISampleLister sampleLister = businessObjectFactory.createSampleLister(session);
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningUtils.java
index aef25719c48..a47b4f94216 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningUtils.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningUtils.java
@@ -72,67 +72,57 @@ public class ScreeningUtils
     public static <T extends DataPE> List<T> filterImageOverlayDatasets(Collection<T> datasets)
     {
         return filterDatasetsByTypePattern(datasets,
-                ScreeningConstants.IMAGE_OVERLAY_DATASET_TYPE_PATTERN);
+                ScreeningConstants.IMAGE_OVERLAY_DATASET_TYPE_PATTERN,
+                ScreeningConstants.HCS_SEGMENTATION_IMAGE_DATASET_TYPE_PATTERN);
     }
 
-    /** excludes overlays even if they match to the image dataset pattern */
+    /** excludes overlay image data sets even when they match to the image dataset pattern */
     public static List<ExternalDataPE> filterImageDatasets(List<ExternalDataPE> datasets)
     {
-        List<ExternalDataPE> allDatasets = new ArrayList<ExternalDataPE>();
-        List<ExternalDataPE> hcsDatasets =
-                filterDatasetsByTypePattern(datasets,
-                        ScreeningConstants.HCS_IMAGE_DATASET_TYPE_PATTERN);
-        List<ExternalDataPE> micDatasets =
+        List<ExternalDataPE> allDatasets =
                 filterDatasetsByTypePattern(datasets,
+                        ScreeningConstants.HCS_IMAGE_DATASET_TYPE_PATTERN,
                         ScreeningConstants.MICROSCOPY_IMAGE_DATASET_TYPE_PATTERN);
 
-        allDatasets.addAll(hcsDatasets);
-        allDatasets.addAll(micDatasets);
-
         allDatasets =
                 excludeDatasetsByTypePattern(allDatasets,
-                        ScreeningConstants.IMAGE_OVERLAY_DATASET_TYPE_PATTERN);
+                        ScreeningConstants.IMAGE_OVERLAY_DATASET_TYPE_PATTERN,
+                        ScreeningConstants.HCS_SEGMENTATION_IMAGE_DATASET_TYPE_PATTERN);
         return allDatasets;
     }
 
     /** chooses datasets of unknown types */
     public static List<ExternalDataPE> filterUnknownDatasets(List<ExternalDataPE> datasets)
     {
-        List<ExternalDataPE> chosenDatasets = new ArrayList<ExternalDataPE>();
-        for (ExternalDataPE dataset : datasets)
-        {
-            if (isTypeMatching(dataset, ScreeningConstants.HCS_IMAGE_ANALYSIS_DATASET_TYPE_PATTERN) == false
-                    && isTypeMatching(dataset, ScreeningConstants.HCS_IMAGE_DATASET_TYPE_PATTERN) == false
-                    && isTypeMatching(dataset,
-                            ScreeningConstants.MICROSCOPY_IMAGE_DATASET_TYPE_PATTERN) == false
-                    && isTypeMatching(dataset,
-                            ScreeningConstants.IMAGE_OVERLAY_DATASET_TYPE_PATTERN) == false)
-            {
-                chosenDatasets.add(dataset);
-            }
-        }
-        return chosenDatasets;
+        return excludeDatasetsByTypePattern(datasets,
+                ScreeningConstants.HCS_IMAGE_ANALYSIS_DATASET_TYPE_PATTERN,
+                ScreeningConstants.HCS_IMAGE_DATASET_TYPE_PATTERN,
+                ScreeningConstants.HCS_RAW_IMAGE_DATASET_TYPE_PATTERN,
+                ScreeningConstants.HCS_RAW_IMAGE_LEGACY_DATASET_TYPE,
+                ScreeningConstants.IMAGE_OVERLAY_DATASET_TYPE_PATTERN,
+                ScreeningConstants.HCS_SEGMENTATION_IMAGE_DATASET_TYPE_PATTERN,
+                ScreeningConstants.MICROSCOPY_IMAGE_DATASET_TYPE_PATTERN);
     }
 
     private static <T extends DataPE> List<T> excludeDatasetsByTypePattern(List<T> datasets,
-            String datasetTypeCodePattern)
+            String... datasetTypeCodePatterns)
     {
-        return filterDatasetsByTypePattern(datasets, datasetTypeCodePattern, false);
+        return filterDatasetsByTypePattern(datasets, false, datasetTypeCodePatterns);
     }
 
     public static <T extends DataPE> List<T> filterDatasetsByTypePattern(Collection<T> datasets,
-            String datasetTypeCodePattern)
+            String... datasetTypeCodePatterns)
     {
-        return filterDatasetsByTypePattern(datasets, datasetTypeCodePattern, true);
+        return filterDatasetsByTypePattern(datasets, true, datasetTypeCodePatterns);
     }
 
     private static <T extends DataPE> List<T> filterDatasetsByTypePattern(Collection<T> datasets,
-            String datasetTypeCodePattern, boolean shouldMatch)
+            boolean doesMatch, String... datasetTypeCodePatterns)
     {
-        List<T> chosenDatasets = new ArrayList<T>();
+        final List<T> chosenDatasets = new ArrayList<T>();
         for (T dataset : datasets)
         {
-            if (isTypeMatching(dataset, datasetTypeCodePattern) == shouldMatch)
+            if (isOneOfTypesMatching(dataset, datasetTypeCodePatterns) == doesMatch)
             {
                 chosenDatasets.add(dataset);
             }
@@ -140,22 +130,50 @@ public class ScreeningUtils
         return chosenDatasets;
     }
 
+    private static boolean isOneOfTypesMatching(DataPE dataset, String... datasetTypeCodePatterns)
+    {
+        for (String datasetTypeCodePattern : datasetTypeCodePatterns)
+        {
+            if (isTypeMatching(dataset, datasetTypeCodePattern))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static boolean isTypeMatching(DataPE dataset, String datasetTypeCodePattern)
     {
         return dataset.getDataSetType().getCode().matches(datasetTypeCodePattern);
     }
 
-    public static boolean isBasicHcsImageDataset(ExternalData externalData)
+    public static boolean isHcsImageDataset(ExternalData externalData)
     {
-        return ScreeningUtils.isTypeMatching(externalData,
-                ScreeningConstants.HCS_IMAGE_DATASET_TYPE_PATTERN)
-                && isTypeMatching(externalData,
-                        ScreeningConstants.IMAGE_OVERLAY_DATASET_TYPE_PATTERN) == false;
+        return isOneOfTypesMatching(externalData,
+                ScreeningConstants.HCS_IMAGE_DATASET_TYPE_PATTERN,
+                ScreeningConstants.HCS_RAW_IMAGE_DATASET_TYPE_PATTERN,
+                ScreeningConstants.HCS_RAW_IMAGE_LEGACY_DATASET_TYPE,
+                ScreeningConstants.HCS_SEGMENTATION_IMAGE_DATASET_TYPE_PATTERN);
     }
 
-    public static boolean isTypeMatching(ExternalData dataset, String datasetTypeCodePattern)
+    public static boolean isRawHcsImageDataset(ExternalData externalData)
     {
-        return dataset.getDataSetType().getCode().matches(datasetTypeCodePattern);
+        return isTypeMatching(externalData, ScreeningConstants.HCS_RAW_IMAGE_DATASET_TYPE_PATTERN)
+                || ScreeningConstants.HCS_RAW_IMAGE_LEGACY_DATASET_TYPE.equals(externalData
+                        .getDataSetType().getCode());
+    }
+
+    public static boolean isSegmentationHcsImageDataset(ExternalData externalData)
+    {
+        return isOneOfTypesMatching(externalData,
+                ScreeningConstants.IMAGE_OVERLAY_DATASET_TYPE_PATTERN,
+                ScreeningConstants.HCS_SEGMENTATION_IMAGE_DATASET_TYPE_PATTERN);
+    }
+
+    public static boolean isBasicHcsImageDataset(ExternalData externalData)
+    {
+        return isHcsImageDataset(externalData)
+                && isSegmentationHcsImageDataset(externalData) == false;
     }
 
     public static List<ExternalData> filterExternalDataByTypePattern(
@@ -164,7 +182,7 @@ public class ScreeningUtils
         List<ExternalData> chosenDatasets = new ArrayList<ExternalData>();
         for (ExternalData dataset : datasets)
         {
-            if (isTypeMatching(dataset, datasetTypeCodePatterns))
+            if (isOneOfTypesMatching(dataset, datasetTypeCodePatterns))
             {
                 chosenDatasets.add(dataset);
             }
@@ -172,7 +190,13 @@ public class ScreeningUtils
         return chosenDatasets;
     }
 
-    private static boolean isTypeMatching(ExternalData dataset, String... datasetTypeCodePatterns)
+    public static boolean isTypeMatching(ExternalData dataset, String datasetTypeCodePattern)
+    {
+        return dataset.getDataSetType().getCode().matches(datasetTypeCodePattern);
+    }
+
+    private static boolean isOneOfTypesMatching(ExternalData dataset,
+            String... datasetTypeCodePatterns)
     {
         for (String datasetTypeCodePattern : datasetTypeCodePatterns)
         {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/IScreeningApiServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/IScreeningApiServer.java
index 1ac2abf7a39..0201927d04b 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/IScreeningApiServer.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/IScreeningApiServer.java
@@ -141,6 +141,34 @@ public interface IScreeningApiServer extends IRpcService
             @AuthorizationGuard(guardClass = ScreeningPlateListReadOnlyPredicate.class) List<? extends PlateIdentifier> plates)
             throws IllegalArgumentException;
 
+    /**
+     * For a given set of plates provide the list of all data sets containing raw images for each of
+     * these plates.
+     * 
+     * @since 1.6
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    @MinimalMinorVersion(6)
+    List<ImageDatasetReference> listRawImageDatasets(
+            String sessionToken,
+            @AuthorizationGuard(guardClass = ScreeningPlateListReadOnlyPredicate.class) List<? extends PlateIdentifier> plates)
+            throws IllegalArgumentException;
+
+    /**
+     * For a given set of plates provide the list of all data sets containing segmentation images
+     * for each of these plates.
+     * 
+     * @since 1.6
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    @MinimalMinorVersion(6)
+    List<ImageDatasetReference> listSegmentationImageDatasets(
+            String sessionToken,
+            @AuthorizationGuard(guardClass = ScreeningPlateListReadOnlyPredicate.class) List<? extends PlateIdentifier> plates)
+            throws IllegalArgumentException;
+
     /**
      * Converts a given list of dataset codes to dataset identifiers.
      */
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/ImageDatasetReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/ImageDatasetReference.java
index 1a2b6f9d7f0..a6311acb17e 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/ImageDatasetReference.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/ImageDatasetReference.java
@@ -28,25 +28,51 @@ public class ImageDatasetReference extends DatasetReference implements IImageDat
 {
     private static final long serialVersionUID = 1L;
 
+    private final ImageDatasetReference parentImageDatasetReference;
+
     @Deprecated
     public ImageDatasetReference(String datasetCode, String datastoreServerUrl,
             PlateIdentifier plate)
     {
-        super(datasetCode, datastoreServerUrl, plate);
+        this(datasetCode, datastoreServerUrl, plate, null, null, null, null, null);
     }
 
     @Deprecated
     public ImageDatasetReference(String datasetCode, String datastoreServerUrl,
             PlateIdentifier plate, Geometry plateGemoetry, Date registrationDate)
     {
-        super(datasetCode, datastoreServerUrl, plate, plateGemoetry, registrationDate);
+        this(datasetCode, datastoreServerUrl, plate, null, plateGemoetry, registrationDate, null,
+                null);
     }
 
+    @Deprecated
     public ImageDatasetReference(String datasetCode, String datastoreServerUrl,
             PlateIdentifier plate, ExperimentIdentifier experimentIdentifier,
             Geometry plateGemoetry, Date registrationDate, Map<String, String> propertiesOrNull)
+    {
+        this(datasetCode, datastoreServerUrl, plate, experimentIdentifier, plateGemoetry,
+                registrationDate, propertiesOrNull, null);
+    }
+
+    public ImageDatasetReference(String datasetCode, String datastoreServerUrl,
+            PlateIdentifier plate, ExperimentIdentifier experimentIdentifier,
+            Geometry plateGemoetry, Date registrationDate, Map<String, String> propertiesOrNull,
+            ImageDatasetReference parentImageSetsetReference)
     {
         super(datasetCode, datastoreServerUrl, plate, experimentIdentifier, plateGemoetry,
                 registrationDate, propertiesOrNull);
+        this.parentImageDatasetReference = parentImageSetsetReference;
     }
+
+    /**
+     * Returns the image parent dataset of this data set, or <code>null</code>, if this data set
+     * doesn't have a parent image dataset or the server version is too old (&lt; 1.6) to fill it.
+     * 
+     * @since 1.6
+     */
+    public ImageDatasetReference getParentImageDatasetReference()
+    {
+        return parentImageDatasetReference;
+    }
+
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ScreeningConstants.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ScreeningConstants.java
index f7713abe4f4..8d12db8fdf4 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ScreeningConstants.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ScreeningConstants.java
@@ -42,10 +42,20 @@ public class ScreeningConstants
     // type of the dataset which stores plate image overlays
     public static final String IMAGE_OVERLAY_DATASET_TYPE_PATTERN = ".*OVERLAY.*";
 
+    // type of the dataset which stores plate image overlays
+    public static final String HCS_SEGMENTATION_IMAGE_DATASET_TYPE_PATTERN =
+            "HCS_IMAGE_SEGMENTATION.*";
+
+    // Type of the dataset which stores raw plate images.
+    public static final String HCS_RAW_IMAGE_DATASET_TYPE_PATTERN = "HCS_IMAGE_RAW.*";
+
+    // The plain old legacy type for raw image data sets.
+    public static final String HCS_RAW_IMAGE_LEGACY_DATASET_TYPE = "HCS_IMAGE";
+    
     // Type of the dataset which stores plate images.
     // We do not want old analysis data to match to this pattern.
     public static final String HCS_IMAGE_DATASET_TYPE_PATTERN =
-            ".*HCS_IMAGE($|[^_].*|_[^A].*|_A[^N].*|_AN[^A].*)";
+            ".*" + HCS_RAW_IMAGE_LEGACY_DATASET_TYPE + "($|[^_].*|_[^A].*|_A[^N].*|_AN[^A].*)";
 
     public static final String HCS_PLATE_SAMPLE_TYPE_PATTERN = ".*PLATE.*";
 
@@ -80,7 +90,7 @@ public class ScreeningConstants
 
     /** It's discouraged to use this constant. Code of the siRNA material type. */
     public static final String SIRNA_PLUGIN_TYPE_NAME = "SIRNA";
-    
+
     public static final String SIRNA_WELL_TYPE_CODE = "SIRNA_WELL";
 
     /** It's discouraged to use this constant. */
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImplTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImplTest.java
index 82a135cf92d..4b29c5d2238 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImplTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImplTest.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -171,6 +172,7 @@ public class ScreeningApiImplTest extends AbstractServerTestCase
             });
 
         List<ImageDatasetReference> dataSets = screeningApi.listImageDatasets(Arrays.asList(pi1));
+        assertEquals(1, dataSets.size());
         assertEquals("1", dataSets.get(0).getDatasetCode());
         assertEquals(Geometry.createFromRowColDimensions(16, 24), dataSets.get(0)
                 .getPlateGeometry());
@@ -179,7 +181,87 @@ public class ScreeningApiImplTest extends AbstractServerTestCase
         // FIXME this check doesn't work because of space code (as well as 2 other cases below)
         // assertEquals(pi1, dataSets.get(0).getPlate());
         assertEquals(pi1.getPlateCode(), dataSets.get(0).getPlate().getPlateCode());
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testListRawImageDatasets()
+    {
+        final PlateIdentifier pi1 = createSharedPlate("p1");
+        context.checking(new Expectations()
+            {
+                {
+                    one(screeningBOFactory).createSampleLister(SESSION);
+                    will(returnValue(sampleLister));
+                    one(sampleLister).list(with(any(ListOrSearchSampleCriteria.class)));
+                    Sample p1 = plateSample(pi1, "384_WELLS_16X24");
+                    will(returnValue(Arrays.asList(p1)));
+
+                    one(screeningBOFactory).createDatasetLister(SESSION);
+                    will(returnValue(datasetLister));
+                    one(datasetLister).listBySampleIds(with(Arrays.asList((long) 1)));
+                    will(returnValue(Arrays.asList(imageRawDataSet(p1, "1", 1),
+                            imageRawDataSet(p1, "2", 2), imageAnalysisDataSet(p1, "3", 3))));
+                }
+            });
+
+        List<ImageDatasetReference> dataSets =
+                screeningApi.listRawImageDatasets(Arrays.asList(pi1));
+        assertEquals(2, dataSets.size());
+        assertEquals("1", dataSets.get(0).getDatasetCode());
+        assertEquals("2", dataSets.get(1).getDatasetCode());
+        assertEquals(Geometry.createFromRowColDimensions(16, 24), dataSets.get(0)
+                .getPlateGeometry());
+        assertEquals(Geometry.createFromRowColDimensions(16, 24), dataSets.get(1)
+                .getPlateGeometry());
+        assertEquals(new Date(100), dataSets.get(0).getRegistrationDate());
+        assertEquals(new Date(200), dataSets.get(1).getRegistrationDate());
+        assertEquals(SERVER_URL, dataSets.get(0).getDatastoreServerUrl());
+        assertEquals(SERVER_URL, dataSets.get(1).getDatastoreServerUrl());
+        // FIXME this check doesn't work because of space code (as well as 2 other cases below)
+        // assertEquals(pi1, dataSets.get(0).getPlate());
+        assertEquals(pi1.getPlateCode(), dataSets.get(0).getPlate().getPlateCode());
+        assertEquals(pi1.getPlateCode(), dataSets.get(1).getPlate().getPlateCode());
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testListSegmentationImageDatasets()
+    {
+        final PlateIdentifier pi1 = createSharedPlate("p1");
+        context.checking(new Expectations()
+            {
+                {
+                    one(screeningBOFactory).createSampleLister(SESSION);
+                    will(returnValue(sampleLister));
+                    one(sampleLister).list(with(any(ListOrSearchSampleCriteria.class)));
+                    Sample p1 = plateSample(pi1, "384_WELLS_16X24");
+                    will(returnValue(Arrays.asList(p1)));
+
+                    one(screeningBOFactory).createDatasetLister(SESSION);
+                    will(returnValue(datasetLister));
+                    one(datasetLister).listBySampleIds(with(Arrays.asList((long) 1)));
+                    final ExternalData rawImage = imageRawDataSet(p1, "2", 2);
+                    will(returnValue(Arrays.asList(imageDataSet(p1, "1", 1), rawImage,
+                            imageSegmentationDataSet(p1, "3", 3, rawImage),
+                            imageAnalysisDataSet(p1, "4", 4))));
+                }
+            });
+
+        List<ImageDatasetReference> dataSets =
+                screeningApi.listSegmentationImageDatasets(Arrays.asList(pi1));
         assertEquals(1, dataSets.size());
+        assertEquals("3", dataSets.get(0).getDatasetCode());
+        assertEquals(Geometry.createFromRowColDimensions(16, 24), dataSets.get(0)
+                .getPlateGeometry());
+        assertEquals(new Date(300), dataSets.get(0).getRegistrationDate());
+        assertEquals(SERVER_URL, dataSets.get(0).getDatastoreServerUrl());
+        assertEquals("2", dataSets.get(0).getParentImageDatasetReference().getDatasetCode());
+        assertEquals(SERVER_URL, dataSets.get(0).getParentImageDatasetReference()
+                .getDatastoreServerUrl());
+        // FIXME this check doesn't work because of space code (as well as 2 other cases below)
+        // assertEquals(pi1, dataSets.get(0).getPlate());
+        assertEquals(pi1.getPlateCode(), dataSets.get(0).getPlate().getPlateCode());
         context.assertIsSatisfied();
     }
 
@@ -368,6 +450,28 @@ public class ScreeningApiImplTest extends AbstractServerTestCase
         return dataSet;
     }
 
+    private ExternalData imageRawDataSet(Sample sample, String code, long id)
+    {
+        ExternalData dataSet = createDataSet(sample, code, id);
+        dataSet.setDataSetType(dataSetType("HCS_IMAGE_RAW"));
+        dataSet.setExperiment(new Experiment());
+        dataSet.getExperiment().setProject(new Project());
+        dataSet.getExperiment().getProject().setSpace(new Space());
+        return dataSet;
+    }
+
+    private ExternalData imageSegmentationDataSet(Sample sample, String code, long id,
+            ExternalData parent)
+    {
+        ExternalData dataSet = createDataSet(sample, code, id);
+        dataSet.setDataSetType(dataSetType("HCS_IMAGE_SEGMENTATION"));
+        dataSet.setParents(Collections.singleton(parent));
+        dataSet.setExperiment(new Experiment());
+        dataSet.getExperiment().setProject(new Project());
+        dataSet.getExperiment().getProject().setSpace(new Space());
+        return dataSet;
+    }
+
     private ExternalData imageAnalysisDataSet(Sample sample, String code, long id)
     {
         ExternalData dataSet = createDataSet(sample, code, id);
-- 
GitLab