From 8a4a7337d0c4821610eb68b07ac08e6de6d1502a Mon Sep 17 00:00:00 2001 From: buczekp <buczekp> Date: Thu, 10 Feb 2011 20:52:10 +0000 Subject: [PATCH] [LMS-2029] limit number of initially loaded features; load subsequent features on demand SVN: 19889 --- .../web/client/IScreeningClientService.java | 9 ++ .../client/IScreeningClientServiceAsync.java | 11 ++- .../heatmaps/HeatmapPresenter.java | 65 ++++++++++++-- .../detailviewers/heatmaps/PlateLayouter.java | 44 +++++----- .../heatmaps/PlateLayouterModel.java | 87 +++++++++++++++---- .../web/server/ScreeningClientService.java | 15 ++++ .../server/FeatureCountLimitProvider.java | 56 ++++++++++++ .../server/IFeatureCountLimitProvider.java | 29 +++++++ .../IScreeningBusinessObjectFactory.java | 5 +- .../ScreeningBusinessObjectFactory.java | 8 ++ .../screening/server/ScreeningServer.java | 11 +++ .../server/ScreeningServerLogger.java | 11 +++ .../server/logic/PlateContentLoader.java | 78 +++++++++++++---- .../screening/shared/IScreeningServer.java | 16 +++- .../screening/shared/ResourceNames.java | 2 + .../DatasetReferencePredicate.java | 45 ++++++++++ .../basic/dto/FeatureVectorDataset.java | 13 +-- .../java/screening-applicationContext.xml | 4 + screening/source/java/service.properties | 7 +- .../heatmaps/WellTooltipGeneratorTest.java | 12 +-- 20 files changed, 450 insertions(+), 78 deletions(-) create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/FeatureCountLimitProvider.java create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IFeatureCountLimitProvider.java create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/authorization/DatasetReferencePredicate.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 f4c27f69fbc..8ccc4f191b0 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 @@ -25,11 +25,14 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteri import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet; import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException; 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.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetEnrichedReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageSampleContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LibraryRegistrationInfo; @@ -70,6 +73,12 @@ public interface IScreeningClientService extends IClientService */ public PlateContent getPlateContent(TechId sampleId) throws UserFailureException; + /** + * Fetches feature vector of specified dataset with one feature specified by name. + */ + public FeatureVectorDataset getFeatureVectorDataset(DatasetReference dataset, + CodeAndLabel featureName); + /** * Fetches information about a plate: metadata and images for wells. The specified dataset is * supposed to be in BDS-HCS format. 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 18e0d5c31b9..4ccba731d5d 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 @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client; +import com.google.gwt.user.client.rpc.AsyncCallback; + import ch.systemsx.cisd.openbis.generic.client.web.client.IClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IResultSetConfig; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialDisplayCriteria; @@ -23,11 +25,14 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet; 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.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetEnrichedReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageSampleContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LibraryRegistrationInfo; @@ -39,8 +44,6 @@ 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.WellSearchCriteria; -import com.google.gwt.user.client.rpc.AsyncCallback; - /** * Service interface for the <i>screening</i> <i>GWT</i> client. * @@ -56,6 +59,10 @@ public interface IScreeningClientServiceAsync extends IClientServiceAsync /** @see IScreeningClientService#getPlateContent(TechId) */ public void getPlateContent(TechId sampleId, final AsyncCallback<PlateContent> callback); + /** @see IScreeningClientService#getFeatureVectorDataset(DatasetReference, CodeAndLabel) */ + public void getFeatureVectorDataset(DatasetReference dataset, CodeAndLabel featureName, + AsyncCallback<FeatureVectorDataset> callback); + /** @see IScreeningClientService#getPlateContentForDataset(TechId) */ public void getPlateContentForDataset(TechId datasetId, AsyncCallback<PlateImages> createDisplayPlateCallback); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/HeatmapPresenter.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/HeatmapPresenter.java index f6597b8bf2d..4f154d29f75 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/HeatmapPresenter.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/HeatmapPresenter.java @@ -8,17 +8,24 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import com.extjs.gxt.ui.client.widget.MessageBox; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Widget; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.IRealNumberRenderer; +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.PropertyType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; +import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningViewContext; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto.WellData; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.heatmaps.dto.Color; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.heatmaps.dto.HeatmapScaleElement; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellMetadata; @@ -50,11 +57,15 @@ class HeatmapPresenter private final IRealNumberRenderer realNumberRenderer; + private final ScreeningViewContext viewContext; + // --- - public HeatmapPresenter(PlateLayouterModel model, IRealNumberRenderer realNumberRenderer, + public HeatmapPresenter(ScreeningViewContext viewContext, PlateLayouterModel model, + IRealNumberRenderer realNumberRenderer, HeatmapPresenter.IHeatmapViewManipulator viewManipulations) { + this.viewContext = viewContext; this.model = model; this.viewManipulations = viewManipulations; this.realNumberRenderer = realNumberRenderer; @@ -71,12 +82,53 @@ class HeatmapPresenter } /** - * Changes the presented heatmap to the one which shows the feature with given label. + * Changes the presented heatmap to the one which shows the feature with given name. */ - public void setFeatureValueMode(String featureName) + public void setFeatureValueMode(CodeAndLabel featureName) + { + if (model.isFeatureAvailable(featureName.getLabel())) + { + doChangeFeatureValueMode(featureName); + } else + { + DatasetReference dataset = model.tryGetDatasetReference(); + if (dataset != null) + { + viewContext.getService().getFeatureVectorDataset(dataset, featureName, + createChangeHeatmapCallback(viewContext, featureName)); + } else + { + MessageBox.alert("Error", "No data set selected", null); + } + } + } + + private void doChangeFeatureValueMode(CodeAndLabel featureName) { - IHeatmapRenderer<WellData> renderer = createFeatureHeatmapRenderer(featureName); - refreshHeatmap(renderer, featureName); + IHeatmapRenderer<WellData> renderer = createFeatureHeatmapRenderer(featureName.getLabel()); + refreshHeatmap(renderer, featureName.getLabel()); + } + + private AsyncCallback<FeatureVectorDataset> createChangeHeatmapCallback( + final ScreeningViewContext context, final CodeAndLabel featureName) + { + return new AbstractAsyncCallback<FeatureVectorDataset>(context) + { + @Override + protected void process(FeatureVectorDataset featureVector) + { + model.updateFeatureVectorDataset(featureVector); + + if (model.isFeatureAvailable(featureName.getLabel())) + { + doChangeFeatureValueMode(featureName); + } else + { + MessageBox.alert("Error", + "No values found for feature " + featureName.getLabel(), null); + } + } + }; } private IHeatmapRenderer<WellData> createFeatureHeatmapRenderer(String featureLabel) @@ -384,8 +436,7 @@ class HeatmapPresenter private int getNumberOfAllFeatures() { - List<String> featureLabels = model.tryGetFeatureLabels(); - return featureLabels == null ? 0 : featureLabels.size(); + return model.getAllFeatureNames().size(); } private String generateOneFeatureDescription(WellData wellData, String featureLabel, diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouter.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouter.java index adf5209da84..4f4e5e0b3ae 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouter.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouter.java @@ -41,6 +41,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget. import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.SimpleModelComboBox; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientServiceAsync; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningViewContext; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.LayoutUtils; @@ -99,7 +100,7 @@ public class PlateLayouter private final Widget view; - private final SimpleModelComboBox<String> heatmapKindChooser; + private final SimpleModelComboBox<CodeAndLabel> heatmapKindChooser; public PlateLayouter(ScreeningViewContext viewContext, PlateMetadata plateMetadata) { @@ -108,7 +109,7 @@ public class PlateLayouter LayoutContainer legendContainer = new LayoutContainer(); IRealNumberRenderer realNumberRenderer = createRealNumberRenderer(viewContext); this.presenter = - new HeatmapPresenter(model, realNumberRenderer, createViewManipulator( + new HeatmapPresenter(viewContext, model, realNumberRenderer, createViewManipulator( renderedWells, legendContainer)); this.heatmapKindChooser = createHeatmapKindComboBox(presenter, viewContext); this.view = renderView(renderedWells, heatmapKindChooser, legendContainer); @@ -164,7 +165,7 @@ public class PlateLayouter public void changeDisplayedFeatureVectorDataset(FeatureVectorDataset dataset) { this.model.setFeatureVectorDataset(dataset); - updateHeatmapKindComboBox(heatmapKindChooser, model.tryGetFeatureLabels()); + updateHeatmapKindComboBox(heatmapKindChooser, model.getAllFeatureNames()); } /** @@ -173,7 +174,7 @@ public class PlateLayouter * re-rendering. */ private static Widget renderView(Component[][] renderedWells, - SimpleModelComboBox<String> heatmapKindChooser, LayoutContainer legendContainer) + SimpleModelComboBox<CodeAndLabel> heatmapKindChooser, LayoutContainer legendContainer) { LayoutContainer container = new LayoutContainer(); container.setScrollMode(Scroll.AUTO); @@ -370,20 +371,20 @@ public class PlateLayouter // --------- - private static SimpleModelComboBox<String> createHeatmapKindComboBox( + private static SimpleModelComboBox<CodeAndLabel> createHeatmapKindComboBox( final HeatmapPresenter presenter, IMessageProvider messageProvider) { - List<LabeledItem<String>> items = createHeatmapKindModel(null); - final SimpleModelComboBox<String> chooser = - new SimpleModelComboBox<String>(messageProvider, items, + List<LabeledItem<CodeAndLabel>> items = createHeatmapKindModel(null); + final SimpleModelComboBox<CodeAndLabel> chooser = + new SimpleModelComboBox<CodeAndLabel>(messageProvider, items, HEATMAP_KIND_COMBOBOX_CHOOSER_WIDTH_PX); - chooser.addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<LabeledItem<String>>>() + chooser.addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<LabeledItem<CodeAndLabel>>>() { @Override public void selectionChanged( - SelectionChangedEvent<SimpleComboValue<LabeledItem<String>>> se) + SelectionChangedEvent<SimpleComboValue<LabeledItem<CodeAndLabel>>> se) { - String featureName = SimpleModelComboBox.getChosenItem(se); + CodeAndLabel featureName = SimpleModelComboBox.getChosenItem(se); if (featureName == null) { presenter.setWellMetadataMode(); @@ -396,25 +397,26 @@ public class PlateLayouter return chooser; } - private static void updateHeatmapKindComboBox(SimpleModelComboBox<String> chooser, - List<String> featureLabelsOrNull) + private static void updateHeatmapKindComboBox(SimpleModelComboBox<CodeAndLabel> chooser, + List<CodeAndLabel> featureNames) { - List<LabeledItem<String>> items = createHeatmapKindModel(featureLabelsOrNull); + List<LabeledItem<CodeAndLabel>> items = createHeatmapKindModel(featureNames); chooser.removeAll(); chooser.add(items); GWTUtils.autoselect(chooser, false); } - private static List<LabeledItem<String>> createHeatmapKindModel(List<String> featureLabelsOrNull) + private static List<LabeledItem<CodeAndLabel>> createHeatmapKindModel( + List<CodeAndLabel> featureNamesOrNull) { - List<LabeledItem<String>> items = new ArrayList<LabeledItem<String>>(); - items.add(new LabeledItem<String>(null, METADATA_HEATMAP_KIND_MSG)); - if (featureLabelsOrNull != null) + List<LabeledItem<CodeAndLabel>> items = new ArrayList<LabeledItem<CodeAndLabel>>(); + items.add(new LabeledItem<CodeAndLabel>(null, METADATA_HEATMAP_KIND_MSG)); + if (featureNamesOrNull != null) { - for (String featureLabel : featureLabelsOrNull) + for (CodeAndLabel featureName : featureNamesOrNull) { - String label = FEATURE_HEATMAP_KIND_PREFIX_MSG + featureLabel; - items.add(new LabeledItem<String>(featureLabel, label)); + String label = FEATURE_HEATMAP_KIND_PREFIX_MSG + featureName.getLabel(); + items.add(new LabeledItem<CodeAndLabel>(featureName, label)); } } return items; diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouterModel.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouterModel.java index 564851df0dd..d7933d2dc7f 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouterModel.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/PlateLayouterModel.java @@ -18,12 +18,15 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application. import java.util.ArrayList; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map.Entry; import java.util.Set; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto.WellData; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorValues; @@ -39,6 +42,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellMetadata; */ class PlateLayouterModel { + private DatasetReference datasetReference; // currently shown dataset + private final WellData[][] wellMatrix; private final List<WellData> wellList; // the same wells as in the matrix @@ -47,8 +52,13 @@ class PlateLayouterModel private ImageDatasetEnrichedReference imageDatasetOrNull; - private List<String> featureLabelsOrNull; // names of all features + // names of all features + private List<CodeAndLabel> allFeatureNames = new ArrayList<CodeAndLabel>(); + + // labels of loaded features + private Set<String> availableFeatureLabels = new LinkedHashSet<String>(); + // labels of loaded vocabulary features private Set<String> vocabularyFeatureLabels = new HashSet<String>(); // --- @@ -59,6 +69,11 @@ class PlateLayouterModel this.wellList = asList(wellMatrix); } + public DatasetReference tryGetDatasetReference() + { + return datasetReference; + } + public WellData[][] getWellMatrix() { return wellMatrix; @@ -79,9 +94,14 @@ class PlateLayouterModel this.imageDatasetOrNull = imageDataset; } - public List<String> tryGetFeatureLabels() + public List<CodeAndLabel> getAllFeatureNames() { - return featureLabelsOrNull; + return allFeatureNames; + } + + public boolean isFeatureAvailable(String featureLabel) + { + return availableFeatureLabels.contains(featureLabel); } public boolean isVocabularyFeature(String featureLabel) @@ -93,14 +113,12 @@ class PlateLayouterModel public void setFeatureVectorDataset(FeatureVectorDataset featureVectorDatasetOrNull) { - unsetFeatureVectors(); - this.vocabularyFeatureLabels.clear(); // TODO PTR: don't clear on update - if (featureVectorDatasetOrNull == null) + cleanFeatureVectors(); + this.datasetReference = null; + if (featureVectorDatasetOrNull != null) { - this.featureLabelsOrNull = null; - } else - { - this.featureLabelsOrNull = featureVectorDatasetOrNull.getFeatureLabels(); + this.datasetReference = featureVectorDatasetOrNull.getDatasetReference(); + this.allFeatureNames.addAll(featureVectorDatasetOrNull.getFeatureNames()); List<? extends FeatureVectorValues> features = featureVectorDatasetOrNull.getDatasetFeatures(); if (features.isEmpty() == false) @@ -118,6 +136,7 @@ class PlateLayouterModel .entrySet()) { String featureLabel = entry.getKey(); + availableFeatureLabels.add(featureLabel); FeatureValue value = entry.getValue(); wellData.addFeatureValue(featureLabel, value); } @@ -126,6 +145,46 @@ class PlateLayouterModel } } + private void cleanFeatureVectors() + { + this.vocabularyFeatureLabels.clear(); + this.availableFeatureLabels.clear(); + this.allFeatureNames.clear(); + for (WellData well : wellList) + { + well.resetFeatureValues(); + } + } + + // add new feature to those already loaded + public void updateFeatureVectorDataset(FeatureVectorDataset featureVectorDataset) + { + assert datasetReference.getCode().equals( + featureVectorDataset.getDatasetReference().getCode()); + + List<? extends FeatureVectorValues> features = featureVectorDataset.getDatasetFeatures(); + if (features.isEmpty() == false) + { + // NOTE: for each feature vector in the dataset this set is the same + this.vocabularyFeatureLabels.addAll(extractVocabularyFeatureLabels(features.get(0))); + } + for (FeatureVectorValues featureVector : features) + { + WellLocation loc = featureVector.getWellLocation(); + WellData wellData = tryGetWellData(loc); + if (wellData != null) + { + for (Entry<String, FeatureValue> entry : featureVector.getFeatureMap().entrySet()) + { + String featureLabel = entry.getKey(); + availableFeatureLabels.add(featureLabel); + FeatureValue value = entry.getValue(); + wellData.addFeatureValue(featureLabel, value); + } + } + } + } + private static Set<String> extractVocabularyFeatureLabels(FeatureVectorValues featureVector) { final Set<String> result = new HashSet<String>(); @@ -155,14 +214,6 @@ class PlateLayouterModel } } - private void unsetFeatureVectors() - { - for (WellData well : wellList) - { - well.resetFeatureValues(); // TODO PTR: needed? keep values of all datasets - } - } - // ------------------------ // Elements will NOT contain null even if well is empty. 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 fe82d66ea8c..c64bd44667a 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 @@ -40,6 +40,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.ITableModelP import ch.systemsx.cisd.openbis.generic.client.web.server.translator.UserFailureExceptionTranslator; import ch.systemsx.cisd.openbis.generic.shared.IServer; 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.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived; @@ -50,6 +51,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.BuildAndEnvironmentInfo; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientService; import ch.systemsx.cisd.openbis.plugin.screening.shared.IScreeningServer; import ch.systemsx.cisd.openbis.plugin.screening.shared.ResourceNames; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetEnrichedReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageSampleContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LibraryRegistrationInfo; @@ -141,6 +144,18 @@ public final class ScreeningClientService extends AbstractClientService implemen } } + public FeatureVectorDataset getFeatureVectorDataset(DatasetReference dataset, + CodeAndLabel featureName) throws UserFailureException + { + try + { + return server.getFeatureVectorDataset(getSessionToken(), dataset, featureName); + } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) + { + throw UserFailureExceptionTranslator.translate(e); + } + } + public PlateImages getPlateContentForDataset(TechId datasetId) { try diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/FeatureCountLimitProvider.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/FeatureCountLimitProvider.java new file mode 100644 index 00000000000..6f9d2224cce --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/FeatureCountLimitProvider.java @@ -0,0 +1,56 @@ +/* + * Copyright 2008 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; + +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Component; + +import ch.systemsx.cisd.openbis.plugin.screening.shared.ResourceNames; + +/** + * The unique {@link IFeatureCountLimitProvider} implementation. + * + * @author Piotr Buczek + */ +@Component(ResourceNames.FEATURE_COUNT_LIMIT_PROVIDER) +public final class FeatureCountLimitProvider implements IFeatureCountLimitProvider +{ + + private static int DEFAULT_FEATURE_COUNT_LIMIT = 5; + + private int limit = DEFAULT_FEATURE_COUNT_LIMIT; + + public FeatureCountLimitProvider() + { + } + + public int getLimit() + { + return limit; + } + + public void setLimitAsString(String limitAsString) + { + // This method is called by spring with value taken from properties file. + // Ignore the new value and keep default value when the property wasn't properly specified. + if (StringUtils.isNumeric(limitAsString)) + { + limit = Integer.parseInt(limitAsString); + } + } + +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IFeatureCountLimitProvider.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IFeatureCountLimitProvider.java new file mode 100644 index 00000000000..bde4a8b02a5 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IFeatureCountLimitProvider.java @@ -0,0 +1,29 @@ +/* + * 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; + +/** + * Provides limit of features to be initially fetched for dataset feature vectors. + * + * @author Piotr Buczek + */ +public interface IFeatureCountLimitProvider +{ + + /** Returns max number of initially loaded features in total for all data sets. */ + int getLimit(); +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IScreeningBusinessObjectFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IScreeningBusinessObjectFactory.java index 38d205b8043..fffa130c737 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IScreeningBusinessObjectFactory.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IScreeningBusinessObjectFactory.java @@ -25,8 +25,8 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatase import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister; import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; -import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IImageDatasetLoader; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSFeatureVectorLoader; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IImageDatasetLoader; /** * A <i>screening</i> plugin specific business object factory. @@ -58,4 +58,7 @@ public interface IScreeningBusinessObjectFactory public IExternalDataBO createExternalDataBO(Session session); public IDatasetLister createDatasetLister(Session session); + + public IFeatureCountLimitProvider getFeatureCountLimitProvider(); + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningBusinessObjectFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningBusinessObjectFactory.java index 3eae7165207..bee199d05a9 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningBusinessObjectFactory.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningBusinessObjectFactory.java @@ -57,6 +57,9 @@ public final class ScreeningBusinessObjectFactory extends AbstractPluginBusiness @Resource(name = ResourceNames.SCREENING_DAO_FACTORY) private IScreeningDAOFactory specificDAOFactory; + @Resource(name = ResourceNames.FEATURE_COUNT_LIMIT_PROVIDER) + private IFeatureCountLimitProvider featureCountLimitProvider; + public ScreeningBusinessObjectFactory() { } @@ -130,4 +133,9 @@ public final class ScreeningBusinessObjectFactory extends AbstractPluginBusiness { return getCommonBusinessObjectFactory().createDatasetLister(session); } + + public IFeatureCountLimitProvider getFeatureCountLimitProvider() + { + return featureCountLimitProvider; + } } 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 925b0325d80..ea0c08a324f 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 @@ -49,6 +49,7 @@ import ch.systemsx.cisd.openbis.generic.server.plugin.ISampleTypeSlaveServerPlug import ch.systemsx.cisd.openbis.generic.shared.ICommonServer; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample; 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.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListMaterialCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; @@ -82,6 +83,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifi import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellMaterialMapping; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellReferenceWithDatasets; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellIdentifier; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetEnrichedReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageSampleContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LogicalImageInfo; @@ -169,6 +172,14 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl return PlateContentLoader.loadImagesAndMetadata(session, businessObjectFactory, plateId); } + public FeatureVectorDataset getFeatureVectorDataset(String sessionToken, + DatasetReference dataset, CodeAndLabel featureName) + { + Session session = getSession(sessionToken); + return PlateContentLoader.loadFeatureVectorDataset(session, businessObjectFactory, dataset, + featureName); + } + public PlateImages getPlateContentForDataset(String sessionToken, TechId datasetId) { 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 3ba6a08231e..68e8f864811 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 @@ -25,6 +25,7 @@ import ch.systemsx.cisd.common.spring.IInvocationLoggerContext; import ch.systemsx.cisd.openbis.generic.shared.AbstractServerLogger; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample; 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.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; @@ -49,6 +50,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifi import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellMaterialMapping; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellReferenceWithDatasets; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellIdentifier; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetEnrichedReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageSampleContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LogicalImageInfo; @@ -91,6 +94,14 @@ final class ScreeningServerLogger extends AbstractServerLogger implements IScree logAccess(sessionToken, "getPlateContent", "PLATE(%s)", plateId.getId()); return null; } + + public FeatureVectorDataset getFeatureVectorDataset(String sessionToken, + DatasetReference dataset, CodeAndLabel featureName) + { + logAccess(sessionToken, "getFeatureVectorDataset", "DATA_SET(%s) FEATURE(%s)", dataset.getCode(), featureName); + return null; + } + public PlateImages getPlateContentForDataset(String sessionToken, TechId datasetId) { diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java index 3a4f4f6269f..a04bba32f56 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java @@ -18,6 +18,7 @@ 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 ch.systemsx.cisd.common.exceptions.UserFailureException; @@ -27,13 +28,13 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister; import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister; 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.ExternalData; 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.ListOrSearchSampleCriteria; 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.basic.dto.CodeAndLabel; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE; @@ -70,9 +71,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IImageDatasetLoa */ public class PlateContentLoader { - // max number of initially loaded features - @SuppressWarnings("unused") - private static int MAX_FEATURES = 7; /** * Loads data about the plate for a specified sample id. Attaches information about images and @@ -84,6 +82,17 @@ public class PlateContentLoader return new PlateContentLoader(session, businessObjectFactory).getPlateContent(plateId); } + /** + * Loads feature vector of specified dataset with one feature specified by name. + */ + public static FeatureVectorDataset loadFeatureVectorDataset(Session session, + IScreeningBusinessObjectFactory businessObjectFactory, DatasetReference dataset, + CodeAndLabel featureName) + { + return new PlateContentLoader(session, businessObjectFactory).fetchFeatureVector(dataset, + featureName); + } + /** * Loads data about the plate for a specified dataset, which is supposed to contain images. */ @@ -270,36 +279,73 @@ public class PlateContentLoader return fetchFeatureVectors(featureVectorDatasetReferences); } + private FeatureVectorDataset fetchFeatureVector(DatasetReference datasetReference, + CodeAndLabel featureName) + { + IHCSFeatureVectorLoader loader = + businessObjectFactory.createHCSFeatureVectorLoader(datasetReference + .getDatastoreCode()); + FeatureVectorDataset result = loadFeatureVector(datasetReference, featureName, loader); + return result; + } + private List<FeatureVectorDataset> fetchFeatureVectors( List<DatasetReference> featureVectorDatasetReferences) { List<FeatureVectorDataset> featureVectorDatasets = new ArrayList<FeatureVectorDataset>(); - for (DatasetReference datasetReference : featureVectorDatasetReferences) + if (featureVectorDatasetReferences.isEmpty() == false) { - IHCSFeatureVectorLoader loader = - businessObjectFactory.createHCSFeatureVectorLoader(datasetReference - .getDatastoreCode()); - FeatureVectorDataset featureVectorDataset = loadFeatureVector(datasetReference, loader); - featureVectorDatasets.add(featureVectorDataset); + int maxFeatures = businessObjectFactory.getFeatureCountLimitProvider().getLimit(); + int maxFeaturesPerDataset = + Math.max(1, maxFeatures / featureVectorDatasetReferences.size()); + for (DatasetReference datasetReference : featureVectorDatasetReferences) + { + IHCSFeatureVectorLoader loader = + businessObjectFactory.createHCSFeatureVectorLoader(datasetReference + .getDatastoreCode()); + FeatureVectorDataset featureVectorDataset = + loadFeatureVector(datasetReference, loader, maxFeaturesPerDataset); + featureVectorDatasets.add(featureVectorDataset); + } } return featureVectorDatasets; } + // loads feature vector with limited number of features private FeatureVectorDataset loadFeatureVector(DatasetReference datasetReference, - IHCSFeatureVectorLoader loader) + IHCSFeatureVectorLoader loader, int maxFeaturesPerDataset) { + List<CodeAndLabel> allFeatureNames = + loader.fetchDatasetFeatureNames(datasetReference.getCode()); + List<CodeAndLabel> featuresToLoad = allFeatureNames; + if (featuresToLoad.size() > maxFeaturesPerDataset) + { + featuresToLoad = featuresToLoad.subList(0, maxFeaturesPerDataset); + } + WellFeatureCollection<FeatureVectorValues> featureValues = + loader.fetchDatasetFeatureValues(datasetReference.getCode(), featuresToLoad); + List<FeatureVectorValues> featureVectors = featureValues.getFeatures(); + + FeatureVectorDataset featureVectorDataset = + new FeatureVectorDataset(datasetReference, featureVectors, allFeatureNames); + return featureVectorDataset; + } - List<CodeAndLabel> featureNames = + // loads feature vector with only one feature specified by name + private FeatureVectorDataset loadFeatureVector(DatasetReference datasetReference, + CodeAndLabel featureName, IHCSFeatureVectorLoader loader) + { + List<CodeAndLabel> allFeatureNames = loader.fetchDatasetFeatureNames(datasetReference.getCode()); - // TODO PTR limit names + WellFeatureCollection<FeatureVectorValues> featureValues = - loader.fetchDatasetFeatureValues(datasetReference.getCode(), featureNames); + loader.fetchDatasetFeatureValues(datasetReference.getCode(), + Collections.singletonList(featureName)); List<FeatureVectorValues> featureVectors = featureValues.getFeatures(); - List<String> featureLabels = CodeAndLabel.asLabels(featureNames); FeatureVectorDataset featureVectorDataset = - new FeatureVectorDataset(datasetReference, featureVectors, featureLabels); + new FeatureVectorDataset(datasetReference, featureVectors, allFeatureNames); return featureVectorDataset; } 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 d0d16455309..befe4fbd8e9 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 @@ -30,6 +30,7 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractT import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodePredicate; import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleTechIdPredicate; 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.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; @@ -39,8 +40,11 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; +import ch.systemsx.cisd.openbis.plugin.screening.shared.authorization.DatasetReferencePredicate; import ch.systemsx.cisd.openbis.plugin.screening.shared.authorization.WellContentValidator; import ch.systemsx.cisd.openbis.plugin.screening.shared.authorization.WellSearchCriteriaPredicate; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetEnrichedReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageSampleContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LogicalImageInfo; @@ -58,7 +62,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCrit public interface IScreeningServer extends IServer { /** - * loads data about the plate for a specified sample id. Attaches information about images and + * Loads data about the plate for a specified sample id. Attaches information about images and * image analysis only if one dataset with such a data exist. */ @Transactional(readOnly = true) @@ -66,6 +70,16 @@ public interface IScreeningServer extends IServer public PlateContent getPlateContent(String sessionToken, @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) TechId plateId); + /** + * Loads feature vector of specified dataset with one feature specified by name. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) + public FeatureVectorDataset getFeatureVectorDataset( + String sessionToken, + @AuthorizationGuard(guardClass = DatasetReferencePredicate.class) DatasetReference dataset, + CodeAndLabel featureName); + /** * Returns plate content for a specified HCS_IMAGE dataset. Loads data about the plate for a * specified dataset, which is supposed to contain images in BDS-HCS format. diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/ResourceNames.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/ResourceNames.java index cba01cf953c..8b545d76ec7 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/ResourceNames.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/ResourceNames.java @@ -43,5 +43,7 @@ public final class ResourceNames public final static String SCREENING_SAMPLE_SERVER_PLUGIN = "screening-sample-server-plugin"; + public final static String FEATURE_COUNT_LIMIT_PROVIDER = "feature-count-limit-provider"; + public static final String MAIL_CLIENT_PARAMETERS = "mail-client-parameters"; } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/authorization/DatasetReferencePredicate.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/authorization/DatasetReferencePredicate.java new file mode 100644 index 00000000000..7572b2e9e99 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/authorization/DatasetReferencePredicate.java @@ -0,0 +1,45 @@ +/* + * Copyright 2008 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.authorization; + +import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodePredicate; +import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DelegatedPredicate; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; + +/** + * @author Piotr Buczek + */ +public final class DatasetReferencePredicate extends DelegatedPredicate<String, DatasetReference> +{ + public DatasetReferencePredicate() + { + super(new DataSetCodePredicate()); + } + + @Override + public final String getCandidateDescription() + { + return "dataset reference"; + } + + @Override + public String tryConvert(DatasetReference value) + { + return value.getCode(); + } + +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/FeatureVectorDataset.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/FeatureVectorDataset.java index 8de439b7180..acbaa665f8a 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/FeatureVectorDataset.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/FeatureVectorDataset.java @@ -19,6 +19,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; import java.util.List; import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; +import ch.systemsx.cisd.openbis.generic.shared.basic.annotation.DoNotEscape; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; /** @@ -26,13 +28,14 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; * * @author Tomasz Pylak */ +@DoNotEscape public class FeatureVectorDataset implements ISerializable { private static final long serialVersionUID = ServiceVersionHolder.VERSION; private DatasetReference datasetReference; - private List<String> featureLabels; + private List<CodeAndLabel> featureNames; private List<FeatureVectorValues> datasetFeatures; @@ -43,11 +46,11 @@ public class FeatureVectorDataset implements ISerializable } public FeatureVectorDataset(DatasetReference datasetReference, - List<FeatureVectorValues> datasetFeatures, List<String> featureLabels) + List<FeatureVectorValues> datasetFeatures, List<CodeAndLabel> featureNames) { this.datasetReference = datasetReference; this.datasetFeatures = datasetFeatures; - this.featureLabels = featureLabels; + this.featureNames = featureNames; } public DatasetReference getDatasetReference() @@ -55,9 +58,9 @@ public class FeatureVectorDataset implements ISerializable return datasetReference; } - public List<String> getFeatureLabels() + public List<CodeAndLabel> getFeatureNames() { - return featureLabels; + return featureNames; } public List<? extends FeatureVectorValues> getDatasetFeatures() diff --git a/screening/source/java/screening-applicationContext.xml b/screening/source/java/screening-applicationContext.xml index fb7b1f1a948..45bc6c0bf0b 100644 --- a/screening/source/java/screening-applicationContext.xml +++ b/screening/source/java/screening-applicationContext.xml @@ -18,6 +18,10 @@ <constructor-arg ref="${data-source-provider}"/> </bean> + <bean id="feature-count-limit-provider" class="ch.systemsx.cisd.openbis.plugin.screening.server.FeatureCountLimitProvider"> + <property name="limitAsString" value="${feature-count-limit}"/> + </bean> + <!-- //Mail Client Parameters --> diff --git a/screening/source/java/service.properties b/screening/source/java/service.properties index 68625e05929..803ff482785 100644 --- a/screening/source/java/service.properties +++ b/screening/source/java/service.properties @@ -55,7 +55,7 @@ cifex-recipient = id:cifexdatamanager hibernate.search.index-base = ./targets/indices-${database.kind} # One of NO_INDEX, SKIP_IF_MARKER_FOUND, INDEX_FROM_SCRATCH. # If not specified, default (SKIP_IF_MARKER_FOUND) is taken. -hibernate.search.index-mode = NO_INDEX +hibernate.search.index-mode = SKIP_IF_MARKER_FOUND #hibernate.search.index-mode = INDEX_FROM_SCRATCH # Defines the maximum number of elements indexed before flushing the transaction-bound queue. # Default is 1000. @@ -66,4 +66,7 @@ hibernate.search.maxResults = 100000 hibernate.search.worker.execution=async # Name of the file that stores Web Client configuration -web-client-configuration-file = etc/web-client.properties \ No newline at end of file +web-client-configuration-file = etc/web-client.properties + +# (optional) max number of features to load initially for every Plate Layout view (default: 5) +feature-count-limit = 10 \ No newline at end of file diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/WellTooltipGeneratorTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/WellTooltipGeneratorTest.java index 2a88079fcb2..05093da83b8 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/WellTooltipGeneratorTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/heatmaps/WellTooltipGeneratorTest.java @@ -29,6 +29,7 @@ import org.testng.annotations.Test; import ch.systemsx.cisd.common.test.AssertionUtil; import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.IRealNumberRenderer; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; @@ -154,18 +155,18 @@ public class WellTooltipGeneratorTest extends AssertJUnit private static FeatureVectorDataset createLargeFeatureVectorDataset() { int size = 40; - List<String> featureLabels = new ArrayList<String>(size); + List<CodeAndLabel> featureNames = new ArrayList<CodeAndLabel>(size); Map<String, FeatureValue> featureValuesMap = new LinkedHashMap<String, FeatureValue>(); for (int i = 0; i < size; i++) { final String label = "Feature" + i; final FeatureValue featureValue = FeatureValue.createFloat(i); - featureLabels.add("Feature" + i); + featureNames.add(new CodeAndLabel(label, label)); featureValuesMap.put(label, featureValue); } List<FeatureVectorValues> features = new ArrayList<FeatureVectorValues>(); features.add(new FeatureVectorValues(null, getLocation(WELL_A2), featureValuesMap)); - return new FeatureVectorDataset(createDatasetReference(), features, featureLabels); + return new FeatureVectorDataset(createDatasetReference(), features, featureNames); } private static FeatureVectorDataset createFeatureVectorDataset() @@ -181,8 +182,9 @@ public class WellTooltipGeneratorTest extends AssertJUnit features.add(new FeatureVectorValues(null, getLocation(WELL_B3), createFeatureVectorMap( featureLabels, new FeatureValue[] { FeatureValue.createFloat(-1), FeatureValue.createFloat(-2) }))); - return new FeatureVectorDataset(createDatasetReference(), features, - Arrays.asList(featureLabels)); + return new FeatureVectorDataset(createDatasetReference(), features, Arrays.asList( + new CodeAndLabel(featureLabels[0], featureLabels[0]), new CodeAndLabel( + featureLabels[1], featureLabels[1]))); } private static Map<String, FeatureValue> createFeatureVectorMap(String[] labels, -- GitLab