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 ff1dbf09870b386840fcb4bae6826a1e2e8d4bed..b67f042828f04296c1fc1c9f2876224f263af8fb 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,10 +16,12 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; +import java.util.LinkedHashMap; 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.CodeAndLabel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; /** @@ -37,31 +39,75 @@ public class FeatureVectorValues implements ISerializable private Map<String /* feature label */, FeatureValue /* value */> featureMap; + private CodeAndLabel[] codesAndLabels; + + private FeatureValue[] featureValues; + + /** + * Convert the two arrays into a map. It is assumed that codesAndLabels has the same length as + * feature values (this is checked before calling this method). + */ + static private Map<String, FeatureValue> asValueMap(CodeAndLabel[] codesAndLabels, + FeatureValue[] featureValues) + { + Map<String, FeatureValue> result = new LinkedHashMap<String, FeatureValue>(); + for (int i = 0; i < featureValues.length; i++) + { + result.put(codesAndLabels[i].getLabel(), featureValues[i]); + } + return result; + } + // GWT only @SuppressWarnings("unused") private FeatureVectorValues() { } + /** + * A copy constructor. + * + * @param featureVector The object to copy. + */ + public FeatureVectorValues(FeatureVectorValues featureVector) + { + this(featureVector.getFeatureVectorReference(), featureVector.getCodesAndLabels(), + featureVector.getFeatureValues(), featureVector.getFeatureMap()); + } + public FeatureVectorValues(String dataSetCode, WellLocation wellLocation, String platePermId, - Map<String, FeatureValue> featureMap) + CodeAndLabel[] codesAndLabels, FeatureValue[] featureValues) { this(new PlateWellFeatureVectorReference(dataSetCode, wellLocation, platePermId), - featureMap); + codesAndLabels, featureValues); } public FeatureVectorValues(PlateWellFeatureVectorReference featureVectorReference, + CodeAndLabel[] codesAndLabels, FeatureValue[] featureValues) + { + this(featureVectorReference, codesAndLabels, featureValues, null); + } + + private FeatureVectorValues(PlateWellFeatureVectorReference featureVectorReference, + CodeAndLabel[] codesAndLabels, FeatureValue[] featureValues, Map<String, FeatureValue> featureMap) { + assert codesAndLabels.length == featureValues.length; this.featureVectorReference = featureVectorReference; - this.featureMap = featureMap; + this.codesAndLabels = codesAndLabels; + this.featureValues = featureValues; + this.featureMap = + (null == featureMap) ? asValueMap(codesAndLabels, featureValues) : featureMap; + } + + public CodeAndLabel[] getCodesAndLabels() + { + return codesAndLabels; } - // NOTE: For performance reasons it is better not to call this method multiple times. - // Use getFeatureMap() instead. public FeatureValue[] getFeatureValues() { - return featureMap.values().toArray(new FeatureValue[0]); + return featureValues; } public Map<String, FeatureValue> getFeatureMap() 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 b2b3056de6612173193ec1eb75cfbb2d76cd28ae..75a5d828a42022246a472b7088765a1fb38ca254 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 @@ -37,8 +37,7 @@ public class FeatureTableRow extends FeatureVectorValues public FeatureTableRow(FeatureVectorValues featureVector) { - super(featureVector.getDataSetCode(), featureVector.getWellLocation(), featureVector - .getPlatePermId(), featureVector.getFeatureMap()); + super(featureVector); } 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 4a09733f4374504caef2394f1219d28cbd6fcb44..073087d73db9bd2a5de01e4068bc753c0370cf04 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 @@ -163,7 +163,7 @@ public class FeatureVectorLoader List<FeatureVectorValues> fvs = new ArrayList<FeatureVectorValues>(); for (FeatureTableRow row : featureRows) { - fvs.add(new FeatureVectorValues(row.getFeatureVectorReference(), row.getFeatureMap())); + fvs.add(new FeatureVectorValues(row)); } return new WellFeatureCollection<FeatureVectorValues>(fvs, featureRowsCollection.getFeatureCodesAndLabels()); @@ -481,7 +481,7 @@ public class FeatureVectorLoader private List<ImgFeatureDefDTO> getRequestedFeatureDefinitions(ImgDatasetDTO dataset) { List<ImgFeatureDefDTO> def = requestedFeatureDefinitionsMap.tryGet(dataset.getId()); - return def == null ? Collections.<ImgFeatureDefDTO>emptyList() : def; + return def == null ? Collections.<ImgFeatureDefDTO> emptyList() : def; } public List<ImgFeatureVocabularyTermDTO> getFeatureVocabularyTerms(ImgDatasetDTO dataSet) @@ -717,20 +717,18 @@ public class FeatureVectorLoader createFeatureValueArray(bundle.featureDefToValuesMap, bundle.featureDefToVocabularyTerms, wellLocation); return new FeatureVectorValues(permId, wellLocation, bundle.container.getPermId(), - asValueMap(valueArray)); + getCodeAndLabelArray(), valueArray); } - private Map<String, FeatureValue> asValueMap(FeatureValue[] valueArray) + private CodeAndLabel[] getCodeAndLabelArray() { - 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++) + CodeAndLabel[] codesAndLabels = new CodeAndLabel[featureCodeLabelToIndexMap.size()]; + for (CodeAndLabel codeAndLabel : featureCodeLabelToIndexMap.keySet()) { - result.put(features.get(i).getLabel(), valueArray[i]); + codesAndLabels[featureCodeLabelToIndexMap.get(codeAndLabel)] = codeAndLabel; } - return result; + + return codesAndLabels; } private FeatureValue[] createFeatureValueArray( 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 7f2c36a031fadd47095463e9e41510850567b866..8b353f433dd4e178b95d37bea41718356c81ab72 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,9 +20,7 @@ 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; @@ -154,18 +152,20 @@ public class WellTooltipGeneratorTest extends AssertJUnit private static FeatureVectorDataset createLargeFeatureVectorDataset() { int size = 40; - List<CodeAndLabel> featureNames = new ArrayList<CodeAndLabel>(size); - Map<String, FeatureValue> featureValuesMap = new LinkedHashMap<String, FeatureValue>(); + CodeAndLabel[] featureNames = new CodeAndLabel[size]; + FeatureValue[] featureValues = new FeatureValue[size]; for (int i = 0; i < size; i++) { final String label = "Feature" + i; final FeatureValue featureValue = FeatureValue.createFloat(i); - featureNames.add(new CodeAndLabel(label, label)); - featureValuesMap.put(label, featureValue); + featureNames[i] = new CodeAndLabel(label, label); + featureValues[i] = featureValue; } List<FeatureVectorValues> features = new ArrayList<FeatureVectorValues>(); - features.add(new FeatureVectorValues(null, getLocation(WELL_A2), null, featureValuesMap)); - return new FeatureVectorDataset(createDatasetReference(), features, featureNames); + features.add(new FeatureVectorValues(null, getLocation(WELL_A2), null, featureNames, + featureValues)); + return new FeatureVectorDataset(createDatasetReference(), features, + Arrays.asList(featureNames)); } private static FeatureVectorDataset createFeatureVectorDataset() @@ -173,32 +173,20 @@ public class WellTooltipGeneratorTest extends AssertJUnit String[] featureLabels = { "FeatureX", "FeatureY" }; + CodeAndLabel[] codesAndLabels = + new CodeAndLabel[] + { new CodeAndLabel(featureLabels[0], featureLabels[0]), + new CodeAndLabel(featureLabels[1], featureLabels[1]) }; List<FeatureVectorValues> features = new ArrayList<FeatureVectorValues>(); - features.add(new FeatureVectorValues(null, getLocation(WELL_A2), null, - createFeatureVectorMap(featureLabels, new FeatureValue[] - { FeatureValue.createFloat(1), FeatureValue.createFloat(2) }))); - features.add(new FeatureVectorValues(null, getLocation(WELL_B3), null, - createFeatureVectorMap(featureLabels, new FeatureValue[] - { FeatureValue.createFloat(-1), FeatureValue.createFloat(-2) }))); - 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, - 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; + features.add(new FeatureVectorValues(null, getLocation(WELL_A2), null, codesAndLabels, + new FeatureValue[] + { FeatureValue.createFloat(1), FeatureValue.createFloat(2) })); + features.add(new FeatureVectorValues(null, getLocation(WELL_B3), null, codesAndLabels, + new FeatureValue[] + { FeatureValue.createFloat(-1), FeatureValue.createFloat(-2) })); + return new FeatureVectorDataset(createDatasetReference(), features, + Arrays.asList(codesAndLabels)); } private static DatasetReference createDatasetReference()