From a1969d32a78b843ff91bd1dc4e68cd089cadb05e Mon Sep 17 00:00:00 2001 From: brinn <brinn> Date: Wed, 28 Jul 2010 09:59:37 +0000 Subject: [PATCH] add: methods IScreeningOpenbisServiceFacade.loadFeaturesForFatasetWellReferences() and IScreeningOpenbisServiceFacade.loadFeaturesForPlateWells() to obtain the feature vectors for a defined set of dataset well references change: minor version of IDssServiceRpcScreening to 1 SVN: 17259 --- .../generic/server/FeatureTableBuilder.java | 106 ++++++++++++------ .../dss/generic/server/FeatureTableRow.java | 38 ++++--- ...mageAnalysisMergedRowsReportingPlugin.java | 20 ++-- .../server/DssServiceRpcScreening.java | 77 ++++++++++--- .../api/v1/IDssServiceRpcScreening.java | 45 +++++++- .../v1/IScreeningOpenbisServiceFacade.java | 98 +++++++++++++--- .../api/v1/ScreeningOpenbisServiceFacade.java | 92 ++++++++++++++- .../FeatureVectorDatasetWellReference.java | 54 +++++++++ .../v1/dto/FeatureVectorWithDescription.java | 55 +++++++++ 9 files changed, 488 insertions(+), 97 deletions(-) create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorDatasetWellReference.java create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorWithDescription.java diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/FeatureTableBuilder.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/FeatureTableBuilder.java index 2a73c86937d..a72ecb55db5 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/FeatureTableBuilder.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/FeatureTableBuilder.java @@ -30,6 +30,8 @@ import java.util.Map.Entry; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetWellReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellPosition; import ch.systemsx.cisd.openbis.plugin.screening.shared.dto.PlateFeatureValues; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImagingQueryDAO; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgContainerDTO; @@ -50,6 +52,8 @@ public class FeatureTableBuilder { private ImgDatasetDTO dataSet; + private FeatureVectorDatasetWellReference reference; + private Map<ImgFeatureDefDTO, List<ImgFeatureValuesDTO>> featureDefToValuesMap; } @@ -86,24 +90,35 @@ public class FeatureTableBuilder this.featureNames = new HashSet<String>(featureNames); } + /** + * Adds feature vectors for specified data set, marking the well position. + */ + public Bundle addFeatureVectorsOfDataSet(FeatureVectorDatasetWellReference reference) + { + final Bundle bundle = addFeatureVectorsOfDataSet(reference.getDatasetCode()); + bundle.reference = reference; + return bundle; + } + /** * Adds feature vectors for specified data set. */ - public void addFeatureVectorsOfDataSet(String dataSetCode) + public Bundle addFeatureVectorsOfDataSet(String dataSetCode) { - ImgDatasetDTO dataSet = dao.tryGetDatasetByPermId(dataSetCode); + final ImgDatasetDTO dataSet = dao.tryGetDatasetByPermId(dataSetCode); if (dataSet == null) { throw new UserFailureException("Unkown data set " + dataSetCode); } - Bundle bundle = new Bundle(); - List<ImgFeatureDefDTO> featureDefinitions = dao.listFeatureDefsByDataSetId(dataSet.getId()); + final Bundle bundle = new Bundle(); + final List<ImgFeatureDefDTO> featureDefinitions = + dao.listFeatureDefsByDataSetId(dataSet.getId()); bundle.dataSet = dataSet; bundle.featureDefToValuesMap = new HashMap<ImgFeatureDefDTO, List<ImgFeatureValuesDTO>>(); bundles.add(bundle); for (ImgFeatureDefDTO featureDefinition : featureDefinitions) { - String featureName = featureDefinition.getName(); + final String featureName = featureDefinition.getName(); if (featureNames.isEmpty() || featureNames.contains(featureName)) { if (featureNameToIndexMap.containsKey(featureName) == false) @@ -121,6 +136,7 @@ public class FeatureTableBuilder bundle.featureDefToValuesMap.put(featureDefinition, featureValueSets); } } + return bundle; } /** @@ -135,7 +151,7 @@ public class FeatureTableBuilder /** * Returns all features per well coordinates. */ - public List<FeatureTableRow> getFeatureTableRows() + public List<FeatureTableRow> createFeatureTableRows() { List<FeatureTableRow> rows = new ArrayList<FeatureTableRow>(); for (Bundle bundle : bundles) @@ -143,40 +159,64 @@ public class FeatureTableBuilder String dataSetCode = bundle.dataSet.getPermId(); ImgContainerDTO container = dao.getContainerById(bundle.dataSet.getContainerId()); SampleIdentifier identifier = service.tryToGetSampleIdentifier(container.getPermId()); - for (int rowIndex = 1; rowIndex <= container.getNumberOfRows(); rowIndex++) + if (bundle.reference == null) { - for (int colIndex = 1; colIndex <= container.getNumberOfColumns(); colIndex++) + for (int rowIndex = 1; rowIndex <= container.getNumberOfRows(); rowIndex++) { - FeatureTableRow row = new FeatureTableRow(); - rows.add(row); - row.setDataSetCode(dataSetCode); - row.setPlateIdentifier(identifier); - row.setRowIndex(rowIndex); - row.setColumnIndex(colIndex); - float[] valueArray = new float[featureNameToIndexMap.size()]; - Arrays.fill(valueArray, Float.NaN); - for (Entry<ImgFeatureDefDTO, List<ImgFeatureValuesDTO>> entry : bundle.featureDefToValuesMap - .entrySet()) + for (int colIndex = 1; colIndex <= container.getNumberOfColumns(); colIndex++) { - ImgFeatureDefDTO featureDefinition = entry.getKey(); - List<ImgFeatureValuesDTO> featureValueSets = entry.getValue(); - // We take only the first set of feature value sets - ImgFeatureValuesDTO featureValueDTO = featureValueSets.get(0); - PlateFeatureValues featureValues = featureValueDTO.getValues(); - if (rowIndex > featureValues.getGeometry().getNumberOfRows() - || colIndex > featureValues.getGeometry().getNumberOfColumns()) - { - break; - } - Integer index = featureNameToIndexMap.get(featureDefinition.getName()); - assert index != null : "No index for feature " - + featureDefinition.getName(); - valueArray[index] = featureValues.getForWellLocation(rowIndex, colIndex); + final FeatureTableRow row = + createFeatureTableRow(bundle.featureDefToValuesMap, dataSetCode, + identifier, null, new WellPosition(rowIndex, + colIndex)); + rows.add(row); } - row.setFeatureValues(valueArray); } + } else + { + final FeatureTableRow row = + createFeatureTableRow(bundle.featureDefToValuesMap, dataSetCode, + identifier, bundle.reference, bundle.reference.getWellPosition()); + rows.add(row); + } } return rows; } + + private FeatureTableRow createFeatureTableRow( + Map<ImgFeatureDefDTO, List<ImgFeatureValuesDTO>> featureDefToValuesMap, + String dataSetCode, SampleIdentifier identifier, + FeatureVectorDatasetWellReference reference, WellPosition wellPosition) + { + FeatureTableRow row = new FeatureTableRow(); + row.setDataSetCode(dataSetCode); + row.setPlateIdentifier(identifier); + row.setReference(reference); + row.setWellPosition(wellPosition); + float[] valueArray = new float[featureNameToIndexMap.size()]; + Arrays.fill(valueArray, Float.NaN); + for (Entry<ImgFeatureDefDTO, List<ImgFeatureValuesDTO>> entry : featureDefToValuesMap + .entrySet()) + { + ImgFeatureDefDTO featureDefinition = entry.getKey(); + List<ImgFeatureValuesDTO> featureValueSets = entry.getValue(); + // We take only the first set of feature value sets + ImgFeatureValuesDTO featureValueDTO = featureValueSets.get(0); + PlateFeatureValues featureValues = featureValueDTO.getValues(); + if (wellPosition.getWellRow() > featureValues.getGeometry().getNumberOfRows() + || wellPosition.getWellColumn() > featureValues.getGeometry() + .getNumberOfColumns()) + { + break; + } + Integer index = featureNameToIndexMap.get(featureDefinition.getName()); + assert index != null : "No index for feature " + featureDefinition.getName(); + valueArray[index] = + featureValues.getForWellLocation(wellPosition.getWellRow(), wellPosition + .getWellColumn()); + } + row.setFeatureValues(valueArray); + return row; + } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/FeatureTableRow.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/FeatureTableRow.java index dd1a3bfd84e..010240425d8 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/FeatureTableRow.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/FeatureTableRow.java @@ -17,10 +17,12 @@ package ch.systemsx.cisd.openbis.dss.generic.server; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetWellReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellPosition; /** * Bean for a row in a table of feature vectors. Each row is specified by data set code, plate - * identifier, well coordinates and and array of feature values. Double.NaN is used for unknown + * identifier, well position and and array of feature values. Double.NaN is used for unknown * feature value in this array. * * @author Franz-Josef Elmer @@ -28,13 +30,13 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; public class FeatureTableRow { private String dataSetCode; + + private FeatureVectorDatasetWellReference reference; private SampleIdentifier plateIdentifier; - private int rowIndex; - - private int columnIndex; - + private WellPosition wellPosition; + private float[] featureValues; public final String getDataSetCode() @@ -47,34 +49,34 @@ public class FeatureTableRow this.dataSetCode = dataSetCode; } - public final SampleIdentifier getPlateIdentifier() + public FeatureVectorDatasetWellReference getReference() { - return plateIdentifier; + return reference; } - public final void setPlateIdentifier(SampleIdentifier plateIdentifier) + public void setReference(FeatureVectorDatasetWellReference reference) { - this.plateIdentifier = plateIdentifier; + this.reference = reference; } - public final int getRowIndex() + public final SampleIdentifier getPlateIdentifier() { - return rowIndex; + return plateIdentifier; } - public final void setRowIndex(int rowIndex) + public final void setPlateIdentifier(SampleIdentifier plateIdentifier) { - this.rowIndex = rowIndex; + this.plateIdentifier = plateIdentifier; } - public final int getColumnIndex() + public void setWellPosition(WellPosition wellPosition) { - return columnIndex; + this.wellPosition = wellPosition; } - - public final void setColumnIndex(int columnIndex) + + public final WellPosition getWellPosition() { - this.columnIndex = columnIndex; + return wellPosition; } public final float[] getFeatureValues() diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ImageAnalysisMergedRowsReportingPlugin.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ImageAnalysisMergedRowsReportingPlugin.java index 532a4194888..05407fbf021 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ImageAnalysisMergedRowsReportingPlugin.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ImageAnalysisMergedRowsReportingPlugin.java @@ -50,14 +50,17 @@ public class ImageAnalysisMergedRowsReportingPlugin extends AbstractDatastorePlu IReportingPluginTask { private static final long serialVersionUID = 1L; - + private static final String DATA_SET_CODE_TITLE = "Data Set Code"; + private static final String PLATE_IDENTIFIER_TITLE = "Plate Identifier"; + private static final String ROW_TITLE = "Row"; + private static final String COLUMN_TITLE = "Column"; - + private IEncapsulatedOpenBISService service; - + private IImagingQueryDAO dao; public ImageAnalysisMergedRowsReportingPlugin(Properties properties, File storeRoot) @@ -72,7 +75,7 @@ public class ImageAnalysisMergedRowsReportingPlugin extends AbstractDatastorePlu this.service = service; this.dao = dao; } - + public TableModel createReport(List<DatasetDescription> datasets) { FeatureTableBuilder featureTableBuilder = new FeatureTableBuilder(getDAO(), getService()); @@ -82,7 +85,7 @@ public class ImageAnalysisMergedRowsReportingPlugin extends AbstractDatastorePlu featureTableBuilder.addFeatureVectorsOfDataSet(dataSetCode); } List<String> featureNames = featureTableBuilder.getFeatureNames(); - List<FeatureTableRow> rows = featureTableBuilder.getFeatureTableRows(); + List<FeatureTableRow> rows = featureTableBuilder.createFeatureTableRows(); SimpleTableModelBuilder builder = new SimpleTableModelBuilder(true); builder.addHeader(DATA_SET_CODE_TITLE); builder.addHeader(PLATE_IDENTIFIER_TITLE); @@ -97,8 +100,9 @@ public class ImageAnalysisMergedRowsReportingPlugin extends AbstractDatastorePlu List<ISerializableComparable> values = new ArrayList<ISerializableComparable>(); values.add(new StringTableCell(row.getDataSetCode())); values.add(new StringTableCell(row.getPlateIdentifier().toString())); - values.add(new StringTableCell(PlateUtils.translateRowNumberIntoLetterCode(row.getRowIndex()))); - values.add(new IntegerTableCell(row.getColumnIndex())); + values.add(new StringTableCell(PlateUtils.translateRowNumberIntoLetterCode(row + .getWellPosition().getWellRow()))); + values.add(new IntegerTableCell(row.getWellPosition().getWellColumn())); float[] featureValues = row.getFeatureValues(); StringTableCell nullValue = new StringTableCell(""); for (float value : featureValues) @@ -124,7 +128,7 @@ public class ImageAnalysisMergedRowsReportingPlugin extends AbstractDatastorePlu } return dao; } - + private IEncapsulatedOpenBISService getService() { if (service == null) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java index f80115e6129..f1970227f39 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java @@ -51,6 +51,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVector; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetWellReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorWithDescription; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IDatasetIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IFeatureVectorDatasetIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IImageDatasetIdentifier; @@ -72,6 +74,11 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements IDssServiceRpcScreening { + /** + * The minor version of this service. + */ + private static final int MINOR_VERSION = 1; + private IImagingQueryDAO dao; public DssServiceRpcScreening(String storeRootDir) @@ -203,17 +210,59 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements new FeatureTableBuilder(featureNames, getDAO(), getOpenBISService()); builder.addFeatureVectorsOfDataSet(dataset.getDatasetCode()); List<String> existingFeatureNames = builder.getFeatureNames(); - List<FeatureTableRow> featureTableRows = builder.getFeatureTableRows(); + List<FeatureTableRow> featureTableRows = builder.createFeatureTableRows(); List<FeatureVector> featureVectors = new ArrayList<FeatureVector>(); for (FeatureTableRow featureTableRow : featureTableRows) { - featureVectors.add(new FeatureVector(new WellPosition( - featureTableRow.getRowIndex(), featureTableRow.getColumnIndex()), - featureTableRow.getFeatureValuesAsDouble())); + featureVectors.add(new FeatureVector(featureTableRow.getWellPosition(), featureTableRow + .getFeatureValuesAsDouble())); } return new FeatureVectorDataset(dataset, existingFeatureNames, featureVectors); } + public List<FeatureVectorWithDescription> loadFeaturesForDatasetWellReferences( + String sessionToken, List<FeatureVectorDatasetWellReference> datasetWellReferences, + List<String> featureNames) + { + assertDataSetsAreAccessible(sessionToken, datasetWellReferences); + final FeatureTableBuilder builder = + createFeatureTableBuilder(datasetWellReferences, featureNames); + return createFeatureVectorList(builder); + } + + private List<FeatureVectorWithDescription> createFeatureVectorList( + final FeatureTableBuilder builder) + { + final List<String> featureNames = builder.getFeatureNames(); + final List<FeatureTableRow> featureTableRows = builder.createFeatureTableRows(); + final List<FeatureVectorWithDescription> result = + new ArrayList<FeatureVectorWithDescription>(featureTableRows.size()); + for (FeatureTableRow featureTableRow : featureTableRows) + { + result.add(createFeatureVector(featureTableRow, featureNames)); + } + return result; + } + + private FeatureVectorWithDescription createFeatureVector(FeatureTableRow featureTableRow, + final List<String> featureNames) + { + return new FeatureVectorWithDescription(featureTableRow.getReference(), featureNames, + featureTableRow.getFeatureValuesAsDouble()); + } + + private FeatureTableBuilder createFeatureTableBuilder( + List<FeatureVectorDatasetWellReference> plateWellReferences, List<String> featureNames) + { + final FeatureTableBuilder builder = + new FeatureTableBuilder(featureNames, getDAO(), getOpenBISService()); + for (FeatureVectorDatasetWellReference datasetWellReference : plateWellReferences) + { + builder.addFeatureVectorsOfDataSet(datasetWellReference); + } + return builder; + } + public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences) { Map<String, IHCSImageDatasetLoader> imageLoadersMap = @@ -353,16 +402,6 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements return dataset.getDataSetType().getCode().equals(ScreeningConstants.IMAGE_DATASET_TYPE); } - public int getMajorVersion() - { - return 1; - } - - public int getMinorVersion() - { - return 0; - } - private List<ImgFeatureDefDTO> getFeatureDefinitions(IDatasetIdentifier identifier) { ImgDatasetDTO dataSet = getDAO().tryGetDatasetByPermId(identifier.getDatasetCode()); @@ -393,4 +432,14 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements return dao; } + public int getMajorVersion() + { + return MAJOR_VERSION; + } + + public int getMinorVersion() + { + return MINOR_VERSION; + } + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/IDssServiceRpcScreening.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/IDssServiceRpcScreening.java index 90367ede094..e2d61d81763 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/IDssServiceRpcScreening.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/shared/api/v1/IDssServiceRpcScreening.java @@ -22,6 +22,8 @@ import java.util.List; import ch.systemsx.cisd.common.api.IRpcService; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetWellReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorWithDescription; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IFeatureVectorDatasetIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IImageDatasetIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ImageDatasetMetadata; @@ -34,21 +36,52 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateImageRef */ public interface IDssServiceRpcScreening extends IRpcService { + /** + * The major version of this service. + */ + public static final int MAJOR_VERSION = 1; + /** * For a given set of feature vector data sets provide the list of all available features. This * is just the name of the feature. If for different data sets different sets of features are * available, provide the union of the features of all data sets. */ - List<String> listAvailableFeatureNames(String sessionToken, + public List<String> listAvailableFeatureNames(String sessionToken, List<? extends IFeatureVectorDatasetIdentifier> featureDatasets); /** - * For a given set of data sets and a set of features (given by their name), provide the feature - * matrix. Each column in that matrix is one feature, each row is one well in one data set. + * Conceptually, for a given list of data well references (i.e. specified wells on specified + * feature vector data sets) and a set of features (given by their name) provide the feature + * matrix. In this matrix, each column is one feature, each row is one well in one data set. + * <p> + * Physically, the result is delivered as a list of feature vector datasets. Each entry in this + * list corresponds to one well in one dataset. + * + * @return The list of {@link FeatureVectorDataset}s, each element corresponds to one of the + * <var>featureDatasets</var>. */ - List<FeatureVectorDataset> loadFeatures(String sessionToken, + public List<FeatureVectorDataset> loadFeatures(String sessionToken, List<FeatureVectorDatasetReference> featureDatasets, List<String> featureNames); + /** + * Conceptually, for a given list of dataset well references (i.e. specified wells on specified + * feature vector data sets) and a set of features (given by their name) provide the feature + * matrix. In this matrix, each column is one feature, each row is one well in one data set. + * <p> + * Physically, the result is delivered as a list of feature vectors. Each entry in this list + * corresponds to one well in one dataset. + * + * @return The list of {@link FeatureVectorWithDescription}s, each element corresponds to one of + * the <var>datasetWellReferences</var>. <b>Note that the order of the returned ist is + * <i>not</i> guaranteed to be the same as the order of the list + * <var>datasetWellReferences</var>. Use + * {@link FeatureVectorWithDescription#getDatasetWellReference()} to find the + * corresponding dataset / well.</b> + */ + public List<FeatureVectorWithDescription> loadFeaturesForDatasetWellReferences( + String sessionToken, List<FeatureVectorDatasetWellReference> datasetWellReferences, + List<String> featureNames); + /** * Provide images for a given list of image references (given by data set code, well position, * channel and tile). The result is encoded into one stream, which consist of multiple blocks in @@ -56,13 +89,13 @@ public interface IDssServiceRpcScreening extends IRpcService * encoded as one long number. The number of blocks is equal to the number of specified * references and the order of blocks corresponds to the order of image references. */ - InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences); + public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences); /** * For a given set of image data sets, provide all image channels that have been acquired and * the available (natural) image size(s). */ - List<ImageDatasetMetadata> listImageMetadata(String sessionToken, + public List<ImageDatasetMetadata> listImageMetadata(String sessionToken, List<? extends IImageDatasetIdentifier> imageDatasets); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java index 5c9d28df3d3..40201e86a1b 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java @@ -23,6 +23,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.ScreeningOpenbisS import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetWellReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorWithDescription; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IDatasetIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IFeatureVectorDatasetIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IImageDatasetIdentifier; @@ -45,66 +47,128 @@ public interface IScreeningOpenbisServiceFacade /** * Return the session token for this authenticated user. */ - public abstract String getSessionToken(); + public String getSessionToken(); /** Closes connection with the server. After calling this method this facade cannot be used. */ - public abstract void logout(); + public void logout(); /** * Return the list of all visible plates assigned to any experiment, along with their * hierarchical context (space, project, experiment). */ - public abstract List<Plate> listPlates(); + public List<Plate> listPlates(); /** - * Return the list of all visible experiments, along with their - * hierarchical context (space, project). + * Return the list of all visible experiments, along with their hierarchical context (space, + * project). */ - public abstract List<ExperimentIdentifier> listExperiments(); + public List<ExperimentIdentifier> listExperiments(); /** * For a given set of plates provides the list of all connected data sets containing feature * vectors. */ - public abstract List<FeatureVectorDatasetReference> listFeatureVectorDatasets( + public List<FeatureVectorDatasetReference> listFeatureVectorDatasets( List<? extends PlateIdentifier> plates); /** * For a given set of plates provides the list of all connected data sets containing images. */ - public abstract List<ImageDatasetReference> listImageDatasets( - List<? extends PlateIdentifier> plates); + public List<ImageDatasetReference> listImageDatasets(List<? extends PlateIdentifier> plates); /** * For the given <var>experimentIdentifier</var> find all plate locations that are connected to * the specified <var>materialIdentifier</var>. If <code>findDatasets == true</code>, find also * the connected image and image analysis data sets for the relevant plates. + * <p> + * For how to get the feature vectors, see + * {@link #convertToFeatureVectorDatasetWellIdentifier(List)}. */ public List<PlateWellReferenceWithDatasets> listPlateWells( ExperimentIdentifier experimentIdentifer, MaterialIdentifier materialIdentifier, boolean findDatasets); - + + /** + * Converts the given list of {@link PlateWellReferenceWithDatasets} into a list of + * {@link FeatureVectorDatasetWellReference}. + * + * @see #listPlateWells(ExperimentIdentifier, MaterialIdentifier, boolean) + * @see #loadFeaturesForDatasetWellReferences(List, List) + */ + public List<FeatureVectorDatasetWellReference> convertToFeatureVectorDatasetWellIdentifier( + List<PlateWellReferenceWithDatasets> plateWellReferenceWithDataSets); + /** * Converts a given list of dataset codes to dataset identifiers which can be used in other API * calls. */ - public abstract List<IDatasetIdentifier> getDatasetIdentifiers(List<String> datasetCodes); + public List<IDatasetIdentifier> getDatasetIdentifiers(List<String> datasetCodes); /** * For a given set of feature vector data sets provides the list of all available features. This * is just the name of the feature. If for different data sets different sets of features are * available, provides the union of the feature names of all data sets. */ - public abstract List<String> listAvailableFeatureNames( + public List<String> listAvailableFeatureNames( List<? extends IFeatureVectorDatasetIdentifier> featureDatasets); /** - * For a given set of data sets and a set of features (given by their name), provide all the - * feature vectors. + * Conceptually, for a given list of dataset well references (i.e. specified wells on specified + * feature vector data sets) and a set of features (given by their name) provide the feature + * matrix. In this matrix, each column is one feature, each row is one well in one data set. + * <p> + * Physically, the result is delivered as a list of feature vector datasets. Each entry in this + * list corresponds to one well in one dataset. + * + * @return The list of {@link FeatureVectorDataset}s, each element corresponds to one of the + * <var>featureDatasets</var>. */ - public abstract List<FeatureVectorDataset> loadFeatures( + public List<FeatureVectorDataset> loadFeatures( List<FeatureVectorDatasetReference> featureDatasets, List<String> featureNames); + /** + * Conceptually, for a given list of dataset well references (i.e. specified wells on specified + * feature vector data sets) and a set of features (given by their name) provide the feature + * matrix. In this matrix, each column is one feature, each row is one well in one data set. + * <p> + * Physically, the result is delivered as a list of feature vectors. Each entry in this list + * corresponds to one well in one dataset. + * + * @param datasetWellReferences The references for datasets / wells to get the feature vectors + * for. + * @param featureNamesOrNull The names of the features to build the feature vectors from, or + * <code>null</code>, if all available features should be included. Note that for an + * empty list as well all features will be included. + * @return The list of {@link FeatureVectorWithDescription}s, each element corresponds to one of + * the <var>datasetWellReferences</var>. <b>Note that the order of the returned list is + * <i>not</i> guaranteed to be the same as the order of the list + * <var>datasetWellReferences</var>. Use + * {@link FeatureVectorWithDescription#getDatasetWellReference()} to find the + * corresponding dataset / well.</b> + */ + public List<FeatureVectorWithDescription> loadFeaturesForDatasetWellReferences( + List<FeatureVectorDatasetWellReference> datasetWellReferences, + List<String> featureNamesOrNull); + + /** + * For the given <var>experimentIdentifier</var> find all plate locations that are connected to + * the specified <var>materialIdentifier</var> and load the feature vectors for the given + * <var>featureNamesOrNull</var> if not <code>null</code>, or all available features otherwise. + * + * @param experimentIdentifer The identifier of the experiment to get the feature vectors for + * @param materialIdentifier The identifier of the material contained in the wells to get the + * feature vectors for. + * @param featureNamesOrNull The names of the features to build the feature vectors from, or + * <code>null</code>, if all available features should be included. Note that for an + * empty list as well all features will be included. + * @return The list of {@link FeatureVectorWithDescription}s found in the given + * <var>experimentIdentifer</var> and connected with the given + * <var>materialIdentifier</var>. + */ + public List<FeatureVectorWithDescription> loadFeaturesForPlateWells( + ExperimentIdentifier experimentIdentifer, MaterialIdentifier materialIdentifier, + List<String> featureNamesOrNull); + /** * Saves images for a given list of image references (given by data set code, well position, * channel and tile) in the provided output streams. Output streams will not be closed @@ -114,14 +178,14 @@ public interface IScreeningOpenbisServiceFacade * @throws IOException when reading images from the server or writing them to the output streams * fails */ - public abstract void loadImages(List<PlateImageReference> imageReferences, + public void loadImages(List<PlateImageReference> imageReferences, IImageOutputStreamProvider outputStreamProvider) throws IOException; /** * For a given set of image data sets, provide all image channels that have been acquired and * the available (natural) image size(s). */ - public abstract List<ImageDatasetMetadata> listImageMetadata( + public List<ImageDatasetMetadata> listImageMetadata( List<? extends IImageDatasetIdentifier> imageDatasets); } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java index 5d1f7593dd9..628bb60df76 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java @@ -19,6 +19,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.IScreeningApiServ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ExperimentIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDataset; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetWellReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorWithDescription; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IDatasetIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IFeatureVectorDatasetIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IImageDatasetIdentifier; @@ -29,6 +31,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Plate; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateImageReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellReferenceWithDatasets; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellPosition; /** * A client side facade of openBIS and Datastore Server API. @@ -61,6 +64,8 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa private final DataStoreMultiplexer<FeatureVectorDatasetReference> featureVectorDataSetReferenceMultiplexer; + private final DataStoreMultiplexer<FeatureVectorDatasetWellReference> featureVectorDataSetWellReferenceMultiplexer; + private final DataStoreMultiplexer<IImageDatasetIdentifier> metaDataMultiplexer; private final String sessionToken; @@ -130,6 +135,8 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa new DataStoreMultiplexer<IFeatureVectorDatasetIdentifier>(dssServiceCache); featureVectorDataSetReferenceMultiplexer = new DataStoreMultiplexer<FeatureVectorDatasetReference>(dssServiceCache); + featureVectorDataSetWellReferenceMultiplexer = + new DataStoreMultiplexer<FeatureVectorDatasetWellReference>(dssServiceCache); } /** @@ -250,6 +257,89 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa return result; } + public List<FeatureVectorDatasetWellReference> convertToFeatureVectorDatasetWellIdentifier( + List<PlateWellReferenceWithDatasets> plateWellReferenceWithDataSets) + { + final List<FeatureVectorDatasetWellReference> result = + new ArrayList<FeatureVectorDatasetWellReference>(plateWellReferenceWithDataSets + .size()); + for (PlateWellReferenceWithDatasets plateWellRef : plateWellReferenceWithDataSets) + { + for (FeatureVectorDatasetReference fvdr : plateWellRef + .getFeatureVectorDatasetReferences()) + { + result.add(createFVDatasetReference(fvdr, plateWellRef.getWellPosition())); + } + } + return result; + } + + private FeatureVectorDatasetWellReference createFVDatasetReference( + FeatureVectorDatasetReference fvdr, WellPosition wellPosition) + { + return new FeatureVectorDatasetWellReference(fvdr.getDatasetCode(), fvdr + .getDatastoreServerUrl(), fvdr.getPlate(), fvdr.getPlateGeometry(), fvdr + .getRegistrationDate(), fvdr.getParentImageDataset(), wellPosition); + } + + public List<FeatureVectorWithDescription> loadFeaturesForDatasetWellReferences( + final List<FeatureVectorDatasetWellReference> datasetWellReferences, + final List<String> featureNamesOrNull) + { + final List<String> featureNames = + (isEmpty(featureNamesOrNull)) ? listAvailableFeatureNames(datasetWellReferences) + : featureNamesOrNull; + + final List<FeatureVectorWithDescription> result = + new ArrayList<FeatureVectorWithDescription>(); + featureVectorDataSetWellReferenceMultiplexer.process(datasetWellReferences, + new IReferenceHandler<FeatureVectorDatasetWellReference>() + { + public void handle(IDssServiceRpcScreening dssService, + List<FeatureVectorDatasetWellReference> references) + { + result.addAll(dssService.loadFeaturesForDatasetWellReferences( + sessionToken, references, featureNames)); + } + }); + return result; + } + + private boolean isEmpty(final List<String> featureNamesOrNull) + { + return featureNamesOrNull == null || featureNamesOrNull.isEmpty(); + } + + public List<FeatureVectorWithDescription> loadFeaturesForPlateWells( + ExperimentIdentifier experimentIdentifer, MaterialIdentifier materialIdentifier, + List<String> featureNamesOrNull) + { + final List<PlateWellReferenceWithDatasets> plateWellRefs = + listPlateWells(experimentIdentifer, materialIdentifier, true); + final List<String> featureNames = + (isEmpty(featureNamesOrNull)) ? listAvailableFeatureNamesForPlateWells(plateWellRefs) + : featureNamesOrNull; + final List<FeatureVectorDatasetWellReference> datasetWellReferences = + convertToFeatureVectorDatasetWellIdentifier(plateWellRefs); + return loadFeaturesForDatasetWellReferences(datasetWellReferences, featureNames); + } + + private List<String> listAvailableFeatureNamesForPlateWells( + final List<PlateWellReferenceWithDatasets> plateWellRefs) + { + final List<String> featureNames; + final List<FeatureVectorDatasetReference> featureVectorDatasetReferences = + new ArrayList<FeatureVectorDatasetReference>(plateWellRefs.size()); + for (PlateWellReferenceWithDatasets plateWellRef : plateWellRefs) + { + featureVectorDatasetReferences.addAll(plateWellRef.getFeatureVectorDatasetReferences()); + } + final List<String> availableFeatureNames = + listAvailableFeatureNames(featureVectorDatasetReferences); + featureNames = availableFeatureNames; + return featureNames; + } + /** * An interface to provide mapping between image references and output streams where the images * should be saved. @@ -362,7 +452,7 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa } - private static interface IReferenceHandler<R extends IDatasetIdentifier> + private interface IReferenceHandler<R extends IDatasetIdentifier> { public void handle(IDssServiceRpcScreening dssService, List<R> references); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorDatasetWellReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorDatasetWellReference.java new file mode 100644 index 00000000000..c5673dc0570 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorDatasetWellReference.java @@ -0,0 +1,54 @@ +/* + * Copyright 2010 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.api.v1.dto; + +import java.util.Date; + +/** + * Reference to one well in a feature vector dataset. + * + * @author Bernd Rinn + */ +public class FeatureVectorDatasetWellReference extends FeatureVectorDatasetReference +{ + private static final long serialVersionUID = 1L; + + private final WellPosition wellPosition; + + public FeatureVectorDatasetWellReference(String datasetCode, String datastoreServerUrl, + PlateIdentifier plate, Geometry plateGeometry, Date registrationDate, + IImageDatasetIdentifier imageDatasetIdentifier, WellPosition wellPosition) + { + super(datasetCode, datastoreServerUrl, plate, plateGeometry, registrationDate, + imageDatasetIdentifier); + this.wellPosition = wellPosition; + } + + /** + * Returns the well position of this reference. + */ + public WellPosition getWellPosition() + { + return wellPosition; + } + + @Override + public String toString() + { + return super.toString() + " " + wellPosition.toString(); + } +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorWithDescription.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorWithDescription.java new file mode 100644 index 00000000000..74a099f456e --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorWithDescription.java @@ -0,0 +1,55 @@ +package ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto; + +import java.io.Serializable; +import java.util.List; + +/** + * Feature vectors of one well in one feature vector dataset. + * + * @author Bernd Rinn + */ +public class FeatureVectorWithDescription extends FeatureVector implements Serializable +{ + private static final long serialVersionUID = 1L; + + private final FeatureVectorDatasetWellReference datasetWellReference; + + private final List<String> featureNames; + + public FeatureVectorWithDescription(FeatureVectorDatasetWellReference dataset, + List<String> featureNames, double[] values) + { + super(dataset.getWellPosition(), values); + this.datasetWellReference = dataset; + this.featureNames = featureNames; + } + + /** + * Identifier of the dataset and well of this feature vector. + */ + public FeatureVectorDatasetWellReference getDatasetWellReference() + { + return datasetWellReference; + } + + /** + * Names (and implicitly order) of the features present in each feature vector. + */ + public List<String> getFeatureNames() + { + return featureNames; + } + + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append("datasetCode: " + datasetWellReference.getDatasetCode()); + sb.append(", storeUrl: " + datasetWellReference.getDatastoreServerUrl()); + sb.append("\n\tfeatures: " + featureNames); + sb.append("\n"); + sb.append(super.toString()); + return sb.toString(); + } + +} \ No newline at end of file -- GitLab