diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java index 26b7a9062be5e42c2332bb24261c159e6f758e67..2a022062940184da6d426067465f85e021de0329 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java @@ -316,7 +316,8 @@ public class ImageUtil { assert (imageLibraryReaderNameOrNull == null || imageLibraryNameOrNull != null) : "if image reader " + "is specified then library name should be specified as well"; - ImageID imageID = parseImageID(imageIdOrNull); + ImageID imageID = parseImageID(imageIdOrNull, contentNode); + if (imageLibraryNameOrNull != null && imageLibraryReaderNameOrNull != null) { IImageReader reader = @@ -353,7 +354,8 @@ public class ImageUtil { assert (imageLibraryReaderNameOrNull == null || imageLibraryNameOrNull != null) : "if image reader " + "is specified then library name should be specified as well"; - ImageID imageID = parseImageID(imageIdOrNull); + ImageID imageID = parseImageID(imageIdOrNull, contentNode); + if (imageLibraryNameOrNull != null && imageLibraryReaderNameOrNull != null) { IImageReader reader = @@ -538,9 +540,16 @@ public class ImageUtil * Parses specified string representation of an {@link ImageID}. If the argument is * <code>null</code> {@link ImageID#NULL} will be returned. */ - public static ImageID parseImageID(String imageIdOrNull) + public static ImageID parseImageID(String imageIdOrNull, IHierarchicalContentNode contentNode) { - return imageIdOrNull == null ? ImageID.NULL : ImageID.parse(imageIdOrNull); + ImageID id = imageIdOrNull == null ? ImageID.NULL : ImageID.parse(imageIdOrNull); + try + { + id.setFileName(contentNode.getFile().getCanonicalPath()); + } catch (Exception ex) { + ex.printStackTrace(); + } + return id; } private static BufferedImage loadImageGuessingLibrary(IHierarchicalContentNode contentNode, diff --git a/image_readers/source/java/ch/systemsx/cisd/imagereaders/ImageID.java b/image_readers/source/java/ch/systemsx/cisd/imagereaders/ImageID.java index 5f80e0e4f11ce58910ab1706374a09123b00ecc3..07dc099c9da22805149cd47f0911b6c73ef562c9 100644 --- a/image_readers/source/java/ch/systemsx/cisd/imagereaders/ImageID.java +++ b/image_readers/source/java/ch/systemsx/cisd/imagereaders/ImageID.java @@ -49,6 +49,15 @@ public class ImageID private final int focalPlaneIndex; private final int colorChannelIndex; private final String id; + private String filename; + + public void setFileName(String f) { + this.filename = f; + } + + public String getFileName() { + return this.filename; + } /** * Creates an instance for the specified series index, time series (or T) index, focal plane (or diff --git a/image_readers/source/java/ch/systemsx/cisd/imagereaders/bioformats/BioFormatsImageUtils.java b/image_readers/source/java/ch/systemsx/cisd/imagereaders/bioformats/BioFormatsImageUtils.java index c20323f7123e2d4bc31e78f7273ad676defcec7c..b440211a8eb67bf045b31d35599cdb09cdca7d7c 100644 --- a/image_readers/source/java/ch/systemsx/cisd/imagereaders/bioformats/BioFormatsImageUtils.java +++ b/image_readers/source/java/ch/systemsx/cisd/imagereaders/bioformats/BioFormatsImageUtils.java @@ -153,7 +153,7 @@ final class BioFormatsImageUtils static List<ImageID> listImageIDs(IFormatReader reader, IRandomAccess handle) { - String handleId = generateHandleId(reader); + String handleId = generateHandleId(reader, null); // Add to static map. Location.mapFile(handleId, handle); try @@ -200,7 +200,8 @@ final class BioFormatsImageUtils static BufferedImage readImage(IFormatReader reader, IRandomAccess handle, ImageID imageID) throws IOExceptionUnchecked, IllegalArgumentException { - String handleId = generateHandleId(reader); + String handleId = generateHandleId(reader, imageID); + // Add to static map. Location.mapFile(handleId, handle); try @@ -243,7 +244,7 @@ final class BioFormatsImageUtils ImageID imageID) { // Add to static map. - String handleId = generateHandleId(reader); + String handleId = generateHandleId(reader, imageID); Location.mapFile(handleId, handle); try @@ -284,7 +285,8 @@ final class BioFormatsImageUtils IllegalArgumentException { // Add to static map. - String handleId = generateHandleId(reader); + String handleId = generateHandleId(reader, imageID); + Location.mapFile(handleId, handle); try { @@ -320,7 +322,7 @@ final class BioFormatsImageUtils throws IOExceptionUnchecked, IllegalArgumentException { // Add to static map. - String handleId = generateHandleId(reader); + String handleId = generateHandleId(reader, imageID); Location.mapFile(handleId, handle); try { @@ -344,9 +346,14 @@ final class BioFormatsImageUtils } } - public static String generateHandleId(IFormatHandler formatHandler) + public static String generateHandleId(IFormatHandler formatHandler, ImageID imageId) { - return UUID.randomUUID().toString() + "." + formatHandler.getSuffixes()[0]; + String id = UUID.randomUUID().toString() + "." + formatHandler.getSuffixes()[0]; + if (imageId != null && imageId.getFileName() != null && (imageId.getFileName().endsWith(".c01") || imageId.getFileName().endsWith("C01"))) { + id = imageId.getFileName(); + } + return id; + } private static void nullSafeAddAll(HashMap<String, Object> accumulator, diff --git a/screening/source/core-plugins/cellomics/1/dss/drop-boxes/cellomics-dropbox/cellomics-dropbox.py b/screening/source/core-plugins/cellomics/1/dss/drop-boxes/cellomics-dropbox/cellomics-dropbox.py new file mode 100644 index 0000000000000000000000000000000000000000..5b49af47e342064aae4b9790a718b86fbac9905d --- /dev/null +++ b/screening/source/core-plugins/cellomics/1/dss/drop-boxes/cellomics-dropbox/cellomics-dropbox.py @@ -0,0 +1,91 @@ +import os +from ch.systemsx.cisd.openbis.dss.etl.dto.api.v1 import SimpleImageDataConfig +from ch.systemsx.cisd.openbis.dss.etl.dto.api.v1 import ImageMetadata +from ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto import Geometry + +SPACE_CODE = "TEST" +PROJECT_CODE = "TEST-PROJECT" +PROJECT_ID = "/%(SPACE_CODE)s/%(PROJECT_CODE)s" % vars() +EXPERIMENT_CODE = "DEMO-EXP-HCS" +EXPERIMENT_ID = "/%(SPACE_CODE)s/%(PROJECT_CODE)s/%(EXPERIMENT_CODE)s" % vars() + +PLATE_CODE = "PLATE1" +PLATE_ID = "/%(SPACE_CODE)s/%(PLATE_CODE)s" % vars() +PLATE_GEOMETRY_PROPERTY_CODE = "$PLATE_GEOMETRY" +PLATE_GEOMETRY = "384_WELLS_16X24" + + +def create_space_if_needed(transaction): + space = transaction.getSpace(SPACE_CODE) + if None == space: + space = transaction.createNewSpace(SPACE_CODE, None) + space.setDescription("A demo space") + +def create_project_if_needed(transaction): + project = transaction.getProject(PROJECT_ID) + if None == project: + create_space_if_needed(transaction) + project = transaction.createNewProject(PROJECT_ID) + project.setDescription("A demo project") + +def create_experiment_if_needed(transaction): + """ Get the specified experiment or register it if necessary """ + exp = transaction.getExperiment(EXPERIMENT_ID) + if None == exp: + create_project_if_needed(transaction) + print 'Creating new experiment : ' + EXPERIMENT_ID + exp = transaction.createNewExperiment(EXPERIMENT_ID, 'SIRNA_HCS') + exp.setPropertyValue("DESCRIPTION", "A sample experiment") + + return exp + +def create_plate_if_needed(transaction): + """ Get the specified sample or register it if necessary """ + + samp = transaction.getSample(PLATE_ID) + + if None == samp: + exp = create_experiment_if_needed(transaction) + samp = transaction.createNewSample(PLATE_ID, 'PLATE') + samp.setPropertyValue(PLATE_GEOMETRY_PROPERTY_CODE, PLATE_GEOMETRY) + samp.setExperiment(exp) + + return samp + + +class MyImageDataSetConfig(SimpleImageDataConfig): + def extractImageMetadata(self, imagePath): + + basename = os.path.splitext(imagePath)[0] + value = basename.split("_")[2] + plate = basename.split("_")[1] + well = value[0:3] + tile = value[4:6] + tile = int(tile) + 1 + channelCode = value[6:8] + + image_tokens = ImageMetadata() + image_tokens.well = well + try: + image_tokens.tileNumber = int(tile) + except ValueError: + raise Exception("Cannot parse field number from '" + tile + "' in '" + basename + "' file name.") + + image_tokens.channelCode = channelCode + return image_tokens + + def getTileGeometry(self, imageTokens, maxTileNumber): + return Geometry.createFromRowColDimensions(maxTileNumber / 3, 3) + +if incoming.isDirectory(): + imageDataset = MyImageDataSetConfig() + imageDataset.setRawImageDatasetType() + #imageDataset.setGenerateThumbnails(True) + imageDataset.setPlate(SPACE_CODE, PLATE_CODE) + imageDataset.setImageLibrary('BioFormats', 'CellomicsReader##SINGLE_IMAGE') + registrationDetails = factory.createImageRegistrationDetails(imageDataset, incoming) + transaction = service.transaction(incoming, factory) + plate = create_plate_if_needed(transaction) + dataset = transaction.createNewDataSet(registrationDetails); + dataset.setSample(plate) + transaction.moveFile(incoming.getPath(), dataset); diff --git a/screening/source/core-plugins/cellomics/1/dss/drop-boxes/cellomics-dropbox/plugin.properties b/screening/source/core-plugins/cellomics/1/dss/drop-boxes/cellomics-dropbox/plugin.properties new file mode 100644 index 0000000000000000000000000000000000000000..a5305fc2e44669a2f84983a23fa7d4260149dcd2 --- /dev/null +++ b/screening/source/core-plugins/cellomics/1/dss/drop-boxes/cellomics-dropbox/plugin.properties @@ -0,0 +1,13 @@ +# +# Drop box for cellomics data sets +# +# Variables: +# incoming-root-dir +# Path to the directory which contains incoming directories for drop boxes. +incoming-dir = ${incoming-root-dir}/incoming-cellomics +incoming-data-completeness-condition = auto-detection +top-level-data-set-handler = ch.systemsx.cisd.openbis.dss.etl.jython.JythonPlateDataSetHandler +script-path = cellomics-dropbox.py +storage-processor = ch.systemsx.cisd.openbis.dss.etl.PlateStorageProcessor +storage-processor.data-source = imaging-db +storage-processor.define-channels-per-experiment = false \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleImageDataConfig.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleImageDataConfig.java index 28d8e5bc85add1991ee7059e70f63b44a5cf2dd3..0a2f2d102752a6a1dd07b883684e4dae78863bdd 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleImageDataConfig.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleImageDataConfig.java @@ -203,7 +203,7 @@ abstract public class SimpleImageDataConfig private boolean isMeasured = false; private String[] recognizedImageExtensions = new String[] - { "tiff", "tif", "png", "gif", "jpg", "jpeg" }; + { "tiff", "tif", "png", "gif", "jpg", "jpeg", "c01" }; private List<IThumbnailsConfiguration> imagePyramid = new ArrayList<IThumbnailsConfiguration>(); @@ -348,7 +348,7 @@ abstract public class SimpleImageDataConfig /** * Only files with these extensions will be recognized as images (e.g. ["jpg", "png"]).<br> - * By default it is set to [ "tiff", "tif", "png", "gif", "jpg", "jpeg" ]. + * By default it is set to [ "tiff", "tif", "png", "gif", "jpg", "jpeg", "c01" ]. */ public void setRecognizedImageExtensions(String[] recognizedImageExtensions) { diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/SimpleImageDataSetRegistrator.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/SimpleImageDataSetRegistrator.java index 0b3b43ea9dadaa92d2d937c946473b5ca984bd9b..6fa62bb2c3d84741a1b77a427ec24b5e4f606f67 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/SimpleImageDataSetRegistrator.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/SimpleImageDataSetRegistrator.java @@ -263,7 +263,10 @@ public class SimpleImageDataSetRegistrator if (readerOrNull != null) { // NOTE: ugly side effect which is used later on - imageLibraryInfoOrNull.setReaderName(readerOrNull.getName()); + // if (null == imageLibraryInfoOrNull.getReaderName()) + // { + imageLibraryInfoOrNull.setReaderName(readerOrNull.getName()); + // } } else { throw ConfigurationFailureException.fromTemplate(