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