From 25ba1a6289df35af77d509760e5855c7632fc66f Mon Sep 17 00:00:00 2001 From: tpylak <tpylak> Date: Mon, 18 Jul 2011 22:02:34 +0000 Subject: [PATCH] LMS-2395 material summary bug, LMS-2355 preparation refactoring (which also improves performance) SVN: 22191 --- .../BasicWellContentQueryResult.java | 19 +- .../server/dataaccess/IWellReference.java | 31 + .../dataaccess/WellContentQueryResult.java | 18 +- .../server/logic/AbstractContentLoader.java | 21 +- .../ExperimentFeatureVectorSummaryLoader.java | 301 ++-------- .../MaterialFeatureVectorSummaryLoader.java | 125 ++-- ...erialFeaturesFromAllExperimentsLoader.java | 228 +------- .../server/logic/WellDataLoader.java | 541 ++++++++++++++++++ .../logic/WellReplicaSummaryCalculator.java | 4 +- .../server/logic/dto/IWellExtendedData.java | 40 -- .../screening/server/logic/dto/WellData.java | 13 +- .../server/logic/dto/WellExtendedData.java | 27 +- .../basic/dto/MaterialSummarySettings.java | 10 +- .../server/dataaccess/ScreeningDAOTest.java | 2 +- ...aterialFeatureVectorSummaryLoaderTest.java | 23 +- .../server/logic}/WellDataCollection.java | 9 +- .../WellReplicaSummaryCalculatorTest.java | 3 +- 17 files changed, 785 insertions(+), 630 deletions(-) create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/IWellReference.java create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellDataLoader.java delete mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/IWellExtendedData.java rename screening/{source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto => sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic}/WellDataCollection.java (79%) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/BasicWellContentQueryResult.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/BasicWellContentQueryResult.java index 76182c72cab..ade4dffa60b 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/BasicWellContentQueryResult.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/BasicWellContentQueryResult.java @@ -17,6 +17,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess; import ch.rinn.restrictions.Private; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReference; /** * Basic information about well content which allows to compute rankings. @@ -24,13 +26,24 @@ import ch.rinn.restrictions.Private; * @author Tomasz Pylak */ @Private -public class BasicWellContentQueryResult +public class BasicWellContentQueryResult implements IWellReference { - public String well_code; + private String well_code; - public String plate_perm_id; + private String plate_perm_id; public String exp_perm_id; public long material_content_id; + + public String getPlatePermId() + { + return plate_perm_id; + } + + public WellReference getWellReference() + { + WellLocation wellLocation = WellLocation.parseLocationStr(well_code); + return new WellReference(wellLocation, plate_perm_id); + } } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/IWellReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/IWellReference.java new file mode 100644 index 00000000000..eb46139a5bd --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/IWellReference.java @@ -0,0 +1,31 @@ +/* + * 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.dataaccess; + +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReference; + +/** + * Allows to reference a well. + * + * @author Tomasz Pylak + */ +public interface IWellReference +{ + String getPlatePermId(); + + WellReference getWellReference(); +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContentQueryResult.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContentQueryResult.java index fa5a0c7713e..1d3d174b821 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContentQueryResult.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContentQueryResult.java @@ -17,12 +17,15 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess; import ch.rinn.restrictions.Private; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReference; /** * @author Tomasz Pylak */ @Private -public class WellContentQueryResult extends ExperimentReferenceQueryResult +public class WellContentQueryResult extends ExperimentReferenceQueryResult implements + IWellReference { // well pointer @@ -42,7 +45,7 @@ public class WellContentQueryResult extends ExperimentReferenceQueryResult public String plate_type_code; - public String plate_perm_id; + private String plate_perm_id; // a pointer to a material which was being searched for inside a well @@ -55,4 +58,15 @@ public class WellContentQueryResult extends ExperimentReferenceQueryResult @Deprecated public String material_content_type_code; + + public String getPlatePermId() + { + return plate_perm_id; + } + + public WellReference getWellReference() + { + WellLocation wellLocation = WellLocation.parseLocationStr(well_code); + return new WellReference(wellLocation, plate_perm_id); + } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/AbstractContentLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/AbstractContentLoader.java index 2e4debdcaa4..b30a9b41855 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/AbstractContentLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/AbstractContentLoader.java @@ -21,6 +21,7 @@ import java.util.Set; import net.lemnik.eodsql.QueryTool; +import org.apache.commons.lang.time.StopWatch; import org.apache.log4j.Logger; import ch.systemsx.cisd.common.exceptions.UserFailureException; @@ -54,6 +55,8 @@ abstract class AbstractContentLoader protected final IDAOFactory daoFactory; + private IScreeningQuery screeningDao = null; + protected AbstractContentLoader(Session session, IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory) { @@ -62,10 +65,14 @@ abstract class AbstractContentLoader this.daoFactory = daoFactory; } - protected static IScreeningQuery createDAO(IDAOFactory daoFactory) + protected IScreeningQuery getScreeningDAO() { - Connection connection = DatabaseContextUtils.getConnection(daoFactory); - return QueryTool.getQuery(connection, IScreeningQuery.class); + if (screeningDao == null) + { + Connection connection = DatabaseContextUtils.getConnection(daoFactory); + screeningDao = QueryTool.getQuery(connection, IScreeningQuery.class); + } + return screeningDao; } protected final ExperimentReference loadExperimentByPermId(String experimentPermId) @@ -106,4 +113,12 @@ abstract class AbstractContentLoader return new FeatureVectorDatasetLoader(session, businessObjectFactory, null, plates, analysisProcedureCriteria); } + + protected final StopWatch createWatchAndStart() + { + StopWatch watch = new StopWatch(); + watch.start(); + return watch; + } + } 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 121438dbc59..cacf849b982 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 @@ -16,13 +16,9 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -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; @@ -30,32 +26,20 @@ import ch.systemsx.cisd.common.collections.CollectionUtils.ICollectionMappingFun 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.business.bo.materiallister.IMaterialLister; -import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister; 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.IEntityProperty; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListMaterialCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; -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.server.logic.dto.IWellData; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellExtendedData; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.WellDataLoader.MaterialIdSummaryAndFeatures; import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary; -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.ExperimentFeatureVectorSummary; 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.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.basic.dto.WellSearchCriteria.AnalysisProcedureCriteria; -import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.WellFeatureCollection; /** * {@See #loadExperimentFeatureVectors}. @@ -64,20 +48,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoa */ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader { - - static class LoaderParameters - { - TechId experimentId; - - AnalysisProcedureCriteria analysisProcedureCriteria; - - LoaderParameters(TechId experimentId, AnalysisProcedureCriteria analysisProcedureCriteria) - { - this.experimentId = experimentId; - this.analysisProcedureCriteria = analysisProcedureCriteria; - } - } - /** * Loads feature vectors summaries for all the materials in the specified experiment. */ @@ -86,57 +56,55 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader TechId experimentId, AnalysisProcedureCriteria analysisProcedureCriteria, MaterialSummarySettings settings) { - LoaderParameters params = new LoaderParameters(experimentId, analysisProcedureCriteria); return new ExperimentFeatureVectorSummaryLoader(session, businessObjectFactory, daoFactory, - settings).loadExperimentFeatureVectors(params); + settings).loadExperimentFeatureVectors(experimentId, analysisProcedureCriteria); } protected final MaterialSummarySettings settings; + private final WellDataLoader wellDataLoader; + protected ExperimentFeatureVectorSummaryLoader(Session session, IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory, MaterialSummarySettings settings) { super(session, businessObjectFactory, daoFactory); this.settings = settings; + this.wellDataLoader = + new WellDataLoader(session, businessObjectFactory, daoFactory, settings); } - private ExperimentFeatureVectorSummary loadExperimentFeatureVectors(LoaderParameters params) + private ExperimentFeatureVectorSummary loadExperimentFeatureVectors(TechId experimentId, + AnalysisProcedureCriteria analysisProcedureCriteria) { - WellDataCollection wellDataCollection = tryLoadWellData(params); - ExperimentReference experiment = loadExperimentByTechId(params.experimentId); - if (wellDataCollection == null) + MaterialIdSummaryAndFeatures summaries = + wellDataLoader.tryCalculateExperimentFeatureVectorSummaries(experimentId, + settings.getReplicaMaterialTypeSubstrings(), analysisProcedureCriteria, + false); + ExperimentReference experiment = loadExperimentByTechId(experimentId); + if (summaries == null) { return createEmptySummary(experiment); } - List<MaterialFeatureVectorSummary> featureSummaries = - calculateReplicasFeatureVectorSummaries(wellDataCollection); - - return new ExperimentFeatureVectorSummary(experiment, featureSummaries, - wellDataCollection.getFeatureDescriptions()); - } - - private List<MaterialFeatureVectorSummary> calculateReplicasFeatureVectorSummaries( - WellDataCollection wellDataCollection) - { - List<? extends IWellData> wellDataList = wellDataCollection.getWellDataList(); - List<MaterialIdFeatureVectorSummary> summaries = - calculateReplicasFeatureVectorSummaries(wellDataList); - return enrichWithMaterial(summaries, wellDataCollection); + List<MaterialFeatureVectorSummary> enrichedFeatureSummaries = + enrichWithMaterials(summaries.getFeatureSummaries()); + return new ExperimentFeatureVectorSummary(experiment, enrichedFeatureSummaries, + summaries.getFeatureNames()); } - private final List<MaterialIdFeatureVectorSummary> calculateReplicasFeatureVectorSummaries( - List<? extends IWellData> wellDataList) + private List<MaterialFeatureVectorSummary> enrichWithMaterials( + List<MaterialIdFeatureVectorSummary> summaries) { - return WellReplicaSummaryCalculator.calculateReplicasFeatureVectorSummaries(wellDataList, - settings.getAggregationType(), false); + Set<Long> materialIds = extractMaterialIds(summaries); + List<Material> materials = fetchMaterials(materialIds); + return enrichWithMaterials(summaries, materials); } - private static List<MaterialFeatureVectorSummary> enrichWithMaterial( - List<MaterialIdFeatureVectorSummary> summaries, WellDataCollection wellDataCollection) + private static List<MaterialFeatureVectorSummary> enrichWithMaterials( + List<MaterialIdFeatureVectorSummary> summaries, List<Material> materials) { - final TableMap<Long, Material> materialMap = createMaterialMap(wellDataCollection); + final TableMap<Long, Material> materialMap = createMaterialMap(materials); return CollectionUtils .map(summaries, new ICollectionMappingFunction<MaterialFeatureVectorSummary, MaterialIdFeatureVectorSummary>() @@ -149,6 +117,22 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader }); } + private List<Material> fetchMaterials(Set<Long> materialIds) + { + return businessObjectFactory.createMaterialLister(session).list( + new ListMaterialCriteria(materialIds), true); + } + + private static Set<Long> extractMaterialIds(List<MaterialIdFeatureVectorSummary> summaries) + { + Set<Long> ids = new HashSet<Long>(); + for (MaterialIdFeatureVectorSummary summary : summaries) + { + ids.add(summary.getMaterial()); + } + return ids; + } + private static MaterialFeatureVectorSummary convert(MaterialIdFeatureVectorSummary summary, TableMap<Long, Material> materialMap) { @@ -157,58 +141,15 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader } private static TableMap<Long/* material id */, Material> createMaterialMap( - WellDataCollection wellDataCollection) + List<Material> materials) { - List<Material> materials = - CollectionUtils.map(wellDataCollection.getWellDataList(), - new ICollectionMappingFunction<Material, IWellExtendedData>() - { - public Material map(IWellExtendedData wellData) - { - return wellData.getMaterial(); - } - }); return new TableMap<Long, Material>(materials, new IKeyExtractor<Long, Material>() { public Long getKey(Material material) { return material.getId(); } - }, UniqueKeyViolationStrategy.KEEP_FIRST); - } - - protected final WellDataCollection tryLoadWellData(LoaderParameters params) - { - ISampleLister sampleLister = businessObjectFactory.createSampleLister(session); - List<Sample> plates = - sampleLister.list(createExperientCriteria(params.experimentId.getId())); - List<Sample> wells = sampleLister.list(createWellsCriteria(plates)); - if (wells.isEmpty()) - { - return null; // no wells in this experiment - } - enrichWithMaterialProperties(wells); - - Set<PlateIdentifier> plateIdentifiers = extractIdentifiers(plates); - WellFeatureCollection<FeatureVectorValues> featureVectorsCollection = - tryLoadWellSingleFeatureVectors(plateIdentifiers, params.analysisProcedureCriteria); - if (featureVectorsCollection == null) - { - return null; // no feature vector datasets connected to plates in this experiment - } - - List<IWellExtendedData> wellDataList = asWellData(wells, featureVectorsCollection); - return new WellDataCollection(wellDataList, - featureVectorsCollection.getFeatureCodesAndLabels()); - } - - private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors( - Set<PlateIdentifier> plateIdentifiers, - AnalysisProcedureCriteria analysisProcedureCriteria) - { - return new WellFeatureCollectionLoader(session, businessObjectFactory, daoFactory) - .tryLoadWellSingleFeatureVectors(plateIdentifiers, settings.getFeatureCodes(), - analysisProcedureCriteria); + }, UniqueKeyViolationStrategy.ERROR); } private static ExperimentFeatureVectorSummary createEmptySummary(ExperimentReference experiment) @@ -217,156 +158,4 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader List<CodeAndLabel> featureDescriptions = Collections.emptyList(); return new ExperimentFeatureVectorSummary(experiment, materialsSummary, featureDescriptions); } - - private void enrichWithMaterialProperties(List<Sample> samples) - { - IMaterialLister materialLister = businessObjectFactory.createMaterialLister(session); - List<Material> containedMaterials = extractMaterialsWithDuplicates(samples); - materialLister.enrichWithProperties(containedMaterials); - } - - private static List<Material> extractMaterialsWithDuplicates(List<Sample> samples) - { - List<Material> materials = new ArrayList<Material>(); - for (Sample sample : samples) - { - materials.addAll(extractMaterials(sample)); - } - return materials; - } - - private static Collection<? extends Material> extractMaterials(Sample sample) - { - List<Material> materials = new ArrayList<Material>(); - List<IEntityProperty> properties = sample.getProperties(); - for (IEntityProperty property : properties) - { - Material material = property.getMaterial(); - if (material != null) - { - materials.add(material); - } - } - return materials; - } - - private List<IWellExtendedData> asWellData(List<Sample> wells, - WellFeatureCollection<FeatureVectorValues> featureVectorsCollection) - { - Map<WellReference, FeatureVectorValues> featureVectors = - createWellToFeatureVectorMap(featureVectorsCollection); - List<String> orderedFeatureLabels = featureVectorsCollection.getFeatureLabels(); - List<IWellExtendedData> wellDataList = new ArrayList<IWellExtendedData>(); - for (Sample well : wells) - { - IWellExtendedData wellData = - tryCreateWellData(well, featureVectors, orderedFeatureLabels); - if (wellData != null) - { - wellDataList.add(wellData); - } - } - return wellDataList; - } - - private IWellExtendedData tryCreateWellData(Sample well, - Map<WellReference, FeatureVectorValues> featureVectorsMap, - List<String> orderedFeatureLabels) - { - final float[] featureVectorNumbers = - tryExtractFeatureVectorValues(well, featureVectorsMap, orderedFeatureLabels); - if (featureVectorNumbers == null) - { - return null; - } - final Material replicaMaterial = tryFindReplicaMaterial(well, settings); - if (replicaMaterial == null) - { - return null; - } - return new WellExtendedData(replicaMaterial.getId(), featureVectorNumbers, well, - replicaMaterial); - } - - private static Material tryFindReplicaMaterial(Sample well, MaterialSummarySettings settings) - { - String replicaMatrialTypePattern = - ScreeningUtils.asJavaRegExpr(settings.getReplicaMatrialTypeSubstrings()); - if (replicaMatrialTypePattern == null) - { - return null; - } - for (Material material : extractMaterials(well)) - { - if (material.getEntityType().getCode().matches(replicaMatrialTypePattern)) - { - return material; - } - } - return null; - } - - private static float[] tryExtractFeatureVectorValues(Sample well, - Map<WellReference, FeatureVectorValues> featureVectorsMap, - List<String> orderedFeatureLabels) - { - WellReference wellReference = asWellReference(well); - FeatureVectorValues featureVector = featureVectorsMap.get(wellReference); - if (featureVector == null) - { - return null; - } - return WellFeatureCollectionLoader.asFeatureVectorValues(featureVector); - } - - private static WellReference asWellReference(Sample well) - { - WellLocation location = - ScreeningUtils.tryCreateLocationFromMatrixCoordinate(well.getSubCode()); - WellReference wellReference = new WellReference(location, well.getContainer().getPermId()); - return wellReference; - } - - private static Set<PlateIdentifier> extractIdentifiers(List<Sample> plates) - { - Set<PlateIdentifier> idents = new HashSet<PlateIdentifier>(); - for (Sample plate : plates) - { - idents.add(PlateIdentifier.createFromPermId(plate.getPermId())); - } - return idents; - } - - private static ListOrSearchSampleCriteria createWellsCriteria(List<Sample> plates) - { - Collection<Long> plateIds = new ArrayList<Long>(); - for (Sample plate : plates) - { - plateIds.add(plate.getId()); - } - ListOrSearchSampleCriteria criteria = - new ListOrSearchSampleCriteria( - ListOrSearchSampleCriteria.createForContainers(plateIds)); - return criteria; - } - - private static ListOrSearchSampleCriteria createExperientCriteria(long expId) - { - return new ListOrSearchSampleCriteria( - ListOrSearchSampleCriteria.createForExperiment(new TechId(expId))); - } - - private static Map<WellReference, FeatureVectorValues> createWellToFeatureVectorMap( - WellFeatureCollection<FeatureVectorValues> featureVectors) - { - Map<WellReference, FeatureVectorValues> wellToFeatureVectorMap = - new HashMap<WellReference, FeatureVectorValues>(); - for (FeatureVectorValues featureValues : featureVectors.getFeatures()) - { - WellReference wellReference = featureValues.getWellReference(); - wellToFeatureVectorMap.put(wellReference, featureValues); - } - return wellToFeatureVectorMap; - } - } 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 75b8031116b..f3d20c0efe6 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 @@ -29,21 +29,21 @@ 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.basic.dto.CodeAndLabel; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityPropertiesHolder; 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.IWellExtendedData; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.WellDataLoader.MaterialIdSummaryAndFeatures; 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.MaterialTechnicalReplicateFeatureVector; -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.basic.dto.MaterialBiologicalReplicateFeatureSummary; 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.MaterialSummarySettings; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria.AnalysisProcedureCriteria; /** * For the specified material in the specified experiment loads feature vectors (details and @@ -52,7 +52,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummar * * @author Tomasz Pylak */ -public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorSummaryLoader +public class MaterialFeatureVectorSummaryLoader extends AbstractContentLoader { /** * For comments {@See MaterialFeatureVectorSummaryLoader}. @@ -165,40 +165,56 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS // ---------------------- + private final MaterialSummarySettings settings; + + private final WellDataLoader wellDataLoader; + @Private MaterialFeatureVectorSummaryLoader(Session session, IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory, MaterialSummarySettings settings) { - super(session, businessObjectFactory, daoFactory, settings); + super(session, businessObjectFactory, daoFactory); + this.settings = settings; + this.wellDataLoader = + new WellDataLoader(session, businessObjectFactory, daoFactory, settings); + } private MaterialAllReplicasFeatureVectors tryLoadMaterialFeatureVectors(TechId materialId, TechId experimentId) { - // TODO KE: 2011-07-15 this should also be changed - LoaderParameters params = new LoaderParameters(experimentId, null); - WellDataCollection experimentWells = tryLoadWellData(params); - if (experimentWells == null) + // TODO KE: 2011-07-15 specify analysis procedure + AnalysisProcedureCriteria analysisProcedureCriteria = + AnalysisProcedureCriteria.createAllProcedures(); + MaterialIdSummaryAndFeatures summaries = + wellDataLoader.tryCalculateExperimentFeatureVectorSummaries(experimentId, + analysisProcedureCriteria, materialId, true); + if (summaries == null) { return null; } - return tryLoadMaterialFeatureVectors(materialId, experimentWells); - } - - @Private - MaterialAllReplicasFeatureVectors tryLoadMaterialFeatureVectors(TechId materialId, - WellDataCollection experimentWells) - { - List<IWellExtendedData> experimentWellsData = experimentWells.getWellDataList(); MaterialIdFeatureVectorSummary materialGeneralSummary = - tryCalculateMaterialSummary(materialId, experimentWellsData); + tryFindMaterialSummary(materialId, summaries.getFeatureSummaries()); if (materialGeneralSummary == null) { return null; } - List<IWellExtendedData> materialWellsData = - filterWellsByMaterial(experimentWellsData, materialId); + List<WellExtendedData> materialWellsData = + wellDataLoader.tryLoadWellData(materialId, experimentId, analysisProcedureCriteria); + if (materialWellsData == null) + { + return null; + } + return createMaterialFeatureVectors(materialId, materialWellsData, materialGeneralSummary, + summaries.getFeatureNames()); + } + + @Private + MaterialAllReplicasFeatureVectors createMaterialFeatureVectors(TechId materialId, + List<WellExtendedData> materialWellsData, + MaterialIdFeatureVectorSummary materialGeneralSummary, List<CodeAndLabel> featureNames) + { ReplicateSequenceProvider replicaSequences = new ReplicateSequenceProvider(materialWellsData, settings.getBiologicalReplicatePropertyTypeCodes()); @@ -208,14 +224,14 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS List<MaterialTechnicalReplicateFeatureVector> replicas = filterDirectTechnicalReplicas(materialWellsData, replicaSequences); - return new MaterialAllReplicasFeatureVectors(experimentWells.getFeatureDescriptions(), - materialGeneralSummary, subgroups, replicas); + return new MaterialAllReplicasFeatureVectors(featureNames, materialGeneralSummary, + subgroups, replicas); } private List<MaterialBiologicalReplicateFeatureVector> createBiologicalReplicates( - List<IWellExtendedData> materialWells, ReplicateSequenceProvider replicaSequences) + List<WellExtendedData> materialWells, ReplicateSequenceProvider replicaSequences) { - GroupByMap<Integer, IWellExtendedData> biologicalReplicateMap = + GroupByMap<Integer, WellExtendedData> biologicalReplicateMap = groupByBiologicalReplicate(materialWells, replicaSequences); List<MaterialBiologicalReplicateFeatureVector> subgroups = @@ -223,7 +239,7 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS MaterialReplicaSummaryAggregationType aggregationType = settings.getAggregationType(); for (Integer biologicalReplicateSeq : replicaSequences.getBiologicalReplicateSequences()) { - List<IWellExtendedData> technicalReplicateWells = + List<WellExtendedData> technicalReplicateWells = biologicalReplicateMap.getOrDie(biologicalReplicateSeq); MaterialBiologicalReplicateFeatureVector subgroup = createBiologicalReplicate(technicalReplicateWells, replicaSequences, @@ -234,7 +250,7 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS } private MaterialBiologicalReplicateFeatureVector createBiologicalReplicate( - List<IWellExtendedData> technicalReplicateWells, + List<WellExtendedData> technicalReplicateWells, ReplicateSequenceProvider replicaSequences, MaterialReplicaSummaryAggregationType aggregationType) { @@ -248,37 +264,28 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS aggregationType, subgroupLabel); } - private String getSubgroupLabel(List<IWellExtendedData> subgroupWellDataList, + private String getSubgroupLabel(List<WellExtendedData> subgroupWellDataList, ReplicateSequenceProvider replicaSequences) { assert subgroupWellDataList.size() > 0 : "empty subgroup"; // all wells belong to the same subgroup, so it does not matter which one we take - Sample well = subgroupWellDataList.get(0).getWell(); + IEntityPropertiesHolder well = subgroupWellDataList.get(0); String label = replicaSequences.tryGetBiologicalReplicateLabel(well); assert label != null : "no biological replicates!"; return label; } - private MaterialIdFeatureVectorSummary tryCalculateMaterialSummary(TechId materialId, - List<? extends IWellData> experimentWellDataList) - { - List<MaterialIdFeatureVectorSummary> featureSummaries = - WellReplicaSummaryCalculator.calculateReplicasFeatureVectorSummaries( - experimentWellDataList, settings.getAggregationType(), true); - return tryFindMaterialSummary(materialId, featureSummaries); - } - // chooses wells which have no information about which biological replicate they are private static List<MaterialTechnicalReplicateFeatureVector> filterDirectTechnicalReplicas( - List<IWellExtendedData> materialWellDataList, + List<WellExtendedData> materialWellDataList, final ReplicateSequenceProvider replicaSequences) { - List<IWellExtendedData> directTechnicalReplicas = + List<WellExtendedData> directTechnicalReplicas = CollectionUtils.filter(materialWellDataList, - new ICollectionFilter<IWellExtendedData>() + new ICollectionFilter<WellExtendedData>() { - public boolean isPresent(IWellExtendedData element) + public boolean isPresent(WellExtendedData element) { return replicaSequences.isBiologicalReplicate(element) == false; } @@ -288,11 +295,11 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS } private static List<MaterialTechnicalReplicateFeatureVector> createTechnicalReplicates( - List<IWellExtendedData> wells, final ReplicateSequenceProvider replicaSequences) + List<WellExtendedData> wells, final ReplicateSequenceProvider replicaSequences) { List<MaterialTechnicalReplicateFeatureVector> replicas = new ArrayList<MaterialTechnicalReplicateFeatureVector>(); - for (IWellExtendedData wellData : wells) + for (WellExtendedData wellData : wells) { int replicaSequenceNumber = replicaSequences.getTechnicalReplicateSequence(wellData); MaterialTechnicalReplicateFeatureVector featureVector = @@ -304,12 +311,12 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS } private static void sortByTechnicalReplicateSequence( - List<IWellExtendedData> materialWellDataList, + List<WellExtendedData> materialWellDataList, final ReplicateSequenceProvider replicaSequences) { - Collections.sort(materialWellDataList, new Comparator<IWellExtendedData>() + Collections.sort(materialWellDataList, new Comparator<WellExtendedData>() { - public int compare(IWellExtendedData w1, IWellExtendedData w2) + public int compare(WellExtendedData w1, WellExtendedData w2) { Integer replicaSequenceNumber1 = replicaSequences.getTechnicalReplicateSequence(w1); @@ -320,33 +327,19 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS }); } - private static List<IWellExtendedData> filterWellsByMaterial( - List<IWellExtendedData> wellDataList, final TechId materialTechId) - { - final Long materialId = materialTechId.getId(); - return CollectionUtils.filter(wellDataList, new ICollectionFilter<IWellExtendedData>() - { - public boolean isPresent(IWellExtendedData element) - { - return materialId.equals(element.getReplicaMaterialId()); - } - }); - } - /** * A subgroup can be e.g. oligo or compound concentration. */ - private GroupByMap<Integer, IWellExtendedData> groupByBiologicalReplicate( - List<IWellExtendedData> materialWellDataList, + private GroupByMap<Integer, WellExtendedData> groupByBiologicalReplicate( + List<WellExtendedData> materialWellDataList, final ReplicateSequenceProvider replicaSequences) { return GroupByMap.create(materialWellDataList, - new IKeyExtractor<Integer, IWellExtendedData>() + new IKeyExtractor<Integer, WellExtendedData>() { - public Integer getKey(IWellExtendedData wellData) + public Integer getKey(WellExtendedData wellData) { - return replicaSequences.tryGetBiologicalReplicateSequence(wellData - .getWell()); + return replicaSequences.tryGetBiologicalReplicateSequence(wellData); } }); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeaturesFromAllExperimentsLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeaturesFromAllExperimentsLoader.java index 2e72507c65d..71b827dc71a 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeaturesFromAllExperimentsLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeaturesFromAllExperimentsLoader.java @@ -18,11 +18,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; import org.apache.commons.lang.time.StopWatch; @@ -34,21 +30,11 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; 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.dataaccess.BasicWellContentQueryResult; import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.ExperimentReferenceQueryResult; import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.IScreeningQuery; -import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.PatternMatchingUtils; -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.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.WellLocation; -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 @@ -65,18 +51,17 @@ public class MaterialFeaturesFromAllExperimentsLoader extends AbstractContentLoa IDAOFactory daoFactory, TechId materialId, TechId projectTechIdOrNull, MaterialSummarySettings settings) { - IScreeningQuery dao = createDAO(daoFactory); + MaterialFeaturesFromAllExperimentsLoader loader = + new MaterialFeaturesFromAllExperimentsLoader(session, businessObjectFactory, + daoFactory, settings); List<ExperimentReference> experiments = - fetchExperiments(materialId, projectTechIdOrNull, dao); - - return new MaterialFeaturesFromAllExperimentsLoader(session, businessObjectFactory, - daoFactory, dao, settings).loadMaterialFeatureVectorsFromAllAssays(materialId, - experiments); + loader.fetchExperiments(materialId, projectTechIdOrNull); + return loader.loadMaterialFeatureVectorsFromAllAssays(materialId, experiments); } - private static List<ExperimentReference> fetchExperiments(TechId materialId, - TechId projectTechIdOrNull, IScreeningQuery dao) + private List<ExperimentReference> fetchExperiments(TechId materialId, TechId projectTechIdOrNull) { + IScreeningQuery dao = getScreeningDAO(); List<ExperimentReferenceQueryResult> experimentRefs; if (projectTechIdOrNull == null) { @@ -111,42 +96,15 @@ public class MaterialFeaturesFromAllExperimentsLoader extends AbstractContentLoa exp.exp_type_code, exp.proj_code, exp.space_code); } - private final MaterialSummarySettings settings; - - private final IScreeningQuery screeningQuery; + private final WellDataLoader wellDataLoader; private MaterialFeaturesFromAllExperimentsLoader(Session session, IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory, - IScreeningQuery screeningQuery, MaterialSummarySettings settings) + MaterialSummarySettings settings) { super(session, businessObjectFactory, daoFactory); - this.settings = settings; - this.screeningQuery = screeningQuery; - } - - private List<BasicWellContentQueryResult> fetchWellLocations( - List<ExperimentReference> experiments) - { - StopWatch watch = createWatchAndStart(); - String materialTypePattern = - PatternMatchingUtils.asPostgresSimilarExpression(settings - .getReplicaMatrialTypeSubstrings()); - List<BasicWellContentQueryResult> wells = - screeningQuery.getPlateLocationsForExperiment(extractIds(experiments), - materialTypePattern); - operationLog.info("[" + watch.getTime() + " msec] Fetching " + wells.size() + " wells."); - return wells; - } - - private static long[] extractIds(List<ExperimentReference> experiments) - { - long[] ids = new long[experiments.size()]; - int i = 0; - for (ExperimentReference experiment : experiments) - { - ids[i++] = experiment.getId(); - } - return ids; + this.wellDataLoader = + new WellDataLoader(session, businessObjectFactory, daoFactory, settings); } /** @@ -182,7 +140,8 @@ public class MaterialFeaturesFromAllExperimentsLoader extends AbstractContentLoa operationLog.info(String.format("Processing %d experiments with %d datasets: %s", experimentsBatch.size(), datasetsInBatch, experimentsBatch)); List<MaterialSimpleFeatureVectorSummary> batchSummaries = - loadMaterialFeatureVectorsFromAllAssaysBatch(materialId, experimentsBatch); + wellDataLoader.loadMaterialFeatureVectorsFromAllAssaysBatch(materialId, + experimentsBatch); summaries.addAll(batchSummaries); experimentsBatch.clear(); datasetsInBatch = 0; @@ -194,54 +153,6 @@ public class MaterialFeaturesFromAllExperimentsLoader extends AbstractContentLoa return summaries; } - // load all experiments in a constant number of selects - private List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssaysBatch( - TechId materialId, List<ExperimentReference> experiments) - { - List<MaterialSimpleFeatureVectorSummary> summaries = - new ArrayList<MaterialSimpleFeatureVectorSummary>(); - StopWatch watch = createWatchAndStart(); - int totalWellsLoaded = 0; - int totalFeatureVectorsLoaded = 0; - - List<BasicWellContentQueryResult> allWells = fetchWellLocations(experiments); - totalWellsLoaded += allWells.size(); - Set<PlateIdentifier> plates = extractPlates(allWells); - WellFeatureCollection<FeatureVectorValues> allWellFeaturesOrNull = - tryLoadWellSingleFeatureVectors(plates); - - if (allWellFeaturesOrNull == null) - { - addEmptySummaries(summaries, experiments); - } else - { - for (ExperimentReference experiment : experiments) - { - totalFeatureVectorsLoaded += allWellFeaturesOrNull.getFeatures().size(); - Map<WellReference, Long/* material id */> wellToMaterialMap = - createWellToMaterialMapForExperiment(allWells, experiment); - - MaterialSimpleFeatureVectorSummary summary = - calculateExperimentFeatureVectorSummary(materialId, experiment, - allWellFeaturesOrNull, wellToMaterialMap); - summaries.add(summary); - } - } - operationLog.info(String.format( - "[%d msec] Experiments batch: %d, wells loaded: %d, feature vectors: %d.", - watch.getTime(), experiments.size(), totalWellsLoaded, totalFeatureVectorsLoaded)); - return summaries; - } - - private void addEmptySummaries(List<MaterialSimpleFeatureVectorSummary> summaries, - List<ExperimentReference> experiments) - { - for (ExperimentReference experiment : experiments) - { - summaries.add(new MaterialSimpleFeatureVectorSummary(experiment)); - } - } - private int countAnalysisDatasets(ExperimentReference experiment) { List<TechId> experiments = Arrays.asList(new TechId(experiment.getId())); @@ -250,117 +161,4 @@ public class MaterialFeaturesFromAllExperimentsLoader extends AbstractContentLoa return ScreeningUtils.filterImageAnalysisDatasets(datasets).size(); } - private StopWatch createWatchAndStart() - { - StopWatch watch = new StopWatch(); - watch.start(); - return watch; - } - - private static Map<WellReference, Long/* material id */> createWellToMaterialMapForExperiment( - List<BasicWellContentQueryResult> wells, ExperimentReference experiment) - { - Map<WellReference, Long> wellToMaterialMap = new HashMap<WellReference, Long>(); - for (BasicWellContentQueryResult well : wells) - { - if (belongsToExperiment(well, experiment)) - { - WellReference wellReference = createWellReference(well); - wellToMaterialMap.put(wellReference, well.material_content_id); - } - } - return wellToMaterialMap; - } - - private static boolean belongsToExperiment(BasicWellContentQueryResult well, - ExperimentReference experiment) - { - return well.exp_perm_id.equals(experiment.getPermId()); - } - - private static WellReference createWellReference(BasicWellContentQueryResult well) - { - WellLocation wellLocation = WellLocation.parseLocationStr(well.well_code); - return new WellReference(wellLocation, well.plate_perm_id); - } - - /** - * @param experimentWellToMaterialMap wells belonging to the specified experiment - * @param allFeatures all features, not only for the specified experiment but possibly also for - * few others - */ - private MaterialSimpleFeatureVectorSummary calculateExperimentFeatureVectorSummary( - TechId materialId, ExperimentReference experiment, - WellFeatureCollection<FeatureVectorValues> allFeatures, - Map<WellReference, Long> experimentWellToMaterialMap) - { - // we have to calculate summaries for all materials in the experiment to get the right - // ranking of the specified material - List<IWellData> experimentWellData = - createWellData(experimentWellToMaterialMap, allFeatures.getFeatures()); - List<MaterialIdFeatureVectorSummary> experimentSummaries = - WellReplicaSummaryCalculator.calculateReplicasFeatureVectorSummaries( - experimentWellData, settings.getAggregationType(), false); - - // select the summary of the right material - MaterialIdFeatureVectorSummary materialSummary = - findMaterialSummary(materialId, experimentSummaries); - return new MaterialSimpleFeatureVectorSummary(experiment, - allFeatures.getFeatureCodesAndLabels(), materialSummary.getFeatureVectorSummary(), - materialSummary.getFeatureVectorRanks()); - } - - private MaterialIdFeatureVectorSummary findMaterialSummary(TechId materialId, - List<MaterialIdFeatureVectorSummary> summaries) - { - for (MaterialIdFeatureVectorSummary summary : summaries) - { - if (summary.getMaterial().equals(materialId.getId())) - { - return summary; - } - } - throw new IllegalStateException("It should not happen: no summary found for material " - + materialId); - } - - // connects each well with a material with its feature vector - private static List<IWellData> createWellData( - Map<WellReference, Long/* material id */> experimentWellToMaterialMap, - List<FeatureVectorValues> allFeatures) - { - List<IWellData> experimentWellDataList = new ArrayList<IWellData>(); - for (FeatureVectorValues feature : allFeatures) - { - Long materialId = experimentWellToMaterialMap.get(feature.getWellReference()); - if (materialId != null) - { - float[] values = WellFeatureCollectionLoader.asFeatureVectorValues(feature); - IWellData wellData = new WellData(materialId, values); - experimentWellDataList.add(wellData); - } - } - return experimentWellDataList; - } - - private static Set<PlateIdentifier> extractPlates(List<BasicWellContentQueryResult> allWells) - { - Set<PlateIdentifier> plates = new HashSet<PlateIdentifier>(); - for (BasicWellContentQueryResult well : allWells) - { - String platePermId = well.plate_perm_id; - PlateIdentifier plateIdent = PlateIdentifier.createFromPermId(platePermId); - plates.add(plateIdent); - } - return plates; - } - - private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors( - Set<PlateIdentifier> plateIdentifiers) - { - // TODO KE: 2011-07-15 specify analysis procedure here ? - return new WellFeatureCollectionLoader(session, businessObjectFactory, daoFactory) - .tryLoadWellSingleFeatureVectors(plateIdentifiers, settings.getFeatureCodes(), null); - } - } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellDataLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellDataLoader.java new file mode 100644 index 00000000000..24c755ace32 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellDataLoader.java @@ -0,0 +1,541 @@ +/* + * 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 net.lemnik.eodsql.DataIterator; + +import org.apache.commons.lang.time.StopWatch; + +import ch.systemsx.cisd.common.collections.CollectionUtils; +import ch.systemsx.cisd.common.collections.CollectionUtils.ICollectionFilter; +import ch.systemsx.cisd.openbis.generic.server.business.bo.IMaterialBO; +import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister; +import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister; +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.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; +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.server.dataaccess.BasicWellContentQueryResult; +import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.IWellReference; +import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.PatternMatchingUtils; +import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContentQueryResult; +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.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.WellReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria.AnalysisProcedureCriteria; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.WellFeatureCollection; + +/** + * Loads well's feature vectors and materials and calculates summaries. + * + * @author Tomasz Pylak + */ +class WellDataLoader extends AbstractContentLoader +{ + private final MaterialSummarySettings settings; + + public WellDataLoader(Session session, IScreeningBusinessObjectFactory businessObjectFactory, + IDAOFactory daoFactory, MaterialSummarySettings settings) + { + super(session, businessObjectFactory, daoFactory); + this.settings = settings; + } + + /** + * Loads feature vectors of each well with the specified material in the specified experiment. + */ + public List<WellExtendedData> tryLoadWellData(TechId materialId, TechId experimentId, + AnalysisProcedureCriteria analysisProcedureCriteria) + { + List<WellContentQueryResult> wells = + getPlateLocationsForMaterialId(materialId, experimentId); + List<WellData> wellsData = + tryCreateWellDataForMaterial(wells, materialId, analysisProcedureCriteria); + if (wellsData == null) + { + return null; + } + Map<WellReference, Sample> wellRefToSampleMap = loadEnrichedWellSamples(wells); + return createWellExtendedData(wellsData, wellRefToSampleMap); + } + + private List<WellContentQueryResult> getPlateLocationsForMaterialId(TechId materialId, + TechId experimentId) + { + DataIterator<WellContentQueryResult> wellsIterator = + getScreeningDAO().getPlateLocationsForMaterialId(materialId.getId(), + experimentId.getId()); + + List<WellContentQueryResult> wells = new ArrayList<WellContentQueryResult>(); + for (WellContentQueryResult well : wellsIterator) + { + wells.add(well); + } + return wells; + } + + private Map<WellReference, Sample> loadEnrichedWellSamples( + Iterable<WellContentQueryResult> wells) + { + Set<Long> wellIds = extractWellIds(wells); + List<Sample> wellSamples = loadSamplesWithMaterialPropertiesEnriched(wellIds); + return asWellRefToSampleMap(wellSamples, wells); + } + + private List<WellData> tryCreateWellDataForMaterial(Iterable<WellContentQueryResult> wells, + TechId materialId, AnalysisProcedureCriteria analysisProcedureCriteria) + { + WellFeatureCollection<FeatureVectorValues> allWellFeatures = + tryLoadWellSingleFeatureVectors(wells, analysisProcedureCriteria); + if (allWellFeatures == null) + { + return null; + } + List<FeatureVectorValues> features = allWellFeatures.getFeatures(); + Map<WellReference, Long> dummyMaterialMap = createDummyMaterialMap(wells, materialId); + return createWellData(dummyMaterialMap, features); + } + + private Map<WellReference, Long/* material id */> createDummyMaterialMap( + Iterable<WellContentQueryResult> wells, TechId materialId) + { + Map<WellReference, Long> experimentWellToMaterialMap = new HashMap<WellReference, Long>(); + for (WellContentQueryResult well : wells) + { + WellReference wellReference = well.getWellReference(); + experimentWellToMaterialMap.put(wellReference, materialId.getId()); + } + return experimentWellToMaterialMap; + } + + private static Map<WellReference, Sample> asWellRefToSampleMap(List<Sample> wellSamples, + Iterable<WellContentQueryResult> wells) + { + Map<WellReference, Sample> wellRefToSampleMap = new HashMap<WellReference, Sample>(); + Map<Long, Sample> idToSampleMap = asSampleIdMap(wellSamples); + for (WellContentQueryResult well : wells) + { + Sample sample = idToSampleMap.get(well.well_id); + wellRefToSampleMap.put(well.getWellReference(), sample); + } + return wellRefToSampleMap; + } + + private List<WellExtendedData> createWellExtendedData(List<WellData> wellsData, + final Map<WellReference, Sample> wellRefToSampleMap) + { + return CollectionUtils.map(wellsData, + new CollectionUtils.ICollectionMappingFunction<WellExtendedData, WellData>() + { + public WellExtendedData map(WellData wellData) + { + WellReference wellReference = wellData.tryGetWellReference(); + assert wellReference != null : "wellReference not available for " + + wellData; + Sample wellSample = wellRefToSampleMap.get(wellReference); + assert wellSample != null : "Cannot find a sample for " + wellReference; + + return new WellExtendedData(wellData, wellSample); + } + }); + } + + private static Map<Long, Sample> asSampleIdMap(List<Sample> samples) + { + Map<Long/* sample id */, Sample> map = new HashMap<Long, Sample>(); + for (Sample sample : samples) + { + map.put(sample.getId(), sample); + } + return map; + } + + private List<Sample> loadSamplesWithMaterialPropertiesEnriched(Set<Long> wellIds) + { + ListOrSearchSampleCriteria criteria = new ListOrSearchSampleCriteria(wellIds); + ISampleLister sampleLister = businessObjectFactory.createSampleLister(session); + List<Sample> wellSamples = sampleLister.list(criteria); + + IMaterialLister materialLister = businessObjectFactory.createMaterialLister(session); + List<Material> containedMaterials = getMaterialsWithDuplicates(wellSamples); + materialLister.enrichWithProperties(containedMaterials); + + return wellSamples; + } + + /** + * Return *all* material objects contained in the wells as list. The list can contained + * different objects representing the same entity in the database, but we need the duplication + * to be able to populate an object graph with wells correctly. + */ + private static List<Material> getMaterialsWithDuplicates(List<Sample> samples) + { + List<Material> materials = new ArrayList<Material>(); + for (Sample sample : samples) + { + for (IEntityProperty property : sample.getProperties()) + { + Material materialOrNull = property.getMaterial(); + if (materialOrNull != null) + { + materials.add(materialOrNull); + } + } + } + return materials; + } + + private static Set<Long> extractWellIds(Iterable<WellContentQueryResult> wells) + { + Set<Long> ids = new HashSet<Long>(); + for (WellContentQueryResult well : wells) + { + ids.add(well.well_id); + } + return ids; + } + + /** + * Calculates summaries of feature vectors for each experiment and a specified material. Uses a + * constant number of selects. + */ + public List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssaysBatch( + TechId materialId, List<ExperimentReference> experiments) + { + List<MaterialSimpleFeatureVectorSummary> summaries = + new ArrayList<MaterialSimpleFeatureVectorSummary>(); + StopWatch watch = createWatchAndStart(); + int totalWellsLoaded = 0; + int totalFeatureVectorsLoaded = 0; + + List<BasicWellContentQueryResult> allWells = + fetchWellLocations(materialId, extractIds(experiments)); + totalWellsLoaded += allWells.size(); + // TODO KE: 2011-07-15 specify analysis procedure here + WellFeatureCollection<FeatureVectorValues> allWellFeaturesOrNull = + tryLoadWellSingleFeatureVectors(allWells, + AnalysisProcedureCriteria.createAllProcedures()); + + if (allWellFeaturesOrNull == null) + { + addEmptySummaries(summaries, experiments); + } else + { + for (ExperimentReference experiment : experiments) + { + totalFeatureVectorsLoaded += allWellFeaturesOrNull.getFeatures().size(); + List<BasicWellContentQueryResult> experimentWells = + filterExperimentWells(allWells, experiment.getPermId()); + List<MaterialIdFeatureVectorSummary> experimentSummaries = + calculateExperimentFeatureVectorSummaries(experimentWells, + allWellFeaturesOrNull, false); + + MaterialSimpleFeatureVectorSummary summary = + findExperimentFeatureVectorSummary(materialId, experiment, + allWellFeaturesOrNull.getFeatureCodesAndLabels(), + experimentSummaries); + summaries.add(summary); + } + } + operationLog.info(String.format( + "[%d msec] Experiments batch: %d, wells loaded: %d, feature vectors: %d.", + watch.getTime(), experiments.size(), totalWellsLoaded, totalFeatureVectorsLoaded)); + return summaries; + } + + private static long[] extractIds(List<ExperimentReference> experiments) + { + long[] ids = new long[experiments.size()]; + int i = 0; + for (ExperimentReference experiment : experiments) + { + ids[i++] = experiment.getId(); + } + return ids; + } + + private void addEmptySummaries(List<MaterialSimpleFeatureVectorSummary> summaries, + List<ExperimentReference> experiments) + { + for (ExperimentReference experiment : experiments) + { + summaries.add(new MaterialSimpleFeatureVectorSummary(experiment)); + } + } + + /** + * Fetches wells containing materials of the same type as the specified one in chosen + * experiment. + */ + private List<BasicWellContentQueryResult> fetchWellLocations(TechId materialId, + TechId experimentId) + { + return fetchWellLocations(materialId, new long[] + { experimentId.getId() }); + } + + /** + * Fetches wells containing materials of the same type as the specified one in chosen + * experiments. + */ + private List<BasicWellContentQueryResult> fetchWellLocations(TechId materialId, + long[] experimentIds) + { + String materialTypeCode = fetchMaterialTypeCode(materialId); + return fetchWellLocations(materialTypeCode, experimentIds); + } + + private List<BasicWellContentQueryResult> fetchWellLocations(String materialTypeCodePattern, + long[] experimentIds) + { + StopWatch watch = createWatchAndStart(); + List<BasicWellContentQueryResult> wells = + getScreeningDAO().getPlateLocationsForExperiment(experimentIds, + materialTypeCodePattern); + operationLog.info("[" + watch.getTime() + " msec] Fetching " + wells.size() + " wells."); + return wells; + } + + private List<MaterialIdFeatureVectorSummary> calculateExperimentFeatureVectorSummaries( + Iterable<BasicWellContentQueryResult> wells, + WellFeatureCollection<FeatureVectorValues> allWellFeatures, boolean calculateDeviations) + { + List<? extends IWellData> experimentWellData = createWellData(wells, allWellFeatures); + + // We have to calculate summaries for all materials in the experiment to get the + // right ranking of the specified material. + return calculateExperimentFeatureVectorSummaries(experimentWellData, calculateDeviations); + } + + private List<WellData> createWellData(Iterable<BasicWellContentQueryResult> wells, + WellFeatureCollection<FeatureVectorValues> allWellFeatures) + { + Map<WellReference, Long/* material id */> wellToMaterialMap = + createWellToMaterialMap(wells); + return createWellData(wellToMaterialMap, allWellFeatures.getFeatures()); + } + + private String fetchMaterialTypeCode(TechId materialId) + { + IMaterialBO materialBO = businessObjectFactory.createMaterialBO(session); + materialBO.loadDataByTechId(materialId); + return materialBO.getMaterial().getEntityType().getCode(); + } + + // NOTE: if there are 2 materials in a well, a random one will be chosen + private static Map<WellReference, Long/* material id */> createWellToMaterialMap( + Iterable<BasicWellContentQueryResult> wells) + { + Map<WellReference, Long> wellToMaterialMap = new HashMap<WellReference, Long>(); + for (BasicWellContentQueryResult well : wells) + { + WellReference wellReference = well.getWellReference(); + wellToMaterialMap.put(wellReference, well.material_content_id); + } + return wellToMaterialMap; + } + + private static List<BasicWellContentQueryResult> filterExperimentWells( + List<BasicWellContentQueryResult> wells, final String experimentPermId) + { + return CollectionUtils.filter(wells, new ICollectionFilter<BasicWellContentQueryResult>() + { + public boolean isPresent(BasicWellContentQueryResult well) + { + return belongsToExperiment(well, experimentPermId); + } + }); + } + + private static boolean belongsToExperiment(BasicWellContentQueryResult well, + String experimentPermId) + { + return well.exp_perm_id.equals(experimentPermId); + } + + private MaterialSimpleFeatureVectorSummary findExperimentFeatureVectorSummary( + TechId materialId, ExperimentReference experiment, List<CodeAndLabel> features, + List<MaterialIdFeatureVectorSummary> experimentSummaries) + { + // select the summary of the right material + MaterialIdFeatureVectorSummary materialSummary = + findMaterialSummary(materialId, experimentSummaries); + return new MaterialSimpleFeatureVectorSummary(experiment, features, + materialSummary.getFeatureVectorSummary(), materialSummary.getFeatureVectorRanks()); + } + + private List<MaterialIdFeatureVectorSummary> calculateExperimentFeatureVectorSummaries( + List<? extends IWellData> experimentWellData, boolean calculateDeviations) + { + return WellReplicaSummaryCalculator.calculateReplicasFeatureVectorSummaries( + experimentWellData, settings.getAggregationType(), calculateDeviations); + } + + private static MaterialIdFeatureVectorSummary findMaterialSummary(TechId materialId, + List<MaterialIdFeatureVectorSummary> summaries) + { + for (MaterialIdFeatureVectorSummary summary : summaries) + { + if (summary.getMaterial().equals(materialId.getId())) + { + return summary; + } + } + throw new IllegalStateException("It should not happen: no summary found for material " + + materialId); + } + + // connects each well with a material with its feature vector + private static List<WellData> createWellData( + Map<WellReference, Long/* material id */> experimentWellToMaterialMap, + List<FeatureVectorValues> allFeatures) + { + List<WellData> experimentWellDataList = new ArrayList<WellData>(); + for (FeatureVectorValues feature : allFeatures) + { + WellReference wellReference = feature.getWellReference(); + Long materialId = experimentWellToMaterialMap.get(wellReference); + if (materialId != null) + { + float[] values = WellFeatureCollectionLoader.asFeatureVectorValues(feature); + WellData wellData = new WellData(materialId, values, wellReference); + experimentWellDataList.add(wellData); + } + } + return experimentWellDataList; + } + + private static Set<PlateIdentifier> extractPlates(Iterable<? extends IWellReference> allWells) + { + Set<PlateIdentifier> plates = new HashSet<PlateIdentifier>(); + for (IWellReference well : allWells) + { + String platePermId = well.getPlatePermId(); + PlateIdentifier plateIdent = PlateIdentifier.createFromPermId(platePermId); + plates.add(plateIdent); + } + return plates; + } + + private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors( + Iterable<? extends IWellReference> allWells, + AnalysisProcedureCriteria analysisProcedureCriteria) + { + Set<PlateIdentifier> plates = extractPlates(allWells); + return tryLoadWellSingleFeatureVectors(plates, analysisProcedureCriteria); + } + + private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors( + Set<PlateIdentifier> plates, AnalysisProcedureCriteria analysisProcedureCriteria) + { + return new WellFeatureCollectionLoader(session, businessObjectFactory, daoFactory) + .tryLoadWellSingleFeatureVectors(plates, settings.getFeatureCodes(), + analysisProcedureCriteria); + } + + /** + * Calculates summaries of feature vectors for each material of the specified type in the given + * experiment. + */ + public MaterialIdSummaryAndFeatures tryCalculateExperimentFeatureVectorSummaries( + TechId experimentId, String[] replicaMaterialTypeSubstrings, + AnalysisProcedureCriteria analysisProcedureCriteria, boolean calculateDeviations) + { + String typePatterns = + PatternMatchingUtils.asPostgresSimilarExpression(settings + .getReplicaMaterialTypeSubstrings()); + List<BasicWellContentQueryResult> wells = fetchWellLocations(typePatterns, new long[] + { experimentId.getId() }); + return tryCalculateExperimentFeatureVectorSummaries(wells, analysisProcedureCriteria, + calculateDeviations); + } + + /** + * Calculates summaries of feature vectors for each material in the given experiment. A material + * of one well is chosen by filtering materials of the same type as the specified one. + */ + public MaterialIdSummaryAndFeatures tryCalculateExperimentFeatureVectorSummaries( + TechId experimentId, AnalysisProcedureCriteria analysisProcedureCriteria, + TechId materialId, boolean calculateDeviations) + { + List<BasicWellContentQueryResult> wells = fetchWellLocations(materialId, experimentId); + return tryCalculateExperimentFeatureVectorSummaries(wells, analysisProcedureCriteria, + calculateDeviations); + } + + private MaterialIdSummaryAndFeatures tryCalculateExperimentFeatureVectorSummaries( + List<BasicWellContentQueryResult> wells, + AnalysisProcedureCriteria analysisProcedureCriteria, boolean calculateDeviations) + { + WellFeatureCollection<FeatureVectorValues> allWellFeatures = + tryLoadWellSingleFeatureVectors(wells, analysisProcedureCriteria); + + if (allWellFeatures == null) + { + return null; + } + List<MaterialIdFeatureVectorSummary> featureSummaries = + calculateExperimentFeatureVectorSummaries(wells, allWellFeatures, + calculateDeviations); + return new MaterialIdSummaryAndFeatures(featureSummaries, + allWellFeatures.getFeatureCodesAndLabels()); + } + + static class MaterialIdSummaryAndFeatures + { + private final List<MaterialIdFeatureVectorSummary> featureSummaries; + + private final List<CodeAndLabel> featureNames; + + public MaterialIdSummaryAndFeatures(List<MaterialIdFeatureVectorSummary> featureSummaries, + List<CodeAndLabel> featureNames) + { + this.featureSummaries = featureSummaries; + this.featureNames = featureNames; + } + + public List<MaterialIdFeatureVectorSummary> getFeatureSummaries() + { + return featureSummaries; + } + + public List<CodeAndLabel> getFeatureNames() + { + return featureNames; + } + } + +} 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 0168e77b0ba..d04db25a867 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.WellExtendedData; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType; /** @@ -196,7 +196,7 @@ public class WellReplicaSummaryCalculator { Long replicaId = entry.getKey(); float[] aggregates = entry.getValue().getAggregates(); - IWellData summaryWellData = new WellExtendedData(replicaId, aggregates, null, null); + IWellData summaryWellData = new WellData(replicaId, aggregates, null); summaryWellDataList.add(summaryWellData); } return summaryWellDataList; diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/IWellExtendedData.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/IWellExtendedData.java deleted file mode 100644 index b7b821b2fa5..00000000000 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/IWellExtendedData.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityPropertiesHolder; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; - -/** - * Enriches interface to access well feature vector with well sample and material metadata. - * - * @author Tomasz Pylak - */ -public interface IWellExtendedData extends IEntityPropertiesHolder, IWellData -{ - /** Well sample for which the data are provided. */ - Sample getWell(); - - /** - * Material in the well which allowed to find replicates (e.g. gene or compound).<br> - * Note: if the replicaId is the same for two wellData then the returned material is also the - * same. - */ - Material getMaterial(); - -} 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 3dc98d7fbd3..aa0f33b76d6 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 @@ -18,6 +18,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto; import java.util.Arrays; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReference; + /** * The simplest implementation of {@Link IWellData}. * @@ -29,10 +31,14 @@ public class WellData implements IWellData private final float[] featureVector; - public WellData(long replicaId, float[] featureVector) + private final WellReference wellReferenceOrNull; + + /** @param wellReferenceOrNull null if these are aggregated data */ + public WellData(long replicaId, float[] featureVector, WellReference wellReferenceOrNull) { this.featureVector = featureVector; this.replicaId = replicaId; + this.wellReferenceOrNull = wellReferenceOrNull; } public long getReplicaMaterialId() @@ -45,6 +51,11 @@ public class WellData implements IWellData return featureVector; } + public WellReference tryGetWellReference() + { + return wellReferenceOrNull; + } + @Override public String toString() { 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 index 32e62f85443..825e925243c 100644 --- 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 @@ -18,36 +18,36 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto; import java.util.List; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityPropertiesHolder; 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}. + * Enriches {@link IWellData} interface with well sample. + * metadata. * * @author Tomasz Pylak */ -public class WellExtendedData extends WellData implements IWellExtendedData +public class WellExtendedData extends WellData implements IEntityPropertiesHolder { - private Sample well; + private final Sample well; - private final Material material; - - public WellExtendedData(long replicaId, float[] featureVector, Sample well, Material material) + public WellExtendedData(WellData wellData, Sample well) { - super(replicaId, featureVector); + super(wellData.getReplicaMaterialId(), wellData.getFeatureVector(), wellData + .tryGetWellReference()); this.well = well; - this.material = material; } + /** Properties of the well sample for which the data are provided. */ public Sample getWell() { return well; } - public Material getMaterial() + public Long getId() { - return material; + return well.getId(); } public List<IEntityProperty> getProperties() @@ -55,9 +55,4 @@ public class WellExtendedData extends WellData implements IWellExtendedData return well.getProperties(); } - public Long getId() - { - return well.getId(); - } - } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSummarySettings.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSummarySettings.java index 3c05eae5d5a..08aceb09feb 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSummarySettings.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSummarySettings.java @@ -30,8 +30,8 @@ public class MaterialSummarySettings implements ISerializable private static final long serialVersionUID = ServiceVersionHolder.VERSION; /** - * the name of a material property type that can be rendered as a link to a details view. TODO - * KE: this should be part of the display settings ?! + * The name of a material property type that can be rendered as a link to a details view when a + * material is shown. */ private String materialDetailsPropertyType; @@ -39,8 +39,8 @@ public class MaterialSummarySettings implements ISerializable private String[] replicaMatrialTypeSubstrings; - // well property codes which links to the material which determins which biological replicate it - // is, e.g. siRNA or compound + // well property codes which links to the material which determines which biological replicate + // it is, e.g. siRNA or compound private List<String> biologicalReplicatePropertyTypeCodes; private MaterialReplicaSummaryAggregationType aggregationType; @@ -55,7 +55,7 @@ public class MaterialSummarySettings implements ISerializable this.featureCodes = featureCodes; } - public String[] getReplicaMatrialTypeSubstrings() + public String[] getReplicaMaterialTypeSubstrings() { return replicaMatrialTypeSubstrings; } diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/ScreeningDAOTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/ScreeningDAOTest.java index 1b06ae8365d..4ea1b80c18b 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/ScreeningDAOTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/ScreeningDAOTest.java @@ -178,7 +178,7 @@ public class ScreeningDAOTest extends AbstractScreeningDAOTest { List<BasicWellContentQueryResult> locations = EntityListingTestUtils.asList(query.getPlateLocationsForExperiment(new long[] - { 1, 2 }, "%GENE%")); + { 1, 2 }, "GENE")); AssertJUnit.assertEquals(0, locations.size()); List<ExperimentReferenceQueryResult> experiments = query.getExperimentsWithMaterial(1); 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 709c5b62848..9bf4efbf043 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 @@ -35,12 +35,10 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; -import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellExtendedData; 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; @@ -61,7 +59,7 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit settings.setAggregationType(MaterialReplicaSummaryAggregationType.MEDIAN); settings.setBiologicalReplicatePropertyTypeCodes(SIRNA_PROPERTY_TYPE_CODE); int replId = 0; - List<IWellExtendedData> wellDataList = Arrays.asList( + List<WellExtendedData> wellDataList = Arrays.asList( // repl. 1 group 1 createSIRNAWellData(replId, 1, 10, 100), @@ -80,18 +78,13 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit createSIRNAWellData(replId + 2, 1, 0, 500)); List<CodeAndLabel> featuresDesc = Arrays.asList(new CodeAndLabel("A", "A"), new CodeAndLabel("B", "B")); - WellDataCollection wellDataCollection = new WellDataCollection(wellDataList, featuresDesc); MaterialAllReplicasFeatureVectors featureVectors = new MaterialFeatureVectorSummaryLoader(null, null, null, settings) - .tryLoadMaterialFeatureVectors(new TechId(replId), wellDataCollection); + .createMaterialFeatureVectors(new TechId(replId), wellDataList, null, + featuresDesc); - MaterialIdFeatureVectorSummary generalSummary = featureVectors.getGeneralSummary(); - assertArraysEqual(new float[] - { 65, 650 }, generalSummary.getFeatureVectorSummary()); - assertArraysEqual(new int[] - { 2, 3 }, generalSummary.getFeatureVectorRanks()); - assertEquals(replId, generalSummary.getMaterial().longValue()); + assertNull(featureVectors.getGeneralSummary()); assertEquals(featuresDesc, featureVectors.getFeatureDescriptions()); int groupId = 1; @@ -120,7 +113,7 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit } - private static IWellExtendedData createSIRNAWellData(long replicaId, long siRNAId, + private static WellExtendedData createSIRNAWellData(long replicaId, long siRNAId, float... featureValues) { MaterialEntityProperty subgroupProperty = new MaterialEntityProperty(); @@ -135,7 +128,7 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit return createWellData(replicaId, subgroupProperty, featureValues); } - private static IWellExtendedData createWellData(long replicaId, + private static WellExtendedData createWellData(long replicaId, IEntityProperty subgroupProperty, float... featureValues) { Material material = new Material(); @@ -147,6 +140,6 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit material.setProperties(properties); well.setProperties(properties); - return new WellExtendedData(replicaId, featureValues, well, material); + return new WellExtendedData(new WellData(replicaId, featureValues, null), well); } } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellDataCollection.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellDataCollection.java similarity index 79% rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellDataCollection.java rename to screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellDataCollection.java index 16bb94d2ad3..3053ff786e5 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellDataCollection.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellDataCollection.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto; +package ch.systemsx.cisd.openbis.plugin.screening.server.logic; import java.util.List; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; +import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData; /** * List of well data and description of each feature. @@ -27,19 +28,19 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel; */ public class WellDataCollection { - private final List<IWellExtendedData> wellDataList; + private final List<WellExtendedData> wellDataList; // has the same length as feature vectors in all wells private final List<CodeAndLabel> featureDescriptions; - public WellDataCollection(List<IWellExtendedData> wellDataList, + public WellDataCollection(List<WellExtendedData> wellDataList, List<CodeAndLabel> featureDescriptions) { this.wellDataList = wellDataList; this.featureDescriptions = featureDescriptions; } - public List<IWellExtendedData> getWellDataList() + public List<WellExtendedData> getWellDataList() { return wellDataList; } 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 e7e6a9ff2ac..8951f6191e0 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,6 +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 +207,7 @@ public class WellReplicaSummaryCalculatorTest extends AssertJUnit { Material material = new Material(); material.setId(replicaId); - return new WellExtendedData(replicaId, featureValues, null, material); + return new WellExtendedData(new WellData(replicaId, featureValues, null), null); } private List<MaterialIdFeatureVectorSummary> calculate(List<IWellData> wellDataList) -- GitLab