From a34e9e38e40310185ba52c8fc91c6099bd0c6cc5 Mon Sep 17 00:00:00 2001 From: buczekp <buczekp> Date: Wed, 9 Feb 2011 20:43:50 +0000 Subject: [PATCH] [LMS-2035] refactoring, use: - feature labels instead of indexes, - map <feature label -> feature value> instead of feature value array; SVN: 19850 --- .../plugin/screening/OpenBISIE.gwt.xml | 13 +++ .../detailviewers/dto/WellData.java | 32 ++++-- .../heatmaps/HeatmapPresenter.java | 99 ++++++++++--------- .../detailviewers/heatmaps/PlateLayouter.java | 37 ++++--- .../heatmaps/PlateLayouterModel.java | 55 ++++++----- .../shared/basic/dto/FeatureVectorValues.java | 20 ++-- .../screening/shared/dto/FeatureTableRow.java | 2 +- .../shared/imaging/FeatureVectorLoader.java | 19 +++- .../server/DssServiceRpcScreeningTest.java | 11 ++- .../heatmaps/WellTooltipGeneratorTest.java | 54 +++++++--- 10 files changed, 216 insertions(+), 126 deletions(-) create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/OpenBISIE.gwt.xml diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/OpenBISIE.gwt.xml b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/OpenBISIE.gwt.xml new file mode 100644 index 00000000000..3f5f98dea52 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/OpenBISIE.gwt.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.1/distro-source/core/src/gwt-module.dtd"> +<module rename-to="ch.systemsx.cisd.openbis.plugin.screening.OpenBIS"> + <inherits name='ch.systemsx.cisd.openbis.OpenBIS-without-entry-point' /> + <set-property name="user.agent" value="ie8" /> + + <entry-point class='ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningClient' /> + + <script src="screening-dictionary.js" /> + <public path="client/web/public" /> + <source path="client/web/client" /> + <source path="shared/basic" /> +</module> diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/WellData.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/WellData.java index 556b9c2c1df..384cdba664c 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/WellData.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/WellData.java @@ -16,6 +16,10 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; @@ -34,7 +38,10 @@ public class WellData private WellMetadata wellMetadataOrNull; - private FeatureValue[] featureValuesOrNull; + // ordered map from feature labels to feature values + // NOTE: it contains a subset of all feature values of a well (only the ones that were loaded) + private Map<String /* feature label */, FeatureValue> featureValuesMap = + new LinkedHashMap<String, FeatureValue>(); public WellData(WellLocation wellLocation, Experiment experiment) { @@ -42,18 +49,25 @@ public class WellData this.experiment = experiment; } - public void setFeatureValues(FeatureValue[] featureValues) + public void addFeatureValue(String featureName, FeatureValue value) + { + featureValuesMap.put(featureName, value); + } + + public void resetFeatureValues() + { + featureValuesMap.clear(); + } + + public FeatureValue tryGetFeatureValue(String featureLabel) { - this.featureValuesOrNull = featureValues; + return featureValuesMap.get(featureLabel); } - public FeatureValue tryGetFeatureValue(int featureVectorIndex) + // ordered set of feature labels for which we have loaded feature values + public Set<String> getFeatureLabels() { - if (featureValuesOrNull == null) - { - return null; - } - return featureValuesOrNull[featureVectorIndex]; + return featureValuesMap.keySet(); } public void setMetadata(WellMetadata well) 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 e90ecca5705..f6597b8bf2d 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 @@ -71,49 +71,48 @@ class HeatmapPresenter } /** - * Changes the presented heatmap to the one which shows the feature which appears in all - * {@link WellData} on a specified index. + * Changes the presented heatmap to the one which shows the feature with given label. */ - public void setFeatureValueMode(int featureIndex) + public void setFeatureValueMode(String featureName) { - IHeatmapRenderer<WellData> renderer = createFeatureHeatmapRenderer(featureIndex); - refreshHeatmap(renderer, featureIndex); + IHeatmapRenderer<WellData> renderer = createFeatureHeatmapRenderer(featureName); + refreshHeatmap(renderer, featureName); } - private IHeatmapRenderer<WellData> createFeatureHeatmapRenderer(int featureIndex) + private IHeatmapRenderer<WellData> createFeatureHeatmapRenderer(String featureLabel) { List<WellData> wellList = model.getWellList(); - if (model.isVocabularyFeature(featureIndex)) + if (model.isVocabularyFeature(featureLabel)) { - return createVocabularyFeatureHeatmapRenderer(wellList, featureIndex); + return createVocabularyFeatureHeatmapRenderer(wellList, featureLabel); } else { - return createFloatFeatureHeatmapRenderer(wellList, featureIndex, realNumberRenderer); + return createFloatFeatureHeatmapRenderer(wellList, featureLabel, realNumberRenderer); } } - // here we are sure that all wells have a vocabulary feature at featureIndex index + // here we are sure that all wells have a vocabulary feature with given featureLabel private static IHeatmapRenderer<WellData> createVocabularyFeatureHeatmapRenderer( - List<WellData> wellList, final int featureIndex) + List<WellData> wellList, final String featureLabel) { - List<String> uniqueValues = extractUniqueVocabularyTerms(wellList, featureIndex); + List<String> uniqueValues = extractUniqueVocabularyTerms(wellList, featureLabel); return new DetegatingStringHeatmapRenderer<WellData>(uniqueValues, null) { @Override protected String extractLabel(WellData well) { - return tryAsVocabularyFeature(well, featureIndex); + return tryAsVocabularyFeature(well, featureLabel); } }; } private static List<String> extractUniqueVocabularyTerms(List<WellData> wellList, - int featureIndex) + String featureLabel) { Set<String> uniqueValues = new HashSet<String>(); for (WellData well : wellList) { - String term = tryAsVocabularyFeature(well, featureIndex); + String term = tryAsVocabularyFeature(well, featureLabel); if (term != null) { uniqueValues.add(term); @@ -125,7 +124,7 @@ class HeatmapPresenter } // updates color of all well components - private void refreshHeatmap(IHeatmapRenderer<WellData> renderer, Integer featureIndexOrNull) + private void refreshHeatmap(IHeatmapRenderer<WellData> renderer, String featureLabelOrNull) { WellData[][] wellMatrix = model.getWellMatrix(); for (int rowIx = 0; rowIx < wellMatrix.length; rowIx++) @@ -136,7 +135,7 @@ class HeatmapPresenter Color color = renderer.getColor(wellData); String tooltipOrNull = WellTooltipGenerator.tryGenerateTooltip(model, rowIx, colIx, - featureIndexOrNull, realNumberRenderer); + featureLabelOrNull, realNumberRenderer); viewManipulations.refreshWellStyle(rowIx, colIx, color, tooltipOrNull); } } @@ -151,15 +150,15 @@ class HeatmapPresenter viewManipulations.updateLegend(legend); } - // here we are sure that all wells have a float feature at featureIndex index + // here we are sure that all wells have a float feature with given featureLabel private static IHeatmapRenderer<WellData> createFloatFeatureHeatmapRenderer( - List<WellData> wells, final int featureIndex, IRealNumberRenderer realNumberRenderer) + List<WellData> wells, final String featureLabel, IRealNumberRenderer realNumberRenderer) { float min = Float.MAX_VALUE; float max = Float.MIN_VALUE; for (WellData well : wells) { - Float value = tryAsFloatFeature(well, featureIndex); + Float value = tryAsFloatFeature(well, featureLabel); if (value != null && Float.isNaN(value) == false && Float.isInfinite(value) == false) { min = Math.min(min, value); @@ -171,20 +170,20 @@ class HeatmapPresenter @Override protected Float convert(WellData well) { - return tryAsFloatFeature(well, featureIndex); + return tryAsFloatFeature(well, featureLabel); } }; } - private static float tryAsFloatFeature(WellData well, final int featureIndex) + private static float tryAsFloatFeature(WellData well, final String featureLabel) { - FeatureValue value = well.tryGetFeatureValue(featureIndex); + FeatureValue value = well.tryGetFeatureValue(featureLabel); return value != null ? value.asFloat() : null; } - private static String tryAsVocabularyFeature(WellData well, final int featureIndex) + private static String tryAsVocabularyFeature(WellData well, final String featureLabel) { - FeatureValue value = well.tryGetFeatureValue(featureIndex); + FeatureValue value = well.tryGetFeatureValue(featureLabel); return value != null ? value.tryAsVocabularyTerm() : null; } @@ -311,14 +310,14 @@ class HeatmapPresenter /** * Generates a short description of the well, which can be used as e.g. a tooltip * - * @param featureIndexOrNull if not null contains an index of the feature which should be + * @param featureLabelOrNull if not null contains label of the feature which should be * distinguished. */ public static String tryGenerateTooltip(PlateLayouterModel model, int rowIx, int colIx, - Integer featureIndexOrNull, IRealNumberRenderer realNumberRenderer) + String featureLabelOrNull, IRealNumberRenderer realNumberRenderer) { return new WellTooltipGenerator(model, realNumberRenderer).tryGenerateShortDescription( - rowIx, colIx, featureIndexOrNull); + rowIx, colIx, featureLabelOrNull); } private final PlateLayouterModel model; @@ -332,19 +331,21 @@ class HeatmapPresenter this.realNumberRenderer = realNumberRenderer; } - private String tryGenerateShortDescription(int rowIx, int colIx, Integer featureIndexOrNull) + private String tryGenerateShortDescription(int rowIx, int colIx, + String distinguishedLabelOrNull) { WellData wellData = model.getWellMatrix()[rowIx][colIx]; String tooltip = ""; - if (featureIndexOrNull != null) + if (distinguishedLabelOrNull != null) { - tooltip += generateOneFeatureDescription(wellData, featureIndexOrNull, true); + tooltip += generateOneFeatureDescription(wellData, distinguishedLabelOrNull, true); } tooltip += generateMetadataDescription(wellData); - int featuresNum = getNumberOfFeatures(); - if (featuresNum - (featureIndexOrNull != null ? 1 : 0) > 0) + int allFeaturesNum = getNumberOfAllFeatures(); + int loadedFeaturesNum = getNumberOfLoadedFeatures(wellData); + if (loadedFeaturesNum - (distinguishedLabelOrNull != null ? 1 : 0) > 0) { if (tooltip.length() == 0) { @@ -353,15 +354,21 @@ class HeatmapPresenter { tooltip += NEWLINE; // separate metadata from the text below } - int describedFeaturesNum = Math.min(MAX_DESCRIBED_FEATURES, featuresNum); - for (int ix = 0; ix < describedFeaturesNum; ix++) + int describedFeaturesNum = Math.min(MAX_DESCRIBED_FEATURES, loadedFeaturesNum); + int fCounter = 0; + for (String featureLabel : wellData.getFeatureLabels()) { - if (featureIndexOrNull == null || ix != featureIndexOrNull.intValue()) + if (featureLabel.equals(distinguishedLabelOrNull) == false) { - tooltip += generateOneFeatureDescription(wellData, ix, false); + tooltip += generateOneFeatureDescription(wellData, featureLabel, false); + } + fCounter++; + if (fCounter == describedFeaturesNum) + { + break; } } - if (featuresNum > describedFeaturesNum) + if (allFeaturesNum > describedFeaturesNum) { tooltip += "..."; } @@ -370,19 +377,21 @@ class HeatmapPresenter } - private int getNumberOfFeatures() + private int getNumberOfLoadedFeatures(WellData wellData) + { + return wellData.getFeatureLabels().size(); + } + + private int getNumberOfAllFeatures() { List<String> featureLabels = model.tryGetFeatureLabels(); return featureLabels == null ? 0 : featureLabels.size(); } - private String generateOneFeatureDescription(WellData wellData, int featureIndex, + private String generateOneFeatureDescription(WellData wellData, String featureLabel, boolean distinguished) { - List<String> featureLabels = model.tryGetFeatureLabels(); - assert featureLabels != null : "feature labels not set"; - - FeatureValue value = wellData.tryGetFeatureValue(featureIndex); + FeatureValue value = wellData.tryGetFeatureValue(featureLabel); // if the value should be distinguished we show it even if it's null if (value == null && distinguished == false) { @@ -393,7 +402,7 @@ class HeatmapPresenter { textValue = "<b>" + textValue + "</b>"; } - return featureLabels.get(featureIndex) + ": " + textValue + NEWLINE; + return featureLabel + ": " + textValue + NEWLINE; } private String renderValue(FeatureValue value) 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 71252b3f483..adf5209da84 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 @@ -99,7 +99,7 @@ public class PlateLayouter private final Widget view; - private final SimpleModelComboBox<Integer> heatmapKindChooser; + private final SimpleModelComboBox<String> heatmapKindChooser; public PlateLayouter(ScreeningViewContext viewContext, PlateMetadata plateMetadata) { @@ -173,7 +173,7 @@ public class PlateLayouter * re-rendering. */ private static Widget renderView(Component[][] renderedWells, - SimpleModelComboBox<Integer> heatmapKindChooser, LayoutContainer legendContainer) + SimpleModelComboBox<String> heatmapKindChooser, LayoutContainer legendContainer) { LayoutContainer container = new LayoutContainer(); container.setScrollMode(Scroll.AUTO); @@ -370,54 +370,51 @@ public class PlateLayouter // --------- - private static SimpleModelComboBox<Integer> createHeatmapKindComboBox( + private static SimpleModelComboBox<String> createHeatmapKindComboBox( final HeatmapPresenter presenter, IMessageProvider messageProvider) { - List<LabeledItem<Integer>> items = createHeatmapKindModel(null); - final SimpleModelComboBox<Integer> chooser = - new SimpleModelComboBox<Integer>(messageProvider, items, + List<LabeledItem<String>> items = createHeatmapKindModel(null); + final SimpleModelComboBox<String> chooser = + new SimpleModelComboBox<String>(messageProvider, items, HEATMAP_KIND_COMBOBOX_CHOOSER_WIDTH_PX); - chooser.addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<LabeledItem<Integer>>>() + chooser.addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<LabeledItem<String>>>() { @Override public void selectionChanged( - SelectionChangedEvent<SimpleComboValue<LabeledItem<Integer>>> se) + SelectionChangedEvent<SimpleComboValue<LabeledItem<String>>> se) { - Integer value = SimpleModelComboBox.getChosenItem(se); - if (value == null) + String featureName = SimpleModelComboBox.getChosenItem(se); + if (featureName == null) { presenter.setWellMetadataMode(); } else { - presenter.setFeatureValueMode(value); + presenter.setFeatureValueMode(featureName); } } }); return chooser; } - private static void updateHeatmapKindComboBox(SimpleModelComboBox<Integer> chooser, + private static void updateHeatmapKindComboBox(SimpleModelComboBox<String> chooser, List<String> featureLabelsOrNull) { - List<LabeledItem<Integer>> items = createHeatmapKindModel(featureLabelsOrNull); + List<LabeledItem<String>> items = createHeatmapKindModel(featureLabelsOrNull); chooser.removeAll(); chooser.add(items); GWTUtils.autoselect(chooser, false); } - private static List<LabeledItem<Integer>> createHeatmapKindModel( - List<String> featureLabelsOrNull) + private static List<LabeledItem<String>> createHeatmapKindModel(List<String> featureLabelsOrNull) { - List<LabeledItem<Integer>> items = new ArrayList<LabeledItem<Integer>>(); - items.add(new LabeledItem<Integer>(null, METADATA_HEATMAP_KIND_MSG)); + List<LabeledItem<String>> items = new ArrayList<LabeledItem<String>>(); + items.add(new LabeledItem<String>(null, METADATA_HEATMAP_KIND_MSG)); if (featureLabelsOrNull != null) { - int i = 0; for (String featureLabel : featureLabelsOrNull) { String label = FEATURE_HEATMAP_KIND_PREFIX_MSG + featureLabel; - items.add(new LabeledItem<Integer>(i, label)); - i++; + items.add(new LabeledItem<String>(featureLabel, 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 9575b487417..564851df0dd 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 @@ -17,7 +17,10 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.heatmaps; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Map.Entry; +import java.util.Set; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto.WellData; @@ -44,9 +47,9 @@ class PlateLayouterModel private ImageDatasetEnrichedReference imageDatasetOrNull; - private List<String> featureLabelsOrNull; + private List<String> featureLabelsOrNull; // names of all features - private boolean[] isVocabularyFeatureMapOrNull; + private Set<String> vocabularyFeatureLabels = new HashSet<String>(); // --- @@ -81,15 +84,9 @@ class PlateLayouterModel return featureLabelsOrNull; } - public boolean isVocabularyFeature(int featureVectorIndex) + public boolean isVocabularyFeature(String featureLabel) { - if (isVocabularyFeatureMapOrNull == null) - { - return false; - } else - { - return isVocabularyFeatureMapOrNull[featureVectorIndex]; - } + return vocabularyFeatureLabels.contains(featureLabel); } // --- some logic @@ -97,7 +94,7 @@ class PlateLayouterModel public void setFeatureVectorDataset(FeatureVectorDataset featureVectorDatasetOrNull) { unsetFeatureVectors(); - this.isVocabularyFeatureMapOrNull = null; + this.vocabularyFeatureLabels.clear(); // TODO PTR: don't clear on update if (featureVectorDatasetOrNull == null) { this.featureLabelsOrNull = null; @@ -106,32 +103,42 @@ class PlateLayouterModel this.featureLabelsOrNull = featureVectorDatasetOrNull.getFeatureLabels(); List<? extends FeatureVectorValues> features = featureVectorDatasetOrNull.getDatasetFeatures(); + if (features.isEmpty() == false) + { + // NOTE: for each feature vector in the dataset this set is the same + this.vocabularyFeatureLabels = extractVocabularyFeatureLabels(features.get(0)); + } for (FeatureVectorValues featureVector : features) { - if (this.isVocabularyFeatureMapOrNull == null) - { - // NOTE: for each feature vector in the dataset this map would be the same - this.isVocabularyFeatureMapOrNull = createIsVocabularyMap(featureVector); - } WellLocation loc = featureVector.getWellLocation(); WellData wellData = tryGetWellData(loc); if (wellData != null) { - wellData.setFeatureValues(featureVector.getFeatureValues()); + for (Entry<String, FeatureValue> entry : featureVector.getFeatureMap() + .entrySet()) + { + String featureLabel = entry.getKey(); + FeatureValue value = entry.getValue(); + wellData.addFeatureValue(featureLabel, value); + } } } } } - private static boolean[] createIsVocabularyMap(FeatureVectorValues featureVector) + private static Set<String> extractVocabularyFeatureLabels(FeatureVectorValues featureVector) { - FeatureValue[] values = featureVector.getFeatureValues(); - boolean[] map = new boolean[values.length]; - for (int i = 0; i < map.length; i++) + final Set<String> result = new HashSet<String>(); + for (Entry<String, FeatureValue> entry : featureVector.getFeatureMap().entrySet()) { - map[i] = values[i].isVocabularyTerm(); + String featureLabel = entry.getKey(); + FeatureValue featureValue = entry.getValue(); + if (featureValue.isVocabularyTerm()) + { + result.add(featureLabel); + } } - return map; + return result; } private WellData tryGetWellData(WellLocation loc) @@ -152,7 +159,7 @@ class PlateLayouterModel { for (WellData well : wellList) { - well.setFeatureValues(null); + well.resetFeatureValues(); // TODO PTR: needed? keep values of all datasets } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/FeatureVectorValues.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/FeatureVectorValues.java index e0c8a21abba..0c76c12be1c 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/FeatureVectorValues.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/FeatureVectorValues.java @@ -16,6 +16,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; +import java.util.Map; + 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.ServiceVersionHolder; @@ -33,7 +35,7 @@ public class FeatureVectorValues implements ISerializable private WellFeatureVectorReference featureVectorReference; - private FeatureValue[] featureValues; + private Map<String /* feature label */, FeatureValue /* value */> featureMap; // GWT only @SuppressWarnings("unused") @@ -42,21 +44,27 @@ public class FeatureVectorValues implements ISerializable } public FeatureVectorValues(String dataSetCode, WellLocation wellLocation, - FeatureValue[] featureValues) + Map<String, FeatureValue> featureMap) { - this(new WellFeatureVectorReference(dataSetCode, wellLocation), featureValues); + this(new WellFeatureVectorReference(dataSetCode, wellLocation), featureMap); } public FeatureVectorValues(WellFeatureVectorReference featureVectorReference, - FeatureValue[] featureValues) + Map<String, FeatureValue> featureMap) { this.featureVectorReference = featureVectorReference; - this.featureValues = featureValues; + this.featureMap = featureMap; } + // NOTE: don't use this method multiple times for performance reasons public FeatureValue[] getFeatureValues() { - return featureValues; + return featureMap.values().toArray(new FeatureValue[0]); + } + + public Map<String, FeatureValue> getFeatureMap() + { + return featureMap; } public String getDataSetCode() diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/dto/FeatureTableRow.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/dto/FeatureTableRow.java index f4003b95aca..28d791d3dd6 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/dto/FeatureTableRow.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/dto/FeatureTableRow.java @@ -38,7 +38,7 @@ public class FeatureTableRow extends FeatureVectorValues public FeatureTableRow(FeatureVectorValues featureVector) { super(featureVector.getDataSetCode(), featureVector.getWellLocation(), featureVector - .getFeatureValues()); + .getFeatureMap()); } public FeatureVectorDatasetWellReference getReference() diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/FeatureVectorLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/FeatureVectorLoader.java index f6e908fbd5b..921c7a9592d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/FeatureVectorLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/FeatureVectorLoader.java @@ -134,12 +134,13 @@ public class FeatureVectorLoader List<FeatureVectorValues> fvs = new ArrayList<FeatureVectorValues>(); for (FeatureTableRow row : featureRows) { - fvs.add(new FeatureVectorValues(row.getFeatureVectorReference(), row.getFeatureValues())); + fvs.add(new FeatureVectorValues(row.getFeatureVectorReference(), row.getFeatureMap())); } return new WellFeatureCollection<FeatureVectorValues>(fvs, featureRowsCollection.getFeatureCodesAndLabels()); } + // TODO PTR use filtering by codes /** * fetches specified features of all wells * @@ -499,10 +500,24 @@ public class FeatureVectorLoader WellLocation wellLocation) { String permId = bundle.dataSet.getPermId(); + FeatureValue[] valueArray = createFeatureValueArray(bundle.featureDefToValuesMap, bundle.featureDefToVocabularyTerms, wellLocation); - return new FeatureVectorValues(permId, wellLocation, valueArray); + return new FeatureVectorValues(permId, wellLocation, asValueMap(valueArray)); + } + + private Map<String, FeatureValue> asValueMap(FeatureValue[] valueArray) + { + List<CodeAndLabel> features = getCodesAndLabels(); + assert features.size() == valueArray.length; + + Map<String, FeatureValue> result = new LinkedHashMap<String, FeatureValue>(); + for (int i = 0; i < valueArray.length; i++) + { + result.put(features.get(i).getLabel(), valueArray[i]); + } + return result; } private FeatureValue[] createFeatureValueArray( diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java index 5e1f8958769..bb399189139 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java @@ -45,7 +45,6 @@ import ch.systemsx.cisd.common.io.ByteArrayBasedContent; import ch.systemsx.cisd.common.io.ConcatenatedFileOutputStreamWriter; import ch.systemsx.cisd.common.io.FileBasedContent; import ch.systemsx.cisd.common.io.IContent; -import ch.systemsx.cisd.etlserver.Constants; import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference; import ch.systemsx.cisd.openbis.dss.etl.IImagingDatasetLoader; import ch.systemsx.cisd.openbis.dss.generic.server.DssServiceRpcAuthorizationAdvisor; @@ -203,7 +202,7 @@ public class DssServiceRpcScreeningTest extends AssertJUnit final String channel = "dapi"; prepareGetHomeDatabaseInstance(); prepareListDataSetsByCode(); - + List<PlateImageReference> plateImageReferences = screeningService .listPlateImageReferences(SESSION_TOKEN, ds, wellPositions, channel); @@ -610,8 +609,12 @@ public class DssServiceRpcScreeningTest extends AssertJUnit { { one(service).listDataSetsByCode(Arrays.asList(DATASET_CODE)); - will(returnValue(Arrays.asList(new DataSetBuilder().code(DATASET_CODE) - .shareId(ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID).getDataSet()))); + will(returnValue(Arrays + .asList(new DataSetBuilder() + .code(DATASET_CODE) + .shareId( + ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID) + .getDataSet()))); } }); } 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 c6deebb9add..2a88079fcb2 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 @@ -20,7 +20,9 @@ import static ch.systemsx.cisd.openbis.plugin.screening.client.web.client.applic import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.testng.AssertJUnit; import org.testng.annotations.Test; @@ -73,9 +75,9 @@ public class WellTooltipGeneratorTest extends AssertJUnit } private static String tryGenerateShortDescription(PlateLayouterModel model, int rowIx, - int colIx, Integer featureIndexOrNull) + int colIx, String featureLabelOrNull) { - return WellTooltipGenerator.tryGenerateTooltip(model, rowIx, colIx, featureIndexOrNull, + return WellTooltipGenerator.tryGenerateTooltip(model, rowIx, colIx, featureLabelOrNull, createDummyRealNumberRenderer()); } @@ -102,7 +104,7 @@ public class WellTooltipGeneratorTest extends AssertJUnit assertEquals(METADATA_EXPECTED_DESC_A2 + "\n" + ALL_FEATURES_DESC, desc); // one feature distingushed - desc = tryGenerateShortDescription(model, 0, 1, 1); + desc = tryGenerateShortDescription(model, 0, 1, "FeatureY"); assertEquals("FeatureY: <b>2.0</b>\n" + METADATA_EXPECTED_DESC_A2 + "\n" + FEATURE_X_DESC, desc); @@ -118,7 +120,7 @@ public class WellTooltipGeneratorTest extends AssertJUnit String desc = tryGenerateShortDescription(model, 0, 1, null); assertEquals(ALL_FEATURES_DESC, desc); - desc = tryGenerateShortDescription(model, 0, 1, 0); + desc = tryGenerateShortDescription(model, 0, 1, "FeatureX"); assertEquals("FeatureX: <b>1.0</b>\n" + "\n" + FEATURE_Y_DESC, desc); } @@ -134,7 +136,7 @@ public class WellTooltipGeneratorTest extends AssertJUnit AssertionUtil.assertStarts("Feature0: 0.0", desc); AssertionUtil.assertEnds("Feature29: 29.0\n" + "...", desc); - desc = tryGenerateShortDescription(model, 0, 1, 4); + desc = tryGenerateShortDescription(model, 0, 1, "Feature4"); AssertionUtil.assertStarts("Feature4: <b>4.0</b>", desc); AssertionUtil.assertEnds("Feature29: 29.0\n" + "...", desc); } @@ -153,27 +155,49 @@ public class WellTooltipGeneratorTest extends AssertJUnit { int size = 40; List<String> featureLabels = new ArrayList<String>(size); - FeatureValue[] featureValues = new FeatureValue[size]; - for (int i = 0; i < featureValues.length; i++) + Map<String, FeatureValue> featureValuesMap = new LinkedHashMap<String, FeatureValue>(); + for (int i = 0; i < size; i++) { - featureValues[i] = FeatureValue.createFloat(i); + final String label = "Feature" + i; + final FeatureValue featureValue = FeatureValue.createFloat(i); featureLabels.add("Feature" + i); + featureValuesMap.put(label, featureValue); } List<FeatureVectorValues> features = new ArrayList<FeatureVectorValues>(); - features.add(new FeatureVectorValues(null, getLocation(WELL_A2), featureValues)); + features.add(new FeatureVectorValues(null, getLocation(WELL_A2), featureValuesMap)); return new FeatureVectorDataset(createDatasetReference(), features, featureLabels); } private static FeatureVectorDataset createFeatureVectorDataset() { - List<String> featureLabels = Arrays.asList("FeatureX", "FeatureY"); + + String[] featureLabels = + { "FeatureX", "FeatureY" }; List<FeatureVectorValues> features = new ArrayList<FeatureVectorValues>(); - features.add(new FeatureVectorValues(null, getLocation(WELL_A2), new FeatureValue[] - { FeatureValue.createFloat(1), FeatureValue.createFloat(2) })); - features.add(new FeatureVectorValues(null, getLocation(WELL_B3), new FeatureValue[] - { FeatureValue.createFloat(-1), FeatureValue.createFloat(-2) })); - return new FeatureVectorDataset(createDatasetReference(), features, featureLabels); + features.add(new FeatureVectorValues(null, getLocation(WELL_A2), createFeatureVectorMap( + featureLabels, new FeatureValue[] + { FeatureValue.createFloat(1), FeatureValue.createFloat(2) }))); + 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)); + } + + private static Map<String, FeatureValue> createFeatureVectorMap(String[] labels, + FeatureValue[] values) + { + assert labels.length == values.length; + + Map<String, FeatureValue> result = new LinkedHashMap<String, FeatureValue>(); + for (int i = 0; i < labels.length; i++) + { + final String label = labels[i]; + final FeatureValue featureValue = values[i]; + result.put(label, featureValue); + } + return result; } private static DatasetReference createDatasetReference() -- GitLab