From 62be1a06215075aca040bf6c84a54410682ffc8f Mon Sep 17 00:00:00 2001 From: gpawel <gpawel> Date: Tue, 18 Dec 2012 16:39:04 +0000 Subject: [PATCH] SP-431 SOB-6: Allow custom image scaling of merged images SVN: 27957 --- .../dss/etl/AbsoluteImageReference.java | 16 ++- .../etl/dataaccess/ImagingDatasetLoader.java | 2 +- .../ImageGenerationDescriptionFactory.java | 41 +++++- .../server/images/ImageChannelsUtils.java | 71 +++++++--- .../dto/ImageGenerationDescription.java | 10 ++ .../images/dto/ImageTransformationParams.java | 26 +++- .../detailviewers/ChannelChooser.java | 29 ++-- .../detailviewers/ChannelChooserPanel.java | 126 ++++++++++++++---- .../ChannelWidgetWithListener.java | 7 +- .../MaterialReplicaSummaryComponent.java | 8 +- .../UserDefinedRescalingSettingsDialog.java | 125 ++++++++++++----- .../detailviewers/WellContentDialog.java | 5 +- .../detailviewers/WellSearchGrid.java | 7 +- .../dto/LogicalImageChannelsReference.java | 15 ++- .../detailviewers/image/Image.java | 43 ++++-- .../client/web/public/screening-dictionary.js | 4 +- .../server/logic/HCSImageDatasetLoader.java | 1 + .../ImageSizeFeedingMaintenanceTaskTest.java | 4 +- .../server/images/ImageChannelsUtilsTest.java | 15 ++- .../server/DssServiceRpcScreeningTest.java | 8 +- 20 files changed, 427 insertions(+), 136 deletions(-) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java index 9283687317c..258036cb404 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java @@ -50,6 +50,8 @@ public class AbsoluteImageReference extends AbstractImageReference private String singleChannelTransformationCodeOrNull; + private final String channelCodeOrNull; + /** * @param contentNode is the original content before choosing the color component and the image * ID @@ -58,7 +60,8 @@ public class AbsoluteImageReference extends AbstractImageReference String imageIdOrNull, ColorComponent colorComponentOrNull, RequestedImageSize imageSize, ChannelColorRGB channelColor, ImageTransfomationFactories imageTransfomationFactories, - ImageLibraryInfo imageLibraryOrNull, String singleChannelTransformationCodeOrNull) + ImageLibraryInfo imageLibraryOrNull, String singleChannelTransformationCodeOrNull, + String channelCodeOrNull) { super(imageIdOrNull, colorComponentOrNull); assert imageSize != null : "image size is null"; @@ -71,6 +74,7 @@ public class AbsoluteImageReference extends AbstractImageReference this.imageTransfomationFactories = imageTransfomationFactories; this.imageLibraryOrNull = imageLibraryOrNull; this.singleChannelTransformationCodeOrNull = singleChannelTransformationCodeOrNull; + this.channelCodeOrNull = channelCodeOrNull; } /** @@ -136,16 +140,24 @@ public class AbsoluteImageReference extends AbstractImageReference return channelColor; } + /** + * Returns the applied transformation code + */ public String tryGetSingleChannelTransformationCode() { return singleChannelTransformationCodeOrNull; } + public String tryGetChannelCode() + { + return channelCodeOrNull; + } + public AbsoluteImageReference createWithoutColorComponent() { ColorComponent colorComponent = null; return new AbsoluteImageReference(contentNode, uniqueId, tryGetImageID(), colorComponent, imageSize, channelColor, imageTransfomationFactories, imageLibraryOrNull, - singleChannelTransformationCodeOrNull); + singleChannelTransformationCodeOrNull, null); } } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingDatasetLoader.java index 794d196d34d..0b32b0a2501 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingDatasetLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingDatasetLoader.java @@ -177,7 +177,7 @@ public class ImagingDatasetLoader extends HCSDatasetLoader implements IImagingDa ImageLibraryInfo imageLibrary = tryGetImageLibrary(dataset, useNativeImageLibrary); return new AbsoluteImageReference(contentNode, path, image.getImageID(), colorComponent, imageSize, getColor(channel), imageTransfomationFactories, imageLibrary, - image.tryGetSingleChannelTransformationCode()); + image.tryGetSingleChannelTransformationCode(), channel.getCode()); } private static ChannelColorRGB getColor(ImgChannelDTO channel) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ImageGenerationDescriptionFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ImageGenerationDescriptionFactory.java index 26da2da889b..a750ad7f60e 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ImageGenerationDescriptionFactory.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ImageGenerationDescriptionFactory.java @@ -27,11 +27,13 @@ import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.shared.basic.string.StringUtils; import ch.systemsx.cisd.hcs.Location; import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.DatasetAcquiredImagesReference; import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackReference; import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageGenerationDescription; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants.ImageServletUrlParameters; /** @@ -83,9 +85,44 @@ class ImageGenerationDescriptionFactory String singleChannelTransformationCodeOrNull = request.getParameter(ImageServletUrlParameters.SINGLE_CHANNEL_TRANSFORMATION_CODE_PARAM); + + Map<String, String> transformationsPerChannel = extractTransformationsPerChannel(request); + return new ImageGenerationDescription(channelsToMerge, - singleChannelTransformationCodeOrNull, overlayChannels, sessionId, - thumbnailSizeOrNull); + singleChannelTransformationCodeOrNull, transformationsPerChannel, overlayChannels, + sessionId, thumbnailSizeOrNull); + } + + private static Map<String, String> extractTransformationsPerChannel(HttpServletRequest request) + { + Map<String, String> transformationsPerChannel = new HashMap<String, String>(); + + Enumeration<?> params = request.getParameterNames(); + while (params.hasMoreElements()) + { + String paramName = (String) params.nextElement(); + if (paramName + .startsWith(ScreeningConstants.ImageServletUrlParameters.SINGLE_CHANNEL_TRANSFORMATION_CODE_PARAM)) + { + if (paramName + .equals(ScreeningConstants.ImageServletUrlParameters.SINGLE_CHANNEL_TRANSFORMATION_CODE_PARAM)) + { + continue; + } + + String channelCode = + paramName + .substring(ScreeningConstants.ImageServletUrlParameters.SINGLE_CHANNEL_TRANSFORMATION_CODE_PARAM + .length()); + String transformationCode = request.getParameter(paramName); + if (StringUtils.isNotBlank(transformationCode)) + { + transformationsPerChannel.put(channelCode, transformationCode); + } + } + } + + return transformationsPerChannel; } private static List<DatasetAcquiredImagesReference> getOverlayChannels( diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java index e1b839ff3e4..8f5fb1cac20 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java @@ -23,7 +23,9 @@ import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.log4j.Logger; @@ -119,8 +121,8 @@ public class ImageChannelsUtils RequestedImageSize imageSize = new RequestedImageSize(thumbnailSizeOrNull, false); image = calculateBufferedImage(imageChannels, - params.tryGetSingleChannelTransformationCode(), contentProvider, - imageSize); + params.tryGetSingleChannelTransformationCode(), + params.tryGetTransformationsPerChannel(), contentProvider, imageSize); } RequestedImageSize overlaySize = calcOverlaySize(image, thumbnailSizeOrNull); @@ -158,11 +160,13 @@ public class ImageChannelsUtils createImageChannelsUtils(imagesReference, contentProvider, imageSize, singleChannelTransformationCodeOrNull); boolean mergeAllChannels = utils.isMergeAllChannels(imagesReference); - List<AbsoluteImageReference> imageContents = - utils.fetchImageContents(imagesReference, mergeAllChannels, true); ImageTransformationParams transformationInfo = - new ImageTransformationParams(true, mergeAllChannels, null); - return calculateSingleImagesForDisplay(imageContents, transformationInfo, 0.0f); + new ImageTransformationParams(true, mergeAllChannels, null, + new HashMap<String, String>()); + List<AbsoluteImageReference> imageContents = + utils.fetchImageContents(imagesReference, mergeAllChannels, true, + transformationInfo); + return calculateSingleImagesForDisplay(imageContents, transformationInfo, 0.0f, null); } private static RequestedImageSize getSize(BufferedImage img, boolean highQuality) @@ -203,6 +207,7 @@ public class ImageChannelsUtils private static BufferedImage calculateBufferedImage( DatasetAcquiredImagesReference imageChannels, String singleChannelTransformationCodeOrNull, + Map<String, String> transformationsPerChannels, IHierarchicalContentProvider contentProvider, RequestedImageSize imageSizeLimit) { ImageChannelsUtils imageChannelsUtils = @@ -212,7 +217,7 @@ public class ImageChannelsUtils imageChannelsUtils.isMergeAllChannels(imageChannels); ImageTransformationParams transformationInfo = new ImageTransformationParams(true, useMergedChannelsTransformation, - singleChannelTransformationCodeOrNull); + singleChannelTransformationCodeOrNull, transformationsPerChannels); return imageChannelsUtils.calculateBufferedImage(imageChannels, transformationInfo); } @@ -234,7 +239,7 @@ public class ImageChannelsUtils { boolean mergeAllChannels = isMergeAllChannels(imageChannels); List<AbsoluteImageReference> imageContents = - fetchImageContents(imageChannels, mergeAllChannels, false); + fetchImageContents(imageChannels, mergeAllChannels, false, transformationInfo); return calculateBufferedImage(imageContents, transformationInfo); } @@ -247,10 +252,11 @@ public class ImageChannelsUtils * @param skipNonExisting if true references to non-existing images are ignored, otherwise an * exception is thrown * @param mergeAllChannels true if all existing channel images should be merged + * @param transformationInfo */ private List<AbsoluteImageReference> fetchImageContents( DatasetAcquiredImagesReference imagesReference, boolean mergeAllChannels, - boolean skipNonExisting) + boolean skipNonExisting, ImageTransformationParams transformationInfo) { List<String> channelCodes = imagesReference.getChannelCodes(getAllChannelCodes()); List<AbsoluteImageReference> images = new ArrayList<AbsoluteImageReference>(); @@ -272,7 +278,8 @@ public class ImageChannelsUtils } // Optimization for a case where all channels are on one image - if (mergeAllChannels) + if (mergeAllChannels + && (false == shouldApplySingleChannelsTransformations(transformationInfo))) { AbsoluteImageReference allChannelsImageReference = tryCreateAllChannelsImageReference(images); @@ -285,6 +292,19 @@ public class ImageChannelsUtils return images; } + private boolean shouldApplySingleChannelsTransformations( + ImageTransformationParams transformationInfo) + { + if (transformationInfo == null + || transformationInfo.tryGetTransformationCodeForChannels() == null + || transformationInfo.tryGetTransformationCodeForChannels().size() == 0) + { + return false; + } + + return true; + } + private static IImagingDatasetLoader createImageAccessor( DatasetAcquiredImagesReference imagesReference, IHierarchicalContentProvider contentProvider) @@ -309,7 +329,7 @@ public class ImageChannelsUtils .getRepresentativeImageReferences(wellLocationOrNull); BufferedImage image = calculateBufferedImage(imageReferences, new ImageTransformationParams(true, true, - null)); + null, new HashMap<String, String>())); String name = createFileName(datasetCode, wellLocationOrNull, imageSizeLimitOrNull); return createResponseContentStream(image, name); } @@ -369,17 +389,19 @@ public class ImageChannelsUtils new ImageChannelsUtils(imageLoaderStrategy, imageSizeLimitOrNull, singleChannelImageTransformationCodeOrNull); boolean mergeAllChannels = imageChannelsUtils.isMergeAllChannels(imagesReference); + ImageTransformationParams transformationInfo = + new ImageTransformationParams(transform, mergeAllChannels, + singleChannelImageTransformationCodeOrNull, new HashMap<String, String>()); + List<AbsoluteImageReference> imageContents = - imageChannelsUtils.fetchImageContents(imagesReference, mergeAllChannels, false); + imageChannelsUtils.fetchImageContents(imagesReference, mergeAllChannels, false, + transformationInfo); IHierarchicalContentNode contentNode = tryGetRawContent(convertToPng, imageContents); if (contentNode != null) { return contentNode; } - ImageTransformationParams transformationInfo = - new ImageTransformationParams(transform, mergeAllChannels, - singleChannelImageTransformationCodeOrNull); BufferedImage image = calculateBufferedImage(imageContents, transformationInfo); return createPngContent(image, null); } @@ -541,7 +563,7 @@ public class ImageChannelsUtils { // We do not transform single images here. List<ImageWithReference> images = - calculateSingleImagesForDisplay(imageReferences, null, null); + calculateSingleImagesForDisplay(imageReferences, null, null, transformationInfo); BufferedImage mergedImage = mergeImages(images); // NOTE: even if we are not merging all the channels but just few of them we use the // merged-channel transformation @@ -626,10 +648,12 @@ public class ImageChannelsUtils /** * @param transformationInfoOrNull if null all transformations (including image-level) will be * skipped + * @param transformationInfo */ private static List<ImageWithReference> calculateSingleImagesForDisplay( List<AbsoluteImageReference> imageReferences, - ImageTransformationParams transformationInfoOrNull, Float threshold) + ImageTransformationParams transformationInfoOrNull, Float threshold, + ImageTransformationParams transformationInfoForMergingOrNull) { List<ImageWithReference> images = new ArrayList<ImageWithReference>(); for (AbsoluteImageReference imageRef : imageReferences) @@ -640,6 +664,19 @@ public class ImageChannelsUtils image = calculateAndTransformSingleImageForDisplay(imageRef, transformationInfoOrNull, threshold); + } else if (transformationInfoForMergingOrNull != null + && null != transformationInfoForMergingOrNull + .tryGetTransformationCodeForChannel(imageRef.tryGetChannelCode())) + { + String transformationCode = + transformationInfoForMergingOrNull + .tryGetTransformationCodeForChannel(imageRef.tryGetChannelCode()); + image = + calculateAndTransformSingleImageForDisplay( + imageRef, + new ImageTransformationParams(transformationInfoForMergingOrNull + .isApplyNonImageLevelTransformation(), false, + transformationCode, null), threshold); } else { // NOTE: here we skip image level transformations as well diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/dto/ImageGenerationDescription.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/dto/ImageGenerationDescription.java index 88579d5892f..3cf10a5b86e 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/dto/ImageGenerationDescription.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/dto/ImageGenerationDescription.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.dss.generic.server.images.dto; import java.util.List; +import java.util.Map; import ch.systemsx.cisd.hcs.Location; import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackReference.HCSChannelStackByLocationReference; @@ -34,6 +35,8 @@ public class ImageGenerationDescription private final String singleChannelTransformationCodeOrNull; + private final Map<String, String> transformationsPerChannelOrNull; + private final List<DatasetAcquiredImagesReference> overlayChannels; private final String sessionId; @@ -43,11 +46,13 @@ public class ImageGenerationDescription public ImageGenerationDescription(DatasetAcquiredImagesReference imageChannelsOrNull, String singleChannelTransformationCodeOrNull, + Map<String, String> transformationsPerChannelOrNull, List<DatasetAcquiredImagesReference> overlayChannels, String sessionId, Size thumbnailSizeOrNull) { this.imageChannelsOrNull = imageChannelsOrNull; this.singleChannelTransformationCodeOrNull = singleChannelTransformationCodeOrNull; + this.transformationsPerChannelOrNull = transformationsPerChannelOrNull; this.overlayChannels = overlayChannels; this.sessionId = sessionId; this.thumbnailSizeOrNull = thumbnailSizeOrNull; @@ -63,6 +68,11 @@ public class ImageGenerationDescription return singleChannelTransformationCodeOrNull; } + public Map<String, String> tryGetTransformationsPerChannel() + { + return transformationsPerChannelOrNull; + } + public List<DatasetAcquiredImagesReference> getOverlayChannels() { return overlayChannels; diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/dto/ImageTransformationParams.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/dto/ImageTransformationParams.java index 4450df0b274..bfbcbfdb20c 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/dto/ImageTransformationParams.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/dto/ImageTransformationParams.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.dss.generic.server.images.dto; +import java.util.Map; + /** * Describes which image transformations should be applied. Note that image-level transformation is * always applied for single channels. @@ -35,12 +37,16 @@ public class ImageTransformationParams */ private final String singleChannelTransformationCodeOrNull; + private Map<String, String> transformationsPerChannel; + public ImageTransformationParams(boolean applyNonImageLevelTransformation, - boolean useMergedChannelsTransformation, String singleChannelTransformationCodeOrNull) + boolean useMergedChannelsTransformation, String singleChannelTransformationCodeOrNull, + Map<String, String> transformationsPerChannel) { this.applyNonImageLevelTransformation = applyNonImageLevelTransformation; this.useMergedChannelsTransformation = useMergedChannelsTransformation; this.singleChannelTransformationCodeOrNull = singleChannelTransformationCodeOrNull; + this.transformationsPerChannel = transformationsPerChannel; } public boolean isApplyNonImageLevelTransformation() @@ -57,4 +63,22 @@ public class ImageTransformationParams { return singleChannelTransformationCodeOrNull; } + + public String tryGetTransformationCodeForChannel(String channelCode) + { + if (channelCode == null || transformationsPerChannel == null) + { + return null; + } + return transformationsPerChannel.get(channelCode); + } + + public Map<String, String> tryGetTransformationCodeForChannels() + { + if (transformationsPerChannel == null) + { + return null; + } + return transformationsPerChannel; + } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java index 849d86e9916..9b42e61d8b8 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -53,6 +54,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageResolutio import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.IntensityRange; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.InternalImageChannel; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.InternalImageTransformationInfo; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria.AnalysisProcedureCriteria; /** @@ -95,7 +97,7 @@ class ChannelChooser private String imageTransformationCodeOrNull; - private IntensityRange rangeOrNull; + private Map<String, IntensityRange> rangesOrNull; public ChannelChooser(LogicalImageReference basicImage, IChanneledViewerFactory viewerFactory, IDefaultChannelState defaultChannelState) @@ -109,7 +111,7 @@ class ChannelChooser this.imageTransformationCodeOrNull = tryGetInitialImageTransformationCode(defaultChannelState, basicChannelCodes, basicImage.getImagetParameters()); - this.rangeOrNull = tryGetInitialIntensityRange(defaultChannelState, basicChannelCodes); + this.rangesOrNull = tryGetInitialIntensityRange(defaultChannelState, basicChannelCodes); this.defaultChannelState = defaultChannelState; this.selectedOverlayChannels = new HashSet<ImageDatasetChannel>(); } @@ -126,7 +128,7 @@ class ChannelChooser { LogicalImageChannelsReference state = new LogicalImageChannelsReference(basicImage, basicChannelCodes, - imageTransformationCodeOrNull, rangeOrNull, selectedOverlayChannels); + imageTransformationCodeOrNull, rangesOrNull, selectedOverlayChannels); LayoutContainer view = viewerFactory.create(state, @@ -337,12 +339,12 @@ class ChannelChooser public void selectionChanged(List<String> newlySelectedChannels, @SuppressWarnings("hiding") String imageTransformationCodeOrNull, @SuppressWarnings("hiding") - IntensityRange rangeOrNull) + Map<String, IntensityRange> rangesOrNull) { basicChannelCodes = newlySelectedChannels; ChannelChooser.this.imageTransformationCodeOrNull = imageTransformationCodeOrNull; - ChannelChooser.this.rangeOrNull = rangeOrNull; + ChannelChooser.this.rangesOrNull = rangesOrNull; refresh(); } }); @@ -387,9 +389,10 @@ class ChannelChooser IDefaultChannelState defaultChannelState, List<String> channels, ImageDatasetParameters imageParameters) { - if (imageParameters != null && channels.size() == 1) + if (imageParameters != null) { - String channel = channels.get(0); + String channel = + channels.size() == 1 ? channels.get(0) : ScreeningConstants.MERGED_CHANNELS; String initialTransformation = defaultChannelState.tryGetDefaultTransformation(channel); if (ChannelChooserPanel.DEFAULT_TRANSFORMATION_CODE.equals(initialTransformation)) { @@ -417,17 +420,17 @@ class ChannelChooser return null; } - private static IntensityRange tryGetInitialIntensityRange( + private static Map<String, IntensityRange> tryGetInitialIntensityRange( IDefaultChannelState defaultChannelState, List<String> channels) { - if (channels.size() == 1) + Map<String, IntensityRange> ranges = new HashMap<String, IntensityRange>(); + + for (String channel : channels) { - String channel = channels.get(0); IntensityRange rangeOrNull = defaultChannelState.tryGetIntensityRange(channel); - - return rangeOrNull; + ranges.put(channel, rangeOrNull); } - return null; + return ranges; } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooserPanel.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooserPanel.java index 0012c3edaeb..80f78a9deeb 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooserPanel.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooserPanel.java @@ -74,7 +74,7 @@ public class ChannelChooserPanel extends LayoutContainer public static interface ChannelSelectionListener { void selectionChanged(List<String> channels, String imageTransformationCodeOrNull, - IntensityRange rangeOrNull); + Map<String, IntensityRange> rangesOrNull); } public static final String DEFAULT_TRANSFORMATION_CODE = "$DEFAULT$"; @@ -126,29 +126,37 @@ public class ChannelChooserPanel extends LayoutContainer @Override public void handleEvent(BaseEvent be) { - String channelCode = getSelectedValues().get(0); + List<LabeledItem<String>> channelCodes = getSelectedLabeledValues(); InternalImageTransformationInfo selectedTransformation = transformationsComboBox.getSimpleValue().getItem(); String transformationCode = selectedTransformation.getCode(); - defaultChannelState.setDefaultTransformation(channelCode, transformationCode); + defaultChannelState.setDefaultTransformation(getChannelCode(channelCodes), + transformationCode); changeTransformationSettingsButtonVisibility(true, false); - IntensityRange intensityRange = - defaultChannelState.tryGetIntensityRange(channelCode); + Map<String, IntensityRange> intensityRanges = new HashMap<String, IntensityRange>(); + for (LabeledItem<String> channelCode : channelCodes) + { + intensityRanges.put(channelCode.getItem(), + defaultChannelState.tryGetIntensityRange(channelCode.getItem())); + } notifySelectionListeners(getSelectedValues(), - tryGetSelectedTransformationCode(false), intensityRange); + tryGetSelectedTransformationCode(false), intensityRanges); String updatedTooltip = selectedTransformation.getLabel(); if (ScreeningConstants.USER_DEFINED_RESCALING_CODE .equalsIgnoreCase(transformationCode)) { - updatedTooltip += - " [" - + (intensityRange == null ? "undefined" : intensityRange - .getBlackPoint() - + " - " - + intensityRange.getWhitePoint()) + "]"; - ChannelChooserPanel.this.intensitiesPerChannel.put(channelCode, intensityRange); + /* + * TODO updatedTooltip += " [" + (intensityRange == null ? "undefined" : + * intensityRange .getBlackPoint() + " - " + intensityRange.getWhitePoint()) + + * "]"; + */ + for (Map.Entry<String, IntensityRange> rangeEntry : intensityRanges.entrySet()) + { + ChannelChooserPanel.this.intensitiesPerChannel.put(rangeEntry.getKey(), + rangeEntry.getValue()); + } } transformationsComboBox.setToolTip(updatedTooltip); } @@ -192,7 +200,7 @@ public class ChannelChooserPanel extends LayoutContainer UserDefinedRescalingSettingsDialog dialog = new UserDefinedRescalingSettingsDialog(messageProvider, intensitiesPerChannel, defaultChannelState, - getSelectedValues().get(0)); + getSelectedLabeledValues()); dialog.addListener(Events.OnChange, transformationSelection); dialog.show(); } @@ -207,6 +215,16 @@ public class ChannelChooserPanel extends LayoutContainer updateChannelSelection(selectedChannelsOrNull); } + private final static String getChannelCode(List<LabeledItem<String>> selection) + { + if (selection.size() == 1) + { + return selection.get(0).getItem(); + } + + return ScreeningConstants.MERGED_CHANNELS; + } + private SimpleModelComboBox<String> createChannelsComboBox() { SimpleModelComboBox<String> comboBox = @@ -287,6 +305,50 @@ public class ChannelChooserPanel extends LayoutContainer return channels; } + /** + * @return the current channel selection. If all channels are selected, returns whole list of + * channels. + */ + public List<LabeledItem<String>> getSelectedLabeledValues() + { + LabeledItem<String> comboBoxValue; + if (channelsComboBox.getSelectedIndex() == -1) + { + comboBoxValue = null; + } else + { + comboBoxValue = channelsComboBox.getSimpleValue(); + } + + if (comboBoxValue == null) + { + return Collections.<LabeledItem<String>> emptyList(); + } + if (ScreeningConstants.MERGED_CHANNELS.equals(comboBoxValue.getItem())) + { + // multiple channel selection + return getMergedChannelLabeledSelection(); + } else + { + // single channel selection + return Collections.singletonList(comboBoxValue); + } + } + + private List<LabeledItem<String>> getMergedChannelLabeledSelection() + { + List<LabeledItem<String>> channels = new ArrayList<LabeledItem<String>>(); + for (CheckBox cb : getAllCheckBoxes()) + { + if (cb.getValue() == true) + { + channels.add(new LabeledItem<String>(cb.getValueAttribute(), cb.getBoxLabel())); + } + } + + return channels; + } + private void addChannelsForParameters(ImageDatasetParameters imageParameters) { addChannelToComboBox(new LabeledItem<String>(MERGED_CHANNELS, MERGED_CHANNELS)); @@ -312,6 +374,8 @@ public class ChannelChooserPanel extends LayoutContainer transformationsForChannel.addAll(imageParameters .getAvailableImageTransformationsFor(code)); + intensitiesPerChannel.put(code, defaultChannelState.tryGetIntensityRange(code)); + if (codeAdded) { // also add a checkBockbox for the channel @@ -408,7 +472,7 @@ public class ChannelChooserPanel extends LayoutContainer updateTransformationComboBox(); notifySelectionListeners(selection, tryGetSelectedTransformationCode(false), - tryGetSelectedIntensityRange()); + tryGetSelectedIntensityRanges()); } public String tryGetSelectedTransformationCode(boolean force) @@ -428,16 +492,21 @@ public class ChannelChooserPanel extends LayoutContainer return transformCode(code); } - public IntensityRange tryGetSelectedIntensityRange() + public Map<String, IntensityRange> tryGetSelectedIntensityRanges() { - List<String> selectedValues = getSelectedValues(); - if (selectedValues != null && selectedValues.size() > 0) + List<LabeledItem<String>> selectedValues = getSelectedLabeledValues(); + if (selectedValues != null) { - return intensitiesPerChannel.get(getSelectedValues().get(0)); - } else - { - return null; + Map<String, IntensityRange> ranges = new HashMap<String, IntensityRange>(); + for (LabeledItem<String> channelCode : selectedValues) + { + ranges.put(channelCode.getItem(), intensitiesPerChannel.get(channelCode.getItem())); + } + + return ranges; } + + return null; } private static String transformCode(String code) @@ -452,11 +521,11 @@ public class ChannelChooserPanel extends LayoutContainer } private void notifySelectionListeners(List<String> selection, - String imageTransformationCodeOrNull, IntensityRange rangeOrNull) + String imageTransformationCodeOrNull, Map<String, IntensityRange> rangesOrNull) { for (ChannelSelectionListener listener : channelSelectionListeners) { - listener.selectionChanged(selection, imageTransformationCodeOrNull, rangeOrNull); + listener.selectionChanged(selection, imageTransformationCodeOrNull, rangesOrNull); } } @@ -569,6 +638,15 @@ public class ChannelChooserPanel extends LayoutContainer selectTransformation(selectedValues.get(0)); setTransformationsVisible(true); + } else if (selectedValues.size() > 0) + { + model.add(DEFAULT_TRANSFORMATION); + model.add(convertToLabeledItem(new InternalImageTransformationInfo( + ScreeningConstants.USER_DEFINED_RESCALING_CODE, "User defined", + "User defined intensity rescaling", "", false))); + transformationsComboBox.add(model); + selectTransformation(ScreeningConstants.MERGED_CHANNELS); + setTransformationsVisible(true); } else { setTransformationsVisible(false); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelWidgetWithListener.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelWidgetWithListener.java index 0e83909df37..c7e5615bc47 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelWidgetWithListener.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelWidgetWithListener.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers; import java.util.List; +import java.util.Map; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.google.gwt.user.client.ui.Widget; @@ -40,7 +41,7 @@ public class ChannelWidgetWithListener implements ChannelChooserPanel.ChannelSel interface ISimpleChanneledViewerFactory { Widget create(List<String> channelCodes, String imageTransformationCodeOrNull, - IntensityRange rangeOrNull); + Map<String, IntensityRange> rangesOrNull); } public ChannelWidgetWithListener(final ISimpleChanneledViewerFactory viewerFactory) @@ -56,12 +57,12 @@ public class ChannelWidgetWithListener implements ChannelChooserPanel.ChannelSel @Override public void selectionChanged(List<String> channelNames, String imageTransformationCodeOrNull, - IntensityRange rangeOrNull) + Map<String, IntensityRange> rangesOrNull) { if (channelNames != null) { GuiUtils.replaceLastItem(container, - viewerFactory.create(channelNames, imageTransformationCodeOrNull, rangeOrNull)); + viewerFactory.create(channelNames, imageTransformationCodeOrNull, rangesOrNull)); } } } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/MaterialReplicaSummaryComponent.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/MaterialReplicaSummaryComponent.java index fc2bcda9326..7b1538095b4 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/MaterialReplicaSummaryComponent.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/MaterialReplicaSummaryComponent.java @@ -59,11 +59,11 @@ import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.d import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.utils.PropertiesUtil; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ui.columns.specific.ScreeningLinkExtractor; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetParameters; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.IntensityRange; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria.AnalysisProcedureCriteria; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria.ExperimentSearchCriteria; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.IntensityRange; /** * Component which for a specified material and experiment presents 1. feature vectors (detailed and @@ -347,17 +347,17 @@ public class MaterialReplicaSummaryComponent { @Override public Widget create(List<String> channels, String imageTransformationCodeOrNull, - IntensityRange rangeOrNull) + Map<String, IntensityRange> rangesOrNull) { return WellContentDialog.createImageViewerForChannel(screeningViewContext, image, oneImageSizeFactorPx, channels, imageTransformationCodeOrNull, - rangeOrNull); + rangesOrNull); } }; ChannelWidgetWithListener widgetWithListener = new ChannelWidgetWithListener(viewerFactory); widgetWithListener.selectionChanged(channelChooser.getSelectedValues(), channelChooser.tryGetSelectedTransformationCode(false), - channelChooser.tryGetSelectedIntensityRange()); + channelChooser.tryGetSelectedIntensityRanges()); ImageDatasetParameters imageParameters = image.tryGetImageDataset().getImageParameters(); channelChooser.addSelectionChangedListener(widgetWithListener); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/UserDefinedRescalingSettingsDialog.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/UserDefinedRescalingSettingsDialog.java index 654640cb3a7..dca1d7a9e45 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/UserDefinedRescalingSettingsDialog.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/UserDefinedRescalingSettingsDialog.java @@ -16,6 +16,9 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import com.extjs.gxt.ui.client.event.BaseEvent; @@ -27,6 +30,7 @@ import com.extjs.gxt.ui.client.widget.button.Button; import com.google.gwt.user.client.ui.Grid; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.IntegerField; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.LabeledItem; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.IntensityRange; @@ -36,46 +40,77 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.IntensityRange */ public class UserDefinedRescalingSettingsDialog extends Dialog { - private final Label labelMin; + private static class SingleChannelIntesityRange + { + private final LabeledItem<String> channelCode; + + private final Label labelMin; + + private final Label labelMax; + + private final IntegerField minTextField; - private final Label labelMax; + private final IntegerField maxTextField; - private final IntegerField minTextField; + public SingleChannelIntesityRange(IMessageProvider messageProvider, + LabeledItem<String> channelCode) + { + this.channelCode = channelCode; + labelMin = + new Label(messageProvider.getMessage(Dict.RESCALING_DIALOG_MIN, + channelCode.getLabel())); + labelMax = + new Label(messageProvider.getMessage(Dict.RESCALING_DIALOG_MAX, + channelCode.getLabel())); + minTextField = + new IntegerField(messageProvider.getMessage(Dict.RESCALING_DIALOG_MIN, + channelCode), true); + maxTextField = + new IntegerField(messageProvider.getMessage(Dict.RESCALING_DIALOG_MAX, + channelCode), true); + } + } - private final IntegerField maxTextField; + private final List<SingleChannelIntesityRange> intensitiesPerChannel; private final IMessageProvider messageProvider; private final IDefaultChannelState defaultChannelState; - private final String channelCode; + private final List<LabeledItem<String>> channelCodes; public UserDefinedRescalingSettingsDialog(IMessageProvider messageProvider, Map<String, IntensityRange> intensitiesPerChannel, - IDefaultChannelState defaultChannelState, String channelCode) + IDefaultChannelState defaultChannelState, List<LabeledItem<String>> channelCodes) { super(); this.messageProvider = messageProvider; this.defaultChannelState = defaultChannelState; - this.channelCode = channelCode; + this.channelCodes = channelCodes; setHeading(this.messageProvider.getMessage(Dict.TITLE_USER_DEFINED_RESCALING_DIALOG)); setButtons(Dialog.OKCANCEL); - labelMin = new Label(this.messageProvider.getMessage(Dict.RESCALING_DIALOG_MIN)); - labelMax = new Label(this.messageProvider.getMessage(Dict.RESCALING_DIALOG_MAX)); - minTextField = - new IntegerField(messageProvider.getMessage(Dict.RESCALING_DIALOG_MIN), true); - maxTextField = - new IntegerField(messageProvider.getMessage(Dict.RESCALING_DIALOG_MAX), true); + + this.intensitiesPerChannel = new ArrayList<SingleChannelIntesityRange>(channelCodes.size()); + for (LabeledItem<String> channelCode : channelCodes) + { + this.intensitiesPerChannel.add(new SingleChannelIntesityRange(messageProvider, + channelCode)); + } setInitialValues(intensitiesPerChannel); - Grid grid = new Grid(2, 2); - grid.setWidget(0, 0, labelMin); - grid.setWidget(0, 1, minTextField); - grid.setWidget(1, 0, labelMax); - grid.setWidget(1, 1, maxTextField); + Grid grid = new Grid(channelCodes.size() * 2, 2); + int counter = 0; + for (SingleChannelIntesityRange scir : this.intensitiesPerChannel) + { + grid.setWidget(2 * counter, 0, scir.labelMin); + grid.setWidget(2 * counter, 1, scir.minTextField); + grid.setWidget(2 * counter + 1, 0, scir.labelMax); + grid.setWidget(2 * counter + 1, 1, scir.maxTextField); + counter++; + } add(grid); @@ -94,14 +129,17 @@ public class UserDefinedRescalingSettingsDialog extends Dialog private void setInitialValues(Map<String, IntensityRange> intensitiesPerChannel) { - minTextField.setValue(0); - maxTextField.setValue(65535); - - IntensityRange range = intensitiesPerChannel.get(channelCode); - if (range != null) + for (SingleChannelIntesityRange scir : this.intensitiesPerChannel) { - minTextField.setValue(range.getBlackPoint()); - maxTextField.setValue(range.getWhitePoint()); + scir.minTextField.setValue(0); + scir.maxTextField.setValue(65535); + + IntensityRange range = intensitiesPerChannel.get(scir.channelCode.getItem()); + if (range != null) + { + scir.minTextField.setValue(range.getBlackPoint()); + scir.maxTextField.setValue(range.getWhitePoint()); + } } } @@ -111,7 +149,7 @@ public class UserDefinedRescalingSettingsDialog extends Dialog if (button.getItemId().equals(Dialog.OK)) { button.disable(); - if (minTextField.isValid() && maxTextField.isValid()) + if (areIntensitiesValid()) { super.onButtonPressed(button); updateIntensityRescaling(); @@ -128,23 +166,40 @@ public class UserDefinedRescalingSettingsDialog extends Dialog } } + private boolean areIntensitiesValid() + { + for (SingleChannelIntesityRange scir : intensitiesPerChannel) + { + if ((false == scir.minTextField.isValid()) || (false == scir.maxTextField.isValid())) + { + return false; + } + } + + return true; + } + public void updateIntensityRescaling() { - IntensityRange result = null; + Map<String, IntensityRange> result = new HashMap<String, IntensityRange>(); try { - int min = Integer.parseInt(minTextField.getValue().toString()); - int max = Integer.parseInt(maxTextField.getValue().toString()); + for (SingleChannelIntesityRange scir : intensitiesPerChannel) + { + int min = Integer.parseInt(scir.minTextField.getValue().toString()); + int max = Integer.parseInt(scir.maxTextField.getValue().toString()); - result = new IntensityRange(min, max); - } catch (NumberFormatException e) - { - } + result.put(scir.channelCode.getItem(), new IntensityRange(min, max)); + } - if (result != null) + for (LabeledItem<String> channelCode : channelCodes) + { + defaultChannelState.setIntensityRange(channelCode.getItem(), + result.get(channelCode.getItem())); + } + } catch (NumberFormatException e) { - defaultChannelState.setIntensityRange(channelCode, result); } } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java index 519c872bd93..e7ecaddeaf6 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application. import java.util.Collections; import java.util.List; +import java.util.Map; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; import com.extjs.gxt.ui.client.Style.Scroll; @@ -172,7 +173,7 @@ public class WellContentDialog extends ImageDialog public static Widget createImageViewerForChannel( final IViewContext<IScreeningClientServiceAsync> viewContext, final WellContent wellImage, int imageSizePx, List<String> channels, - String imageTransformationCodeOrNull, IntensityRange rangeOrNull) + String imageTransformationCodeOrNull, Map<String, IntensityRange> rangesOrNull) { final ImageDatasetEnrichedReference imageDataset = tryGetImageDataset(wellImage); if (imageDataset == null) @@ -210,7 +211,7 @@ public class WellContentDialog extends ImageDialog new LogicalImageReference(imageDataset, locationOrNull); LogicalImageChannelsReference channelReferences = LogicalImageChannelsReference.createWithoutOverlays(wellImages, channels, - imageTransformationCodeOrNull, rangeOrNull); + imageTransformationCodeOrNull, rangesOrNull); LayoutContainer staticTilesGrid = LogicalImageViewer.createTilesGrid(channelReferences, sessionId, imageSizePx, clickHandler, null); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java index 76abc4000ed..961bd58e11d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java @@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application. import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.Set; import com.extjs.gxt.ui.client.store.ListStore; @@ -639,18 +640,18 @@ public class WellSearchGrid extends TypedTableGrid<WellContent> implements @Override public Widget create(List<String> channels, String imageTransformationCodeOrNull, - IntensityRange rangeOrNull) + Map<String, IntensityRange> rangesOrNull) { return WellContentDialog.createImageViewerForChannel( getViewContext(), entity, IMAGE_SIZE_PX, channels, - imageTransformationCodeOrNull, rangeOrNull); + imageTransformationCodeOrNull, rangesOrNull); } }; ChannelWidgetWithListener widgetWithListener = new ChannelWidgetWithListener(viewerFactory); widgetWithListener.selectionChanged(channelChooser.getSelectedValues(), channelChooser.tryGetSelectedTransformationCode(false), - channelChooser.tryGetSelectedIntensityRange()); + channelChooser.tryGetSelectedIntensityRanges()); ImageDatasetParameters imageParameters = images.getImageParameters(); channelChooser.addSelectionChangedListener(widgetWithListener); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/LogicalImageChannelsReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/LogicalImageChannelsReference.java index 87034aefc2d..71e4f79a1e5 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/LogicalImageChannelsReference.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/LogicalImageChannelsReference.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application. import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.IntensityRange; @@ -31,10 +32,10 @@ public class LogicalImageChannelsReference { public static LogicalImageChannelsReference createWithoutOverlays( LogicalImageReference basicImage, List<String> channels, - String imageTransformationCodeOrNull, IntensityRange rangeOrNull) + String imageTransformationCodeOrNull, Map<String, IntensityRange> rangesOrNull) { return new LogicalImageChannelsReference(basicImage, channels, - imageTransformationCodeOrNull, rangeOrNull, new HashSet<ImageDatasetChannel>()); + imageTransformationCodeOrNull, rangesOrNull, new HashSet<ImageDatasetChannel>()); } // ---- @@ -45,18 +46,18 @@ public class LogicalImageChannelsReference private final String imageTransformationCodeOrNull; - private final IntensityRange rangeOrNull; + private final Map<String, IntensityRange> rangesOrNull; private final Set<ImageDatasetChannel> overlayChannels; public LogicalImageChannelsReference(LogicalImageReference basicImage, List<String> channels, - String imageTransformationCodeOrNull, IntensityRange rangeOrNull, + String imageTransformationCodeOrNull, Map<String, IntensityRange> rangesOrNull, Set<ImageDatasetChannel> overlayChannels) { this.basicImage = basicImage; this.channels = channels; this.imageTransformationCodeOrNull = imageTransformationCodeOrNull; - this.rangeOrNull = rangeOrNull; + this.rangesOrNull = rangesOrNull; this.overlayChannels = overlayChannels; } @@ -80,8 +81,8 @@ public class LogicalImageChannelsReference return imageTransformationCodeOrNull; } - public IntensityRange tryGetIntensityRange() + public Map<String, IntensityRange> tryGetIntensityRanges() { - return rangeOrNull; + return rangesOrNull; } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/image/Image.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/image/Image.java index 27b95c867b8..099f9b31fac 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/image/Image.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/image/Image.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.image; import java.util.List; +import java.util.Map; import java.util.Set; import com.extjs.gxt.ui.client.widget.LayoutContainer; @@ -62,20 +63,46 @@ public class Image extends LayoutContainer if (getInitializer().getChannelReferences().tryGetImageTransformationCode() != null) { - String suffix = ""; if (ScreeningConstants.USER_DEFINED_RESCALING_CODE.equalsIgnoreCase(getInitializer() .getChannelReferences().tryGetImageTransformationCode())) { - IntensityRange range = - getInitializer().getChannelReferences().tryGetIntensityRange(); - if (range != null) + Map<String, IntensityRange> rangesOrNull = + getInitializer().getChannelReferences().tryGetIntensityRanges(); + if (rangesOrNull != null) { - suffix = "(" + range.getBlackPoint() + "," + range.getWhitePoint() + ")"; + for (Map.Entry<String, IntensityRange> range : rangesOrNull.entrySet()) + { + String suffix = ""; + if (range.getValue() != null) + { + suffix = + "(" + range.getValue().getBlackPoint() + "," + + range.getValue().getWhitePoint() + ")"; + } + + if (rangesOrNull.size() == 1) + { + url.addParameter( + ImageServletUrlParameters.SINGLE_CHANNEL_TRANSFORMATION_CODE_PARAM, + getInitializer().getChannelReferences() + .tryGetImageTransformationCode() + suffix); + } else + { + url.addParameter( + ImageServletUrlParameters.SINGLE_CHANNEL_TRANSFORMATION_CODE_PARAM + + range.getKey(), getInitializer() + .getChannelReferences().tryGetImageTransformationCode() + + suffix); + } + + } } + } else + { + url.addParameter( + ImageServletUrlParameters.SINGLE_CHANNEL_TRANSFORMATION_CODE_PARAM, + getInitializer().getChannelReferences().tryGetImageTransformationCode()); } - url.addParameter(ImageServletUrlParameters.SINGLE_CHANNEL_TRANSFORMATION_CODE_PARAM, - getInitializer().getChannelReferences().tryGetImageTransformationCode() - + suffix); } addImageTransformerSignature(url, getInitializer().getChannelReferences()); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/public/screening-dictionary.js b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/public/screening-dictionary.js index b47d96e6c8f..24f0567e29e 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/public/screening-dictionary.js +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/public/screening-dictionary.js @@ -142,8 +142,8 @@ RESOLUTION_CHOOSER_DEFAULT: "Default", RESOLUTION_CHOOSER_RESOLUTION: "{0}x{1}", TITLE_USER_DEFINED_RESCALING_DIALOG: "Set rescaling parameters", -RESCALING_DIALOG_MIN: "black point: ", -RESCALING_DIALOG_MAX: "white point: ", +RESCALING_DIALOG_MIN: "{0} black point: ", +RESCALING_DIALOG_MAX: "{0} white point: ", // LAST LINE: KEEP IT AT THE END lastline: "" // we need a line without a comma diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/HCSImageDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/HCSImageDatasetLoader.java index e068c430b37..0942ad3d12c 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/HCSImageDatasetLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/HCSImageDatasetLoader.java @@ -303,6 +303,7 @@ class HCSImageDatasetLoader extends PlateDatasetLoader DataStore dataStore = externalData.getDataStore(); DataSetType dataSetType = externalData.getDataSetType(); String dataSetTypeCodeOrNull = dataSetType == null ? null : dataSetType.getCode(); + return new ImageDatasetReference(externalData.getCode(), dataSetTypeCodeOrNull, getDataStoreUrlFromDataStore(dataStore), createPlateIdentifier(externalData), createExperimentIdentifier(externalData), extractPlateGeometry(externalData), diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/ImageSizeFeedingMaintenanceTaskTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/ImageSizeFeedingMaintenanceTaskTest.java index 949f4a09471..4ae052c1388 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/ImageSizeFeedingMaintenanceTaskTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/ImageSizeFeedingMaintenanceTaskTest.java @@ -28,9 +28,9 @@ import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContent; import ch.systemsx.cisd.common.logging.BufferedAppender; import ch.systemsx.cisd.common.test.RecordingMatcher; +import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContent; import ch.systemsx.cisd.openbis.dss.etl.dataaccess.IImagingQueryDAO; import ch.systemsx.cisd.openbis.dss.etl.dto.ImageTransfomationFactories; import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.RequestedImageSize; @@ -57,7 +57,7 @@ public class ImageSizeFeedingMaintenanceTaskTest extends AssertJUnit public MockAbsoluteImageReference(int width, int height) { super(null, null, null, null, new RequestedImageSize(null, false), null, - new ImageTransfomationFactories(), null, null); + new ImageTransfomationFactories(), null, null, null); this.width = width; this.height = height; } diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java index ceac2fb6ed1..eec32f3828b 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java @@ -38,10 +38,10 @@ import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.base.image.IImageTransformer; import ch.systemsx.cisd.base.image.IImageTransformerFactory; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; -import ch.systemsx.cisd.openbis.common.io.FileBasedContentNode; -import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContentNode; import ch.systemsx.cisd.imagereaders.ImageReaderConstants; import ch.systemsx.cisd.imagereaders.ImageReadersTestHelper; +import ch.systemsx.cisd.openbis.common.io.FileBasedContentNode; +import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContentNode; import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference; import ch.systemsx.cisd.openbis.dss.etl.IImagingDatasetLoader; import ch.systemsx.cisd.openbis.dss.etl.ImagingLoaderStrategyFactory; @@ -136,7 +136,7 @@ public class ImageChannelsUtilsTest extends AssertJUnit private ImageTransformationParams createSingleChannelTransformationParams() { - return new ImageTransformationParams(true, false, null); + return new ImageTransformationParams(true, false, null, new HashMap<String, String>()); } @Test @@ -226,8 +226,10 @@ public class ImageChannelsUtilsTest extends AssertJUnit }); BufferedImage image = - createImageChannelsUtils(null).calculateBufferedImage(imageRef, - new ImageTransformationParams(true, false, transformationCode)); + createImageChannelsUtils(null).calculateBufferedImage( + imageRef, + new ImageTransformationParams(true, false, transformationCode, + new HashMap<String, String>())); assertEquals("e00 f00 f00 e00\n" + "f00 c00 c00 f00\n" + "f00 c00 c00 f00\n" + "e00 f00 f00 e00\n", getImageContentDescription(image)); @@ -247,7 +249,8 @@ public class ImageChannelsUtilsTest extends AssertJUnit RequestedImageSize imageSize) { return new AbsoluteImageReference(image(fileName), "id42", null, null, imageSize, - new ChannelColorRGB(0, 0, 255), new ImageTransfomationFactories(), null, null); + new ChannelColorRGB(0, 0, 255), new ImageTransfomationFactories(), null, null, + "ch2"); } private ImageChannelsUtils createImageChannelsUtils(Size thumbnailSizeOrNull) diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java index 085064a35e8..e88cabc523c 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java @@ -456,14 +456,14 @@ public class DssServiceRpcScreeningTest extends AssertJUnit new Location(1, 1)), thumbnailSize, null); will(returnValue(new AbsoluteImageReference(image("img1.jpg"), "img1", null, null, thumbnailSize, createBlueColor(), - new ImageTransfomationFactories(), null, null))); + new ImageTransfomationFactories(), null, null, CHANNEL_CODE))); one(imageLoader).tryGetImage( CHANNEL_CODE, ImageChannelStackReference.createHCSFromLocations(new Location(3, 1), new Location(2, 1)), thumbnailSize, null); will(returnValue(new AbsoluteImageReference(image("img1.gif"), "img1", null, null, thumbnailSize, createBlueColor(), - new ImageTransfomationFactories(), null, null))); + new ImageTransfomationFactories(), null, null, CHANNEL_CODE))); } }); } @@ -590,7 +590,7 @@ public class DssServiceRpcScreeningTest extends AssertJUnit new Location(1, 1)), thumbnailSize, null); will(returnValue(new AbsoluteImageReference(image("img1.jpg"), "img1", null, null, thumbnailSize, createBlueColor(), - new ImageTransfomationFactories(), null, null))); + new ImageTransfomationFactories(), null, null, CHANNEL_CODE))); one(imageLoader).tryGetImage( CHANNEL_CODE, @@ -598,7 +598,7 @@ public class DssServiceRpcScreeningTest extends AssertJUnit new Location(2, 1)), thumbnailSize, null); will(returnValue(new AbsoluteImageReference(image("img1.png"), "img1", null, null, thumbnailSize, createBlueColor(), - new ImageTransfomationFactories(), null, null))); + new ImageTransfomationFactories(), null, null, CHANNEL_CODE))); } }); -- GitLab