From d791a88e6743d1125c057c69bd182d8beed7eb8a Mon Sep 17 00:00:00 2001 From: tpylak <tpylak> Date: Fri, 6 May 2011 12:50:23 +0000 Subject: [PATCH] LMS-2190 show images in a grid, fix heights SVN: 21159 --- .../web/client/IScreeningClientService.java | 3 +- .../client/IScreeningClientServiceAsync.java | 4 +- .../detailviewers/LogicalImageViewer.java | 38 +-- .../MaterialReplicaFeatureSummaryViewer.java | 206 +++++++++++-- .../detailviewers/WellContentDialog.java | 6 +- .../detailviewers/WellSearchGrid.java | 7 +- ...MaterialReplicaFeatureSummaryProvider.java | 16 +- .../web/server/ScreeningClientService.java | 4 +- .../screening/server/ScreeningServer.java | 9 +- .../server/ScreeningServerLogger.java | 5 +- .../MaterialFeatureVectorSummaryLoader.java | 287 +++++++----------- .../logic/ReplicateSequenceProvider.java | 189 ++++++++++++ .../server/logic/WellContentLoader.java | 51 +++- .../screening/server/logic/dto/IWellData.java | 3 +- .../MaterialAllReplicasFeatureVectors.java | 12 +- ...rialBiologicalReplicateFeatureVector.java} | 16 +- ...erialTechnicalReplicateFeatureVector.java} | 23 +- .../screening/server/logic/dto/WellData.java | 12 + .../screening/shared/IScreeningServer.java | 5 +- ...ialBiologicalReplicateFeatureSummary.java} | 7 +- .../dto/MaterialReplicaFeatureSummary.java | 22 +- .../MaterialReplicaFeatureSummaryResult.java | 5 +- .../basic/dto/MaterialSummarySettings.java | 12 +- .../shared/basic/dto/WellContent.java | 15 +- .../shared/basic/dto/WellReplicaImage.java | 67 ++++ ...aterialFeatureVectorSummaryLoaderTest.java | 10 +- 26 files changed, 719 insertions(+), 315 deletions(-) create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ReplicateSequenceProvider.java rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/{MaterialReplicaSubgroupFeatureVector.java => MaterialBiologicalReplicateFeatureVector.java} (75%) rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/{MaterialSingleReplicaFeatureVector.java => MaterialTechnicalReplicateFeatureVector.java} (62%) rename screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/{MaterialReplicaSubgroupFeatureSummary.java => MaterialBiologicalReplicateFeatureSummary.java} (87%) create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellReplicaImage.java diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientService.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientService.java index 6dc79a00e7d..62976b8ed3d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientService.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientService.java @@ -47,6 +47,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellMetadata; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria; /** @@ -119,7 +120,7 @@ public interface IScreeningClientService extends IClientService * for the well, all but the first one are ignored. If there is no image dataset for the well, * the whole well is ignored. */ - public List<WellContent> listWellImages(TechId materialId, TechId experimentId) + public List<WellReplicaImage> listWellImages(TechId materialId, TechId experimentId) throws UserFailureException; /** diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientServiceAsync.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientServiceAsync.java index 29721c23bd8..ce723e028f6 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientServiceAsync.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientServiceAsync.java @@ -48,6 +48,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellMetadata; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria; /** @@ -96,7 +97,7 @@ public interface IScreeningClientServiceAsync extends IClientServiceAsync * @see IScreeningClientService#listWellImages(TechId, TechId) */ public void listWellImages(TechId materialId, TechId experimentId, - AsyncCallback<List<WellContent>> callback); + AsyncCallback<List<WellReplicaImage>> callback); /** * @see IScreeningClientService#prepareExportPlateWells(TableExportCriteria) @@ -192,6 +193,7 @@ public interface IScreeningClientServiceAsync extends IClientServiceAsync IResultSetConfig<String, TableModelRowWithObject<MaterialReplicaFeatureSummary>> resultSetConfig, TechId experimentId, TechId materialId, AsyncCallback<TypedTableResultSet<MaterialReplicaFeatureSummary>> callback); + /** * @see IScreeningClientService#prepareExportMaterialReplicaFeatureSummary(TableExportCriteria) */ diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/LogicalImageViewer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/LogicalImageViewer.java index 0a811946bb9..7ec13c984f9 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/LogicalImageViewer.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/LogicalImageViewer.java @@ -59,9 +59,7 @@ public class LogicalImageViewer { private static final String NO_IMAGES_AVAILABLE_MSG = "No images available"; - private static final int ONE_IMAGE_WIDTH_PX = 200; - - private static final int ONE_IMAGE_HEIGHT_PX = 120; + private static final int ONE_IMAGE_SIZE_PX = 120; private static final int CHANNEL_SPLITER_AND_LABEL_HEIGHT_PX = 120; @@ -161,7 +159,8 @@ public class LogicalImageViewer private int getSeriesImageWidgetHeight() { - return CHANNEL_SPLITER_AND_LABEL_HEIGHT_PX + getImageHeight(logicalImageReference) + return CHANNEL_SPLITER_AND_LABEL_HEIGHT_PX + + getImageHeight(ONE_IMAGE_SIZE_PX, logicalImageReference) * logicalImageReference.getTileRowsNum(); } @@ -176,8 +175,8 @@ public class LogicalImageViewer String sessionId = getSessionId(viewContext); setAdjustColorsButtonState(adjustColorsButton, channelReferences.getChannelCodes()); - int imageWidth = getImageWidth(logicalImageReference); - int imageHeight = getImageHeight(logicalImageReference); + int imageWidth = getImageWidth(ONE_IMAGE_SIZE_PX, logicalImageReference); + int imageHeight = getImageHeight(ONE_IMAGE_SIZE_PX, logicalImageReference); return LogicalImageSeriesGrid.create(sessionId, channelStackImages, channelReferences, imageWidth, imageHeight); } @@ -288,7 +287,7 @@ public class LogicalImageViewer setAdjustColorsButtonState(adjustColorsButton, channelReferences.getChannelCodes()); String sessionId = getSessionId(viewContext); - return createTilesGrid(channelReferences, sessionId); + return createTilesGrid(channelReferences, sessionId, ONE_IMAGE_SIZE_PX, true); } }; @@ -340,17 +339,18 @@ public class LogicalImageViewer return "true".equals(viewContext.getPropertyOrNull("image-viewer-enabled")); } - private static LayoutContainer createTilesGrid(LogicalImageChannelsReference channelReferences, - String sessionId) + /** Creates a widget with a representative image of the specified logical image. */ + public static LayoutContainer createTilesGrid(LogicalImageChannelsReference channelReferences, + String sessionId, int imageSizePx, boolean createImageLinks) { LogicalImageReference images = channelReferences.getBasicImage(); - return createTilesGrid(channelReferences, sessionId, getImageWidth(images), - getImageHeight(images), true); + return createTilesGrid(channelReferences, sessionId, getImageWidth(imageSizePx, images), + getImageHeight(imageSizePx, images), createImageLinks); } - /** Creates a widget with a representative image of the specified logical image. */ - public static LayoutContainer createTilesGrid(LogicalImageChannelsReference channelReferences, - String sessionId, int imageWidth, int imageHeight, boolean createImageLinks) + private static LayoutContainer createTilesGrid(LogicalImageChannelsReference channelReferences, + String sessionId, int logicalImageWidth, int logicalImageHeight, + boolean createImageLinks) { LogicalImageReference images = channelReferences.getBasicImage(); LayoutContainer container = new LayoutContainer(new TableLayout(images.getTileColsNum())); @@ -359,7 +359,7 @@ public class LogicalImageViewer for (int col = 1; col <= images.getTileColsNum(); col++) { ImageUrlUtils.addImageUrlWidget(container, sessionId, channelReferences, row, col, - imageWidth, imageHeight, createImageLinks); + logicalImageWidth, logicalImageHeight, createImageLinks); } } return container; @@ -389,16 +389,16 @@ public class LogicalImageViewer return viewContext.getModel().getSessionContext().getSessionID(); } - private static int getImageHeight(LogicalImageReference images) + private static int getImageHeight(int imageSizePx, LogicalImageReference images) { float imageSizeMultiplyFactor = getImageSizeMultiplyFactor(images); - return (int) (ONE_IMAGE_HEIGHT_PX * imageSizeMultiplyFactor); + return (int) (imageSizePx * imageSizeMultiplyFactor); } - private static int getImageWidth(LogicalImageReference images) + private static int getImageWidth(int imageSizePx, LogicalImageReference images) { float imageSizeMultiplyFactor = getImageSizeMultiplyFactor(images); - return (int) (ONE_IMAGE_WIDTH_PX * imageSizeMultiplyFactor); + return (int) (imageSizePx * imageSizeMultiplyFactor); } private static float getImageSizeMultiplyFactor(LogicalImageReference images) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/MaterialReplicaFeatureSummaryViewer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/MaterialReplicaFeatureSummaryViewer.java index bc5dd275e04..5de170c288c 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/MaterialReplicaFeatureSummaryViewer.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/MaterialReplicaFeatureSummaryViewer.java @@ -16,7 +16,12 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import com.extjs.gxt.ui.client.Style.Orientation; @@ -30,6 +35,7 @@ import com.extjs.gxt.ui.client.widget.Text; import com.extjs.gxt.ui.client.widget.Viewport; import com.extjs.gxt.ui.client.widget.layout.RowData; import com.extjs.gxt.ui.client.widget.layout.RowLayout; +import com.extjs.gxt.ui.client.widget.layout.TableLayout; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.Widget; @@ -58,8 +64,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.d 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.ScreeningConstants; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellImage; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; /** * A viewer that comprises several UI elements to produce a holistic UI for material replica feature @@ -69,7 +75,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellImage; */ public class MaterialReplicaFeatureSummaryViewer { - private static final int WELL_IMAGES_SIZE_PX = 400; + private static final int ONE_IMAGE_SIZE_PX = 80; public static void openTab(IViewContext<IScreeningClientServiceAsync> screeningViewContext, String experimentPermId, MaterialIdentifier materialIdentifier) @@ -196,7 +202,7 @@ public class MaterialReplicaFeatureSummaryViewer }; } - private class ImagesFoundCallback extends AbstractAsyncCallback<List<WellContent>> + private class ImagesFoundCallback extends AbstractAsyncCallback<List<WellReplicaImage>> { private final LayoutContainer panel; @@ -207,14 +213,14 @@ public class MaterialReplicaFeatureSummaryViewer } @Override - protected void process(List<WellContent> images) + protected void process(List<WellReplicaImage> images) { - panel.add(createImagesViewer(images)); + panel.add(createImagePanel(images)); panel.layout(); } } - private Widget createImagesViewer(List<? extends WellImage> images) + private Widget createImagePanel(List<WellReplicaImage> images) { if (images.isEmpty()) { @@ -226,27 +232,161 @@ public class MaterialReplicaFeatureSummaryViewer ChannelChooserPanel channelChooser = new ChannelChooserPanel(defaultChannelState); LayoutContainer panel = new LayoutContainer(); panel.setLayout(new RowLayout()); - Html headingWidget = createHeader("<br><br><hr>" + "Images" + "<br><br>"); - panel.add(headingWidget, new RowData(1, -1)); + panel.add(new Html("<br>"), new RowData(1, -1)); panel.add(channelChooser); - LayoutContainer imagePanel = new LayoutContainer(); - imagePanel.setScrollMode(Scroll.AUTOY); - imagePanel.setLayout(new RowLayout()); - int imageSize = Math.min(100, WELL_IMAGES_SIZE_PX / images.size()); - for (WellImage wellImage : images) + Map<String, List<WellReplicaImage>> labelToReplicasMap = createSortedImageMap(images); + String orphanGroupKey = null; + List<WellReplicaImage> orphanTechnicalReplicates = labelToReplicasMap.get(orphanGroupKey); + if (orphanTechnicalReplicates != null) + { + panel.add(createOrphanTechnicalReplicatesPanel(orphanTechnicalReplicates, + channelChooser)); + labelToReplicasMap.remove(orphanGroupKey); + } + panel.add(createBiologicalReplicatesImagesPanel(labelToReplicasMap, channelChooser)); + if (screeningViewContext.isSimpleOrEmbeddedMode() == false) { - Widget imageViewer = createImageViewer(wellImage, channelChooser, imageSize); - imagePanel.add(imageViewer); + // WORKAROUND: in normal mode the height of menu and tab is not taken into account, + // so we add empty space to make + Text box = new Text(); + box.setHeight(100); + panel.add(box); } - // TODO 2011-04-12, Tomasz Pylak: correct the height - double imagePanelHeight = Math.min(500, images.size() * imageSize + 150); - panel.add(imagePanel, new RowData(1, imagePanelHeight)); return panel; } - private Widget createImageViewer(final WellImage image, ChannelChooserPanel channelChooser, - final int imageSize) + private Widget createOrphanTechnicalReplicatesPanel( + List<WellReplicaImage> orphanTechnicalReplicates, ChannelChooserPanel channelChooser) + { + LayoutContainer imagePanel = new LayoutContainer(); + for (WellReplicaImage image : orphanTechnicalReplicates) + { + LayoutContainer imageWithLabel = new LayoutContainer(); + imageWithLabel.setLayout(new RowLayout()); + + Widget label = + createTechnicalReplicateLabel(image.getTechnicalReplicateSequenceNumber()); + imageWithLabel.add(label); + + Widget imageViewer = createImageViewer(image.getWellImage(), channelChooser); + imageWithLabel.add(imageViewer); + + imagePanel.add(imageWithLabel); + } + return imagePanel; + } + + private LayoutContainer createBiologicalReplicatesImagesPanel( + Map<String, List<WellReplicaImage>> labelToReplicasMap, + ChannelChooserPanel channelChooser) + { + int maxReplicaNumber = calcMaxReplicaNumber(labelToReplicasMap); + LayoutContainer imagePanel = new LayoutContainer(); + TableLayout layout = new TableLayout(maxReplicaNumber + 1); + layout.setBorder(1); + imagePanel.setLayout(layout); + + addImageTableHeader(maxReplicaNumber, imagePanel); + List<String> sortedLabels = sortCopy(labelToReplicasMap.keySet()); + for (String label : sortedLabels) + { + List<WellReplicaImage> sortedTechnicalReplicates = labelToReplicasMap.get(label); + + imagePanel.add(new Text(label)); + for (int i = 0; i < maxReplicaNumber; i++) + { + if (i < sortedTechnicalReplicates.size()) + { + WellImage wellImage = sortedTechnicalReplicates.get(i).getWellImage(); + Widget imageViewer = createImageViewer(wellImage, channelChooser); + imagePanel.add(imageViewer); + } else + { + imagePanel.add(createEmptyBox()); + } + } + } + return imagePanel; + } + + private static List<String> sortCopy(Set<String> values) + { + List<String> sorted = new ArrayList<String>(values); + Collections.sort(sorted); + return sorted; + } + + private void addImageTableHeader(int maxReplicaNumber, LayoutContainer imagePanel) + { + for (int i = 0; i <= maxReplicaNumber; i++) + { + if (i == 0) + { + imagePanel.add(createEmptyBox()); + } else + { + imagePanel.add(createTechnicalReplicateLabel(i)); + } + } + } + + private Widget createTechnicalReplicateLabel(int technicalReplicateSequence) + { + return new Text("repl. " + technicalReplicateSequence); + } + + private Widget createEmptyBox() + { + return new Text(); + } + + private static int calcMaxReplicaNumber(Map<String, List<WellReplicaImage>> labelToReplicasMap) + { + int max = 0; + for (List<WellReplicaImage> technicalReplicates : labelToReplicasMap.values()) + { + max = Math.max(max, technicalReplicates.size()); + } + return max; + } + + private static Map<String/* label */, List<WellReplicaImage>> createSortedImageMap( + List<WellReplicaImage> images) + { + Map<String, List<WellReplicaImage>> map = new HashMap<String, List<WellReplicaImage>>(); + for (WellReplicaImage image : images) + { + String label = image.tryGetBiologicalReplicateLabel(); + List<WellReplicaImage> technicalReplicas = map.get(label); + if (technicalReplicas == null) + { + technicalReplicas = new ArrayList<WellReplicaImage>(); + } + technicalReplicas.add(image); + map.put(label, technicalReplicas); + } + sortTechnicalReplicas(map); + return map; + } + + private static void sortTechnicalReplicas(Map<String, List<WellReplicaImage>> map) + { + for (List<WellReplicaImage> technicalReplicas : map.values()) + { + Collections.sort(technicalReplicas, new Comparator<WellReplicaImage>() + { + public int compare(WellReplicaImage arg1, WellReplicaImage arg2) + { + Integer s1 = arg1.getTechnicalReplicateSequenceNumber(); + Integer s2 = arg2.getTechnicalReplicateSequenceNumber(); + return s1.compareTo(s2); + } + }); + } + } + + private Widget createImageViewer(final WellImage image, ChannelChooserPanel channelChooser) { assert image.tryGetImageDataset() != null; final ISimpleChanneledViewerFactory viewerFactory = new ISimpleChanneledViewerFactory() @@ -254,7 +394,7 @@ public class MaterialReplicaFeatureSummaryViewer public Widget create(List<String> channels) { return WellContentDialog.createImageViewerForChannel(screeningViewContext, - image, imageSize, imageSize, channels); + image, ONE_IMAGE_SIZE_PX, channels); } }; ChannelWidgetWithListener widgetWithListener = new ChannelWidgetWithListener(viewerFactory); @@ -271,6 +411,7 @@ public class MaterialReplicaFeatureSummaryViewer { final LayoutContainer panel = new Viewport(); panel.setLayout(new RowLayout(Orientation.VERTICAL)); + panel.setScrollMode(Scroll.AUTOY); final Widget northPanel = createNorth(screeningViewContext, experiment, material); panel.add(northPanel); @@ -278,8 +419,8 @@ public class MaterialReplicaFeatureSummaryViewer final IDisposableComponent gridComponent = MaterialReplicaFeatureSummaryGrid.create(screeningViewContext, new TechId( experiment), new TechId(material)); - // TODO 2011-04-13, Tomasz Pylak: fix height - panel.add(gridComponent.getComponent(), new RowData(1, 400)); + // NOTE: if the width is 100% then the vertical scrollbar of the grid is not visible + panel.add(gridComponent.getComponent(), new RowData(0.97, 400)); screeningViewContext.getService().listWellImages(new TechId(material.getId()), new TechId(experiment.getId()), new ImagesFoundCallback(panel)); @@ -339,6 +480,14 @@ public class MaterialReplicaFeatureSummaryViewer return panel; } + private static Html createHeader(String headingText) + { + Html headingWidget = new Html(headingText); + // NOTE: this should be refactored to an external CSS style + headingWidget.setTagName("h1"); + return headingWidget; + } + private static String getMaterialType(Material material) { String materialTypeCode = material.getMaterialType().getCode(); @@ -352,14 +501,6 @@ public class MaterialReplicaFeatureSummaryViewer return ("" + text.charAt(0)).toUpperCase() + text.substring(1).toLowerCase(); } - private static Html createHeader(String headingText) - { - Html headingWidget = new Html(headingText); - // NOTE: this should be refactored to an external CSS style - headingWidget.setTagName("h1"); - return headingWidget; - } - private static String getMaterialName(Material material) { if (material.getEntityType().getCode() @@ -393,9 +534,8 @@ public class MaterialReplicaFeatureSummaryViewer { public void onClick(ClickEvent event) { - // TODO KE: ugly, ugly, ugly !!! We bind ourselves with + // TODO KE: We bind ourselves with // the implementation of the other view instead of relying on the browser - // report a refactoring JIRA FeatureVectorSummaryViewer.openTab(viewContext, experiment.getPermId()); } }, linkUrl); 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 92285b59109..e4cfd9442ee 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 @@ -136,7 +136,7 @@ public class WellContentDialog extends Dialog */ public static Widget createImageViewerForChannel( final IViewContext<IScreeningClientServiceAsync> viewContext, - final WellImage wellImage, int imageWidthPx, int imageHeightPx, List<String> channels) + final WellImage wellImage, int imageSizePx, List<String> channels) { final ImageDatasetEnrichedReference imageDataset = tryGetImageDataset(wellImage); if (imageDataset == null) @@ -162,8 +162,8 @@ public class WellContentDialog extends Dialog LogicalImageChannelsReference channelReferences = LogicalImageChannelsReference.createWithoutOverlays(wellImages, channels); LayoutContainer staticTilesGrid = - LogicalImageViewer.createTilesGrid(channelReferences, sessionId, imageWidthPx, - imageHeightPx, createImageLinks); + LogicalImageViewer.createTilesGrid(channelReferences, sessionId, imageSizePx, + createImageLinks); if (imageParameters.isMultidimensional()) { 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 7e3081465e0..dd9108cb18d 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 @@ -104,9 +104,7 @@ public class WellSearchGrid extends TypedTableGrid<WellContent> private static final String CHOOSE_ONE_EXPERIMENT_TEXT = "Choose one experiment..."; - private static final int IMAGE_WIDTH_PX = 200; - - private static final int IMAGE_HEIGHT_PX = 120; + private static final int IMAGE_SIZE_PX = 80; // by experiment perm id public static void openTab( @@ -679,8 +677,7 @@ public class WellSearchGrid extends TypedTableGrid<WellContent> public Widget create(List<String> channels) { return WellContentDialog.createImageViewerForChannel( - viewContext, entity, IMAGE_WIDTH_PX, - IMAGE_HEIGHT_PX, channels); + viewContext, entity, IMAGE_SIZE_PX, channels); } }; ChannelWidgetWithListener widgetWithListener = diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/MaterialReplicaFeatureSummaryProvider.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/MaterialReplicaFeatureSummaryProvider.java index 9e4fa939bbd..e8a3324832c 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/MaterialReplicaFeatureSummaryProvider.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/MaterialReplicaFeatureSummaryProvider.java @@ -32,7 +32,7 @@ import ch.systemsx.cisd.openbis.generic.shared.util.TypedTableModelBuilder; import ch.systemsx.cisd.openbis.plugin.screening.shared.IScreeningServer; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaFeatureSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaFeatureSummaryResult; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSubgroupFeatureSummary; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialBiologicalReplicateFeatureSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType; /** @@ -68,14 +68,14 @@ class MaterialReplicaFeatureSummaryProvider extends TypedTableModelBuilder<MaterialReplicaFeatureSummary> builder = new TypedTableModelBuilder<MaterialReplicaFeatureSummary>(); MaterialReplicaFeatureSummaryResult replicaResult = - server.getFeatureVectorReplicaSummary(sessionToken, experimentId, materialId); + server.getMaterialFeatureVectorSummary(sessionToken, experimentId, materialId); builder.addColumn(FEATURE); builder.addColumn(MEDIAN).withDataType(DataTypeCode.REAL); builder.addColumn(DEVIATION).withDataType(DataTypeCode.REAL); builder.addColumn(RANK).withDataType(DataTypeCode.INTEGER); - List<MaterialReplicaFeatureSummary> rows = replicaResult.getReplicaSummaries(); + List<MaterialReplicaFeatureSummary> rows = replicaResult.getFeatureSummaries(); List<String> subgroupLabels = replicaResult.getSubgroupLabels(); if (rows.isEmpty()) { @@ -88,7 +88,7 @@ class MaterialReplicaFeatureSummaryProvider extends builder.columnGroup(subgroup); } - if (rows.get(0).getDefaultSubgroup() != null) + if (rows.get(0).getTechnicalReplicates() != null) { builder.columnGroup(DEFAULT_SUBGROUP); } @@ -111,24 +111,24 @@ class MaterialReplicaFeatureSummaryProvider extends builder.column(DEVIATION).addDouble(row.getFeatureVectorDeviation()); builder.column(RANK).addInteger((long) row.getFeatureVectorRank()); - MaterialReplicaSubgroupFeatureSummary defaultSubgroup = row.getDefaultSubgroup(); + MaterialBiologicalReplicateFeatureSummary defaultSubgroup = row.getTechnicalReplicates(); if (defaultSubgroup != null) { addSubgroup(builder, DEFAULT_SUBGROUP, "", defaultSubgroup); } int numSubgroups = subgroupLabels.size(); - List<MaterialReplicaSubgroupFeatureSummary> subgroups = row.getReplicaSubgroups(); + List<MaterialBiologicalReplicateFeatureSummary> subgroups = row.getBiologicalRelicates(); for (int i = 0; i < numSubgroups; i++) { String subgroupLabel = subgroupLabels.get(i); - MaterialReplicaSubgroupFeatureSummary subgroup = subgroups.get(i); + MaterialBiologicalReplicateFeatureSummary subgroup = subgroups.get(i); addSubgroup(builder, subgroupLabel, subgroupLabel, subgroup); } } private void addSubgroup(TypedTableModelBuilder<MaterialReplicaFeatureSummary> builder, - String groupId, String groupLabel, MaterialReplicaSubgroupFeatureSummary subgroup) + String groupId, String groupLabel, MaterialBiologicalReplicateFeatureSummary subgroup) { IColumnGroup columnGroup = builder.columnGroup(groupId); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/ScreeningClientService.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/ScreeningClientService.java index 2a49cae3efb..15d27e1b107 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/ScreeningClientService.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/ScreeningClientService.java @@ -67,6 +67,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConst import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellMetadata; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria; /** @@ -212,7 +213,7 @@ public final class ScreeningClientService extends AbstractClientService implemen return prepareExportEntities(criteria); } - public List<WellContent> listWellImages(TechId materialId, TechId experimentId) + public List<WellReplicaImage> listWellImages(TechId materialId, TechId experimentId) throws UserFailureException { return server.listWellImages(getSessionToken(), materialId, experimentId); @@ -355,6 +356,7 @@ public final class ScreeningClientService extends AbstractClientService implemen materialId); return listEntities(provider, resultSetConfig); } + public String prepareExportFeatureVectorSummary( TableExportCriteria<TableModelRowWithObject<MaterialFeatureVectorSummary>> criteria) throws UserFailureException diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java index b5a059215e9..7213a26b21c 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java @@ -102,6 +102,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria; /** @@ -204,12 +205,12 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl materialCriteria); } - public List<WellContent> listWellImages(String sessionToken, TechId materialId, + public List<WellReplicaImage> listWellImages(String sessionToken, TechId materialId, TechId experimentId) { Session session = getSession(sessionToken); return WellContentLoader.loadWithImages(session, businessObjectFactory, getDAOFactory(), - materialId, experimentId); + materialId, experimentId, createDefaultSettings()); } public List<Material> listMaterials(String sessionToken, WellSearchCriteria materialCriteria) @@ -311,11 +312,11 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl settings.setAggregationType(MaterialReplicaSummaryAggregationType.MEDIAN); settings.setFeatureCodes(new ArrayList<String>()); settings.setReplicaMatrialTypePatterns(ScreeningConstants.REPLICA_METERIAL_TYPE_PATTERN); - settings.setSubgroupPropertyTypeCodes("CONCENTRATION", "SIRNA"); + settings.setBiologicalReplicatePropertyTypeCodes("CONCENTRATION", "SIRNA"); return settings; } - public MaterialReplicaFeatureSummaryResult getFeatureVectorReplicaSummary(String sessionToken, + public MaterialReplicaFeatureSummaryResult getMaterialFeatureVectorSummary(String sessionToken, TechId experimentId, TechId materialId) { Session session = getSession(sessionToken); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java index 3d6b7c02516..02cb5fb1232 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java @@ -62,6 +62,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria; /** @@ -118,7 +119,7 @@ final class ScreeningServerLogger extends AbstractServerLogger implements IScree return null; } - public List<WellContent> listWellImages(String sessionToken, TechId materialId, + public List<WellReplicaImage> listWellImages(String sessionToken, TechId materialId, TechId experimentId) { logAccess(sessionToken, "listWellImages", "material(%s) experiment(%s)", materialId, @@ -352,7 +353,7 @@ final class ScreeningServerLogger extends AbstractServerLogger implements IScree return null; } - public MaterialReplicaFeatureSummaryResult getFeatureVectorReplicaSummary(String sessionToken, + public MaterialReplicaFeatureSummaryResult getMaterialFeatureVectorSummary(String sessionToken, TechId experimentId, TechId materialId) { logAccess(sessionToken, "getFeatureVectorReplicaSummary", diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java index 97aa99f268a..ccc887bbf1f 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java @@ -17,10 +17,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Set; import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.collections.CollectionUtils; @@ -30,26 +28,25 @@ import ch.systemsx.cisd.common.collections.IKeyExtractor; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObjectFactory; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialAllReplicasFeatureVectors; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialReplicaSubgroupFeatureVector; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialSingleReplicaFeatureVector; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialBiologicalReplicateFeatureVector; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialTechnicalReplicateFeatureVector; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellDataCollection; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialBiologicalReplicateFeatureSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialFeatureVectorSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaFeatureSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaFeatureSummaryResult; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSubgroupFeatureSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings; /** - * Loads feature vectors (details and statistics) for the specified material in the specified - * experiment. + * For the specified material in the specified experiment loads feature vectors (details and + * statistics).<br> + * Considers only one dataset of a particular type per plate. * * @author Tomasz Pylak */ @@ -62,35 +59,27 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory, TechId materialId, TechId experimentId, MaterialSummarySettings settings) { - MaterialAllReplicasFeatureVectors result = + MaterialAllReplicasFeatureVectors resultOrNull = new MaterialFeatureVectorSummaryLoader(session, businessObjectFactory, daoFactory, settings).tryLoadMaterialFeatureVectors(materialId, experimentId); - if (result == null) - { - return createEmptyMaterialReplicaFeatureSummaryResult(); - } - return convert(result); - } - private static MaterialReplicaFeatureSummaryResult createEmptyMaterialReplicaFeatureSummaryResult() - { - return new MaterialReplicaFeatureSummaryResult(new ArrayList<String>(), - new ArrayList<MaterialReplicaFeatureSummary>()); + List<MaterialReplicaFeatureSummary> replicaRows = convertToFeatureRows(resultOrNull); + List<String> subgroupLabels = tryGetSubgroupLabels(resultOrNull); + return new MaterialReplicaFeatureSummaryResult(subgroupLabels, replicaRows); } - private static MaterialReplicaFeatureSummaryResult convert( + private static List<MaterialReplicaFeatureSummary> convertToFeatureRows( MaterialAllReplicasFeatureVectors backendResult) { - List<String> subgroupLabels = new ArrayList<String>(); - final List<MaterialReplicaSubgroupFeatureVector> backendSubgroups = - backendResult.getSubgroups(); - for (MaterialReplicaSubgroupFeatureVector backendSubgroup : backendSubgroups) + List<MaterialReplicaFeatureSummary> replicaRows = + new ArrayList<MaterialReplicaFeatureSummary>(); + if (backendResult == null) { - subgroupLabels.add(backendSubgroup.getSubgroupLabel()); + return replicaRows; } + final List<MaterialBiologicalReplicateFeatureVector> backendSubgroups = + backendResult.getSubgroups(); - List<MaterialReplicaFeatureSummary> replicaRows = - new ArrayList<MaterialReplicaFeatureSummary>(); float[] featureVectorDeviatons = backendResult.getGeneralSummary().getFeatureVectorDeviations(); float[] featureVectorSummaries = @@ -113,41 +102,54 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS float[] defaultFeatureValues = extractFeatureValues(i, backendResult.getReplicas()); if (defaultFeatureValues != null) { - MaterialReplicaSubgroupFeatureSummary defaultReplica = - new MaterialReplicaSubgroupFeatureSummary(defaultFeatureValues, 0, + MaterialBiologicalReplicateFeatureSummary defaultReplica = + new MaterialBiologicalReplicateFeatureSummary(defaultFeatureValues, 0, MaterialReplicaSummaryAggregationType.MEDIAN); - replicaRow.setDefaultSubgroup(defaultReplica); + replicaRow.setTechnicalReplicates(defaultReplica); } - List<MaterialReplicaSubgroupFeatureSummary> subgroups = - new ArrayList<MaterialReplicaSubgroupFeatureSummary>(); - replicaRow.setReplicaSubgroups(subgroups); + List<MaterialBiologicalReplicateFeatureSummary> subgroups = + new ArrayList<MaterialBiologicalReplicateFeatureSummary>(); + replicaRow.setBiologicalRelicates(subgroups); for (int tmp = 0; tmp < backendSubgroups.size(); tmp++) { - MaterialReplicaSubgroupFeatureVector backendGroup = backendSubgroups.get(tmp); + MaterialBiologicalReplicateFeatureVector backendGroup = backendSubgroups.get(tmp); final float[] aggregatedSummaries = backendGroup.getAggregatedSummary(); float[] featureValues = - extractFeatureValues(i, backendGroup.getSingleReplicaValues()); - MaterialReplicaSubgroupFeatureSummary subgroup = - new MaterialReplicaSubgroupFeatureSummary(featureValues, + extractFeatureValues(i, backendGroup.getTechnicalReplicatesValues()); + MaterialBiologicalReplicateFeatureSummary subgroup = + new MaterialBiologicalReplicateFeatureSummary(featureValues, aggregatedSummaries[i], backendGroup.getSummaryAggregationType()); subgroups.add(subgroup); } } + return replicaRows; + } - return new MaterialReplicaFeatureSummaryResult(subgroupLabels, replicaRows); - + private static List<String> tryGetSubgroupLabels( + MaterialAllReplicasFeatureVectors backendResultOrNull) + { + List<String> subgroupLabels = new ArrayList<String>(); + if (backendResultOrNull == null) + { + return subgroupLabels; + } + for (MaterialBiologicalReplicateFeatureVector backendSubgroup : backendResultOrNull + .getSubgroups()) + { + subgroupLabels.add(backendSubgroup.getSubgroupLabel()); + } + return subgroupLabels; } private static float[] extractFeatureValues(int i, - List<MaterialSingleReplicaFeatureVector> replicas) + List<MaterialTechnicalReplicateFeatureVector> replicas) { float[] result = new float[replicas.size()]; for (int pos = 0; pos < result.length; pos++) { - float[] aggregatedValues = replicas.get(pos).getFeatueVectorSummary(); + float[] aggregatedValues = replicas.get(pos).getFeatueVector(); result[pos] = aggregatedValues[i]; - } return result; } @@ -165,165 +167,112 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS private MaterialAllReplicasFeatureVectors tryLoadMaterialFeatureVectors(TechId materialId, TechId experimentId) { - WellDataCollection wellDataCollection = tryLoadWellData(experimentId); - if (wellDataCollection == null) + WellDataCollection experimentWells = tryLoadWellData(experimentId); + if (experimentWells == null) { return null; } - return tryLoadMaterialFeatureVectors(materialId, wellDataCollection); + return tryLoadMaterialFeatureVectors(materialId, experimentWells); } @Private MaterialAllReplicasFeatureVectors tryLoadMaterialFeatureVectors(TechId materialId, - WellDataCollection wellDataCollection) + WellDataCollection experimentWells) { MaterialFeatureVectorSummary materialGeneralSummary = - tryCalculateMaterialSummary(materialId, wellDataCollection); + tryCalculateMaterialSummary(materialId, experimentWells); if (materialGeneralSummary == null) { return null; } - List<IWellData> materialWellDataList = - filterWellsByMaterial(wellDataCollection.getWellDataList(), materialId); - GroupByMap<Double, IWellData> subgroupMap = groupBySubgroup(materialWellDataList); - - List<MaterialReplicaSubgroupFeatureVector> subgroups = Collections.emptyList(); - List<MaterialSingleReplicaFeatureVector> replicas = Collections.emptyList(); - if (hasNoSubgroups(subgroupMap)) + List<IWellData> materialWells = + filterWellsByMaterial(experimentWells.getWellDataList(), materialId); + ReplicateSequenceProvider replicaSequences = + new ReplicateSequenceProvider(materialWells, + settings.getBiologicalReplicatePropertyTypeCodes()); + + List<MaterialBiologicalReplicateFeatureVector> subgroups = Collections.emptyList(); + List<MaterialTechnicalReplicateFeatureVector> replicas = Collections.emptyList(); + if (replicaSequences.hasNoBiologicalReplicates()) { - replicas = createReplicas(materialWellDataList); + replicas = createTechnicalReplicas(materialWells, replicaSequences); } else { - subgroups = createSubgroups(subgroupMap); + subgroups = createBiologicalReplicates(materialWells, replicaSequences); } - return new MaterialAllReplicasFeatureVectors(wellDataCollection.getFeatureDescriptions(), + return new MaterialAllReplicasFeatureVectors(experimentWells.getFeatureDescriptions(), materialGeneralSummary, subgroups, replicas); } - private List<MaterialReplicaSubgroupFeatureVector> createSubgroups( - GroupByMap<Double, IWellData> subgroupMap) + private List<MaterialBiologicalReplicateFeatureVector> createBiologicalReplicates( + List<IWellData> materialWells, ReplicateSequenceProvider replicaSequences) { - List<MaterialReplicaSubgroupFeatureVector> subgroups = - new ArrayList<MaterialReplicaSubgroupFeatureVector>(); + GroupByMap<Integer, IWellData> biologicalReplicateMap = + groupByBiologicalReplicate(materialWells, replicaSequences); + + List<MaterialBiologicalReplicateFeatureVector> subgroups = + new ArrayList<MaterialBiologicalReplicateFeatureVector>(); MaterialReplicaSummaryAggregationType aggregationType = settings.getAggregationType(); - int subgroupSequenceNumber = 1; - Collection<Double> sortedKeys = sortSubgroupKeys(subgroupMap.getKeys()); - for (Double subgroupKey : sortedKeys) + for (Integer biologicalReplicateSeq : replicaSequences.getBiologicalReplicateKeys()) { - if (subgroupKey != null) - { - List<IWellData> subgroupWellDataList = subgroupMap.getOrDie(subgroupKey); - MaterialReplicaSubgroupFeatureVector subgroup = - createSubgroup(subgroupWellDataList, subgroupSequenceNumber, - aggregationType); - subgroups.add(subgroup); - subgroupSequenceNumber++; - } + List<IWellData> technicalReplicateWells = + biologicalReplicateMap.getOrDie(biologicalReplicateSeq); + MaterialBiologicalReplicateFeatureVector subgroup = + createBiologicalReplicate(technicalReplicateWells, replicaSequences, + aggregationType); + subgroups.add(subgroup); } return subgroups; } - private static Collection<Double> sortSubgroupKeys(Set<Double> keys) - { - ArrayList<Double> sortedKeys = new ArrayList<Double>(keys); - Collections.sort(sortedKeys); - return sortedKeys; - } - - private MaterialReplicaSubgroupFeatureVector createSubgroup( - List<IWellData> subgroupWellDataList, int subgroupSequenceNumber, + private MaterialBiologicalReplicateFeatureVector createBiologicalReplicate( + List<IWellData> technicalReplicateWells, ReplicateSequenceProvider replicaSequences, MaterialReplicaSummaryAggregationType aggregationType) { float[] aggregatedSummary = - WellReplicaSummaryCalculator.calculateSummaryFeatureVector(subgroupWellDataList, + WellReplicaSummaryCalculator.calculateSummaryFeatureVector(technicalReplicateWells, aggregationType); - List<MaterialSingleReplicaFeatureVector> replicas = createReplicas(subgroupWellDataList); - String subgroupLabel = getSubgroupLabel(subgroupWellDataList, subgroupSequenceNumber); - return new MaterialReplicaSubgroupFeatureVector(replicas, aggregatedSummary, + List<MaterialTechnicalReplicateFeatureVector> replicas = + createTechnicalReplicas(technicalReplicateWells, replicaSequences); + String subgroupLabel = getSubgroupLabel(technicalReplicateWells, replicaSequences); + return new MaterialBiologicalReplicateFeatureVector(replicas, aggregatedSummary, aggregationType, subgroupLabel); } - private String getSubgroupLabel(List<IWellData> subgroupWellDataList, int subgroupSequenceNumber) + private String getSubgroupLabel(List<IWellData> subgroupWellDataList, + ReplicateSequenceProvider replicaSequences) { assert subgroupWellDataList.size() > 0 : "empty subgroup"; + // all wells belong to the same subgroup, so it does not matter which one we take Sample well = subgroupWellDataList.get(0).getWell(); - IEntityProperty subgroupProperty = tryFindSubgroupProperty(well); - assert subgroupProperty != null : "cannot fnd the subgroup property"; - - String propertyLabel = subgroupProperty.getPropertyType().getLabel(); - Material subgroupMaterial = subgroupProperty.getMaterial(); - if (subgroupMaterial != null) - { - return propertyLabel + " " + subgroupSequenceNumber; - } else - { - return propertyLabel + " " + subgroupProperty.tryGetAsString(); - } - } - - /** - * A subgroup can be e.g. oligo or compound concentration. - */ - private GroupByMap<Double, IWellData> groupBySubgroup(List<IWellData> materialWellDataList) - { - return GroupByMap.create(materialWellDataList, new IKeyExtractor<Double, IWellData>() - { - public Double getKey(IWellData wellData) - { - return tryFindSubgroup(wellData.getWell()); - } - }); - } - private Double tryFindSubgroup(Sample well) - { - IEntityProperty subgroupProperty = tryFindSubgroupProperty(well); - if (subgroupProperty == null) - { - return null; - } - return tryExtractSubgroupValue(subgroupProperty); - } - - private IEntityProperty tryFindSubgroupProperty(Sample well) - { - List<String> subgroupPropertyTypeCodes = settings.getSubgroupPropertyTypeCodes(); - if (subgroupPropertyTypeCodes == null) - { - return null; - } - return tryFindProperty(well.getProperties(), subgroupPropertyTypeCodes); + return replicaSequences.getBiologicalReplicateLabel(well); } private MaterialFeatureVectorSummary tryCalculateMaterialSummary(TechId materialId, - WellDataCollection wellDataCollection) + WellDataCollection experimentWellDataList) { List<MaterialFeatureVectorSummary> featureSummaries = - calculateReplicasFeatureVectorSummaries(wellDataCollection); + calculateReplicasFeatureVectorSummaries(experimentWellDataList); return tryFindMaterialSummary(materialId, featureSummaries); } - private static List<MaterialSingleReplicaFeatureVector> createReplicas( - List<IWellData> materialWellDataList) + private static List<MaterialTechnicalReplicateFeatureVector> createTechnicalReplicas( + List<IWellData> materialWellDataList, ReplicateSequenceProvider replicaSequences) { - List<MaterialSingleReplicaFeatureVector> replicas = - new ArrayList<MaterialSingleReplicaFeatureVector>(); - int replicaSequenceNumber = 1; + List<MaterialTechnicalReplicateFeatureVector> replicas = + new ArrayList<MaterialTechnicalReplicateFeatureVector>(); for (IWellData wellData : materialWellDataList) { - MaterialSingleReplicaFeatureVector featureVector = - new MaterialSingleReplicaFeatureVector(replicaSequenceNumber++, + int replicaSequenceNumber = replicaSequences.getTechnicalReplicateSequenceNum(wellData); + MaterialTechnicalReplicateFeatureVector featureVector = + new MaterialTechnicalReplicateFeatureVector(replicaSequenceNumber, wellData.getFeatureVector()); replicas.add(featureVector); } return replicas; } - private static boolean hasNoSubgroups(GroupByMap<Double, IWellData> subgroupMap) - { - return subgroupMap.getKeys().size() == 1 && subgroupMap.getKeys().contains(null); - } - private static List<IWellData> filterWellsByMaterial(List<IWellData> wellDataList, final TechId materialId) { @@ -336,6 +285,21 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS }); } + /** + * A subgroup can be e.g. oligo or compound concentration. + */ + private GroupByMap<Integer, IWellData> groupByBiologicalReplicate( + List<IWellData> materialWellDataList, final ReplicateSequenceProvider replicaSequences) + { + return GroupByMap.create(materialWellDataList, new IKeyExtractor<Integer, IWellData>() + { + public Integer getKey(IWellData wellData) + { + return replicaSequences.tryGetBiologicalReplicateSequenceNum(wellData.getWell()); + } + }); + } + private static MaterialFeatureVectorSummary tryFindMaterialSummary(TechId materialId, List<MaterialFeatureVectorSummary> featureSummaries) { @@ -348,33 +312,4 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS } return null; } - - private static Double tryExtractSubgroupValue(IEntityProperty subgroupProperty) - { - Material subgroupMaterial = subgroupProperty.getMaterial(); - if (subgroupMaterial != null) - { - return new Double(subgroupMaterial.getId()); - } - try - { - return new Double(subgroupProperty.tryGetAsString()); - } catch (NumberFormatException ex) - { - return null; - } - } - - private static IEntityProperty tryFindProperty(List<IEntityProperty> properties, - List<String> subgroupPropertyTypeCodes) - { - for (IEntityProperty property : properties) - { - if (subgroupPropertyTypeCodes.contains(property.getPropertyType().getCode())) - { - return property; - } - } - return null; - } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ReplicateSequenceProvider.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ReplicateSequenceProvider.java new file mode 100644 index 00000000000..ba11ffca355 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ReplicateSequenceProvider.java @@ -0,0 +1,189 @@ +/* + * 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.plugin.screening.server.logic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import ch.systemsx.cisd.common.collections.GroupByMap; +import ch.systemsx.cisd.common.collections.IKeyExtractor; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityPropertiesHolder; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; + +/** + * Provides sequence numbers for technical and biological well replicates for a fixed material. + * + * @author Tomasz Pylak + */ +class ReplicateSequenceProvider +{ + private final List<String> biologicalReplicatePropertyTypeCodesOrNull; + + private final Map<Double/* subgroup key */, Integer/* biological replicate sequence number */> biologicalReplicateSeqMap; + + private final Map<Long/* well id */, Integer/* technical replicate sequence number */> technicalReplicateSeqMap; + + public ReplicateSequenceProvider(List<? extends IEntityPropertiesHolder> replicaWells, + List<String> biologicalReplicatePropertyTypeCodesOrNull) + { + this.biologicalReplicatePropertyTypeCodesOrNull = biologicalReplicatePropertyTypeCodesOrNull; + this.biologicalReplicateSeqMap = new LinkedHashMap<Double, Integer>(); + this.technicalReplicateSeqMap = new LinkedHashMap<Long, Integer>(); + + GroupByMap<Double, IEntityPropertiesHolder> biologicalReplicates = + groupByBiologicalReplicate(replicaWells); + int biologicalReplicateSeq = 1; + for (Double biologicalReplicateKey : createSortedCopy(biologicalReplicates.getKeys())) + { + if (biologicalReplicateKey != null) + { + biologicalReplicateSeqMap.put(biologicalReplicateKey, biologicalReplicateSeq++); + } + + int technicalReplicateSeq = 1; + List<IEntityPropertiesHolder> technicalReplicates = + biologicalReplicates.getOrDie(biologicalReplicateKey); + for (IEntityPropertiesHolder technicalReplicate : technicalReplicates) + { + technicalReplicateSeqMap.put(technicalReplicate.getId(), technicalReplicateSeq++); + } + } + } + + public Collection<Integer> getBiologicalReplicateKeys() + { + return createSortedCopy(biologicalReplicateSeqMap.values()); + } + + private GroupByMap<Double, IEntityPropertiesHolder> groupByBiologicalReplicate( + List<? extends IEntityPropertiesHolder> wells) + { + return GroupByMap.create(wells, new IKeyExtractor<Double, IEntityPropertiesHolder>() + { + public Double getKey(IEntityPropertiesHolder well) + { + return tryFindSubgroup(well); + } + }); + } + + /** Subgroup sequence, the same for all technical replicates of one biological replicate. */ + public Integer tryGetBiologicalReplicateSequenceNum(IEntityPropertiesHolder well) + { + Double subgroupKey = tryFindSubgroup(well); + if (subgroupKey == null) + { + return null; + } + Integer seqNum = biologicalReplicateSeqMap.get(subgroupKey); + assert seqNum != null : "no biological replicate found for " + subgroupKey; + return seqNum; + } + + /** + * Technical Replicate Sequence (unique in one biological replicate) + */ + public int getTechnicalReplicateSequenceNum(IEntityPropertiesHolder well) + { + return technicalReplicateSeqMap.get(well.getId()); + } + + private static <T extends Comparable<T>> Collection<T> createSortedCopy(Collection<T> keys) + { + ArrayList<T> sortedKeys = new ArrayList<T>(keys); + Collections.sort(sortedKeys); + return sortedKeys; + } + + public boolean hasNoBiologicalReplicates() + { + Set<Double> keys = biologicalReplicateSeqMap.keySet(); + return keys.size() == 1 && keys.contains(null); + } + + public String getBiologicalReplicateLabel(IEntityPropertiesHolder well) + { + int biologicalReplicateSeq = tryGetBiologicalReplicateSequenceNum(well); + IEntityProperty subgroupProperty = tryFindSubgroupProperty(well); + assert subgroupProperty != null : "cannot fnd the subgroup property"; + boolean isMaterialProperty = (subgroupProperty.getMaterial() != null); + + String propertyLabel = subgroupProperty.getPropertyType().getLabel(); + if (isMaterialProperty) + { + return propertyLabel + " " + biologicalReplicateSeq; + } else + { + return propertyLabel + " " + subgroupProperty.tryGetAsString(); + } + } + + private Double tryFindSubgroup(IEntityPropertiesHolder well) + { + IEntityProperty subgroupProperty = tryFindSubgroupProperty(well); + if (subgroupProperty == null) + { + return null; + } + return tryExtractSubgroupValue(subgroupProperty); + } + + private IEntityProperty tryFindSubgroupProperty(IEntityPropertiesHolder well) + { + if (biologicalReplicatePropertyTypeCodesOrNull == null) + { + return null; + } + return tryFindProperty(well.getProperties(), biologicalReplicatePropertyTypeCodesOrNull); + } + + private static Double tryExtractSubgroupValue(IEntityProperty subgroupProperty) + { + Material subgroupMaterial = subgroupProperty.getMaterial(); + if (subgroupMaterial != null) + { + return new Double(subgroupMaterial.getId()); + } + try + { + return new Double(subgroupProperty.tryGetAsString()); + } catch (NumberFormatException ex) + { + return null; + } + } + + private static IEntityProperty tryFindProperty(List<IEntityProperty> properties, + List<String> subgroupPropertyTypeCodes) + { + for (IEntityProperty property : properties) + { + if (subgroupPropertyTypeCodes.contains(property.getPropertyType().getCode())) + { + return property; + } + } + return null; + } + +} \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoader.java index 63a1d5464d3..99757e5a419 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoader.java @@ -65,10 +65,12 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReferen import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorValues; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetParameters; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.NamedFeatureVector; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellFeatureVectorReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria.ExperimentSearchCriteria; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria.MaterialSearchCodesCriteria; @@ -138,28 +140,59 @@ public class WellContentLoader extends AbstractContentLoader * for the well, all but the first one are ignored. If there is no image dataset for the well, * the whole well is ignored. */ - public static List<WellContent> loadWithImages(Session session, + public static List<WellReplicaImage> loadWithImages(Session session, IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory, - TechId materialId, TechId experimentId) + TechId materialId, TechId experimentId, MaterialSummarySettings settings) { WellContentLoader loader = new WellContentLoader(session, businessObjectFactory, daoFactory); List<WellContent> locations = loader.loadLocations(materialId, experimentId.getId()); - return loader.enrichWithSingleImageDatasets(locations); + locations = loader.enrichWithSingleImageDatasets(locations); + return annotateWithReplicaLabels(locations, settings); + } + + private static List<WellReplicaImage> annotateWithReplicaLabels( + List<WellContent> wellsWithImages, MaterialSummarySettings settings) + { + ReplicateSequenceProvider replicaSequences = + new ReplicateSequenceProvider(wellsWithImages, + settings.getBiologicalReplicatePropertyTypeCodes()); + List<WellReplicaImage> wellReplicaImages = new ArrayList<WellReplicaImage>(); + for (WellContent wellContent : wellsWithImages) + { + wellReplicaImages.add(annotateWithReplicaLabels(wellContent, replicaSequences)); + } + return wellReplicaImages; + } + + private static WellReplicaImage annotateWithReplicaLabels(WellContent wellContent, + ReplicateSequenceProvider replicaSequences) + { + int technicalReplicaSequenceNumber = + replicaSequences.getTechnicalReplicateSequenceNum(wellContent); + String biologicalReplicateLabel = replicaSequences.getBiologicalReplicateLabel(wellContent); + return new WellReplicaImage(wellContent, technicalReplicaSequenceNumber, + biologicalReplicateLabel); } private List<WellContent> enrichWithSingleImageDatasets(List<WellContent> locations) { - HCSImageDatasetLoader datasetsRetriever = - createImageDatasetsRetriever(extractPlates(locations)); + Set<PlateIdentifier> plateIdentifiers = extractPlates(locations); + Map<Long, DatasetImagesReference> plateToDatasetReferenceMap = + loadPlateToSingleImageDatasetMap(plateIdentifiers); + return enrichWithSingleImageDatasets(locations, plateToDatasetReferenceMap); + } + + private Map<Long, DatasetImagesReference> loadPlateToSingleImageDatasetMap( + Set<PlateIdentifier> plateIdentifiers) + { + HCSImageDatasetLoader datasetsRetriever = createImageDatasetsRetriever(plateIdentifiers); Collection<ExternalData> imageDatasets = datasetsRetriever.getImageDatasets(); if (imageDatasets.isEmpty()) { - return Collections.emptyList(); + return new HashMap<Long, DatasetImagesReference>(); } - Map<Long, DatasetImagesReference> plateToDatasetReferenceMap = - createPlateToSingleDatasetReferenceMap(imageDatasets); - return enrichWithSingleImageDatasets(locations, plateToDatasetReferenceMap); + return createPlateToSingleDatasetReferenceMap(imageDatasets); } /** Note: locations without a corresponding image dataset are removed */ diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/IWellData.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/IWellData.java index 48878136684..2d91dad7530 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/IWellData.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/IWellData.java @@ -16,6 +16,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityPropertiesHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.WellReplicaSummaryCalculator; @@ -26,7 +27,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.server.logic.WellReplicaSummary * * @author Tomasz Pylak */ -public interface IWellData +public interface IWellData extends IEntityPropertiesHolder { /** @return feature vector for the well */ float[] getFeatureVector(); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialAllReplicasFeatureVectors.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialAllReplicasFeatureVectors.java index c6f6a6cf908..658782483fb 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialAllReplicasFeatureVectors.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialAllReplicasFeatureVectors.java @@ -22,10 +22,10 @@ public class MaterialAllReplicasFeatureVectors implements ISerializable private MaterialFeatureVectorSummary generalSummary; // NOTE: Can be empty. - private List<MaterialReplicaSubgroupFeatureVector> subgroups; + private List<MaterialBiologicalReplicateFeatureVector> subgroups; // NOTE: Can be empty. Used for replicas which have no subgroups - private List<MaterialSingleReplicaFeatureVector> replicas; + private List<MaterialTechnicalReplicateFeatureVector> replicas; // GWT only @SuppressWarnings("unused") @@ -35,8 +35,8 @@ public class MaterialAllReplicasFeatureVectors implements ISerializable public MaterialAllReplicasFeatureVectors(List<CodeAndLabel> featureDescriptions, MaterialFeatureVectorSummary generalSummary, - List<MaterialReplicaSubgroupFeatureVector> subgroups, - List<MaterialSingleReplicaFeatureVector> replicas) + List<MaterialBiologicalReplicateFeatureVector> subgroups, + List<MaterialTechnicalReplicateFeatureVector> replicas) { this.featureDescriptions = featureDescriptions; this.generalSummary = generalSummary; @@ -54,12 +54,12 @@ public class MaterialAllReplicasFeatureVectors implements ISerializable return generalSummary; } - public List<MaterialReplicaSubgroupFeatureVector> getSubgroups() + public List<MaterialBiologicalReplicateFeatureVector> getSubgroups() { return subgroups; } - public List<MaterialSingleReplicaFeatureVector> getReplicas() + public List<MaterialTechnicalReplicateFeatureVector> getReplicas() { return replicas; } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialReplicaSubgroupFeatureVector.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialBiologicalReplicateFeatureVector.java similarity index 75% rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialReplicaSubgroupFeatureVector.java rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialBiologicalReplicateFeatureVector.java index b064c3e85e9..c1167af2ae0 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialReplicaSubgroupFeatureVector.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialBiologicalReplicateFeatureVector.java @@ -12,11 +12,11 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplic * * @author Tomasz Pylak */ -public class MaterialReplicaSubgroupFeatureVector implements ISerializable +public class MaterialBiologicalReplicateFeatureVector implements ISerializable { private static final long serialVersionUID = ServiceVersionHolder.VERSION; - private List<MaterialSingleReplicaFeatureVector> singleReplicaValues; + private List<MaterialTechnicalReplicateFeatureVector> technicalReplicatesValues; // e.g. average or median of all replica values in this supgroup // This is the aggregation of a subgroup of replicas for e.g. the same SIRNA @@ -29,24 +29,24 @@ public class MaterialReplicaSubgroupFeatureVector implements ISerializable // GWT only @SuppressWarnings("unused") - private MaterialReplicaSubgroupFeatureVector() + private MaterialBiologicalReplicateFeatureVector() { } - public MaterialReplicaSubgroupFeatureVector( - List<MaterialSingleReplicaFeatureVector> singleReplicaValues, + public MaterialBiologicalReplicateFeatureVector( + List<MaterialTechnicalReplicateFeatureVector> singleReplicaValues, float[] aggregatedSummary, MaterialReplicaSummaryAggregationType summaryAggregationType, String subgroupLabel) { - this.singleReplicaValues = singleReplicaValues; + this.technicalReplicatesValues = singleReplicaValues; this.aggregatedSummary = aggregatedSummary; this.summaryAggregationType = summaryAggregationType; this.subgroupLabel = subgroupLabel; } - public List<MaterialSingleReplicaFeatureVector> getSingleReplicaValues() + public List<MaterialTechnicalReplicateFeatureVector> getTechnicalReplicatesValues() { - return singleReplicaValues; + return technicalReplicatesValues; } public float[] getAggregatedSummary() diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialSingleReplicaFeatureVector.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialTechnicalReplicateFeatureVector.java similarity index 62% rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialSingleReplicaFeatureVector.java rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialTechnicalReplicateFeatureVector.java index cc71a22746b..97bf703ecba 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialSingleReplicaFeatureVector.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/MaterialTechnicalReplicateFeatureVector.java @@ -24,34 +24,35 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; * * @author Tomasz Pylak */ -public class MaterialSingleReplicaFeatureVector implements ISerializable +public class MaterialTechnicalReplicateFeatureVector implements ISerializable { private static final long serialVersionUID = ServiceVersionHolder.VERSION; - private int replicaSequenceNumber; + private int technicalReplicateSequenceNumber; - private float[] featueVectorSummary; + private float[] featueVector; // GWT only @SuppressWarnings("unused") - private MaterialSingleReplicaFeatureVector() + private MaterialTechnicalReplicateFeatureVector() { } - public MaterialSingleReplicaFeatureVector(int replicaSequenceNumber, float[] featueVectorSummary) + public MaterialTechnicalReplicateFeatureVector(int technicalReplicateSequenceNumber, + float[] featueVector) { - this.replicaSequenceNumber = replicaSequenceNumber; - this.featueVectorSummary = featueVectorSummary; + this.technicalReplicateSequenceNumber = technicalReplicateSequenceNumber; + this.featueVector = featueVector; } - public int getReplicaSequenceNumber() + public int getTechnicalReplicateSequenceNumber() { - return replicaSequenceNumber; + return technicalReplicateSequenceNumber; } - public float[] getFeatueVectorSummary() + public float[] getFeatueVector() { - return featueVectorSummary; + return featueVector; } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java index d6e7bce5036..9e0734c3111 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java @@ -17,7 +17,9 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto; import java.util.Arrays; +import java.util.List; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; @@ -70,4 +72,14 @@ public class WellData implements IWellData return "repl " + replicaId + ": " + Arrays.toString(featureVector); } + public List<IEntityProperty> getProperties() + { + return well.getProperties(); + } + + public Long getId() + { + return well.getId(); + } + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java index 0983c1a5768..3b317136f1d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java @@ -55,6 +55,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReplicaImage; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria; /** @@ -121,7 +122,7 @@ public interface IScreeningServer extends IServer */ @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) - public List<WellContent> listWellImages(String sessionToken, TechId materialId, + public List<WellReplicaImage> listWellImages(String sessionToken, TechId materialId, @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId experimentId); /** @@ -223,7 +224,7 @@ public interface IScreeningServer extends IServer */ @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) - public MaterialReplicaFeatureSummaryResult getFeatureVectorReplicaSummary(String sessionToken, + public MaterialReplicaFeatureSummaryResult getMaterialFeatureVectorSummary(String sessionToken, @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) TechId experimentId, TechId materialId); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaSubgroupFeatureSummary.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialBiologicalReplicateFeatureSummary.java similarity index 87% rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaSubgroupFeatureSummary.java rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialBiologicalReplicateFeatureSummary.java index cb9ee0e0eae..bb8cc2126fe 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaSubgroupFeatureSummary.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialBiologicalReplicateFeatureSummary.java @@ -22,10 +22,11 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; /** * @author Kaloyan Enimanev */ -public class MaterialReplicaSubgroupFeatureSummary implements ISerializable +public class MaterialBiologicalReplicateFeatureSummary implements ISerializable { private static final long serialVersionUID = ServiceVersionHolder.VERSION; + // i-th element is the value for (i+1) technical replicate private float[] featureValues; // e.g. average or median of all replica values in this subgroup @@ -39,11 +40,11 @@ public class MaterialReplicaSubgroupFeatureSummary implements ISerializable // GWT only @SuppressWarnings("unused") - private MaterialReplicaSubgroupFeatureSummary() + private MaterialBiologicalReplicateFeatureSummary() { } - public MaterialReplicaSubgroupFeatureSummary(float[] featureValues, float aggregatedSummary, + public MaterialBiologicalReplicateFeatureSummary(float[] featureValues, float aggregatedSummary, MaterialReplicaSummaryAggregationType summaryAggregationType) { this.featureValues = featureValues; diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaFeatureSummary.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaFeatureSummary.java index b541a087508..eb94e95da5d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaFeatureSummary.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaFeatureSummary.java @@ -40,9 +40,10 @@ public class MaterialReplicaFeatureSummary implements ISerializable // DISPLAY NOTE: The header of each column should be: // <subgroupName> repl. <replicaSequenceNumber> // e.g. SIRNA XYZ repl. 2 - private List<MaterialReplicaSubgroupFeatureSummary> replicaSubgroups; + private List<MaterialBiologicalReplicateFeatureSummary> biologicalRelicates; - private MaterialReplicaSubgroupFeatureSummary defaultSubgroup; + // technical replicates which do not belong to any biological replicate + private MaterialBiologicalReplicateFeatureSummary technicalReplicates; public CodeAndLabel getFeatureDescription() { @@ -84,24 +85,25 @@ public class MaterialReplicaFeatureSummary implements ISerializable this.featureVectorRank = featureVectorRank; } - public List<MaterialReplicaSubgroupFeatureSummary> getReplicaSubgroups() + public List<MaterialBiologicalReplicateFeatureSummary> getBiologicalRelicates() { - return replicaSubgroups; + return biologicalRelicates; } - public void setReplicaSubgroups(List<MaterialReplicaSubgroupFeatureSummary> replicaSubgroups) + public void setBiologicalRelicates( + List<MaterialBiologicalReplicateFeatureSummary> replicaSubgroups) { - this.replicaSubgroups = replicaSubgroups; + this.biologicalRelicates = replicaSubgroups; } - public MaterialReplicaSubgroupFeatureSummary getDefaultSubgroup() + public MaterialBiologicalReplicateFeatureSummary getTechnicalReplicates() { - return defaultSubgroup; + return technicalReplicates; } - public void setDefaultSubgroup(MaterialReplicaSubgroupFeatureSummary defaultReplica) + public void setTechnicalReplicates(MaterialBiologicalReplicateFeatureSummary defaultReplica) { - this.defaultSubgroup = defaultReplica; + this.technicalReplicates = defaultReplica; } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaFeatureSummaryResult.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaFeatureSummaryResult.java index 0a7f3c66d0f..5ed046fb71b 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaFeatureSummaryResult.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialReplicaFeatureSummaryResult.java @@ -23,6 +23,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; /** + * Info about feature vectors of all wells for one material in one experiment. + * * @author Kaloyan Enimanev */ public class MaterialReplicaFeatureSummaryResult implements ISerializable @@ -46,7 +48,8 @@ public class MaterialReplicaFeatureSummaryResult implements ISerializable return subgroupLabels; } - public List<MaterialReplicaFeatureSummary> getReplicaSummaries() + /** Can be empty if there are no analysis results. */ + public List<MaterialReplicaFeatureSummary> getFeatureSummaries() { return replicaSummaries; } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSummarySettings.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSummarySettings.java index df09b8bbc71..df15eca9ba5 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSummarySettings.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSummarySettings.java @@ -33,7 +33,7 @@ public class MaterialSummarySettings implements ISerializable private String replicaMatrialTypePattern; - private List<String> subgroupPropertyTypeCodes; + private List<String> biologicalReplicatePropertyTypeCodes; private MaterialReplicaSummaryAggregationType aggregationType; @@ -57,14 +57,16 @@ public class MaterialSummarySettings implements ISerializable this.replicaMatrialTypePattern = replicaMatrialTypePattern; } - public List<String> getSubgroupPropertyTypeCodes() + public List<String> getBiologicalReplicatePropertyTypeCodes() { - return subgroupPropertyTypeCodes; + return biologicalReplicatePropertyTypeCodes; } - public void setSubgroupPropertyTypeCodes(String... subgroupPropertyTypeCodes) + public void setBiologicalReplicatePropertyTypeCodes( + String... biologicalReplicatePropertyTypeCodes) { - this.subgroupPropertyTypeCodes = Arrays.asList(subgroupPropertyTypeCodes); + this.biologicalReplicatePropertyTypeCodes = + Arrays.asList(biologicalReplicatePropertyTypeCodes); } public MaterialReplicaSummaryAggregationType getAggregationType() diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellContent.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellContent.java index de9a523d829..78fec8caa49 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellContent.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellContent.java @@ -23,6 +23,7 @@ import java.util.List; import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityReference; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityPropertiesHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; @@ -33,7 +34,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; * * @author Tomasz Pylak */ -public class WellContent extends WellImage implements ISerializable +public class WellContent extends WellImage implements ISerializable, IEntityPropertiesHolder { private static final long serialVersionUID = ServiceVersionHolder.VERSION; @@ -177,4 +178,16 @@ public class WellContent extends WellImage implements ISerializable this.wellProperties = properties; } + /** id of the well */ + public Long getId() + { + return well.getId(); + } + + /** properties of the well */ + public List<IEntityProperty> getProperties() + { + return getWellProperties(); + } + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellReplicaImage.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellReplicaImage.java new file mode 100644 index 00000000000..eba7366ace1 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellReplicaImage.java @@ -0,0 +1,67 @@ +/* + * 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.plugin.screening.shared.basic.dto; + +import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; + +/** + * Contains well description, its image dataset (single) and biological and technical replicate + * labels. + * + * @author Tomasz Pylak + */ +public class WellReplicaImage implements ISerializable +{ + private static final long serialVersionUID = ServiceVersionHolder.VERSION; + + private WellContent wellImage; + + private int technicalReplicateSequenceNumber; + + // null if there are no biological replicates + private String biologicalReplicateLabelOrNull; + + // GWT only + @SuppressWarnings("unused") + private WellReplicaImage() + { + } + + public WellReplicaImage(WellContent wellImage, int technicalReplicaSequenceNumber, + String subgroupLabelOrNull) + { + this.wellImage = wellImage; + this.technicalReplicateSequenceNumber = technicalReplicaSequenceNumber; + this.biologicalReplicateLabelOrNull = subgroupLabelOrNull; + } + + public WellContent getWellImage() + { + return wellImage; + } + + public int getTechnicalReplicateSequenceNumber() + { + return technicalReplicateSequenceNumber; + } + + public String tryGetBiologicalReplicateLabel() + { + return biologicalReplicateLabelOrNull; + } +} diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java index c3b77dea110..f966bad4db2 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java @@ -37,7 +37,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialAllReplicasFeatureVectors; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialReplicaSubgroupFeatureVector; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialBiologicalReplicateFeatureVector; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellDataCollection; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialFeatureVectorSummary; @@ -59,7 +59,7 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit { MaterialSummarySettings settings = new MaterialSummarySettings(); settings.setAggregationType(MaterialReplicaSummaryAggregationType.MEDIAN); - settings.setSubgroupPropertyTypeCodes(SIRNA_PROPERTY_TYPE_CODE); + settings.setBiologicalReplicatePropertyTypeCodes(SIRNA_PROPERTY_TYPE_CODE); int replId = 0; List<IWellData> wellDataList = Arrays.asList( // repl. 1 group 1 @@ -95,7 +95,7 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit assertEquals(featuresDesc, featureVectors.getFeatureDescriptions()); int groupId = 1; - for (MaterialReplicaSubgroupFeatureVector subgroup : featureVectors.getSubgroups()) + for (MaterialBiologicalReplicateFeatureVector subgroup : featureVectors.getSubgroups()) { switch (groupId) { @@ -103,13 +103,13 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit assertArraysEqual(new float[] { 20, 200 }, subgroup.getAggregatedSummary()); assertEquals("siRNA 1", subgroup.getSubgroupLabel()); - assertEquals(3, subgroup.getSingleReplicaValues().size()); + assertEquals(3, subgroup.getTechnicalReplicatesValues().size()); break; case 2: assertArraysEqual(new float[] { 200, 2000 }, subgroup.getAggregatedSummary()); assertEquals("siRNA 2", subgroup.getSubgroupLabel()); - assertEquals(3, subgroup.getSingleReplicaValues().size()); + assertEquals(3, subgroup.getTechnicalReplicatesValues().size()); break; default: fail("unexpected subgroup " + groupId); -- GitLab