diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageFileExtractor.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageFileExtractor.java index 517facb2e2ecf3de2fd15c0c1e2f376551dcda02..145289ca196fa61995db760f18f4df33e428d1df 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageFileExtractor.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageFileExtractor.java @@ -44,7 +44,6 @@ import ch.systemsx.cisd.openbis.dss.etl.dto.RelativeImageFile; import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.ThumbnailsInfo; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.Channel; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageFileInfo; -import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageIdentifier; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelDescription; @@ -472,8 +471,7 @@ abstract public class AbstractImageFileExtractor implements IImageFileExtractor { RelativeImageReference relativeImageRef = new RelativeImageReference(imageInfo.getImageRelativePath(), - getUniqueStringIdentifier(imageInfo.tryGetImageIdentifier()), - colorComponentOrNull); + imageInfo.tryGetUniqueStringIdentifier(), colorComponentOrNull); RelativeImageReference relativeThumbnailRef = null; if (thumbnailFilePathsOrNull != null) @@ -499,15 +497,6 @@ abstract public class AbstractImageFileExtractor implements IImageFileExtractor relativeThumbnailRef); } - private static String getUniqueStringIdentifier(ImageIdentifier identifier) - { - if (identifier == null) - { - return null; - } - return identifier.getUniqueStringIdentifier(); - } - protected static Integer tryAsInt(String valueOrNull) { if (valueOrNull == null) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Hdf5ThumbnailGenerator.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Hdf5ThumbnailGenerator.java index 5b2ba043d3f7d3dcea05499873a153267f1643a6..53344e76af13efa29c340e4e7b4bf36249d2d740 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Hdf5ThumbnailGenerator.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/Hdf5ThumbnailGenerator.java @@ -44,6 +44,7 @@ import ch.systemsx.cisd.common.hdf5.HDF5Container.IHDF5WriterClient; import ch.systemsx.cisd.common.hdf5.IHDF5ContainerWriter; import ch.systemsx.cisd.common.io.ByteArrayBasedContentNode; import ch.systemsx.cisd.common.io.FileBasedContentNode; +import ch.systemsx.cisd.common.io.hierarchical_content.api.IHierarchicalContent; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.common.process.ProcessExecutionHelper; @@ -56,7 +57,6 @@ import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.ThumbnailsInfo; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.Channel; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ChannelColorComponent; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageFileInfo; -import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageIdentifier; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageStorageConfiguraton; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ThumbnailsStorageFormat; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.transformations.ImageTransformation; @@ -99,13 +99,14 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient * imagesParentDirectory * @param thumbnailFilePath absolute path to the file where thumbnails will be saved * @param imageStorageConfiguraton describes how the thumbnails should be generated + * @param content */ public static void tryGenerateThumbnails(ImageDataSetStructure imageDataSetStructure, File imagesParentDirectory, String thumbnailFilePath, ImageStorageConfiguraton imageStorageConfiguraton, String thumbnailPhysicalDatasetPermId, ThumbnailsStorageFormat thumbnailsStorageFormatOrNull, ThumbnailsInfo thumbnailPaths, - boolean registerOriginalImageAsThumbnail) + boolean registerOriginalImageAsThumbnail, IHierarchicalContent content) { if (thumbnailsStorageFormatOrNull != null) { @@ -121,7 +122,7 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient new Hdf5ThumbnailGenerator(imageDataSetStructure, imagesParentDirectory, thumbnailPhysicalDatasetPermId, thumbnailsStorageFormatOrNull, imageLibrary, thumbnailPaths, registerOriginalImageAsThumbnail, - operationLog); + content, operationLog); container.runWriterClient(thumbnailsStorageFormatOrNull.isStoreCompressed(), thumbnailsGenerator); } @@ -158,11 +159,13 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient private final boolean registerOriginalImageAsThumbnail; + private IHierarchicalContent contentOrNull; + private Hdf5ThumbnailGenerator(ImageDataSetStructure imageDataSetStructure, File imagesParentDirectory, String thumbnailPhysicalDatasetPermId, ThumbnailsStorageFormat thumbnailsStorageFormat, ImageLibraryInfo imageLibraryOrNull, ThumbnailsInfo thumbnailPathCollector, boolean registerOriginalImageAsThumbnail, - Logger operationLog) + IHierarchicalContent contentOrNull, Logger operationLog) { this.imageDataSetStructure = imageDataSetStructure; this.imagesParentDirectory = imagesParentDirectory; @@ -171,6 +174,7 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient this.imageLibraryOrNull = imageLibraryOrNull; this.thumbnailPathCollector = thumbnailPathCollector; this.registerOriginalImageAsThumbnail = registerOriginalImageAsThumbnail; + this.contentOrNull = contentOrNull; this.logger = operationLog; for (Channel ch : imageDataSetStructure.getChannels()) @@ -216,7 +220,7 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient try { long start = System.currentTimeMillis(); - String imageIdOrNull = tryExtractImageID(image); + String imageIdOrNull = image.tryGetUniqueStringIdentifier(); List<ThumbnailData> thumbnailData = generateThumbnail(bufferOutputStream, image, imageIdOrNull); @@ -282,7 +286,7 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient } newImagePath.append("_c").append(channelCode); - String imageIdOrNull = tryExtractImageID(plateImage); + String imageIdOrNull = plateImage.tryGetUniqueStringIdentifier(); if (imageIdOrNull != null) { newImagePath.append(imageIdOrNull); @@ -295,12 +299,6 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient return sb.length() > 0 ? "_" : ""; } - private static String tryExtractImageID(ImageFileInfo image) - { - ImageIdentifier imageIdentifier = image.tryGetImageIdentifier(); - return imageIdentifier == null ? null : imageIdentifier.getUniqueStringIdentifier(); - } - private List<ThumbnailData> generateThumbnail(ByteArrayOutputStream bufferOutputStream, ImageFileInfo img, String imageIdOrNull) throws IOException { @@ -323,7 +321,7 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient { final File imageFile = new File(imagesParentDirectory, imageFileInfo.getImageRelativePath()); - Size originalSize = loadUnchangedImageDimension(imageFile, null); + Size originalSize = loadUnchangedImageDimension(imageFileInfo.getImageRelativePath(), null); return Collections.singletonList(new ThumbnailData( FileUtilities.loadToByteArray(imageFile), originalSize.getWidth(), originalSize @@ -333,21 +331,29 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient private List<ThumbnailData> generateThumbnailWithImageMagic(ImageFileInfo imageFileInfo) throws IOException { - final File imageFile = - new File(imagesParentDirectory, imageFileInfo.getImageRelativePath()); int width = thumbnailsStorageFormat.getMaxWidth(); int height = thumbnailsStorageFormat.getMaxHeight(); if (thumbnailsStorageFormat.getZoomLevel() != null) { - Size originalSize = loadUnchangedImageDimension(imageFile, null); + Size originalSize = + loadUnchangedImageDimension(imageFileInfo.getImageRelativePath(), null); double zoomLevel = thumbnailsStorageFormat.getZoomLevel(); width = (int) Math.round(zoomLevel * originalSize.getWidth()); height = (int) Math.round(zoomLevel * originalSize.getHeight()); } String size = width + "x" + height; - String imageFilePath = imageFile.getPath(); + String imageFilePath = null; + if (contentOrNull == null) + { + imageFilePath = new File(imageFilePath, imageFileInfo.getImageRelativePath()).getPath(); + } else + { + imageFilePath = + contentOrNull.getNode(imageFileInfo.getImageRelativePath()).getFile().getPath(); + } + List<String> params = new ArrayList<String>(); params.addAll(Arrays.asList(convertUtilityOrNull.getPath(), imageFilePath, "-scale", size)); List<String> additionalParams = thumbnailsStorageFormat.getImageMagicParams(); @@ -413,9 +419,7 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient String imageIdOrNull, ByteArrayOutputStream bufferOutputStream) throws IOException { BufferedImage image = - loadUnchangedImage( - new File(imagesParentDirectory, imageFileInfo.getImageRelativePath()), - imageIdOrNull); + loadUnchangedImage(imageFileInfo.getImageRelativePath(), imageIdOrNull); int widht = thumbnailsStorageFormat.getMaxWidth(); int height = thumbnailsStorageFormat.getMaxHeight(); @@ -512,16 +516,30 @@ public class Hdf5ThumbnailGenerator implements IHDF5WriterClient return null; } - private BufferedImage loadUnchangedImage(File imageFile, String imageIdOrNull) + private BufferedImage loadUnchangedImage(String imageRelativePath, String imageIdOrNull) { - return Utils.loadUnchangedImage(new FileBasedContentNode(imageFile), imageIdOrNull, - imageLibraryOrNull); + if (contentOrNull == null) + { + return Utils.loadUnchangedImage(new FileBasedContentNode(new File( + imagesParentDirectory, imageRelativePath)), imageIdOrNull, imageLibraryOrNull); + } else + { + return Utils.loadUnchangedImage(contentOrNull.getNode(imageRelativePath), + imageIdOrNull, imageLibraryOrNull); + } } - private Size loadUnchangedImageDimension(File imageFile, String imageIdOrNull) + private Size loadUnchangedImageDimension(String imageRelativePath, String imageIdOrNull) { - return Utils.loadUnchangedImageSize(new FileBasedContentNode(imageFile), imageIdOrNull, - imageLibraryOrNull); + if (contentOrNull == null) + { + return Utils.loadUnchangedImageSize(new FileBasedContentNode(new File( + imagesParentDirectory, imageRelativePath)), imageIdOrNull, imageLibraryOrNull); + } else + { + return Utils.loadUnchangedImageSize(contentOrNull.getNode(imageRelativePath), + imageIdOrNull, imageLibraryOrNull); + } } private Status createStatus(String thumbnailPath, IOException ex) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/RelativeImageFile.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/RelativeImageFile.java index 051161ecac4297d0a966725576fd693a24ab78fc..652abe2ac7796bc92a6a9ae0fbfefb45f1dc2d64 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/RelativeImageFile.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/RelativeImageFile.java @@ -20,7 +20,6 @@ import java.io.Serializable; import ch.systemsx.cisd.common.utilities.AbstractHashable; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageFileInfo; -import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageIdentifier; /** * Points to one image on the file system. @@ -37,10 +36,8 @@ public class RelativeImageFile extends AbstractHashable implements Serializable public static RelativeImageFile create(ImageFileInfo imageFileInfo) { - ImageIdentifier imageIdentifier = imageFileInfo.tryGetImageIdentifier(); - String imageIDOrNull = - (imageIdentifier == null) ? null : imageIdentifier.getUniqueStringIdentifier(); - return new RelativeImageFile(imageFileInfo.getImageRelativePath(), imageIDOrNull); + return new RelativeImageFile(imageFileInfo.getImageRelativePath(), + imageFileInfo.tryGetUniqueStringIdentifier()); } public RelativeImageFile(String imageRelativePath, String imageIDOrNull) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/impl/ImageDataSetInformation.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/impl/ImageDataSetInformation.java index 3171778ecedd8cb3939683e5ed52273a2699576b..a4f686564d227c9ef5b7cd24aa3d6033181b18dd 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/impl/ImageDataSetInformation.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/impl/ImageDataSetInformation.java @@ -51,6 +51,8 @@ public class ImageDataSetInformation extends BasicDataSetInformation private boolean registerAsOverviewImageDataSet; + private boolean generateOverviewImagesFromRegisteredImages; + private int maximumImageWidth; private int maximumImageHeight; @@ -160,6 +162,18 @@ public class ImageDataSetInformation extends BasicDataSetInformation this.registerAsOverviewImageDataSet = registerAsOverviewImageDataSet; } + public boolean isGenerateOverviewImagesFromRegisteredImages() + { + return generateOverviewImagesFromRegisteredImages; + } + + public void setGenerateOverviewImagesFromRegisteredImages( + boolean generateOverviewImagesFromRegisteredImages) + { + this.generateOverviewImagesFromRegisteredImages = + generateOverviewImagesFromRegisteredImages; + } + @Override public String toString() { diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/ImageFileInfo.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/ImageFileInfo.java index 85c50c1d8932508bb9374fa8892be0b64ead5774..30ad984638920be66b0696e3180d1206afe81bcc 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/ImageFileInfo.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/ImageFileInfo.java @@ -30,6 +30,10 @@ public final class ImageFileInfo implements Serializable private ImageIdentifier imageIdentifier; + private String uniqueImageIdentifier; + + private String containerDataSetCode; + public ImageFileInfo(String channelCode, int tileRow, int tileColumn, String imageRelativePath) { assert channelCode != null; @@ -40,10 +44,17 @@ public final class ImageFileInfo implements Serializable setTile(tileRow, tileColumn); } - public ImageIdentifier tryGetImageIdentifier() + public String tryGetUniqueStringIdentifier() { - return imageIdentifier; + if (imageIdentifier != null) + { + return imageIdentifier.getUniqueStringIdentifier(); + } else if (uniqueImageIdentifier != null) + { + return uniqueImageIdentifier; + } + return null; } public Integer tryGetWellRow() @@ -146,6 +157,21 @@ public final class ImageFileInfo implements Serializable this.seriesNumberOrNull = value; } + public void setUniqueImageIdentifier(String uniqueImageIdentifier) + { + this.uniqueImageIdentifier = uniqueImageIdentifier; + } + + public String getContainerDataSetCode() + { + return containerDataSetCode; + } + + public void setContainerDataSetCode(String containerDataSetCode) + { + this.containerDataSetCode = containerDataSetCode; + } + @Override public String toString() { @@ -154,5 +180,4 @@ public final class ImageFileInfo implements Serializable + timepointOrNull + ", depth=" + depthOrNull + ", seriesNumber=" + seriesNumberOrNull + "]"; } - } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleOverviewImageDataConfig.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleOverviewImageDataConfig.java index f57b0ab05cb88a7bcfd9fc25e1590df5c5e245a5..3fe34cf61299aae241ece223042ef454e6760b46 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleOverviewImageDataConfig.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleOverviewImageDataConfig.java @@ -25,6 +25,8 @@ public class SimpleOverviewImageDataConfig extends SimpleImageDataConfig { private String containerDataSetCode; + private boolean generateOverviewImagesFromRegisteredImages; + public String getContainerDataSetCode() { return containerDataSetCode; @@ -34,4 +36,16 @@ public class SimpleOverviewImageDataConfig extends SimpleImageDataConfig { this.containerDataSetCode = containerDataSetCode; } + + public boolean isGenerateOverviewImagesFromRegisteredImages() + { + return generateOverviewImagesFromRegisteredImages; + } + + public void setGenerateOverviewImagesFromRegisteredImages( + boolean generateOverviewImagesFromRegisteredImages) + { + this.generateOverviewImagesFromRegisteredImages = + generateOverviewImagesFromRegisteredImages; + } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/ImagingDataSetRegistrationTransaction.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/ImagingDataSetRegistrationTransaction.java index ea1943f1affb36efb8f01c94bb2705e548396f6a..3e5f727c8d4a0b4b9e7c6af44d8a27ebd72df4bb 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/ImagingDataSetRegistrationTransaction.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/ImagingDataSetRegistrationTransaction.java @@ -30,6 +30,7 @@ import java.util.Properties; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.io.FileBasedContentNode; +import ch.systemsx.cisd.common.io.hierarchical_content.api.IHierarchicalContent; import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationDetails; import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationService; import ch.systemsx.cisd.etlserver.registrator.IDataSetRegistrationDetailsFactory; @@ -59,6 +60,7 @@ import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ThumbnailsStorageFormat; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v2.IFeatureVectorDataSet; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v2.SimpleFeatureVectorDataConfig; import ch.systemsx.cisd.openbis.dss.etl.featurevector.CsvFeatureVectorParser; +import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider; import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IDataSetImmutable; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size; @@ -242,7 +244,7 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr thumbnailDatasets.add(thumbnailDataset); generateThumbnails(imageDataSetStructure, incomingDirectory, thumbnailDataset, - thumbnailsStorageFormat, thumbnailsInfo, false); + thumbnailsStorageFormat, thumbnailsInfo, false, null); containedDataSetCodes.add(thumbnailDataset.getDataSetCode()); } imageDataSetInformation.setThumbnailsInfo(thumbnailsInfo); @@ -271,7 +273,7 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr return containerDataset; } - public IDataSet createNewOverviewImageDataSet( + private IDataSet createNewOverviewImageDataSet( DataSetRegistrationDetails<ImageDataSetInformation> imageRegistrationDetails) { ImageDataSetInformation imageDataSetInformation = @@ -290,6 +292,8 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr container); } + calculateBoundingBox(imageDataSetInformation, imageDataSetStructure, incomingDirectory); + SearchCriteria searchCriteria = new SearchCriteria(); SearchCriteria searchSubCriteria = new SearchCriteria(); searchSubCriteria.addMatchClause(MatchClause.createAttributeMatch( @@ -302,8 +306,6 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr IDataSetImmutable exampleDataSet = containedDataSets.iterator().next(); - calculateBoundingBox(imageDataSetInformation, imageDataSetStructure, incomingDirectory); - imageDataSetStructure .validateImageRepresentationGenerationParameters(imageDataSetInformation); @@ -311,23 +313,73 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr List<String> containedDataSetCodes = new ArrayList<String>(); containedDataSetCodes.addAll(container.getContainedDataSetCodes()); - @SuppressWarnings("unchecked") - DataSet<ImageDataSetInformation> thumbnailDataset = - (DataSet<ImageDataSetInformation>) super.createNewDataSet(imageRegistrationDetails); - thumbnailDataset.setFileFormatType(imageDataSetInformation.getFileFormatTypeCode()); - thumbnailDataset.setMeasuredData(false); - - generateThumbnails(imageDataSetStructure, incomingDirectory, thumbnailDataset, - createThumbnailsStorageFormat(imageDataSetInformation), thumbnailsInfo, true); - containedDataSetCodes.add(thumbnailDataset.getDataSetCode()); + List<IDataSet> thumbnailDatasets = new ArrayList<IDataSet>(); + if (imageDataSetInformation.isGenerateOverviewImagesFromRegisteredImages()) + { + IHierarchicalContent content = + ServiceProvider.getHierarchicalContentProvider().asContent(containerCode); + try + { + imageDataSetStructure + .validateImageRepresentationGenerationParameters(imageDataSetInformation); + + List<ThumbnailsStorageFormat> thumbnailsStorageFormatList = + imageDataSetStructure.getImageStorageConfiguraton() + .getThumbnailsStorageFormat(); + + boolean isFirst = true; + for (ThumbnailsStorageFormat thumbnailsStorageFormat : thumbnailsStorageFormatList) + { + IDataSet thumbnailDataset = null; + if (isFirst) + { + thumbnailDataset = super.createNewDataSet(imageRegistrationDetails); + isFirst = false; + } else + { + thumbnailDataset = + createThumbnailDataset(imageDataSetInformation, + thumbnailsStorageFormat); + } + thumbnailDatasets.add(thumbnailDataset); + + generateThumbnails(imageDataSetStructure, incomingDirectory, thumbnailDataset, + thumbnailsStorageFormat, thumbnailsInfo, false, content); + containedDataSetCodes.add(thumbnailDataset.getDataSetCode()); + } + } finally + { + if (content != null) + { + content.close(); + } + } + } else + { + @SuppressWarnings("unchecked") + DataSet<ImageDataSetInformation> thumbnailDataset = + (DataSet<ImageDataSetInformation>) super + .createNewDataSet(imageRegistrationDetails); + thumbnailDataset.setFileFormatType(imageDataSetInformation.getFileFormatTypeCode()); + thumbnailDataset.setMeasuredData(false); + thumbnailDatasets.add(thumbnailDataset); + + generateThumbnails(imageDataSetStructure, incomingDirectory, thumbnailDataset, + createThumbnailsStorageFormat(imageDataSetInformation), thumbnailsInfo, true, + null); + containedDataSetCodes.add(thumbnailDataset.getDataSetCode()); + } imageDataSetInformation.setThumbnailsInfo(thumbnailsInfo); - setSameDatasetOwner(exampleDataSet, thumbnailDataset); + for (IDataSet thumbnailDataset : thumbnailDatasets) + { + setSameDatasetOwner(exampleDataSet, thumbnailDataset); + } container.setContainedDataSetCodes(containedDataSetCodes); - return thumbnailDataset; + return thumbnailDatasets.iterator().next(); } private static ThumbnailsStorageFormat createThumbnailsStorageFormat( @@ -349,15 +401,45 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr ImageLibraryInfo imageLibrary = imageDataSetStructure.getImageStorageConfiguraton().tryGetImageLibrary(); List<ImageFileInfo> images = imageDataSetStructure.getImages(); - for (ImageFileInfo imageFileInfo : images) - { - File file = new File(incomingDirectory, imageFileInfo.getImageRelativePath()); - Size size = - Utils.loadUnchangedImageSize(new FileBasedContentNode(file), null, imageLibrary); - imageDataSetInformation.setMaximumImageWidth(Math.max( - imageDataSetInformation.getMaximumImageWidth(), size.getWidth())); - imageDataSetInformation.setMaximumImageHeight(Math.max( - imageDataSetInformation.getMaximumImageHeight(), size.getHeight())); + + if (imageDataSetInformation.isGenerateOverviewImagesFromRegisteredImages()) + { + IHierarchicalContent content = + ServiceProvider.getHierarchicalContentProvider().asContent( + imageDataSetInformation.getContainerDatasetPermId()); + try + { + for (ImageFileInfo imageFileInfo : images) + { + Size size = + Utils.loadUnchangedImageSize( + content.getNode(imageFileInfo.getImageRelativePath()), null, + imageLibrary); + imageDataSetInformation.setMaximumImageWidth(Math.max( + imageDataSetInformation.getMaximumImageWidth(), size.getWidth())); + imageDataSetInformation.setMaximumImageHeight(Math.max( + imageDataSetInformation.getMaximumImageHeight(), size.getHeight())); + } + } finally + { + if (content != null) + { + content.close(); + } + } + } else + { + for (ImageFileInfo imageFileInfo : images) + { + File file = new File(incomingDirectory, imageFileInfo.getImageRelativePath()); + Size size = + Utils.loadUnchangedImageSize(new FileBasedContentNode(file), null, + imageLibrary); + imageDataSetInformation.setMaximumImageWidth(Math.max( + imageDataSetInformation.getMaximumImageWidth(), size.getWidth())); + imageDataSetInformation.setMaximumImageHeight(Math.max( + imageDataSetInformation.getMaximumImageHeight(), size.getHeight())); + } } } @@ -369,7 +451,7 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr private void generateThumbnails(ImageDataSetStructure imageDataSetStructure, File incomingDirectory, IDataSet thumbnailDataset, ThumbnailsStorageFormat thumbnailsStorageFormatOrNull, ThumbnailsInfo thumbnailPaths, - boolean registerOriginalImageAsThumbnail) + boolean registerOriginalImageAsThumbnail, IHierarchicalContent content) { String thumbnailFile; if (thumbnailsStorageFormatOrNull == null) @@ -386,7 +468,7 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr Hdf5ThumbnailGenerator.tryGenerateThumbnails(imageDataSetStructure, incomingDirectory, thumbnailFile, imageDataSetStructure.getImageStorageConfiguraton(), thumbnailDataset.getDataSetCode(), thumbnailsStorageFormatOrNull, thumbnailPaths, - registerOriginalImageAsThumbnail); + registerOriginalImageAsThumbnail, content); enhanceWithResolution(thumbnailDataset, thumbnailPaths); } @@ -643,5 +725,4 @@ public class ImagingDataSetRegistrationTransaction extends DataSetRegistrationTr return null; } } - } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java index 045573b617bbd2ecc857e51db7beff94d415f5b5..6a3c1368dfeca5688ce5636e9eb5589f9f7f7948 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/jython/JythonPlateDataSetHandler.java @@ -21,7 +21,6 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; */ public class JythonPlateDataSetHandler extends JythonTopLevelDataSetHandler<DataSetInformation> { - private final String originalDirName; public JythonPlateDataSetHandler(TopLevelDataSetRegistratorGlobalState globalState) 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 f40870e744f9f0488e12d6329b42c470bba970bd..1b7f57f4531fcf1b7199f2132a7d0a7e8c7d62ab 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 @@ -52,6 +52,7 @@ import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.ImageDataSetInformation; import ch.systemsx.cisd.openbis.dss.etl.dto.api.impl.ImageDataSetStructure; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.Channel; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ChannelColorComponent; +import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ChannelColorRGB; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageFileInfo; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageIdentifier; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ImageMetadata; @@ -63,10 +64,16 @@ import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.transformations.ImageTransfor import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.transformations.ImageTransformationBuffer; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtil; +import ch.systemsx.cisd.openbis.dss.shared.DssScreeningUtils; import ch.systemsx.cisd.openbis.generic.shared.basic.CodeNormalizer; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FileFormatType; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Geometry; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImagingReadonlyQueryDAO; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgAcquiredImageEnrichedDTO; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgChannelDTO; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgImageDatasetDTO; +import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgImageTransformationDTO; /** * Allows to prepare the image dataset which should be registered easily using the specified @@ -166,6 +173,19 @@ public class SimpleImageDataSetRegistrator DataSetRegistrationDetails<ImageDataSetInformation> registrationDetails = imageDatasetFactory.createDataSetRegistrationDetails(); ImageDataSetInformation imageDataset = registrationDetails.getDataSetInformation(); + + if (simpleImageConfig instanceof SimpleOverviewImageDataConfig) + { + SimpleOverviewImageDataConfig simpleOverviewImageConfig = + (SimpleOverviewImageDataConfig) simpleImageConfig; + + imageDataset.setContainerDatasetPermId(simpleOverviewImageConfig + .getContainerDataSetCode()); + imageDataset.setGenerateOverviewImagesFromRegisteredImages(simpleOverviewImageConfig + .isGenerateOverviewImagesFromRegisteredImages()); + imageDataset.setRegisterAsOverviewImageDataSet(true); + } + setImageDataset(incoming, imageDataset); List<Channel> channels = simpleImageConfig.getChannels(); if (channels != null) @@ -181,16 +201,6 @@ public class SimpleImageDataSetRegistrator } } - if (simpleImageConfig instanceof SimpleOverviewImageDataConfig) - { - SimpleOverviewImageDataConfig simpleOverviewImageConfig = - (SimpleOverviewImageDataConfig) simpleImageConfig; - - imageDataset.setContainerDatasetPermId(simpleOverviewImageConfig - .getContainerDataSetCode()); - imageDataset.setRegisterAsOverviewImageDataSet(true); - } - setRegistrationDetails(registrationDetails, imageDataset); return registrationDetails; } @@ -620,30 +630,43 @@ public class SimpleImageDataSetRegistrator dataset.setSample(simpleImageConfig.getPlateSpace(), simpleImageConfig.getPlateCode()); dataset.setIncomingDirectory(incoming); - ImageDataSetStructure imageStruct = createImageDataSetStructure(incoming); + ImageDataSetStructure imageStruct = createImageDataSetStructure(incoming, dataset); dataset.setImageDataSetStructure(imageStruct); } - private ImageDataSetStructure createImageDataSetStructure(File incoming) + private ImageDataSetStructure createImageDataSetStructure(File incoming, + ImageDataSetInformation dataset) { - List<File> imageFiles = extractImageFiles(incoming); - IImageReader imageReaderOrNull = tryCreateAndSaveImageReader(imageFiles); - List<ImageTokensWithPath> imageTokensList = - parseImageTokens(imageFiles, incoming, imageReaderOrNull); - - int maxTileNumber = getMaxTileNumber(imageTokensList); - Geometry tileGeometry = simpleImageConfig.getTileGeometry(imageTokensList, maxTileNumber); - List<ImageFileInfo> images = createImageInfos(imageTokensList, tileGeometry); - List<Channel> channels = getAvailableChannels(images); - - if (simpleImageConfig.isFixedIntensityRangeForAllImagesDefined()) - { - computeAndAppendCommonFixedIntensityRangeTransformation(images, incoming, channels, - imageReaderOrNull); + List<ImageFileInfo> images = null; + List<Channel> channels = null; + Geometry tileGeometry = null; + if (dataset.isGenerateOverviewImagesFromRegisteredImages()) + { + images = new ArrayList<ImageFileInfo>(); + channels = new ArrayList<Channel>(); + tileGeometry = extractImageFileInfos(dataset, images, channels); } else { - computeAndAppendCommonIntensityRangeTransformation(images, incoming, channels, - imageReaderOrNull); + List<File> imageFiles = extractImageFiles(incoming); + IImageReader imageReaderOrNull = tryCreateAndSaveImageReader(imageFiles); + List<ImageTokensWithPath> imageTokensList = + parseImageTokens(imageFiles, incoming, imageReaderOrNull); + + int maxTileNumber = getMaxTileNumber(imageTokensList); + tileGeometry = simpleImageConfig.getTileGeometry(imageTokensList, maxTileNumber); + + images = createImageInfos(imageTokensList, tileGeometry); + channels = getAvailableChannels(images); + + if (simpleImageConfig.isFixedIntensityRangeForAllImagesDefined()) + { + computeAndAppendCommonFixedIntensityRangeTransformation(images, incoming, channels, + imageReaderOrNull); + } else + { + computeAndAppendCommonIntensityRangeTransformation(images, incoming, channels, + imageReaderOrNull); + } } ImageDataSetStructure imageStruct = new ImageDataSetStructure(); @@ -656,6 +679,85 @@ public class SimpleImageDataSetRegistrator return imageStruct; } + private Geometry extractImageFileInfos(ImageDataSetInformation dataset, + List<ImageFileInfo> images, List<Channel> channels) + { + IImagingReadonlyQueryDAO query = DssScreeningUtils.getQuery(); + + List<ImgImageDatasetDTO> containers = + DssScreeningUtils.getQuery().listImageDatasetsByPermId( + dataset.getContainerDatasetPermId()); + + for (ImgImageDatasetDTO container : containers) + { + List<ImgAcquiredImageEnrichedDTO> acquiredImages = + query.listAllEnrichedAcquiredImagesForDataSet(container.getId()); + for (ImgAcquiredImageEnrichedDTO acquiredImage : acquiredImages) + { + images.add(createImageFileInfo(container, acquiredImage)); + } + + List<ImgChannelDTO> channelDTOs = query.getChannelsByDatasetId(container.getId()); + for (ImgChannelDTO channelDTO : channelDTOs) + { + Channel channel = createChannel(query, channelDTO); + + channels.add(channel); + } + + return Geometry.createFromRowColDimensions(container.getFieldNumberOfRows(), + container.getFieldNumberOfColumns()); + } + + return null; + } + + private Channel createChannel(IImagingReadonlyQueryDAO query, ImgChannelDTO channelDTO) + { + Channel channel = + new Channel(channelDTO.getCode(), channelDTO.getLabel(), new ChannelColorRGB( + channelDTO.getRedColorComponent(), channelDTO.getGreenColorComponent(), + channelDTO.getBlueColorComponent())); + channel.setDescription(channelDTO.getDescription()); + channel.setWavelength(channelDTO.getWavelength()); + + List<ImgImageTransformationDTO> transformationDTOs = + query.listImageTransformations(channelDTO.getId()); + ImageTransformation[] transformations = new ImageTransformation[transformationDTOs.size()]; + int counter = 0; + for (ImgImageTransformationDTO transformationDTO : transformationDTOs) + { + ImageTransformation transformation = + new ImageTransformation(transformationDTO.getCode(), + transformationDTO.getLabel(), transformationDTO.getDescription(), + transformationDTO.getImageTransformerFactory()); + transformations[counter++] = transformation; + } + channel.setAvailableTransformations(transformations); + + return channel; + } + + private ImageFileInfo createImageFileInfo(ImgImageDatasetDTO container, + ImgAcquiredImageEnrichedDTO acquiredImage) + { + ImageFileInfo img = + new ImageFileInfo(acquiredImage.getChannelCode(), acquiredImage.getTileRow(), + acquiredImage.getTileColumn(), acquiredImage.getImageFilePath()); + img.setTimepoint(acquiredImage.getT()); + img.setDepth(acquiredImage.getZ()); + img.setSeriesNumber(acquiredImage.getSeriesNumber()); + + if (acquiredImage.getSpotRow() != null && acquiredImage.getSpotColumn() != null) + { + img.setWell(acquiredImage.getSpotRow(), acquiredImage.getSpotColumn()); + } + img.setUniqueImageIdentifier(acquiredImage.getImageIdOrNull()); + img.setContainerDataSetCode(container.getPermId()); + + return img; + } + private <T extends DataSetInformation> void setRegistrationDetails( DataSetRegistrationDetails<T> registrationDetails, T dataset) { diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/plugins/MarkerFileCreatingProcessingPlugin.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/plugins/MarkerFileCreatingProcessingPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..6d6e826fac38a5e6e38b56bdb60174f9bdc23526 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/plugins/MarkerFileCreatingProcessingPlugin.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012 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.screening.server.plugins; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Properties; + +import org.apache.log4j.Logger; + +import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; +import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.common.utilities.PropertyUtils; +import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IProcessingPluginTask; +import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext; +import ch.systemsx.cisd.openbis.dss.generic.shared.ProcessingStatus; +import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; + +/** + * A processing plugin that create a marker file (named with the dataset code) in specified + * location. + * + * @author Pawel Glyzewski + */ +public class MarkerFileCreatingProcessingPlugin implements IProcessingPluginTask +{ + private static final String OUTPUT_DIR = "output-dir"; + + private static final long serialVersionUID = 1L; + + private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, + MarkerFileCreatingProcessingPlugin.class); + + private final File outputDirectory; + + public MarkerFileCreatingProcessingPlugin(Properties properties, File storeRoot) + { + String directoryPath = PropertyUtils.getMandatoryProperty(properties, OUTPUT_DIR); + this.outputDirectory = new File(directoryPath); + if (false == outputDirectory.exists() || false == outputDirectory.isDirectory()) + { + throw new ConfigurationFailureException("'" + OUTPUT_DIR + "' (" + directoryPath + + ") should point to an existing directory."); + } + } + + @Override + public ProcessingStatus process(List<DatasetDescription> datasets, + DataSetProcessingContext context) + { + for (DatasetDescription dataset : datasets) + { + File markerFile = new File(outputDirectory, dataset.getDataSetCode()); + try + { + markerFile.createNewFile(); + } catch (IOException ex) + { + CheckedExceptionTunnel.unwrapIfNecessary(ex); + } + } + + operationLog.info("Processing done."); + return null; + } +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingReadonlyQueryDAO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingReadonlyQueryDAO.java index b091337343400b7f117a93646663f01d117f3a18..a9d7027bdc2bc711dbc208890f7c60029b84f065 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingReadonlyQueryDAO.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingReadonlyQueryDAO.java @@ -243,6 +243,19 @@ public interface IImagingReadonlyQueryDAO extends BaseQuery // lists all acquired images available for given dataset public List<ImgAcquiredImageDTO> listAllAcquiredImagesForDataSet(long datasetId); + @Select("select ai.ID as ID, ai.IMAGE_TRANSFORMER_FACTORY as IMAGE_TRANSFORMER_FACTORY, ai.IMG_ID as IMG_ID, ai.CHANNEL_STACK_ID as CHANNEL_STACK_ID, ai.CHANNEL_ID as CHANNEL_ID, " + + " s.X as SPOT_X, s.Y as SPOT_Y, i.path as IMAGE_PATH, i.IMAGE_ID as IMAGE_ID, i.color as IMAGE_COLOR, " + + " th.path as THUMBNAIL_PATH, th.IMAGE_ID as THUMBNAIL_IMAGE_ID, th.color as THUMBNAIL_COLOR, " + + " ch.code as CHANNEL_CODE, cs.X as X, cs.Y as Y, cs.Z_in_M as Z_in_M, cs.T_in_SEC as T_in_SEC, cs.SERIES_NUMBER as SERIES_NUMBER " + + "from acquired_images ai " + + " join images i on ai.img_id = i.id " + + " left outer join images th on ai.thumbnail_id = th.id " + + " left outer join channels ch on ai.channel_id = ch.id " + + " left outer join channel_stacks cs on ai.channel_stack_id = cs.id " + + " left outer join spots s on cs.spot_id = s.id " + + "where ch.ds_id = ?{1} or cs.ds_id = ?{1}") + public List<ImgAcquiredImageEnrichedDTO> listAllEnrichedAcquiredImagesForDataSet(long datasetId); + // simple getters @Select("select * from IMAGE_DATA_SETS where PERM_ID = ?{1}") diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgAcquiredImageEnrichedDTO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgAcquiredImageEnrichedDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..0d70a8994f9927f2e54114df72d0dbc6ea913f69 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgAcquiredImageEnrichedDTO.java @@ -0,0 +1,213 @@ +/* + * Copyright 2012 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.shared.imaging.dataaccess; + +import net.lemnik.eodsql.ResultColumn; + +/** + * @author Pawel Glyzewski + */ +public class ImgAcquiredImageEnrichedDTO extends ImgAcquiredImageDTO +{ + @ResultColumn("SPOT_X") + private Integer spotColumn; + + // position in the container, one-based (e.g. well row, 1 is the first row) + @ResultColumn("SPOT_Y") + private Integer spotRow; + + @ResultColumn("IMAGE_PATH") + private String imageFilePath; + + @ResultColumn("IMAGE_ID") + private String imageIdOrNull; + + @ResultColumn("IMAGE_COLOR") + private String imageColorComponentOrNull; + + @ResultColumn("THUMBNAIL_PATH") + private String filePath; + + @ResultColumn("THUMBNAIL_IMAGE_ID") + private String thumbnailImageIdOrNull; + + @ResultColumn("THUMBNAIL_COLOR") + private String thumbnailColorComponentOrNull; + + @ResultColumn("CHANNEL_CODE") + private String channelCode; + + // x and y are kind of a two dimensional sequence number, (e.g. tile column) + @ResultColumn("X") + private Integer tileColumn; + + // x and y are kind of a two dimensional sequence number, (e.g. tile row, 1 is the first row) + // Some use case may only use x and leave y alone. + @ResultColumn("Y") + private Integer tileRow; + + // can be null + @ResultColumn("Z_in_M") + private Float z; + + // can be null + @ResultColumn("T_in_SEC") + private Float t; + + @ResultColumn("SERIES_NUMBER") + private Integer seriesNumber; + + public Integer getSpotColumn() + { + return spotColumn; + } + + public void setSpotColumn(Integer spotColumn) + { + this.spotColumn = spotColumn; + } + + public Integer getSpotRow() + { + return spotRow; + } + + public void setSpotRow(Integer spotRow) + { + this.spotRow = spotRow; + } + + public String getImageFilePath() + { + return imageFilePath; + } + + public void setImageFilePath(String imageFilePath) + { + this.imageFilePath = imageFilePath; + } + + public String getImageIdOrNull() + { + return imageIdOrNull; + } + + public void setImageIdOrNull(String imageIdOrNull) + { + this.imageIdOrNull = imageIdOrNull; + } + + public String getImageColorComponentOrNull() + { + return imageColorComponentOrNull; + } + + public void setImageColorComponentOrNull(String imageColorComponentOrNull) + { + this.imageColorComponentOrNull = imageColorComponentOrNull; + } + + public String getFilePath() + { + return filePath; + } + + public void setFilePath(String filePath) + { + this.filePath = filePath; + } + + public String getThumbnailImageIdOrNull() + { + return thumbnailImageIdOrNull; + } + + public void setThumbnailImageIdOrNull(String thumbnailImageIdOrNull) + { + this.thumbnailImageIdOrNull = thumbnailImageIdOrNull; + } + + public String getThumbnailColorComponentOrNull() + { + return thumbnailColorComponentOrNull; + } + + public void setThumbnailColorComponentOrNull(String thumbnailColorComponentOrNull) + { + this.thumbnailColorComponentOrNull = thumbnailColorComponentOrNull; + } + + public String getChannelCode() + { + return channelCode; + } + + public void setChannelCode(String channelCode) + { + this.channelCode = channelCode; + } + + public Integer getTileColumn() + { + return tileColumn; + } + + public void setTileColumn(Integer tileColumn) + { + this.tileColumn = tileColumn; + } + + public Integer getTileRow() + { + return tileRow; + } + + public void setTileRow(Integer tileRow) + { + this.tileRow = tileRow; + } + + public Float getZ() + { + return z; + } + + public void setZ(Float z) + { + this.z = z; + } + + public Float getT() + { + return t; + } + + public void setT(Float t) + { + this.t = t; + } + + public Integer getSeriesNumber() + { + return seriesNumber; + } + + public void setSeriesNumber(Integer seriesNumber) + { + this.seriesNumber = seriesNumber; + } +}