From 5f8e95e446c1a489f0d98c6b1a753e94e1383524 Mon Sep 17 00:00:00 2001
From: cramakri <cramakri>
Date: Tue, 10 Apr 2012 11:48:25 +0000
Subject: [PATCH] LMS-2875 Initial test

SVN: 24845
---
 .../bPLATE_wA1_s1_cRGB.png                    | Bin 0 -> 13062 bytes
 .../data-set-handler.py                       | 150 +++++++++++++++++
 .../etl/AbstractImageStorageProcessor.java    |   7 +-
 .../TransformedImageRepresentationsTest.java  | 158 ++++++++++++++++++
 4 files changed, 311 insertions(+), 4 deletions(-)
 create mode 100644 screening/resource/test-data/TransformedImageRepresentationsTest/TRANSFORMED-THUMB-PLATE/bPLATE_wA1_s1_cRGB.png
 create mode 100644 screening/resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py
 create mode 100644 screening/sourceTest/java/ch/systemsx/cisd/openbis/screening/systemtests/TransformedImageRepresentationsTest.java

diff --git a/screening/resource/test-data/TransformedImageRepresentationsTest/TRANSFORMED-THUMB-PLATE/bPLATE_wA1_s1_cRGB.png b/screening/resource/test-data/TransformedImageRepresentationsTest/TRANSFORMED-THUMB-PLATE/bPLATE_wA1_s1_cRGB.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec584cf9b80a7c13bfb5a06c9a043bd67b806618
GIT binary patch
literal 13062
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

literal 0
HcmV?d00001

