Skip to content
Snippets Groups Projects
Commit 382f798f authored by tpylak's avatar tpylak
Browse files

LMS-2189 gene in all assays - server side (slow, no ranks)

SVN: 21435
parent 403c5a7c
No related branches found
No related tags found
No related merge requests found
Showing
with 546 additions and 268 deletions
......@@ -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;
}
}
......@@ -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;
}
}
/*
* 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());
}
}
......@@ -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);
}
......
/*
* 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;
}
}
......@@ -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;
......
......@@ -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();
}
}
/*
* 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();
}
}
......@@ -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;
}
}
......@@ -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;
}
......
......@@ -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
......@@ -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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment