diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java index 4a8fe7f1c55b58253c2dddc5406f519bccfffb0d..d6f6aa0e6036b383d65d9519a3c4b0a6d3176835 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java @@ -69,6 +69,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.IScreeningQue import ch.systemsx.cisd.openbis.plugin.screening.server.logic.ExperimentFeatureVectorSummaryLoader; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.FeatureVectorValuesLoader; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.LogicalImageLoader; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.MaterialAllAssaysFeatureVectorSummaryLoader; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.MaterialFeatureVectorSummaryLoader; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.PlateContentLoader; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.ScreeningApiImpl; @@ -313,8 +314,8 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl Session session = getSession(sessionToken); // NOTE: we want the settings to be passed form the client in future MaterialSummarySettings settings = createDefaultSettings(); - return MaterialFeatureVectorSummaryLoader.loadMaterialFeatureVectorsFromAllAssays(session, - businessObjectFactory, getDAOFactory(), materialId, settings); + return MaterialAllAssaysFeatureVectorSummaryLoader.loadMaterialFeatureVectorsFromAllAssays( + session, businessObjectFactory, getDAOFactory(), materialId, settings); } public static MaterialSummarySettings createDefaultSettings() @@ -469,5 +470,4 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl return MINOR_VERSION; } - } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ExperimentFeatureVectorSummaryLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ExperimentFeatureVectorSummaryLoader.java index 0ad99b5018a3abcd5d618eec1008f8feb43e8cc3..c337dd81e44dc616f778bfee379b10b2a7642974 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ExperimentFeatureVectorSummaryLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ExperimentFeatureVectorSummaryLoader.java @@ -27,7 +27,6 @@ import java.util.Set; import ch.systemsx.cisd.common.collections.CollectionUtils; import ch.systemsx.cisd.common.collections.CollectionUtils.ICollectionMappingFunction; -import ch.systemsx.cisd.common.collections.GroupByMap; import ch.systemsx.cisd.common.collections.IKeyExtractor; import ch.systemsx.cisd.common.collections.TableMap; import ch.systemsx.cisd.common.collections.TableMap.UniqueKeyViolationStrategy; @@ -36,7 +35,6 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleL import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; @@ -46,20 +44,17 @@ import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObject import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellExtendedData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellDataCollection; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentFeatureVectorSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentReference; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorValues; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialFeatureVectorSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.WellFeatureCollection; -import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSFeatureVectorLoader; /** * {@See #loadExperimentFeatureVectors}. @@ -114,7 +109,7 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader return enrichWithMaterial(summaries, wellDataCollection); } - protected final List<MaterialIdFeatureVectorSummary> calculateReplicasFeatureVectorSummaries( + private final List<MaterialIdFeatureVectorSummary> calculateReplicasFeatureVectorSummaries( List<? extends IWellData> wellDataList) { return WellReplicaSummaryCalculator.calculateReplicasFeatureVectorSummaries(wellDataList, @@ -189,6 +184,13 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader featureVectorsCollection.getFeatureCodesAndLabels()); } + private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors( + Set<PlateIdentifier> plateIdentifiers) + { + return new WellFeatureCollectionLoader(session, businessObjectFactory, daoFactory) + .tryLoadWellSingleFeatureVectors(plateIdentifiers, settings.getFeatureCodes()); + } + private static ExperimentFeatureVectorSummary createEmptySummary(ExperimentReference experiment) { List<MaterialFeatureVectorSummary> materialsSummary = Collections.emptyList(); @@ -262,7 +264,8 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader { return null; } - return new WellData(replicaMaterial.getId(), featureVectorNumbers, well, replicaMaterial); + return new WellExtendedData(replicaMaterial.getId(), featureVectorNumbers, well, + replicaMaterial); } private static Material tryFindReplicaMaterial(Sample well, MaterialSummarySettings settings) @@ -292,26 +295,8 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader { return null; } - return asFeatureVectorValues(featureVector, orderedFeatureLabels); - } - - private static float[] asFeatureVectorValues(FeatureVectorValues featureVector, - List<String> orderedFeatureLabels) - { - Map<String, FeatureValue> featureMap = featureVector.getFeatureMap(); - float[] values = new float[featureMap.size()]; - int i = 0; - for (String featureLabel : orderedFeatureLabels) - { - FeatureValue featureValue = featureMap.get(featureLabel); - values[i++] = asFloat(featureValue); - } - return values; - } - - private static float asFloat(FeatureValue featureValue) - { - return featureValue.isFloat() ? featureValue.asFloat() : Float.NaN; + return WellFeatureCollectionLoader.asFeatureVectorValues(featureVector, + orderedFeatureLabels); } private static WellReference asWellReference(Sample well) @@ -332,32 +317,6 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader return idents; } - // private static List<WellContent> convert(List<Sample> wells, ExperimentReference experiment) - // { - // List<WellContent> wellContents = new ArrayList<WellContent>(); - // for (Sample well : wells) - // { - // wellContents.add(convert(well, experiment)); - // } - // return wellContents; - // } - // - // private static WellContent convert(Sample well, ExperimentReference experiment) - // { - // WellLocation location = - // ScreeningUtils.tryCreateLocationFromMatrixCoordinate(well.getSubCode()); - // EntityReference wellReference = asEntityReference(well); - // EntityReference plate = asEntityReference(well.getContainer()); - // - // return new WellContent(location, wellReference, plate, experiment); - // } - // - // private static EntityReference asEntityReference(Sample sample) - // { - // return new EntityReference(sample.getId(), sample.getSubCode(), sample.getSampleType() - // .getCode(), EntityKind.SAMPLE, sample.getPermId()); - // } - private static ListOrSearchSampleCriteria createWellsCriteria(List<Sample> plates) { Collection<Long> plateIds = new ArrayList<Long>(); @@ -377,112 +336,6 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader ListOrSearchSampleCriteria.createForExperiment(new TechId(expId))); } - /** - * Fetches feature vectors from different datastores and merges them (assuming that feature - * codes are the same). - */ - private static class FeatureVectorRetriever - { - public static WellFeatureCollection<FeatureVectorValues> tryFetch( - Collection<DatasetReference> datasets, List<String> featureCodes, - IScreeningBusinessObjectFactory businessObjectFactory) - { - assert datasets.size() > 0 : "No feature vector datasets specified."; - return new FeatureVectorRetriever(businessObjectFactory, featureCodes) - .tryFetch(datasets); - } - - private final IScreeningBusinessObjectFactory businessObjectFactory; - - private final List<String> featureCodes; - - public FeatureVectorRetriever(IScreeningBusinessObjectFactory businessObjectFactory, - List<String> featureCodes) - { - this.businessObjectFactory = businessObjectFactory; - this.featureCodes = featureCodes; - } - - private WellFeatureCollection<FeatureVectorValues> tryFetch( - Collection<DatasetReference> datasets) - { - GroupByMap<String/* datastore code */, DatasetReference> datastoreToDatasetsMap = - GroupByMap.create(datasets, new IKeyExtractor<String, DatasetReference>() - { - public String getKey(DatasetReference datasetReference) - { - return datasetReference.getDatastoreCode(); - } - }); - WellFeatureCollection<FeatureVectorValues> allFeatures = null; - for (String datastoreCode : datastoreToDatasetsMap.getKeys()) - { - List<DatasetReference> datasetsForDatastore = - datastoreToDatasetsMap.getOrDie(datastoreCode); - WellFeatureCollection<FeatureVectorValues> features = - fetchFromDatastore(datastoreCode, datasetsForDatastore); - if (allFeatures == null) - { - allFeatures = features; - } else - { - mergeFeatures(allFeatures, features); - } - } - return allFeatures; - } - - private static void mergeFeatures(WellFeatureCollection<FeatureVectorValues> allFeatures, - WellFeatureCollection<FeatureVectorValues> features) - { - if (allFeatures.getFeatureCodes().equals(features.getFeatureCodes()) == false) - { - throw new IllegalStateException( - "Cannot merge feature vectors from different datastores because the have different set of features: '" - + allFeatures.getFeatureCodes() - + "' and '" - + features.getFeatureCodes() + "'."); - } - allFeatures.getFeatures().addAll(features.getFeatures()); - } - - private WellFeatureCollection<FeatureVectorValues> fetchFromDatastore(String datastoreCode, - List<DatasetReference> datasets) - { - IHCSFeatureVectorLoader loader = - businessObjectFactory.createHCSFeatureVectorLoader(datastoreCode); - return loader.fetchDatasetFeatureValues(extractCodes(datasets), featureCodes); - } - - private static List<String> extractCodes(List<DatasetReference> datasets) - { - return CollectionUtils.map(datasets, - new ICollectionMappingFunction<String, DatasetReference>() - { - public String map(DatasetReference element) - { - return element.getCode(); - } - }); - } - } - - private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors( - Set<PlateIdentifier> plates) - { - FeatureVectorDatasetLoader datasetsRetriever = createFeatureVectorDatasetsRetriever(plates); - Collection<ExternalData> featureVectorDatasets = - datasetsRetriever.getFeatureVectorDatasets(); - if (featureVectorDatasets.isEmpty()) - { - return null; - } - List<DatasetReference> datasetPerPlate = chooseSingleDatasetForPlate(featureVectorDatasets); - List<String> featureCodes = settings.getFeatureCodes(); - return FeatureVectorRetriever - .tryFetch(datasetPerPlate, featureCodes, businessObjectFactory); - } - private static Map<WellReference, FeatureVectorValues> createWellToFeatureVectorMap( WellFeatureCollection<FeatureVectorValues> featureVectors) { @@ -496,35 +349,4 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader return wellToFeatureVectorMap; } - // TODO 2011-04-04, Tomasz Pylak: here if the plate has more than one dataset assigned, we - // take the first and ignore the rest. The clean solution would be to introduce analysis - // runs, where each plate has at most one analysis dataset in each run. {@link - // UniqueKeyViolationStrategy} could be set to {@link UniqueKeyViolationStrategy.ERROR} in - // such a case. - protected static List<DatasetReference> chooseSingleDatasetForPlate( - Collection<ExternalData> datasets) - { - TableMap<String, ExternalData> plateToDatasetMap = - new TableMap<String, ExternalData>(datasets, - new IKeyExtractor<String, ExternalData>() - { - public String getKey(ExternalData externalData) - { - Sample plate = externalData.getSample(); - return plate != null ? plate.getPermId() : null; - } - }, UniqueKeyViolationStrategy.KEEP_FIRST); - - List<DatasetReference> datasetPerPlate = new ArrayList<DatasetReference>(); - for (String platePermId : plateToDatasetMap.keySet()) - { - if (platePermId != null) - { - ExternalData dataset = plateToDatasetMap.getOrDie(platePermId); - DatasetReference datasetReference = ScreeningUtils.createDatasetReference(dataset); - datasetPerPlate.add(datasetReference); - } - } - return datasetPerPlate; - } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialAllAssaysFeatureVectorSummaryLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialAllAssaysFeatureVectorSummaryLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..15789fed5d4c25cb29944fda1516a38e14c70152 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialAllAssaysFeatureVectorSummaryLoader.java @@ -0,0 +1,203 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.plugin.screening.server.logic; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import ch.systemsx.cisd.common.collections.CollectionUtils; +import ch.systemsx.cisd.common.collections.CollectionUtils.ICollectionMappingFunction; +import ch.systemsx.cisd.common.collections.GroupByMap; +import ch.systemsx.cisd.common.collections.IKeyExtractor; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; +import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; +import ch.systemsx.cisd.openbis.generic.shared.dto.Session; +import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObjectFactory; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorValues; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSimpleFeatureVectorSummary; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.WellFeatureCollection; + +/** + * Finds all experiments where the given material is present and calculates summaries for feature + * vectors (if analysis data are available) . + * + * @author Tomasz Pylak + */ +public class MaterialAllAssaysFeatureVectorSummaryLoader extends AbstractContentLoader +{ + public static List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssays( + Session session, IScreeningBusinessObjectFactory businessObjectFactory, + IDAOFactory daoFactory, TechId materialId, MaterialSummarySettings settings) + { + List<WellContent> allAssayWellsForMaterial = + WellContentLoader.loadOnlyMetadata(session, businessObjectFactory, daoFactory, + materialId); + return new MaterialAllAssaysFeatureVectorSummaryLoader(session, businessObjectFactory, + daoFactory, settings).loadMaterialFeatureVectorsFromAllAssays(materialId, + allAssayWellsForMaterial); + } + + private final MaterialSummarySettings settings; + + private MaterialAllAssaysFeatureVectorSummaryLoader(Session session, + IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory, + MaterialSummarySettings settings) + { + super(session, businessObjectFactory, daoFactory); + this.settings = settings; + } + + /** + * Note that different experiments can have different set of features! + */ + private List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssays( + TechId materialId, List<WellContent> allAssayWellsForMaterial) + { + Set<PlateIdentifier> plates = extractPlates(allAssayWellsForMaterial); + WellFeatureCollection<FeatureVectorValues> allWellFeaturesOrNull = + tryLoadWellSingleFeatureVectors(plates); + + Map<ExperimentReference, Set<WellReference>> wellsForExperimentMap = + groupWellsByExperiment(allAssayWellsForMaterial); + + List<MaterialSimpleFeatureVectorSummary> summaries = + new ArrayList<MaterialSimpleFeatureVectorSummary>(); + for (ExperimentReference experiment : wellsForExperimentMap.keySet()) + { + Set<WellReference> experimentWells = wellsForExperimentMap.get(experiment); + + MaterialSimpleFeatureVectorSummary summary = + calculateExperimentFeatureVectorSummary(materialId, experiment, + experimentWells, allWellFeaturesOrNull); + summaries.add(summary); + } + return summaries; + } + + private MaterialSimpleFeatureVectorSummary calculateExperimentFeatureVectorSummary( + TechId materialId, ExperimentReference experiment, Set<WellReference> experimentWells, + WellFeatureCollection<FeatureVectorValues> allWellFeaturesOrNull) + { + if (allWellFeaturesOrNull == null) + { + return new MaterialSimpleFeatureVectorSummary(experiment); + } + + List<IWellData> experimentWellData = + selectExperimentWellData(experimentWells, allWellFeaturesOrNull, materialId); + float[] summaryFeatureVector = + WellReplicaSummaryCalculator.calculateSummaryFeatureVector(experimentWellData, + settings.getAggregationType()); + return new MaterialSimpleFeatureVectorSummary(experiment, + allWellFeaturesOrNull.getFeatureCodesAndLabels(), summaryFeatureVector); + } + + private static List<IWellData> selectExperimentWellData(Set<WellReference> experimentWells, + WellFeatureCollection<FeatureVectorValues> allWellFeatures, TechId materialId) + { + List<String> orderedFeatureLabels = allWellFeatures.getFeatureLabels(); + + List<IWellData> experimentWellDataList = new ArrayList<IWellData>(); + List<FeatureVectorValues> features = allWellFeatures.getFeatures(); + for (FeatureVectorValues feature : features) + { + if (experimentWells.contains(feature.getWellReference())) + { + float[] values = + WellFeatureCollectionLoader.asFeatureVectorValues(feature, + orderedFeatureLabels); + IWellData wellData = new WellData(materialId.getId(), values); + experimentWellDataList.add(wellData); + } + } + return experimentWellDataList; + } + + private static Map<ExperimentReference, Set<WellReference>> groupWellsByExperiment( + List<WellContent> allAssayWellsForMaterial) + { + GroupByMap<ExperimentReference, WellContent> expToWellContentMap = + GroupByMap.create(allAssayWellsForMaterial, + new IKeyExtractor<ExperimentReference, WellContent>() + { + public ExperimentReference getKey(WellContent wellContent) + { + return wellContent.getExperiment(); + } + }); + return convertToWellReferences(expToWellContentMap); + } + + private static Map<ExperimentReference, Set<WellReference>> convertToWellReferences( + GroupByMap<ExperimentReference, WellContent> expToWellContentMap) + { + Map<ExperimentReference, Set<WellReference>> map = + new HashMap<ExperimentReference, Set<WellReference>>(); + for (ExperimentReference exp : expToWellContentMap.getKeys()) + { + List<WellContent> wellContents = expToWellContentMap.getOrDie(exp); + map.put(exp, asWellReferences(wellContents)); + } + return map; + } + + private static Set<WellReference> asWellReferences(List<WellContent> wellContents) + { + List<WellReference> wells = + CollectionUtils.map(wellContents, + new ICollectionMappingFunction<WellReference, WellContent>() + { + public WellReference map(WellContent wellContent) + { + return new WellReference(wellContent.tryGetLocation(), + wellContent.getPlate().getPermId()); + } + }); + return new HashSet<WellReference>(wells); + } + + private static Set<PlateIdentifier> extractPlates(List<WellContent> wells) + { + Set<PlateIdentifier> plates = new HashSet<PlateIdentifier>(); + for (WellContent well : wells) + { + String platePermId = well.getPlate().getPermId(); + PlateIdentifier plateIdent = PlateIdentifier.createFromPermId(platePermId); + plates.add(plateIdent); + } + return plates; + } + + private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors( + Set<PlateIdentifier> plateIdentifiers) + { + return new WellFeatureCollectionLoader(session, businessObjectFactory, daoFactory) + .tryLoadWellSingleFeatureVectors(plateIdentifiers, settings.getFeatureCodes()); + } + +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java index 1430c9256d587e62553293aebfb617393e52ccd3..09604792a2df91c636d6f05963b172800dce9f79 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java @@ -43,9 +43,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialBiolog import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaFeatureSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaFeatureSummaryResult; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSimpleFeatureVectorSummary; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; /** * For the specified material in the specified experiment loads feature vectors (details and @@ -56,30 +54,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; */ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorSummaryLoader { - public static List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssays( - Session session, IScreeningBusinessObjectFactory businessObjectFactory, - IDAOFactory daoFactory, TechId materialId, MaterialSummarySettings settings) - { - List<WellContent> allAssayWellsForMaterial = - WellContentLoader.loadOnlyMetadata(session, businessObjectFactory, daoFactory, - materialId); - // Probably the result DTO has to be converted (here?) to fit the GUI needs better. - // Note that different experiments can have different set of features! - return new MaterialFeatureVectorSummaryLoader(session, businessObjectFactory, daoFactory, - settings).loadMaterialFeatureVectorsFromAllAssays(materialId, - allAssayWellsForMaterial); - } - - /** - * Note that different experiments can have different set of features! - */ - private List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssays( - TechId materialId, List<WellContent> allAssayWellsForMaterial) - { - // TODO 2011-05-20, Tomasz Pylak: implement me! - return null; - } - /** * For comments {@See MaterialFeatureVectorSummaryLoader}. */ @@ -286,7 +260,8 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS List<? extends IWellData> experimentWellDataList) { List<MaterialIdFeatureVectorSummary> featureSummaries = - calculateReplicasFeatureVectorSummaries(experimentWellDataList); + WellReplicaSummaryCalculator.calculateReplicasFeatureVectorSummaries( + experimentWellDataList, settings.getAggregationType()); return tryFindMaterialSummary(materialId, featureSummaries); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellFeatureCollectionLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellFeatureCollectionLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..18c5fe2bce031389b194e8a6472dc22345bdf5b4 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellFeatureCollectionLoader.java @@ -0,0 +1,212 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.plugin.screening.server.logic; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import ch.systemsx.cisd.common.collections.CollectionUtils; +import ch.systemsx.cisd.common.collections.CollectionUtils.ICollectionMappingFunction; +import ch.systemsx.cisd.common.collections.GroupByMap; +import ch.systemsx.cisd.common.collections.IKeyExtractor; +import ch.systemsx.cisd.common.collections.TableMap; +import ch.systemsx.cisd.common.collections.TableMap.UniqueKeyViolationStrategy; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; +import ch.systemsx.cisd.openbis.generic.shared.dto.Session; +import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObjectFactory; +import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorValues; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.WellFeatureCollection; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSFeatureVectorLoader; + +/** + * Loads feature vectors for chosen plates. + * + * @author Tomasz Pylak + */ +public class WellFeatureCollectionLoader extends AbstractContentLoader +{ + public WellFeatureCollectionLoader(Session session, + IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory) + { + super(session, businessObjectFactory, daoFactory); + } + + /** Loads feature vectors for chosen plates and set of features */ + public WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors( + Set<PlateIdentifier> plates, List<String> featureCodes) + { + FeatureVectorDatasetLoader datasetsRetriever = createFeatureVectorDatasetsRetriever(plates); + Collection<ExternalData> featureVectorDatasets = + datasetsRetriever.getFeatureVectorDatasets(); + if (featureVectorDatasets.isEmpty()) + { + return null; + } + List<DatasetReference> datasetPerPlate = chooseSingleDatasetForPlate(featureVectorDatasets); + return FeatureVectorRetriever + .tryFetch(datasetPerPlate, featureCodes, businessObjectFactory); + } + + // TODO 2011-04-04, Tomasz Pylak: here if the plate has more than one dataset assigned, we + // take the first and ignore the rest. The clean solution would be to introduce analysis + // runs, where each plate has at most one analysis dataset in each run. {@link + // UniqueKeyViolationStrategy} could be set to {@link UniqueKeyViolationStrategy.ERROR} in + // such a case. + private static List<DatasetReference> chooseSingleDatasetForPlate( + Collection<ExternalData> datasets) + { + TableMap<String, ExternalData> plateToDatasetMap = + new TableMap<String, ExternalData>(datasets, + new IKeyExtractor<String, ExternalData>() + { + public String getKey(ExternalData externalData) + { + Sample plate = externalData.getSample(); + return plate != null ? plate.getPermId() : null; + } + }, UniqueKeyViolationStrategy.KEEP_FIRST); + + List<DatasetReference> datasetPerPlate = new ArrayList<DatasetReference>(); + for (String platePermId : plateToDatasetMap.keySet()) + { + if (platePermId != null) + { + ExternalData dataset = plateToDatasetMap.getOrDie(platePermId); + DatasetReference datasetReference = ScreeningUtils.createDatasetReference(dataset); + datasetPerPlate.add(datasetReference); + } + } + return datasetPerPlate; + } + + /** + * Fetches feature vectors from different datastores and merges them (assuming that feature + * codes are the same). + */ + private static class FeatureVectorRetriever + { + public static WellFeatureCollection<FeatureVectorValues> tryFetch( + Collection<DatasetReference> datasets, List<String> featureCodes, + IScreeningBusinessObjectFactory businessObjectFactory) + { + assert datasets.size() > 0 : "No feature vector datasets specified."; + return new FeatureVectorRetriever(businessObjectFactory, featureCodes) + .tryFetch(datasets); + } + + private final IScreeningBusinessObjectFactory businessObjectFactory; + + private final List<String> featureCodes; + + public FeatureVectorRetriever(IScreeningBusinessObjectFactory businessObjectFactory, + List<String> featureCodes) + { + this.businessObjectFactory = businessObjectFactory; + this.featureCodes = featureCodes; + } + + private WellFeatureCollection<FeatureVectorValues> tryFetch( + Collection<DatasetReference> datasets) + { + GroupByMap<String/* datastore code */, DatasetReference> datastoreToDatasetsMap = + GroupByMap.create(datasets, new IKeyExtractor<String, DatasetReference>() + { + public String getKey(DatasetReference datasetReference) + { + return datasetReference.getDatastoreCode(); + } + }); + WellFeatureCollection<FeatureVectorValues> allFeatures = null; + for (String datastoreCode : datastoreToDatasetsMap.getKeys()) + { + List<DatasetReference> datasetsForDatastore = + datastoreToDatasetsMap.getOrDie(datastoreCode); + WellFeatureCollection<FeatureVectorValues> features = + fetchFromDatastore(datastoreCode, datasetsForDatastore); + if (allFeatures == null) + { + allFeatures = features; + } else + { + mergeFeatures(allFeatures, features); + } + } + return allFeatures; + } + + private static void mergeFeatures(WellFeatureCollection<FeatureVectorValues> allFeatures, + WellFeatureCollection<FeatureVectorValues> features) + { + if (allFeatures.getFeatureCodes().equals(features.getFeatureCodes()) == false) + { + throw new IllegalStateException( + "Cannot merge feature vectors from different datastores because the have different set of features: '" + + allFeatures.getFeatureCodes() + + "' and '" + + features.getFeatureCodes() + "'."); + } + allFeatures.getFeatures().addAll(features.getFeatures()); + } + + private WellFeatureCollection<FeatureVectorValues> fetchFromDatastore(String datastoreCode, + List<DatasetReference> datasets) + { + IHCSFeatureVectorLoader loader = + businessObjectFactory.createHCSFeatureVectorLoader(datastoreCode); + return loader.fetchDatasetFeatureValues(extractCodes(datasets), featureCodes); + } + + private static List<String> extractCodes(List<DatasetReference> datasets) + { + return CollectionUtils.map(datasets, + new ICollectionMappingFunction<String, DatasetReference>() + { + public String map(DatasetReference element) + { + return element.getCode(); + } + }); + } + } + + public static float[] asFeatureVectorValues(FeatureVectorValues featureVector, + List<String> orderedFeatureLabels) + { + Map<String, FeatureValue> featureMap = featureVector.getFeatureMap(); + float[] values = new float[featureMap.size()]; + int i = 0; + for (String featureLabel : orderedFeatureLabels) + { + FeatureValue featureValue = featureMap.get(featureLabel); + values[i++] = asFloat(featureValue); + } + return values; + } + + private static float asFloat(FeatureValue featureValue) + { + return featureValue.isFloat() ? featureValue.asFloat() : Float.NaN; + } +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculator.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculator.java index 877c98c50581c84218792d7a75c61360f52ba1b7..518f0d53227b3c7638b2f686eb609706490bce11 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculator.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculator.java @@ -30,7 +30,7 @@ import ch.systemsx.cisd.common.collections.GroupByMap; import ch.systemsx.cisd.common.collections.IKeyExtractor; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType; /** @@ -188,7 +188,7 @@ public class WellReplicaSummaryCalculator { Long replicaId = entry.getKey(); float[] aggregates = entry.getValue().getAggregates(); - IWellData summaryWellData = new WellData(replicaId, aggregates, null, null); + IWellData summaryWellData = new WellExtendedData(replicaId, aggregates, null, null); summaryWellDataList.add(summaryWellData); } return summaryWellDataList; diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java index faad1e050314296d1307c6ea2b3cfaeb081139df..3dc98d7fbd3b38c7a66dbb224679ca37982147a4 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java @@ -17,33 +17,22 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto; import java.util.Arrays; -import java.util.List; - -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; /** - * The simplest implementation of {@Link IWellExtendedData}. + * The simplest implementation of {@Link IWellData}. * * @author Tomasz Pylak */ -public class WellData implements IWellExtendedData +public class WellData implements IWellData { private final long replicaId; - private Sample well; - private final float[] featureVector; - private final Material material; - - public WellData(long replicaId, float[] featureVector, Sample well, Material material) + public WellData(long replicaId, float[] featureVector) { - this.well = well; this.featureVector = featureVector; this.replicaId = replicaId; - this.material = material; } public long getReplicaMaterialId() @@ -51,35 +40,14 @@ public class WellData implements IWellExtendedData return replicaId; } - public Sample getWell() - { - return well; - } - public float[] getFeatureVector() { return featureVector; } - public Material getMaterial() - { - return material; - } - @Override public String toString() { return "repl " + replicaId + ": " + Arrays.toString(featureVector); } - - public List<IEntityProperty> getProperties() - { - return well.getProperties(); - } - - public Long getId() - { - return well.getId(); - } - } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellExtendedData.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellExtendedData.java new file mode 100644 index 0000000000000000000000000000000000000000..32e62f85443b20d71f30ec1a19ea9745e96949d9 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellExtendedData.java @@ -0,0 +1,63 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto; + +import java.util.List; + +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; + +/** + * The simplest implementation of {@Link IWellExtendedData}. + * + * @author Tomasz Pylak + */ +public class WellExtendedData extends WellData implements IWellExtendedData +{ + private Sample well; + + private final Material material; + + public WellExtendedData(long replicaId, float[] featureVector, Sample well, Material material) + { + super(replicaId, featureVector); + this.well = well; + this.material = material; + } + + public Sample getWell() + { + return well; + } + + public Material getMaterial() + { + return material; + } + + public List<IEntityProperty> getProperties() + { + return well.getProperties(); + } + + public Long getId() + { + return well.getId(); + } + +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ExperimentReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ExperimentReference.java index 2e98b79183291e89803629d71d682eb2226188ba..6473e4f7b5e1cc07e7f0e277068e6557acdb44cd 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ExperimentReference.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ExperimentReference.java @@ -107,4 +107,29 @@ public class ExperimentReference implements ISerializable, IEntityInformationHol { return getIdentifier(); } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + (int) (experimentId ^ (experimentId >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ExperimentReference other = (ExperimentReference) obj; + if (experimentId != other.experimentId) + return false; + return true; + } + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSimpleFeatureVectorSummary.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSimpleFeatureVectorSummary.java index ba74534835193d5f92c8558414786fbb02fd8496..f9094b78fd7c58fe0816b7533c94264b3cd456b9 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSimpleFeatureVectorSummary.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSimpleFeatureVectorSummary.java @@ -16,11 +16,12 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; +import java.util.ArrayList; import java.util.List; import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentReference; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; /** @@ -32,21 +33,30 @@ public class MaterialSimpleFeatureVectorSummary implements ISerializable { private static final long serialVersionUID = ServiceVersionHolder.VERSION; - private Experiment experiment; + private ExperimentReference experiment; - // has the same length as feature vectors summary + // Has the same length as feature vectors summary. + // Note that it can be empty if there are no analysis results! private List<CodeAndLabel> featureDescriptions; private float[] featureVectorSummary; // GTW - // TODO KE: create a separate DTO for the UI layer if there is enough time @SuppressWarnings("unused") private MaterialSimpleFeatureVectorSummary() { } - public MaterialSimpleFeatureVectorSummary(Experiment experiment, + /** + * Useful when there are no analysis results for a material in the experiment (but there can be + * still some images acquired). + */ + public MaterialSimpleFeatureVectorSummary(ExperimentReference experiment) + { + this(experiment, new ArrayList<CodeAndLabel>(), new float[0]); + } + + public MaterialSimpleFeatureVectorSummary(ExperimentReference experiment, List<CodeAndLabel> featureDescriptions, float[] featureVectorSummary) { this.experiment = experiment; @@ -54,7 +64,7 @@ public class MaterialSimpleFeatureVectorSummary implements ISerializable this.featureVectorSummary = featureVectorSummary; } - public Experiment getExperiment() + public ExperimentReference getExperiment() { return experiment; } diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java index c9fefa41a60c69f011c7c7f65f7e57093678dfc4..2a6db8a96558385d63bcc1afe8d5b7169c3f9036 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java @@ -39,7 +39,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellExtendedD import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialAllReplicasFeatureVectors; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialBiologicalReplicateFeatureVector; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellDataCollection; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings; @@ -147,6 +147,6 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit material.setProperties(properties); well.setProperties(properties); - return new WellData(replicaId, featureValues, well, material); + return new WellExtendedData(replicaId, featureValues, well, material); } } \ No newline at end of file diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculatorTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculatorTest.java index 69f2f5322fc4d09d5bc49ca3926ebdc732746840..739e1be813f4bce3e7726cbb24d0bbf8b7eddfc7 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculatorTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculatorTest.java @@ -33,7 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.WellReplicaSummaryCalculator.SummaryFeatureVector; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType; /** @@ -206,7 +206,7 @@ public class WellReplicaSummaryCalculatorTest extends AssertJUnit { Material material = new Material(); material.setId(replicaId); - return new WellData(replicaId, featureValues, null, material); + return new WellExtendedData(replicaId, featureValues, null, material); } private List<MaterialIdFeatureVectorSummary> calculate(List<IWellData> wellDataList)