diff --git a/screening/resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py b/screening/resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py
new file mode 100644
index 00000000000..74db9b21d85
--- /dev/null
+++ b/screening/resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+
+PLATE_GEOMETRY_PROPERTY_CODE = "$PLATE_GEOMETRY"
+PLATE_GEOMETRY = "384_WELLS_16X24"
+
+"""
+An Jython dropbox for importing HCS image datasets for use by the TransformedImageRepresentationsTest
+
+The folder loaded to the dropbox folder should have the same name as the plate that the data will be attached to.
+"""
+
+import os
+from ch.systemsx.cisd.openbis.dss.etl.dto.api.v1 import SimpleImageDataConfig, ImageMetadata, Location, Channel, ChannelColor, ChannelColorComponent
+from ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto import Geometry
+from ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.transformations import ImageTransformationBuffer
+from ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.thumbnails import ResolutionBasedThumbnailsConfiguration
+
+  
+class ImageDataSetFlexible(SimpleImageDataConfig):
+  def extractImageMetadata(self, imagePath):
+    """
+    Extracts tile number, channel code and well code for a given relative path to an image.
+    Will be called for each file found in the incoming directory which has the allowed image extension.
+    
+    Example file name: bDZ01-1A_wD17_s3_z123_t321_cGFP
+    Returns:
+      ImageMetadata
+    """
+    image_tokens = ImageMetadata()
+  
+    basename = os.path.splitext(imagePath)[0]
+    # 
+    token_dict = {}
+    for token in basename.split("_"):
+      token_dict[token[:1]] = token[1:]
+    
+    image_tokens.well = token_dict["w"]
+    fieldText = token_dict["s"]
+    try:
+      image_tokens.tileNumber = int(fieldText)
+    except ValueError:
+      raise Exception("Cannot parse field number from '" + fieldText + "' in '" + basename + "' file name.")
+  
+    image_tokens.channelCode = token_dict["c"]
+    return image_tokens
+
+  def getTileGeometry(self, imageTokens, maxTileNumber):
+    """
+    Overrides the default implementation which returns (1, maxTileNumber) geometry.
+  
+    Calculates the width and height of the matrix of tiles (a.k.a. fields or sides) in the well.
+  
+    Parameter imageMetadataList: a list of metadata for each encountered image
+    Parameter maxTileNumber: the biggest tile number among all encountered images
+    Returns:
+      Geometry
+    """
+    return Geometry.createFromRowColDimensions(1, 1);
+  
+  def getTileCoordinates(self, tileNumber, tileGeometry):
+    """
+    Overrides the default implementation which does the same thing (to demonstrate how this can be done). 
+  
+    For a given tile number and tiles geometry returns (x,y) which describes where the tile is
+    located on the well.
+  
+    Parameter tileNumber: number of the tile
+    Parameter tileGeometry: the geometry of the well matrix
+    Returns:
+       Location
+    """
+    columns = tileGeometry.getWidth()
+    row = ((tileNumber - 1) / columns) + 1
+    col = ((tileNumber - 1) % columns) + 1
+    return Location(row, col)
+    
+
+def getAvailableChannelTransformations():
+  """
+  Create a collection of transformations that are applicable to the image
+  """
+  transforms = ImageTransformationBuffer()
+  transforms.appendImageMagicConvert("-edge 1", "Edge detection")
+  transforms.appendImageMagicConvert("-radial-blur 30", "Radial Blur")
+  transforms.appendImageMagicConvert("-blur 3x.7 -solarize 50% -level 50%,0", "Fuzzy")
+  transforms.appendImageMagicConvert("-shade 0x45", "3D 1")
+  transforms.appendImageMagicConvert("-shade 90x60", "3D 2")
+  transforms.appendImageMagicConvert("-blur 0x3 -shade 120x45 -normalize", "3D 3")
+  transforms.appendImageMagicConvert("-motion-blur 0x12+45", "Motion Blur")
+  transforms.appendImageMagicConvert("-fft -delete 1 -auto-level -evaluate log 100000", "FFT")
+  
+  return transforms.getTransformations()
+  
+def create_experiment(tr):
+    space = tr.createNewSpace("TEST", "etlserver")
+    project = tr.createNewProject("/TEST/TEST-PROJECT")
+    expid = "/TEST/TEST-PROJECT/TRANSFORMED_THUMBNAILS_EXP"
+
+    exp = tr.createNewExperiment(expid, 'SIRNA_HCS')
+    exp.setPropertyValue("DESCRIPTION", "Test experiment")
+        
+    return exp
+
+def create_plate(tr, experiment, plateCode):
+    plateId = "/TEST/" + plateCode
+    plate = tr.createNewSample(plateId, 'PLATE')
+    plate.setPropertyValue(PLATE_GEOMETRY_PROPERTY_CODE, PLATE_GEOMETRY)
+    plate.setExperiment(experiment)
+    
+    wellA1 = tr.createNewSample(plate.getSampleIdentifier() + ":A1", "SIRNA_WELL")
+    wellA1.setContainer(plate)
+
+    wellA2 = tr.createNewSample(plate.getSampleIdentifier() + ":A2", "SIRNA_WELL")
+    wellA2.setContainer(plate)
+    
+    return plate
+
+      
+if incoming.isDirectory(): 
+  tr = service.transaction()
+  experiment = create_experiment(tr)
+  plate = create_plate(tr, experiment, 'TRANSFORMED-THUMB-PLATE')
+  tr.commit()
+  
+  
+  imageDataset = ImageDataSetFlexible()
+  imageDataset.setRawImageDatasetType()
+  imageDataset.setPlate("TEST", 'TRANSFORMED-THUMB-PLATE')
+  transforms = getAvailableChannelTransformations()
+  # We want thumbnails generarted for the following resolutions, and they should be JPEG and have the
+  # Radial Blur transform applied
+  for resolution in ['64x64', '128x128', '256x256']:
+    representation = imageDataset.addGeneratedImageRepresentationWithResolution(resolution)
+    for channel in ["DAPI", "GFP", "Cy5"]:
+      representation.setTransformation(channel, transforms[1].getCode())
+    storageFormat = representation.getThumbnailsStorageFormat(imageDataset)
+    storageFormat.setFileFormat('JPEG')
+
+  imageRegistrationDetails = factory.createImageRegistrationDetails(imageDataset, incoming)
+  datasetInfo = imageRegistrationDetails.getDataSetInformation()
+  channels = [ Channel(code, code) for code in ["DAPI", "GFP", "Cy5"]]
+  colorComponents = [ ChannelColorComponent.BLUE, ChannelColorComponent.GREEN, ChannelColorComponent.RED]
+  
+  # Add transforms to the channels
+  for channel in channels:
+    channel.setAvailableTransformations(transforms)
+  
+  datasetInfo.setChannels(channels, colorComponents)
+  
+  factory.registerImageDataset(imageRegistrationDetails, incoming, service)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageStorageProcessor.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageStorageProcessor.java
index c639f8cbf66..67099adfe53 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageStorageProcessor.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageStorageProcessor.java
@@ -665,10 +665,9 @@ abstract class AbstractImageStorageProcessor extends AbstractStorageProcessor im
         ImageDataSetStructure imageDataSetStructure = dataSetInformation.getImageDataSetStructure();
         if (imageDataSetStructure.isValid() == false)
         {
-            throw ConfigurationFailureException
-                    .fromTemplate("Invalid image dataset info object, check if your jython script fills all the required fields. "
-                            + "Or maybe the recognized files extensions is set incorrectly? Dataset: "
-                            + imageDataSetStructure);
+            throw new ConfigurationFailureException("Invalid image dataset info object, check if your jython script fills all the required fields. "
+                    + "Or maybe the recognized files extensions is set incorrectly? Dataset: "
+                    + imageDataSetStructure);
         }
         Geometry tileGeometry =
                 new Geometry(imageDataSetStructure.getTileRowsNumber(),
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/screening/systemtests/TransformedImageRepresentationsTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/screening/systemtests/TransformedImageRepresentationsTest.java
new file mode 100644
index 00000000000..4e2310cdfbb
--- /dev/null
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/screening/systemtests/TransformedImageRepresentationsTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.screening.systemtests;
+
+import static ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil.OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.common.servlet.SpringRequestContextProvider;
+import ch.systemsx.cisd.etlserver.DefaultStorageProcessor;
+import ch.systemsx.cisd.openbis.dss.etl.PlateStorageProcessor;
+import ch.systemsx.cisd.openbis.dss.etl.jython.JythonPlateDataSetHandler;
+import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.IScreeningOpenbisServiceFacade;
+import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.ScreeningOpenbisServiceFacade;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientService;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.ResourceNames;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.IScreeningApiServer;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.DatasetImageRepresentationFormats;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ImageDatasetReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ImageRepresentationFormat;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+@Test(groups =
+    { "slow", "systemtest" })
+public class TransformedImageRepresentationsTest extends AbstractScreeningSystemTestCase
+{
+    private MockHttpServletRequest request;
+
+    private String sessionToken;
+
+    private IScreeningClientService screeningClientService;
+
+    private IScreeningApiServer screeningServer;
+
+    private IScreeningOpenbisServiceFacade screeningFacade;
+
+    @Override
+    protected void setUpTestThread()
+    {
+        setUpTestThread(JythonPlateDataSetHandler.class, PlateStorageProcessor.class,
+                getTestDataFolder() + "data-set-handler.py");
+
+        System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX
+                + "dss-system-test-thread.storage-processor.processor", DefaultStorageProcessor.class.getName());
+        System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX
+                + "dss-system-test-thread.storage-processor.data-source", "imaging-db");
+    }
+
+    @BeforeMethod
+    public void setUp() throws Exception
+    {
+        screeningClientService =
+                (IScreeningClientService) applicationContext
+                        .getBean(ResourceNames.SCREENING_PLUGIN_SERVICE);
+        request = new MockHttpServletRequest();
+        ((SpringRequestContextProvider) applicationContext.getBean("request-context-provider"))
+                .setRequest(request);
+        Object bean = applicationContext.getBean(ResourceNames.SCREENING_PLUGIN_SERVER);
+        screeningServer = (IScreeningApiServer) bean;
+        sessionToken = screeningClientService.tryToLogin("admin", "a").getSessionID();
+        screeningFacade = ScreeningOpenbisServiceFacade.tryCreateForTest(sessionToken, "http://localhost:" + SYSTEM_TEST_CASE_SERVER_PORT, screeningServer);
+    }
+
+    @AfterMethod
+    public void tearDown()
+    {
+        File[] files = getIncomingDirectory().listFiles();
+        for (File file : files)
+        {
+            FileUtilities.deleteRecursively(file);
+        }
+    }
+
+    @Test
+    public void testTransformedThumbnails() throws Exception
+    {
+        dropAnExampleDataSet();
+        // The components of the plate identifier come from the dropbox code
+        // (resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py)
+        PlateIdentifier plate = new PlateIdentifier("TRANSFORMED-THUMB-PLATE", "TEST", null);
+        List<ImageDatasetReference> imageDataSets = screeningFacade.listRawImageDatasets(Arrays.asList(plate));
+        List<DatasetImageRepresentationFormats> representationFormats = screeningFacade.listAvailableImageRepresentationFormats(imageDataSets);
+        assertEquals(1, representationFormats.size());
+        List<ImageRepresentationFormat> formats = representationFormats.get(0).getImageRepresentationFormats();
+
+        HashSet<Dimension> expectedResolutions = new HashSet<Dimension>();
+        expectedResolutions.addAll(Arrays.asList(new Dimension(64, 64), new Dimension(128, 128), new Dimension(256, 256), new Dimension(512, 512)));
+        for (ImageRepresentationFormat format : formats)
+        {
+            Dimension resolution = new Dimension(format.getWidth(), format.getHeight());
+            // Make sure the resolution we specified was found
+            assertTrue("" + resolution + " was not expected", expectedResolutions.remove(resolution));
+        }
+        assertEquals(0, expectedResolutions.size());
+
+        System.err.println(representationFormats);
+    }
+
+    private void dropAnExampleDataSet() throws IOException, Exception
+    {
+        File exampleDataSet = createTestDataContents();
+        moveFileToIncoming(exampleDataSet);
+        waitUntilDataSetImported();
+    }
+
+    private File createTestDataContents() throws IOException
+    {
+        File dest = new File(workingDirectory, "test-data");
+        dest.mkdirs();
+        File src = new File(getTestDataFolder(), "TRANSFORMED-THUMB-PLATE");
+
+        // Copy the test data set to the location for processing
+        FileUtils.copyDirectory(src, dest);
+        return dest;
+    }
+
+    private String getTestDataFolder()
+    {
+        return "../screening/resource/test-data/" + getClass().getSimpleName() + "/";
+    }
+
+    @Override
+    protected int dataSetImportWaitDurationInSeconds()
+    {
+        return 60;
+    }
+
+}
-- 
GitLab