diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVector.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVector.java index a68a1a0b5a3aea81c8f47542d3713c19df6dad3a..82e404f96943c3fa95f640c08a3307fd302835fe 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVector.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVector.java @@ -1,7 +1,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto; import java.io.Serializable; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; /** * Feature vector for one well. @@ -15,28 +16,101 @@ public class FeatureVector implements Serializable private final WellPosition wellPosition; private final double[] values; + + private final boolean[] vocabularyFeatureFlags; + + private final String[] vocabularyTerms; + /** + * Creates an instance for the specified well assuming all features are numbers. + */ public FeatureVector(WellPosition well, double[] values) + { + this(well, values, new boolean[values.length], new String[values.length]); + } + + /** + * Creates an instance for the specified well. + * + * @param values Array with values of numerical features. + * @param vocabularyFeatureFlags Array telling which feature is a numerical one ( + * <code>false</code>) or a vocabulary term (<code>true</code>). + * @param vocabularyTerms Array with values of vocabulary-based features. + * @throws IllegalArgumentException if all arrays have not the same length. + */ + public FeatureVector(WellPosition well, double[] values, boolean[] vocabularyFeatureFlags, + String[] vocabularyTerms) { this.wellPosition = well; this.values = values; + this.vocabularyFeatureFlags = vocabularyFeatureFlags; + this.vocabularyTerms = vocabularyTerms; + if (values.length != vocabularyFeatureFlags.length + || values.length != vocabularyTerms.length) + { + throw new IllegalArgumentException("Array lengths different: " + values.length + " " + + vocabularyFeatureFlags.length + " " + vocabularyTerms.length); + } } - /** well position on a plate */ + /** Returns the well position on a plate. */ public WellPosition getWellPosition() { return wellPosition; } - /** feature vector values */ + /** + * Returns the array of numerical features. If the value is {@link Double#NaN} it means either + * an unknown value of the numerical feature or a vocabulary-based feature. + */ public double[] getValues() { return values; } + + /** + * Return the array of flags specifying the type of feature where <code>true</code> means + * vocabulary-based feature and <code>false</code> numerical feature. + */ + public final boolean[] getVocabularyFeatureFlags() + { + return vocabularyFeatureFlags; + } + + /** + * Returns the array of vocabulary-based features. If the value is <code>null</code> it means + * either an unknown value of the vocabulary-base feature or a numerical feature. + */ + public final String[] getVocabularyTerms() + { + return vocabularyTerms; + } + + /** + * Returns the feature vector as a list of objects. The list element is either an instance of + * String (vocabulary-based feature), an instance of Double (numerical feature), or + * <code>null</code> if the feature is unknown. + */ + public List<Object> getValueObjects() + { + ArrayList<Object> result = new ArrayList<Object>(); + for (int i = 0; i < values.length; i++) + { + if (vocabularyFeatureFlags[i]) + { + result.add(vocabularyTerms[i]); + } else + { + double number = values[i]; + result.add(Double.isNaN(number) ? null : number); + } + } + return result; + } @Override public String toString() { - return "wellPosition: " + wellPosition + ", values: " + Arrays.toString(values); + return "wellPosition: " + wellPosition + ", values: " + getValueObjects(); } } \ No newline at end of file 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 5a80fab3c06211386637bef80dc86f177056c17c..407e23ce651b1377243be3804a5b4487abfa2b36 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 @@ -449,22 +449,12 @@ public class DssServiceRpcScreeningTest extends AssertJUnit } private void assertFeatureVector(int expectedRowNumber, int expectedColumnNumber, - FeatureVector featureVector, double... expectedValues) + FeatureVector featureVector, Object... expectedValues) { assertEquals(expectedRowNumber, featureVector.getWellPosition().getWellRow()); assertEquals(expectedColumnNumber, featureVector.getWellPosition().getWellColumn()); - assertEquals(asList(expectedValues), asList(featureVector.getValues())); - } - - private List<Double> asList(double[] values) - { - List<Double> list = new ArrayList<Double>(); - for (double value : values) - { - list.add(value); - } - return list; + assertEquals(Arrays.asList(expectedValues).toString(), featureVector.getValueObjects().toString()); } private void prepareGetHomeDatabaseInstance()