diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/genedata/DataSetInfoExtractorForDataAcquisition.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/genedata/DataSetInfoExtractorForDataAcquisition.java new file mode 100644 index 0000000000000000000000000000000000000000..f0710f24226b224d9eb8bddfaeb3dd260a793b98 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/genedata/DataSetInfoExtractorForDataAcquisition.java @@ -0,0 +1,55 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.dss.genedata; + +import java.io.File; +import java.util.Properties; + +import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; +import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.etlserver.DefaultDataSetInfoExtractor; +import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; +import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; + +/** + * {@link DefaultDataSetInfoExtractor} which sets the dataset code to 'spaceCode-plateCode'. Useful + * for screening image datasets. + * + * @author Tomasz Pylak + */ +public class DataSetInfoExtractorForDataAcquisition extends DefaultDataSetInfoExtractor +{ + + public DataSetInfoExtractorForDataAcquisition(Properties globalProperties) + { + super(globalProperties); + } + + @Override + public DataSetInformation getDataSetInformation(final File incomingDataSetPath, + IEncapsulatedOpenBISService openbisService) throws EnvironmentFailureException, + UserFailureException + { + DataSetInformation dataSetInformation = + super.getDataSetInformation(incomingDataSetPath, openbisService); + String dataSetCode = + dataSetInformation.getSpaceCode() + "-" + dataSetInformation.getSampleCode(); + dataSetCode = dataSetCode.toUpperCase(); + dataSetInformation.setDataSetCode(dataSetCode); + return dataSetInformation; + } +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/genedata/DataSetInfoExtractorForImageAnalysis.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/genedata/DataSetInfoExtractorForImageAnalysis.java new file mode 100644 index 0000000000000000000000000000000000000000..c2954c65c3b1f0a0b4a4f0522eaeafb5bafdea24 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/genedata/DataSetInfoExtractorForImageAnalysis.java @@ -0,0 +1,76 @@ +/* + * Copyright 2010 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.dss.genedata; + +import java.io.File; +import java.util.Arrays; +import java.util.Properties; + +import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; +import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.etlserver.DefaultDataSetInfoExtractor; +import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; +import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; + +/** + * {@link DefaultDataSetInfoExtractor} which sets the parent dataset code to 'spaceCode-plateCode'. + * Useful for screening image analysis datasets. + * + * @author Tomasz Pylak + */ +public class DataSetInfoExtractorForImageAnalysis extends DefaultDataSetInfoExtractor +{ + + public DataSetInfoExtractorForImageAnalysis(Properties globalProperties) + { + super(globalProperties); + } + + @Override + public DataSetInformation getDataSetInformation(final File incomingDataSetPath, + IEncapsulatedOpenBISService openbisService) throws EnvironmentFailureException, + UserFailureException + { + DataSetInformation dataSetInformation = + super.getDataSetInformation(incomingDataSetPath, openbisService); + String parentDataSetCode = + dataSetInformation.getSpaceCode() + "-" + dataSetInformation.getSampleCode(); + parentDataSetCode = parentDataSetCode.toUpperCase(); + dataSetInformation.setParentDataSetCodes(Arrays.asList(parentDataSetCode)); + + // by default the dataset is conected to the sample. We want to reconnect it directly to the + // experiment, since datasets which have parents cannot be connected directly to samples. + Sample sample = + openbisService.tryGetSampleWithExperiment(dataSetInformation.getSampleIdentifier()); + if (sample == null) + { + throw UserFailureException.fromTemplate( + "Cannot register dataset %s because the sample %s does not exist.", + dataSetInformation.getDataSetCode(), dataSetInformation.getSampleIdentifier()); + } + Experiment experiment = sample.getExperiment(); + dataSetInformation.setExperiment(experiment); + dataSetInformation.setExperimentIdentifier(new ExperimentIdentifier(experiment)); + dataSetInformation.setSample(null); + dataSetInformation.setSampleCode(null); + + return dataSetInformation; + } +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java index 701a7415bc772563eefa8bc5943fb102285b5182..b9b656889e90a5bd5fab4692f7eafcef14c4fee6 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java @@ -233,7 +233,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements private InputStream getImageStream(ExternalData imageDataset, PlateImageReference imageRef) { - HCSDatasetLoader imageAccessor = createImageLoader(imageRef.getDatasetCode()); + HCSDatasetLoader imageAccessor = createImageLoader(imageDataset.getCode()); Location wellLocation = asLocation(imageRef.getWellPosition()); Location tileLocation = getTileLocation(imageRef.getTile(), imageAccessor.getWellGeometry()); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTest.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTest.java index 86d16dbaae4b98e62ff74d1c62efdf826d35be8e..6ff5e5464d7c39542ade8d5dfcf11a421237f574 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTest.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningClientApiTest.java @@ -70,9 +70,13 @@ public class ScreeningClientApiTest System.out.println("Feature vector datasets: " + featureVectorDatasets); // test for feature vector dataset - // String featureVectorDatasetCode = "20100423170945059-29"; // feature vector - String imageDatasetCode = "20100423163638457-16"; // image - IDatasetIdentifier datasetIdentifier = getDatasetIdentifier(facade, imageDatasetCode); + String featureVectorDatasetCode = "20100424125121572-43"; // feature vector + IDatasetIdentifier datasetIdentifier = + getDatasetIdentifier(facade, featureVectorDatasetCode); + loadImages(facade, datasetIdentifier); + + String imageDatasetCode = "DEMO-PLATE002"; // image + datasetIdentifier = getDatasetIdentifier(facade, imageDatasetCode); loadImages(facade, datasetIdentifier); List<String> featureNames = facade.listAvailableFeatureNames(featureVectorDatasets); @@ -83,7 +87,7 @@ public class ScreeningClientApiTest List<ImageDatasetMetadata> imageMetadata = facade.listImageMetadata(imageDatasets); System.out.println("Image metadata: " + imageMetadata); - + facade.logout(); } @@ -108,18 +112,20 @@ public class ScreeningClientApiTest imageRefs.add(new PlateImageReference(well, well, tile, channel, datasetIdentifier)); List<PlateSingleImage> images = facade.loadImages(imageRefs); - saveImages(images); + saveImages(images, datasetIdentifier.getDatasetCode()); } } } } - private static void saveImages(List<PlateSingleImage> images) throws FileNotFoundException, - IOException + private static void saveImages(List<PlateSingleImage> images, String dirName) + throws FileNotFoundException, IOException { + File dir = new File(dirName); + dir.mkdir(); for (PlateSingleImage image : images) { - FileOutputStream out = new FileOutputStream(new File(createImageFileName(image))); + FileOutputStream out = new FileOutputStream(new File(dir, createImageFileName(image))); InputStream in = image.getImage(); StreamUtils.copyThenClose(in, out); out.close(); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java index c8b629f2ab067c83308fd7b4a88a8cf56c6f9464..ce74eb4d07a236e9a047af25977682e3a7288277 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java @@ -17,7 +17,9 @@ package ch.systemsx.cisd.openbis.plugin.screening.server.logic; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import ch.systemsx.cisd.openbis.generic.server.business.bo.IExternalDataBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO; @@ -31,7 +33,9 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE; import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE; @@ -75,9 +79,62 @@ public class ScreeningApiImpl public List<FeatureVectorDatasetReference> listFeatureVectorDatasets( List<? extends PlateIdentifier> plates) { - List<ExternalDataPE> datasets = - loadDatasets(plates, ScreeningConstants.IMAGE_ANALYSIS_DATASET_TYPE); - return asFeatureVectorDatasets(datasets); + List<FeatureVectorDatasetReference> result = new ArrayList<FeatureVectorDatasetReference>(); + List<ImageDatasetReference> imageDatasets = listImageDatasets(plates); + ISampleBO sampleBO = businessObjectFactory.createSampleBO(session); + for (PlateIdentifier plate : plates) + { + ExperimentPE experiment = tryGetExperiment(sampleBO, plate); + if (experiment != null) + { + List<ExternalDataPE> datasets = + daoFactory.getExternalDataDAO().listExternalData(experiment); + List<ExternalDataPE> childrenDatasets = filterChildren(imageDatasets, datasets); + List<ExternalDataPE> featureVectorDatasets = + ScreeningUtils.filterDatasetsByType(childrenDatasets, + ScreeningConstants.IMAGE_ANALYSIS_DATASET_TYPE); + result.addAll(asFeatureVectorDatasets(featureVectorDatasets)); + } + } + return result; + } + + // return those datasets which have exactly one parent, which is contained in the parent set + private static List<ExternalDataPE> filterChildren( + List<? extends IDatasetIdentifier> parentDatasets, List<ExternalDataPE> datasets) + { + Set<String> parentDatasetCodes = createDatasetCodesSet(parentDatasets); + List<ExternalDataPE> children = new ArrayList<ExternalDataPE>(); + for (ExternalDataPE dataset : datasets) + { + Set<DataPE> parents = dataset.getParents(); + if (parents.size() == 1) + { + DataPE parent = parents.iterator().next(); + if (parentDatasetCodes.contains(parent.getCode())) + { + children.add(dataset); + } + } + } + return children; + } + + private static Set<String> createDatasetCodesSet(List<? extends IDatasetIdentifier> datasets) + { + Set<String> result = new HashSet<String>(); + for (IDatasetIdentifier dataset : datasets) + { + result.add(dataset.getDatasetCode()); + } + return result; + } + + private ExperimentPE tryGetExperiment(ISampleBO sampleBO, PlateIdentifier plate) + { + sampleBO.loadBySampleIdentifier(createSampleIdentifier(plate)); + SamplePE sample = sampleBO.getSample(); + return sample.getExperiment(); } public List<ImageDatasetReference> listImageDatasets(List<? extends PlateIdentifier> plates) @@ -124,8 +181,10 @@ public class ScreeningApiImpl private static FeatureVectorDatasetReference asFeatureVectorDataset(ExternalDataPE externalData) { DataStorePE dataStore = externalData.getDataStore(); + DataPE parentDataset = externalData.getParents().iterator().next(); return new FeatureVectorDatasetReference(externalData.getCode(), - dataStore.getDownloadUrl(), createPlateIdentifier(externalData)); + dataStore.getDownloadUrl(), createPlateIdentifier(parentDataset), + asImageDataset(parentDataset)); } private static List<ImageDatasetReference> asImageDatasets(List<ExternalDataPE> datasets) @@ -138,17 +197,17 @@ public class ScreeningApiImpl return result; } - private static ImageDatasetReference asImageDataset(ExternalDataPE externalData) + private static ImageDatasetReference asImageDataset(DataPE parentDataset) { - DataStorePE dataStore = externalData.getDataStore(); - return new ImageDatasetReference(externalData.getCode(), dataStore.getDownloadUrl(), - createPlateIdentifier(externalData)); + DataStorePE dataStore = parentDataset.getDataStore(); + return new ImageDatasetReference(parentDataset.getCode(), dataStore.getDownloadUrl(), + createPlateIdentifier(parentDataset)); } - private static PlateIdentifier createPlateIdentifier(ExternalDataPE externalData) + private static PlateIdentifier createPlateIdentifier(DataPE parentDataset) { - SamplePE sample = externalData.tryGetSample(); - assert sample != null : "dataset not connected to a sample: " + externalData; + SamplePE sample = parentDataset.tryGetSample(); + assert sample != null : "dataset not connected to a sample: " + parentDataset; final String plateCode = sample.getCode(); GroupPE group = sample.getGroup(); final String spaceCodeOrNull = (group != null) ? group.getCode() : null; diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorDatasetReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorDatasetReference.java index 3dcdc208943c4a5719af4868156907c0865213d9..8e1ddebab632d9a46329fd23fa6271cbdd524d31 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorDatasetReference.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/api/v1/dto/FeatureVectorDatasetReference.java @@ -26,9 +26,24 @@ public class FeatureVectorDatasetReference extends DatasetReference implements { private static final long serialVersionUID = 1L; + private final IImageDatasetIdentifier imageDatasetIdentifier; + public FeatureVectorDatasetReference(String datasetCode, String datastoreServerUrl, - PlateIdentifier plate) + PlateIdentifier plate, IImageDatasetIdentifier imageDatasetIdentifier) { super(datasetCode, datastoreServerUrl, plate); + this.imageDatasetIdentifier = imageDatasetIdentifier; + } + + /** parent image dataset which has been analyzed to obtain the feature vectors */ + public IImageDatasetIdentifier getParentImageDataset() + { + return imageDatasetIdentifier; + } + + @Override + public String toString() + { + return super.toString() + " from image dataset " + imageDatasetIdentifier.getDatasetCode(); } }