From b1a898fa688a85a7eea08c16913cd44de61a9be4 Mon Sep 17 00:00:00 2001 From: cramakri <cramakri> Date: Tue, 5 Jul 2011 11:40:55 +0000 Subject: [PATCH] LMS-2333 Extended API to allow downloading transformed images. SVN: 21978 --- .../v1/IScreeningOpenbisServiceFacade.java | 42 ++++++---- .../api/v1/ScreeningOpenbisServiceFacade.java | 52 ++++++++++++ .../v1/ScreeningOpenbisServiceFacadeTest.java | 84 ++++++++++++++++--- 3 files changed, 151 insertions(+), 27 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 92e8d670cb4..a758ecdd6cf 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 @@ -25,6 +25,7 @@ import ch.systemsx.cisd.base.image.IImageTransformerFactory; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO; +import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.LoadImageConfiguration; import ch.systemsx.cisd.openbis.generic.shared.api.v1.filter.IDataSetFilter; import ch.systemsx.cisd.openbis.generic.shared.api.v1.filter.TypeBasedDataSetFilter; import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.ScreeningOpenbisServiceFacade.IImageOutputStreamProvider; @@ -64,7 +65,7 @@ public interface IScreeningOpenbisServiceFacade /** Closes connection with the server. After calling this method this facade cannot be used. */ public void logout(); - + /** * Removes all images loaded by {@link #loadImageWellCaching(PlateImageReference, ImageSize)} * and {@link #loadThumbnailImageWellCaching(PlateImageReference)} from the image cache, thus @@ -88,7 +89,7 @@ public interface IScreeningOpenbisServiceFacade * Each returned plate has at least one data set with the specified analysis procedure. */ public List<Plate> listPlates(ExperimentIdentifier experiment, String analysisProcedure); - + /** * Return the list of all visible experiments, along with their hierarchical context (space, * project). @@ -126,7 +127,7 @@ public interface IScreeningOpenbisServiceFacade */ public List<FeatureVectorDatasetReference> listFeatureVectorDatasets( List<? extends PlateIdentifier> plates, String analysisProcedureOrNull); - + /** * For a given set of plates provides the list of all connected data sets containing images * which are not segmentation images. @@ -151,7 +152,7 @@ public interface IScreeningOpenbisServiceFacade @Deprecated public List<ImageDatasetReference> listSegmentationImageDatasets( List<? extends PlateIdentifier> plates); - + /** * For a given set of plates provides the list of all connected data sets containing * segmentation images (overlays) and calculated by specified analysis procedure. @@ -211,7 +212,7 @@ public interface IScreeningOpenbisServiceFacade public List<IDataSetDss> getDataSets(WellIdentifier wellIdentifier, String datasetTypeCodePattern) throws IllegalStateException, EnvironmentFailureException; - + /** * Gets proxies to the data sets owned by specified well and passing specified filter.. * @@ -219,10 +220,9 @@ public interface IScreeningOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ - public List<IDataSetDss> getDataSets(WellIdentifier wellIdentifier, - IDataSetFilter dataSetFilter) throws IllegalStateException, - EnvironmentFailureException; - + public List<IDataSetDss> getDataSets(WellIdentifier wellIdentifier, IDataSetFilter dataSetFilter) + throws IllegalStateException, EnvironmentFailureException; + public IDataSetDss getDataSet(String dataSetCode) throws IllegalStateException, EnvironmentFailureException; @@ -267,9 +267,8 @@ public interface IScreeningOpenbisServiceFacade * the server. */ public List<IDataSetDss> getDataSets(PlateIdentifier plateIdentifier, - IDataSetFilter dataSetFilter) throws IllegalStateException, - EnvironmentFailureException; - + IDataSetFilter dataSetFilter) throws IllegalStateException, EnvironmentFailureException; + /** * Upload a new data set to the DSS for a plate. * @@ -440,7 +439,7 @@ public interface IScreeningOpenbisServiceFacade public List<FeatureVectorWithDescription> loadFeaturesForPlateWells( ExperimentIdentifier experimentIdentifer, MaterialIdentifier materialIdentifier, String analysisProcedureOrNull, List<String> featureCodesOrNull); - + /** * For the given <var>materialIdentifier</var> find all plate locations that are connected to it * and load the feature vectors for the given feature code if not <code>null</code>, or all @@ -481,7 +480,7 @@ public interface IScreeningOpenbisServiceFacade public List<FeatureVectorWithDescription> loadFeaturesForPlateWells( MaterialIdentifier materialIdentifier, String analysisProcedureOrNull, List<String> featureCodesOrNull); - + /** * Converts the given <var>WellIdentifiers</var> to <var>WellPositions</var> */ @@ -631,6 +630,19 @@ public interface IScreeningOpenbisServiceFacade public void loadImages(List<PlateImageReference> imageReferences, ImageSize imageSizeOrNull, IPlateImageHandler plateImageHandler) throws IOException; + /** + * Loads images where the desired properties of the images are specified by a + * LoadImageConfiguration. The options and their behavior are described in the + * {@link LoadImageConfiguration} documentation. + * + * @param configuration The configuration of the images to load. + * @param plateImageHandler Handler for the delivered images. + * @see LoadImageConfiguration + */ + public void loadImages(List<PlateImageReference> imageReferences, + LoadImageConfiguration configuration, IPlateImageHandler plateImageHandler) + throws IOException; + /** * Loads the PNG-encoded image for the specified <var>imageReference</var>. * <p> @@ -707,7 +719,7 @@ public interface IScreeningOpenbisServiceFacade public List<PlateWellMaterialMapping> listPlateMaterialMapping( List<? extends PlateIdentifier> plates, MaterialTypeIdentifier materialTypeIdentifierOrNull); - + /** * Returns an alphabetically sorted list of analysis procedure codes of all data sets of the * specified experiment. 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 6f9fc4d0d10..e78e07db901 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 @@ -37,6 +37,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetO import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwnerType; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO; import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening; +import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.LoadImageConfiguration; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationChangingService; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet; @@ -1686,4 +1687,55 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa } } + public void loadImages(List<PlateImageReference> imageReferences, + final LoadImageConfiguration configuration, final IPlateImageHandler plateImageHandler) + throws IOException + { + plateImageReferencesMultiplexer.process(imageReferences, + new IReferenceHandler<PlateImageReference>() + { + public void handle(DssServiceRpcScreeningHolder dssService, + List<PlateImageReference> references) + { + checkDSSMinimalMinorVersion(dssService, "loadImages", List.class, + LoadImageConfiguration.class); + final InputStream stream = + dssService.getService().loadImages(sessionToken, references, + configuration); + try + { + final ConcatenatedFileOutputStreamWriter imagesWriter = + new ConcatenatedFileOutputStreamWriter(stream); + int index = 0; + long size; + do + { + final ByteArrayOutputStream outputStream = + new ByteArrayOutputStream(); + size = imagesWriter.writeNextBlock(outputStream); + if (size > 0) + { + plateImageHandler.handlePlateImage(references.get(index), + outputStream.toByteArray()); + } + index++; + } while (size >= 0); + } catch (IOException ex) + { + throw new WrappedIOException(ex); + } finally + { + try + { + stream.close(); + } catch (IOException ex) + { + throw new WrappedIOException(ex); + } + } + + } + }); + } + } diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacadeTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacadeTest.java index 7058b3a14ca..41b058e6a37 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacadeTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacadeTest.java @@ -50,6 +50,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetO import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO; import ch.systemsx.cisd.openbis.dss.screening.server.DssServiceRpcScreening; import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening; +import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.LoadImageConfiguration; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationChangingService; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet; @@ -629,8 +630,8 @@ public class ScreeningOpenbisServiceFacadeTest extends AbstractFileSystemTestCas new ImageDatasetReference(DATA_SET1, null, URL1, plate, null, null, null, properties, null); final ImageDatasetReference r2 = - new ImageDatasetReference(DATA_SET2, null, URL2, plate, null, null, null, - null, null); + new ImageDatasetReference(DATA_SET2, null, URL2, plate, null, null, null, null, + null); context.checking(new Expectations() { { @@ -639,27 +640,28 @@ public class ScreeningOpenbisServiceFacadeTest extends AbstractFileSystemTestCas } }); - List<ImageDatasetReference> dataSets = facade.listSegmentationImageDatasets(plates, "AP-42"); + List<ImageDatasetReference> dataSets = + facade.listSegmentationImageDatasets(plates, "AP-42"); assertSame(r1, dataSets.get(0)); assertEquals(1, dataSets.size()); context.assertIsSatisfied(); } - + @Test public void testListSegmentationImageDataSetsWithUnspecifiedAnalysisProcedure() { final Plate plate = - new Plate("p1", "s", "s-12", new ExperimentIdentifier("e", "p1", "s", "e-13")); + new Plate("p1", "s", "s-12", new ExperimentIdentifier("e", "p1", "s", "e-13")); final List<Plate> plates = Arrays.asList(plate); HashMap<String, String> properties = new HashMap<String, String>(); properties.put(ScreeningConstants.ANALYSIS_PROCEDURE, "AP-42"); final ImageDatasetReference r1 = - new ImageDatasetReference(DATA_SET1, null, URL1, plate, null, null, null, - properties, null); + new ImageDatasetReference(DATA_SET1, null, URL1, plate, null, null, null, + properties, null); final ImageDatasetReference r2 = - new ImageDatasetReference(DATA_SET2, null, URL2, plate, null, null, null, - null, null); + new ImageDatasetReference(DATA_SET2, null, URL2, plate, null, null, null, null, + null); context.checking(new Expectations() { { @@ -667,15 +669,15 @@ public class ScreeningOpenbisServiceFacadeTest extends AbstractFileSystemTestCas will(returnValue(Arrays.asList(r1, r2))); } }); - + List<ImageDatasetReference> dataSets = facade.listSegmentationImageDatasets(plates, null); - + assertSame(r1, dataSets.get(0)); assertSame(r2, dataSets.get(1)); assertEquals(2, dataSets.size()); context.assertIsSatisfied(); } - + @Test public void testListPlateWells() { @@ -740,6 +742,64 @@ public class ScreeningOpenbisServiceFacadeTest extends AbstractFileSystemTestCas context.assertIsSatisfied(); } + @Test + public void testLoadImagesUsingConfiguration() throws IOException + { + final LoadImageConfiguration config = new LoadImageConfiguration(); + config.setDesiredImageFormatPng(true); + + final PlateImageReference r1 = new PlateImageReference(1, 2, 1, "c1", i1id); + final PlateImageReference r2 = new PlateImageReference(12, 22, 1, "c1", i2id); + final ByteArrayOutputStream stream1 = new ByteArrayOutputStream(); + final ByteArrayOutputStream stream2 = new ByteArrayOutputStream(); + context.checking(new Expectations() + { + { + one(dssService1).loadImages(SESSION_TOKEN, Arrays.asList(r1), config); + ConcatenatedContentInputStream s1 = + new ConcatenatedContentInputStream(true, Arrays + .<IContent> asList(new ByteArrayBasedContent("hello 1" + .getBytes(), "h1"))); + will(returnValue(s1)); + + one(dssService2).loadImages(SESSION_TOKEN, Arrays.asList(r2), config); + ConcatenatedContentInputStream s2 = + new ConcatenatedContentInputStream(true, Arrays + .<IContent> asList(new ByteArrayBasedContent("hello 2" + .getBytes(), "h2"))); + will(returnValue(s2)); + } + }); + + IPlateImageHandler handler = new IPlateImageHandler() + { + + public void handlePlateImage(PlateImageReference plateImageReference, + byte[] imageFileBytes) + { + + try + { + if (r1.equals(plateImageReference)) + { + stream1.write(imageFileBytes); + } else if (r2.equals(plateImageReference)) + { + stream2.write(imageFileBytes); + } + } catch (IOException ex) + { + ex.printStackTrace(); + } + } + }; + facade.loadImages(Arrays.asList(r1, r2), config, handler); + + assertEquals("hello 1", stream1.toString()); + assertEquals("hello 2", stream2.toString()); + context.assertIsSatisfied(); + } + @Test public void testListImageMetaData() { -- GitLab