diff --git a/screening/etc/service.properties b/screening/etc/service.properties index 7f7a322157ba0688a5e5a1c0492aecf1b2c7a571..32409fbca4b575a15d9028978454ad3df55bb7ea 100644 --- a/screening/etc/service.properties +++ b/screening/etc/service.properties @@ -79,25 +79,7 @@ quiet-period = 3 # --------------------------------------------------------------------------- # Comma separated names of reporting plugins. Each plugin should have configuration properties prefixed with its name. -reporting-plugins = plate-image-reporter, plate-image-params-reporter, default-plate-image-analysis-merger, plate-image-analysis-graph, demo-reporter - -# Label of the plugin which will be shown for the users. -demo-reporter.label = Show Dataset Size -# Comma separated list of dataset type codes which can be handled by this plugin. -demo-reporter.dataset-types = UNKNOWN -# Plugin class specification (together with the list of packages this class belongs to). -demo-reporter.class = ch.systemsx.cisd.openbis.dss.generic.server.plugins.demo.DemoReportingPlugin -# The property file. Its content will be passed as a parameter to the plugin. -demo-reporter.properties-file = - -# Label of the plugin which will be shown for the users. -plate-image-reporter.label = Show Plate Images -# Comma separated list of dataset type codes which can be handled by this plugin. -plate-image-reporter.dataset-types = HCS_IMAGE -# Plugin class specification (together with the list of packages this class belongs to). -plate-image-reporter.class = ch.systemsx.cisd.openbis.dss.generic.server.plugins.ScreeningImageReportingPlugin -# The property file. Its content will be passed as a parameter to the plugin. -plate-image-reporter.properties-file = +reporting-plugins = plate-image-params-reporter, default-plate-image-analysis-merger, plate-image-analysis-graph # Label of the plugin which will be shown for the users. plate-image-params-reporter.label = Show Plate Image Parameters @@ -169,7 +151,7 @@ imaging-db.scriptFolder = source/sql # Comma separated names of processing threads. Each thread should have configuration properties prefixed with its name. # E.g. 'code-extractor' property for the thread 'my-etl' should be specified as 'my-etl.code-extractor' -inputs=raw-data, plate-analysis-data, lmc-raw-data, lmc-jpg-data, lmc-segmented-jpg-data, image-db-data +inputs=raw-data, plate-analysis-data, lmc-raw-data, lmc-jpg-data, lmc-segmented-jpg-data, image-db-data, pelk-raw-img-db, lmc-raw-img-db # --------------------------------------------------------------------------- # 'raw-data' thread configuration @@ -377,6 +359,62 @@ image-db-data.storage-processor.well_geometry = 1x1 image-db-data.storage-processor.deprecated-file-extractor = ch.systemsx.cisd.openbis.dss.etl.genedata.HCSImageFileExtractor image-db-data.storage-processor.data-source = imaging-db +# --------------------------------------------------------------------------- + +# The directory to watch for incoming data. +pelk-raw-img-db.incoming-dir = targets/raw-images-pelk-db +pelk-raw-img-db.incoming-data-completeness-condition = auto-detection + +# The extractor class to use for code extraction +pelk-raw-img-db.data-set-info-extractor = ch.systemsx.cisd.etlserver.DefaultDataSetInfoExtractor +pelk-raw-img-db.data-set-info-extractor.entity-separator = ${data-set-file-name-entity-separator} +pelk-raw-img-db.data-set-info-extractor.index-of-sample-code = -1 +pelk-raw-img-db.data-set-info-extractor.index-of-data-producer-code = 1 +pelk-raw-img-db.data-set-info-extractor.index-of-data-production-date = 0 +pelk-raw-img-db.data-set-info-extractor.space-code = DEMO + +# The extractor class to use for type extraction +pelk-raw-img-db.type-extractor = ch.systemsx.cisd.etlserver.SimpleTypeExtractor +pelk-raw-img-db.type-extractor.file-format-type = PNG +pelk-raw-img-db.type-extractor.locator-type = RELATIVE_LOCATION +pelk-raw-img-db.type-extractor.data-set-type = HCS_IMAGE +pelk-raw-img-db.type-extractor.is-measured = true + +pelk-raw-img-db.storage-processor = ch.systemsx.cisd.openbis.dss.etl.PlateStorageProcessor +pelk-raw-img-db.storage-processor.channel-names = blue, green +pelk-raw-img-db.storage-processor.well_geometry = 3x3 +pelk-raw-img-db.storage-processor.deprecated-file-extractor = ch.systemsx.cisd.etlserver.imsb.HCSImageFileExtractor +pelk-raw-img-db.storage-processor.data-source = imaging-db + + +# --------------------------------------------------------------------------- + +# The directory to watch for incoming data. +lmc-raw-img-db.incoming-dir = targets/raw-images-lmc-db +lmc-raw-img-db.incoming-data-completeness-condition = auto-detection + +# The extractor class to use for code extraction +lmc-raw-img-db.data-set-info-extractor = ch.systemsx.cisd.etlserver.DefaultDataSetInfoExtractor +lmc-raw-img-db.data-set-info-extractor.entity-separator = . +lmc-raw-img-db.data-set-info-extractor.index-of-sample-code = 0 +lmc-raw-img-db.data-set-info-extractor.index-of-data-producer-code = +lmc-raw-img-db.data-set-info-extractor.space-code = DEMO + +# The extractor class to use for type extraction +lmc-raw-img-db.type-extractor = ch.systemsx.cisd.etlserver.SimpleTypeExtractor +lmc-raw-img-db.type-extractor.file-format-type = JPG +lmc-raw-img-db.type-extractor.locator-type = RELATIVE_LOCATION +lmc-raw-img-db.type-extractor.data-set-type = HCS_IMAGE +lmc-raw-img-db.type-extractor.is-measured = true + +lmc-raw-img-db.storage-processor = ch.systemsx.cisd.openbis.dss.etl.PlateStorageProcessor +lmc-raw-img-db.storage-processor.channel-names = dapi, gfp +lmc-raw-img-db.storage-processor.well_geometry = 3x3 +lmc-raw-img-db.storage-processor.deprecated-file-extractor = ch.systemsx.cisd.openbis.dss.etl.lmc.HCSImageFileExtractor +lmc-raw-img-db.storage-processor.data-source = imaging-db +#lmc-raw-img-db.storage-processor. +#lmc-raw-img-db.storage-processor.compute_file_checksums = false + # --------------------------------------------------------------------------- # (optional) archiver configuration # --------------------------------------------------------------------------- diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java new file mode 100644 index 0000000000000000000000000000000000000000..0d225fa9feccd6beac8c15101949fb3fe03a0570 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.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.etl; + +import ch.systemsx.cisd.openbis.dss.etl.dataaccess.ImgImageDTO.ColorComponent; + +/** + * @author Tomasz Pylak + */ +public class AbsoluteImageReference +{ + private final String imageAbsolutePath; + + private final Integer pageOrNull; + + private final ColorComponent colorComponentOrNull; + + public AbsoluteImageReference(String imageAbsolutePath, Integer pageOrNull, + ColorComponent colorComponentOrNull) + { + this.imageAbsolutePath = imageAbsolutePath; + this.pageOrNull = pageOrNull; + this.colorComponentOrNull = colorComponentOrNull; + } + + public String getImageAbsolutePath() + { + return imageAbsolutePath; + } + + public Integer tryGetPage() + { + return pageOrNull; + } + + public ColorComponent tryGetColorComponent() + { + return colorComponentOrNull; + } + +} \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetLoaderFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetLoaderFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..a7568cbf59e6378bc8b92893777cb506a6f1838d --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetLoaderFactory.java @@ -0,0 +1,100 @@ +/* + * 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.etl; + +import java.io.File; + +import javax.sql.DataSource; + +import net.lemnik.eodsql.QueryTool; + +import ch.systemsx.cisd.bds.hcs.Geometry; +import ch.systemsx.cisd.bds.hcs.Location; +import ch.systemsx.cisd.openbis.dss.etl.dataaccess.HCSDatasetLoader; +import ch.systemsx.cisd.openbis.dss.etl.dataaccess.IImagingUploadDAO; +import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; + +/** + * @author Tomasz Pylak + */ +public class HCSDatasetLoaderFactory +{ + private static final IImagingUploadDAO query = createQuery(); + + private static IImagingUploadDAO createQuery() + { + DataSource dataSource = + ServiceProvider.getDataSourceProvider().getDataSource( + ScreeningConstants.IMAGING_DATA_SOURCE); + return QueryTool.getQuery(dataSource, IImagingUploadDAO.class); + } + + public static final IHCSDatasetLoader create(File datasetRootDir, String datasetCode) + { + return createImageDBLoader(datasetRootDir, datasetCode); + // return createBDSLoader(datasetRootDir); + } + + private static HCSDatasetLoader createImageDBLoader(File datasetRootDir, String datasetCode) + { + return new HCSDatasetLoader(query, datasetCode, datasetRootDir); + } + + private static IHCSDatasetLoader createBDSLoader(File datasetRootDir) + { + final ch.systemsx.cisd.bds.hcs.HCSDatasetLoader loader = + new ch.systemsx.cisd.bds.hcs.HCSDatasetLoader(datasetRootDir); + return adapt(loader); + } + + private static IHCSDatasetLoader adapt(final ch.systemsx.cisd.bds.hcs.HCSDatasetLoader loader) + { + return new IHCSDatasetLoader() + { + + public void close() + { + loader.close(); + } + + public int getChannelCount() + { + return loader.getChannelCount(); + } + + public Geometry getPlateGeometry() + { + return loader.getPlateGeometry(); + } + + public Geometry getWellGeometry() + { + return loader.getWellGeometry(); + } + + public AbsoluteImageReference tryGetImage(int chosenChannel, Location wellLocation, + Location tileLocation) + { + String absPath = + loader.tryGetStandardNodeAt(chosenChannel, wellLocation, tileLocation); + return new AbsoluteImageReference(absPath, null, null); + } + + }; + } +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetUploader.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetUploader.java index 07603feebe67fd071c55b83e34b6f1d204fb0f31..6bb1120e83769a1b2e5def7063deeebe124d4efa 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetUploader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetUploader.java @@ -24,6 +24,7 @@ import java.util.Set; import java.util.Map.Entry; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.openbis.dss.etl.HCSImageFileExtractionResult.Channel; import ch.systemsx.cisd.openbis.dss.etl.dataaccess.IImagingUploadDAO; import ch.systemsx.cisd.openbis.dss.etl.dataaccess.ImgAcquiredImageDTO; import ch.systemsx.cisd.openbis.dss.etl.dataaccess.ImgChannelDTO; @@ -66,17 +67,45 @@ class HCSDatasetUploader private Map<String, Long> getOrCreateChannels(long expId, Set<HCSImageFileExtractionResult.Channel> channels) { - Map<String/* name */, ImgChannelDTO> existingChannels = - asNameMap(dao.getChannelsByExperimentId(expId)); + List<ImgChannelDTO> allChannels = dao.getChannelsByExperimentId(expId); + if (allChannels.size() == 0) + { + return createChannels(expId, channels); + } else + { + return updateChannels(expId, channels, allChannels); + } + } + + private Map<String, Long> updateChannels(long expId, Set<Channel> channels, + List<ImgChannelDTO> allChannels) + { + Map<String/* name */, ImgChannelDTO> existingChannels = asNameMap(allChannels); + Map<String, Long> map = new HashMap<String, Long>(); + for (HCSImageFileExtractionResult.Channel channel : channels) + { + ImgChannelDTO channelDTO = updateChannel(channel, expId, existingChannels); + addChannel(map, channelDTO); + } + return map; + } + + private Map<String, Long> createChannels(long expId, Set<Channel> channels) + { Map<String, Long> map = new HashMap<String, Long>(); for (HCSImageFileExtractionResult.Channel channel : channels) { - ImgChannelDTO channelDTO = getOrCreateChannel(channel, expId, existingChannels); - map.put(channelDTO.getName(), channelDTO.getId()); + ImgChannelDTO channelDTO = createChannel(expId, channel); + addChannel(map, channelDTO); } return map; } + private static void addChannel(Map<String, Long> map, ImgChannelDTO channelDTO) + { + map.put(channelDTO.getName(), channelDTO.getId()); + } + private static Map<String, ImgChannelDTO> asNameMap(List<ImgChannelDTO> channels) { Map<String, ImgChannelDTO> nameMap = new HashMap<String, ImgChannelDTO>(); @@ -87,37 +116,51 @@ class HCSDatasetUploader return nameMap; } - private ImgChannelDTO getOrCreateChannel(HCSImageFileExtractionResult.Channel channel, - long expId, Map<String, ImgChannelDTO> existingChannels) + private ImgChannelDTO updateChannel(HCSImageFileExtractionResult.Channel channel, long expId, + Map<String, ImgChannelDTO> existingChannels) { - ImgChannelDTO channelDTO = createChannelDTO(channel, expId); - ImgChannelDTO existingChannel = existingChannels.get(channelDTO.getName()); - if (existingChannel != null) + ImgChannelDTO channelDTO = makeChannelDTO(channel, expId); + String channelName = channelDTO.getName(); + ImgChannelDTO existingChannel = existingChannels.get(channelName); + if (existingChannel == null) { - // if a channel with a specified name already exists for an experiment, its description - // will be updated - if (existingChannel.getWavelength() != channelDTO.getWavelength()) - { - throw UserFailureException - .fromTemplate( - "There are already datasets registered for the experiment " - + "which use the same channel name, but with a different wavelength! " - + "Channel %s, old wavelength %d, new wavelength %d.", - channelDTO.getName(), existingChannel.getWavelength(), channelDTO - .getWavelength()); - } - channelDTO.setId(existingChannel.getId()); - dao.updateChannel(channelDTO); - } else + throw createInvalidNewChannelException(expId, existingChannels, channelName); + } + // a channel with a specified name already exists for an experiment, its description + // will be updated + if (existingChannel.getWavelength().equals(channelDTO.getWavelength()) == false) { - // if a channel with a specified name does not exists for an experiment, it's created - long channelId = dao.addChannel(channelDTO); - channelDTO.setId(channelId); + throw UserFailureException.fromTemplate( + "There are already datasets registered for the experiment " + + "which use the same channel name, but with a different wavelength! " + + "Channel %s, old wavelength %d, new wavelength %d.", channelName, + existingChannel.getWavelength(), channelDTO.getWavelength()); } + channelDTO.setId(existingChannel.getId()); + dao.updateChannel(channelDTO); + return channelDTO; + } + + private static UserFailureException createInvalidNewChannelException(long expId, + Map<String, ImgChannelDTO> existingChannels, String channelName) + { + return UserFailureException.fromTemplate( + "Experiment with id '%d' has already some channels registered " + + "and does not have a channel with a name '%s'. " + + "Register a new experiment to use new channels. " + + "Available channel names in this experiment: %s.", expId, channelName, + existingChannels.keySet()); + } + + private ImgChannelDTO createChannel(long expId, HCSImageFileExtractionResult.Channel channel) + { + ImgChannelDTO channelDTO = makeChannelDTO(channel, expId); + long channelId = dao.addChannel(channelDTO); + channelDTO.setId(channelId); return channelDTO; } - private static ImgChannelDTO createChannelDTO(HCSImageFileExtractionResult.Channel channel, + private static ImgChannelDTO makeChannelDTO(HCSImageFileExtractionResult.Channel channel, long expId) { return ImgChannelDTO.createExperimentChannel(channel.getName(), channel.getDescription(), @@ -156,7 +199,7 @@ class HCSDatasetUploader createImages(stackImagesMap, channelsMap); } - private Map<ImgChannelStackDTO, List<AcquiredImageInStack>> makeStackImagesMap( + private static Map<ImgChannelStackDTO, List<AcquiredImageInStack>> makeStackImagesMap( List<AcquiredPlateImage> images, Long[][] spotIds, long datasetId) { Map<ImgChannelStackDTO, List<AcquiredImageInStack>> map = @@ -260,8 +303,8 @@ class HCSDatasetUploader return newSpots; } - private Boolean[][] extractNewSpots(int rows, int columns, List<AcquiredPlateImage> images, - List<ImgSpotDTO> existingSpots) + private static Boolean[][] extractNewSpots(int rows, int columns, + List<AcquiredPlateImage> images, List<ImgSpotDTO> existingSpots) { Boolean[][] spots = extractExistingSpots(rows, columns, images); unmarkSpots(existingSpots, spots); @@ -312,15 +355,15 @@ class HCSDatasetUploader { for (ImgSpotDTO existingSpot : existingSpots) { - spotMatrix[existingSpot.getRow()][existingSpot.getColumn()] = false; + spotMatrix[existingSpot.getRow() - 1][existingSpot.getColumn() - 1] = false; } } private long createDataset(long contId, ScreeningContainerDatasetInfo info) { ImgDatasetDTO dataset = - new ImgDatasetDTO(info.getDatasetPermId(), info.getTileRows(), info - .getTileColumns(), contId); + new ImgDatasetDTO(info.getDatasetPermId(), info.getRelativeImagesDirectory(), info + .getTileRows(), info.getTileColumns(), contId); return dao.addDataset(dataset); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSImageCheckList.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSImageCheckList.java index 70b6872723a9490090b889088d7d2cdbd1cd62ad..7ee65431e9f9cab8b0cfe244cde7fbef94fd390b 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSImageCheckList.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSImageCheckList.java @@ -23,6 +23,7 @@ import java.util.Map; import ch.systemsx.cisd.bds.hcs.Geometry; import ch.systemsx.cisd.common.utilities.AbstractHashable; +import ch.systemsx.cisd.etlserver.PlateDimension; /** * Helper class to set the <code>is_complete</code> flag in the <i>BDS</i> library. @@ -38,7 +39,7 @@ public final class HCSImageCheckList private final Map<FullLocation, Check> imageMap; - public HCSImageCheckList(final String[] channelNames, final Geometry plateGeometry, + public HCSImageCheckList(final String[] channelNames, final PlateDimension plateGeometry, final Geometry wellGeometry) { if (channelNames.length < 1) @@ -56,9 +57,9 @@ public final class HCSImageCheckList imageMap = new HashMap<FullLocation, Check>(); for (String channelName : channelNames) { - for (int wellCol = 1; wellCol <= plateGeometry.getColumns(); wellCol++) + for (int wellCol = 1; wellCol <= plateGeometry.getColsNum(); wellCol++) { - for (int wellRow = 1; wellRow <= plateGeometry.getRows(); wellRow++) + for (int wellRow = 1; wellRow <= plateGeometry.getRowsNum(); wellRow++) { for (int tileCol = 1; tileCol <= wellGeometry.getColumns(); tileCol++) { @@ -71,8 +72,8 @@ public final class HCSImageCheckList } } } - assert imageMap.size() == channelNames.length * plateGeometry.getColumns() - * plateGeometry.getRows() * wellGeometry.getColumns() * wellGeometry.getRows() : "Wrong map size"; + assert imageMap.size() == channelNames.length * plateGeometry.getColsNum() + * plateGeometry.getRowsNum() * wellGeometry.getColumns() * wellGeometry.getRows() : "Wrong map size"; } public final void checkOff(AcquiredPlateImage image) @@ -147,7 +148,7 @@ public final class HCSImageCheckList private final static String toString(final int row, final int col, final String type) { - return type + "= (" + row + ", " + col + ")"; + return type + "=(" + row + "," + col + ")"; } // @@ -157,7 +158,7 @@ public final class HCSImageCheckList @Override public final String toString() { - return "[ channel = " + channelName + "," + toString(wellRow, wellCol, "well") + "," + return "[channel=" + channelName + ", " + toString(wellRow, wellCol, "well") + ", " + toString(tileRow, tileCol, "tile") + "]"; } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/IHCSDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/IHCSDatasetLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..fb3fab8b5a9c27a35b5980589c32ca5e23d2eca3 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/IHCSDatasetLoader.java @@ -0,0 +1,43 @@ +/* + * 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.etl; + +import ch.systemsx.cisd.bds.hcs.Geometry; +import ch.systemsx.cisd.bds.hcs.Location; + +/** + * @author Tomasz Pylak + */ +public interface IHCSDatasetLoader +{ + + /** has to be called at the end */ + void close(); + + Geometry getPlateGeometry(); + + Geometry getWellGeometry(); + + int getChannelCount(); + + /** + * @param chosenChannel start from 1 + * @return image (with absolute path, page and color) + */ + AbsoluteImageReference tryGetImage(int chosenChannel, Location wellLocation, + Location tileLocation); +} \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/PlateStorageProcessor.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/PlateStorageProcessor.java index 37f1f3eb844631bb6200da552cd6b2254b714214..72b8be9eaf574e62dd91ce94f8c1701caf41970f 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/PlateStorageProcessor.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/PlateStorageProcessor.java @@ -35,7 +35,6 @@ import org.apache.log4j.Logger; import ch.systemsx.cisd.bds.hcs.Channel; import ch.systemsx.cisd.bds.hcs.Geometry; import ch.systemsx.cisd.bds.hcs.Location; -import ch.systemsx.cisd.bds.hcs.PlateGeometry; import ch.systemsx.cisd.bds.storage.IFile; import ch.systemsx.cisd.bds.storage.filesystem.NodeFactory; import ch.systemsx.cisd.common.collections.CollectionUtils; @@ -168,8 +167,8 @@ public final class PlateStorageProcessor extends AbstractStorageProcessor // --------------------------------- - private ScreeningContainerDatasetInfo createScreeningDatasetInfo(final Experiment experiment, - final DataSetInformation dataSetInformation) + private ScreeningContainerDatasetInfo createScreeningDatasetInfo(Experiment experiment, + DataSetInformation dataSetInformation, String relativeImagesDirectory) { ScreeningContainerDatasetInfo info = new ScreeningContainerDatasetInfo(); info.setExperimentPermId(experiment.getPermId()); @@ -179,19 +178,21 @@ public final class PlateStorageProcessor extends AbstractStorageProcessor info.setContainerPermId(sample.getPermId()); info.setDatasetPermId(dataSetInformation.getDataSetCode()); - Geometry plateGeometry = getPlateGeometry(dataSetInformation); - int plateRows = plateGeometry.getRows(); - int plateCols = plateGeometry.getColumns(); + PlateDimension plateGeometry = getPlateGeometry(dataSetInformation); + int plateRows = plateGeometry.getRowsNum(); + int plateCols = plateGeometry.getColsNum(); info.setContainerRows(plateRows); info.setContainerColumns(plateCols); info.setTileRows(spotGeometry.getRows()); info.setTileColumns(spotGeometry.getColumns()); + info.setRelativeImagesDirectory(relativeImagesDirectory); + return info; } - private Geometry getPlateGeometry(final DataSetInformation dataSetInformation) + private PlateDimension getPlateGeometry(final DataSetInformation dataSetInformation) { final IEntityProperty[] sampleProperties = dataSetInformation.getProperties(); final PlateDimension plateDimension = @@ -202,9 +203,7 @@ public final class PlateStorageProcessor extends AbstractStorageProcessor "Missing plate geometry for the plate registered for sample identifier '" + dataSetInformation.getSampleIdentifier() + "'."); } - final Geometry plateGeometry = - new PlateGeometry(plateDimension.getRowsNum(), plateDimension.getColsNum()); - return plateGeometry; + return plateDimension; } // --------------------------------- @@ -275,22 +274,33 @@ public final class PlateStorageProcessor extends AbstractStorageProcessor HCSImageFileExtractionResult extractionResult = extractImages(dataSetInformation, incomingDataSetDirectory); - ScreeningContainerDatasetInfo info = - createScreeningDatasetInfo(experiment, dataSetInformation); + validateImages(dataSetInformation, mailClient, incomingDataSetDirectory, extractionResult); - validateImages(dataSetInformation, mailClient, incomingDataSetDirectory, info, - extractionResult); + File imagesInStoreFolder = moveFileToDirectory(incomingDataSetDirectory, originalFolder); + String relativeImagesDirectory = + getRelativeImagesDirectory(rootDirectory, imagesInStoreFolder); - moveFileToDirectory(incomingDataSetDirectory, originalFolder); - storeInDatabase(info, extractionResult.getImages(), extractionResult.getChannels()); + storeInDatabase(experiment, dataSetInformation, extractionResult, relativeImagesDirectory); return rootDirectory; } + private String getRelativeImagesDirectory(File rootDirectory, File imagesInStoreFolder) + { + String root = rootDirectory.getAbsolutePath(); + String imgDir = imagesInStoreFolder.getAbsolutePath(); + if (imgDir.startsWith(root) == false) + { + throw UserFailureException.fromTemplate( + "Directory %s should be a subdirectory of directory %s.", imgDir, root); + } + return imgDir.substring(root.length()); + } + private void validateImages(final DataSetInformation dataSetInformation, final IMailClient mailClient, final File incomingDataSetDirectory, - ScreeningContainerDatasetInfo info, HCSImageFileExtractionResult extractionResult) + HCSImageFileExtractionResult extractionResult) { - HCSImageCheckList imageCheckList = createImageCheckList(info); + HCSImageCheckList imageCheckList = createImageCheckList(dataSetInformation); checkImagesForDuplicates(extractionResult, imageCheckList); if (extractionResult.getInvalidFiles().size() > 0) { @@ -318,12 +328,10 @@ public final class PlateStorageProcessor extends AbstractStorageProcessor } } - private HCSImageCheckList createImageCheckList(ScreeningContainerDatasetInfo info) + private HCSImageCheckList createImageCheckList(DataSetInformation dataSetInformation) { - Geometry plateGeometry = getPlateGeometry(info); - HCSImageCheckList imageCheckList = - new HCSImageCheckList(channelNames, plateGeometry, spotGeometry); - return imageCheckList; + PlateDimension plateGeometry = getPlateGeometry(dataSetInformation); + return new HCSImageCheckList(channelNames, plateGeometry, spotGeometry); } private HCSImageFileExtractionResult extractImages(final DataSetInformation dataSetInformation, @@ -386,6 +394,12 @@ public final class PlateStorageProcessor extends AbstractStorageProcessor checkParameters(incomingDataSetDirectory, storedDataDirectory); final File originalDataFile = tryGetProprietaryData(storedDataDirectory); + if (originalDataFile == null) + { + // nothing has been stored in the file system yet, + // e.g. because images could not be validated + return; + } // Move the data from the 'original' directory back to the 'incoming' directory. final File incomingDirectory = incomingDataSetDirectory.getParentFile(); try @@ -420,22 +434,27 @@ public final class PlateStorageProcessor extends AbstractStorageProcessor } } - private void storeInDatabase(ScreeningContainerDatasetInfo info, - List<AcquiredPlateImage> images, Set<HCSImageFileExtractionResult.Channel> channels) + private void storeInDatabase(Experiment experiment, DataSetInformation dataSetInformation, + HCSImageFileExtractionResult extractionResult, String relativeImagesDirectory) { + ScreeningContainerDatasetInfo info = + createScreeningDatasetInfo(experiment, dataSetInformation, relativeImagesDirectory); + if (currentTransaction != null) { throw new IllegalStateException("previous transaction has not been commited!"); } currentTransaction = createQuery(); - HCSDatasetUploader.upload(currentTransaction, info, images, channels); + + HCSDatasetUploader.upload(currentTransaction, info, extractionResult.getImages(), + extractionResult.getChannels()); } private void rollbackDatabaseChanges() { if (currentTransaction == null) { - throw new IllegalStateException("there is no transaction to rollback"); + return; // storing in the imaging db has not started } try { diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ScreeningContainerDatasetInfo.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ScreeningContainerDatasetInfo.java index 46a5705dbdf843bfd5a03f051543d31d1adc41ba..8c2de3f9987c3f2ca76926c96028eba4e978c0da 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ScreeningContainerDatasetInfo.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ScreeningContainerDatasetInfo.java @@ -33,6 +33,10 @@ class ScreeningContainerDatasetInfo private int tileRows, tileColumns; + // All images paths are relative to the IMAGES_DIRECTORY folder. + // The folder path itself is relative to the dataset root directory. + private String relativeImagesDirectory; + public String getExperimentPermId() { return experimentPermId; @@ -103,4 +107,13 @@ class ScreeningContainerDatasetInfo this.tileColumns = tileColumns; } + public String getRelativeImagesDirectory() + { + return relativeImagesDirectory; + } + + public void setRelativeImagesDirectory(String relativeImagesDirectory) + { + this.relativeImagesDirectory = relativeImagesDirectory; + } } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/HCSDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/HCSDatasetLoader.java index c4742d1454a76c272ed0285deb757638d51da7a0..14210b9c8e72360d3aa15f77f3a2969a759eae4d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/HCSDatasetLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/HCSDatasetLoader.java @@ -16,14 +16,12 @@ package ch.systemsx.cisd.openbis.dss.etl.dataaccess; -import java.sql.Connection; -import java.sql.SQLException; - -import net.lemnik.eodsql.QueryTool; +import java.io.File; import ch.systemsx.cisd.bds.hcs.Geometry; import ch.systemsx.cisd.bds.hcs.Location; -import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference; +import ch.systemsx.cisd.openbis.dss.etl.IHCSDatasetLoader; /** * Helper class for easy handling of HCS image dataset standard structure. @@ -31,26 +29,26 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException; * @author Tomasz Pylak * @author Piotr Buczek */ -public class HCSDatasetLoader +public class HCSDatasetLoader implements IHCSDatasetLoader { + private final File datasetRootDir; + private final IImagingUploadDAO query; private final ImgDatasetDTO dataset; private ImgContainerDTO container; - private Long channelCount; + private Integer channelCount; - /** - * @exception SQLException if a database access error occurs - */ - public HCSDatasetLoader(Connection connection, String datasetPermId) throws SQLException + public HCSDatasetLoader(IImagingUploadDAO query, String datasetPermId, File datasetRootDir) { - this.query = QueryTool.getQuery(connection, IImagingUploadDAO.class); + this.datasetRootDir = datasetRootDir; + this.query = query; this.dataset = query.tryGetDatasetByPermId(datasetPermId); if (dataset == null) { - throw UserFailureException.fromTemplate("Dataset '%s' not found", datasetPermId); + throw new IllegalStateException(String.format("Dataset '%s' not found", datasetPermId)); } } @@ -85,7 +83,7 @@ public class HCSDatasetLoader .getFieldNumberOfColumns()); } - public long getChannelCount() + public int getChannelCount() { if (channelCount == null) { @@ -100,7 +98,7 @@ public class HCSDatasetLoader * @param chosenChannel start from 1 * @return image (with absolute path, page and color) */ - public ImgImageDTO tryGetStandardNodeAt(int chosenChannel, Location wellLocation, + public AbsoluteImageReference tryGetImage(int chosenChannel, Location wellLocation, Location tileLocation) { assert chosenChannel > 0; @@ -116,6 +114,23 @@ public class HCSDatasetLoader long chosenChannelId = channelIds[chosenChannel - 1]; - return query.getImage(chosenChannelId, getDataset().getId(), tileLocation, wellLocation); + ImgImageDTO imageDTO = + query + .tryGetImage(chosenChannelId, getDataset().getId(), tileLocation, + wellLocation); + if (imageDTO != null) + { + return new AbsoluteImageReference(getAbsolutePath(imageDTO), imageDTO.getPage(), + imageDTO.getColorComponent()); + } else + { + return null; + } + } + + private String getAbsolutePath(ImgImageDTO imageDTO) + { + File imgDir = new File(datasetRootDir, dataset.getImagesDirectoryPath()); + return new File(imgDir, imageDTO.getFilePath()).getAbsolutePath(); } } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/IImagingUploadDAO.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/IImagingUploadDAO.java index 299b774adea26d6ea9950bb95f286a8b69e9ab62..54ece75b656834d9629a8d429dd960d2d930af5f 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/IImagingUploadDAO.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/IImagingUploadDAO.java @@ -31,8 +31,7 @@ public interface IImagingUploadDAO extends TransactionQuery { public static final int FETCH_SIZE = 1000; - // select acquired_images.images.* - // from acquired_images + // select acquired_images.images.* from acquired_images @Select("select i.* from IMAGES i, ACQUIRED_IMAGES ai, CHANNEL_STACKS cs, SPOTS s " + "where " // where acquired_images.channel.id = ?{channelId} @@ -45,8 +44,7 @@ public interface IImagingUploadDAO extends TransactionQuery + "cs.x = ?{3.x} and cs.y = ?{3.y} and s.x = ?{4.x} and s.y = ?{4.y} and " // joins + "ai.IMG_ID = i.ID and ai.CHANNEL_STACK_ID = cs.ID and cs.SPOT_ID = s.ID") - // TODO 2010-05-19, Tomasz Pylak: add unit tests - public ImgImageDTO getImage(long channelId, long datasetId, Location tileLocation, + public ImgImageDTO tryGetImage(long channelId, long datasetId, Location tileLocation, Location wellLocation); // simple getters @@ -64,7 +62,7 @@ public interface IImagingUploadDAO extends TransactionQuery public ImgContainerDTO getContainerById(long containerId); @Select("select count(*) from CHANNELS where DS_ID = ?{1} or EXP_ID = ?{2}") - public long countChannelByDatasetIdOrExperimentId(long datasetId, long experimentId); + public int countChannelByDatasetIdOrExperimentId(long datasetId, long experimentId); @Select(sql = "select id from CHANNELS where DS_ID = ?{1} or EXP_ID = ?{2} order by name", fetchSize = FETCH_SIZE) public long[] getChannelIdsByDatasetIdOrExperimentId(long datasetId, long experimentId); @@ -96,8 +94,9 @@ public interface IImagingUploadDAO extends TransactionQuery + "(?{1.permId}, ?{1.numberOfColumns}, ?{1.numberOfRows}, ?{1.experimentId}) returning ID") public long addContainer(ImgContainerDTO container); - @Select("insert into DATA_SETS (PERM_ID, FIELDS_WIDTH, FIELDS_HEIGHT, CONT_ID) values " - + "(?{1.permId}, ?{1.fieldNumberOfColumns}, ?{1.fieldNumberOfRows}, ?{1.containerId}) returning ID") + @Select("insert into DATA_SETS (PERM_ID, IMAGES_DIRECTORY, FIELDS_WIDTH, FIELDS_HEIGHT, CONT_ID) values " + + "(?{1.permId}, ?{1.imagesDirectoryPath}, ?{1.fieldNumberOfColumns}, " + + "?{1.fieldNumberOfRows}, ?{1.containerId}) returning ID") public long addDataset(ImgDatasetDTO dataset); @Select("insert into IMAGES (PATH, PAGE, COLOR) values " diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImgDatasetDTO.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImgDatasetDTO.java index 18a1ee6d1090b95769835af1ab91297690146f5f..f53826a611d55ada0bd909c8d37a3ed6f16b5372 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImgDatasetDTO.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImgDatasetDTO.java @@ -32,6 +32,9 @@ public class ImgDatasetDTO extends AbstractHashable @ResultColumn("PERM_ID") private String permId; + @ResultColumn("IMAGES_DIRECTORY") + private String imagesDirectoryPath; + @ResultColumn("FIELDS_WIDTH") private Integer fieldNumberOfColumnsOrNull; @@ -47,10 +50,11 @@ public class ImgDatasetDTO extends AbstractHashable // All Data-Object classes must have a default constructor. } - public ImgDatasetDTO(String permId, Integer fieldNumberOfRowsOrNull, - Integer fieldNumberOfColumnsOrNull, long containerId) + public ImgDatasetDTO(String permId, String imagesDirectoryPath, + Integer fieldNumberOfRowsOrNull, Integer fieldNumberOfColumnsOrNull, long containerId) { this.permId = permId; + this.imagesDirectoryPath = imagesDirectoryPath; this.fieldNumberOfColumnsOrNull = fieldNumberOfColumnsOrNull; this.fieldNumberOfRowsOrNull = fieldNumberOfRowsOrNull; this.containerId = containerId; @@ -106,4 +110,14 @@ public class ImgDatasetDTO extends AbstractHashable this.containerId = containerId; } + public String getImagesDirectoryPath() + { + return imagesDirectoryPath; + } + + public void setImagesDirectoryPath(String imagesDirectoryPath) + { + this.imagesDirectoryPath = imagesDirectoryPath; + } + } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java index dc7dfbb46460f146566ffe723741858016d2549e..0a8ff8c0f5381a7b6c261d2dbe8d2f39f222975d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java @@ -43,7 +43,7 @@ abstract class AbstractImagesDownloadServlet extends AbstractDatasetDownloadServ * @throw EnvironmentFailureException if image does not exist */ protected abstract ResponseContentStream createImageResponse(TileImageReference params, - File datasetRoot) throws IOException, EnvironmentFailureException; + File datasetRoot, String datasetCode) throws IOException, EnvironmentFailureException; protected static class RequestParams extends TileImageReference { @@ -151,7 +151,7 @@ abstract class AbstractImagesDownloadServlet extends AbstractDatasetDownloadServ ResponseContentStream responseStream; try { - responseStream = createImageResponse(params, datasetRoot); + responseStream = createImageResponse(params, datasetRoot, params.getDatasetCode()); } catch (EnvironmentFailureException e) { operationLog.warn(e.getMessage()); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/MergingImagesDownloadServlet.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/MergingImagesDownloadServlet.java index a2f4ee4a544f5164a057981ebd5f8cde4d1509cd..6b389338437e6d1d25eb1b27440865a19e66771d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/MergingImagesDownloadServlet.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/MergingImagesDownloadServlet.java @@ -42,9 +42,9 @@ public class MergingImagesDownloadServlet extends AbstractImagesDownloadServlet **/ @Override protected final ResponseContentStream createImageResponse(TileImageReference params, - File datasetRoot) throws IOException, EnvironmentFailureException + File datasetRoot, String datasetCode) throws IOException, EnvironmentFailureException { - List<File> imageFiles = ImageChannelsUtils.getImagePaths(datasetRoot, params); + List<File> imageFiles = ImageChannelsUtils.getImagePaths(datasetRoot, datasetCode, params); BufferedImage image = ImageChannelsUtils.mergeImageChannels(params, imageFiles); File singleFileOrNull = imageFiles.size() == 1 ? imageFiles.get(0) : null; return createResponseContentStream(image, singleFileOrNull); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/SplittingImagesDownloadServlet.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/SplittingImagesDownloadServlet.java index 82739794b59e9f341e52130b3620bbb8bc563b67..0da94aff87d4eec92ea8af9461d2b4c794d2ca7d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/SplittingImagesDownloadServlet.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/SplittingImagesDownloadServlet.java @@ -20,9 +20,10 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -import ch.systemsx.cisd.bds.hcs.HCSDatasetLoader; import ch.systemsx.cisd.bds.hcs.Location; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; +import ch.systemsx.cisd.openbis.dss.etl.HCSDatasetLoaderFactory; +import ch.systemsx.cisd.openbis.dss.etl.IHCSDatasetLoader; import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelsUtils; import ch.systemsx.cisd.openbis.dss.generic.server.images.TileImageReference; @@ -38,10 +39,10 @@ public class SplittingImagesDownloadServlet extends AbstractImagesDownloadServle private static final long serialVersionUID = 1L; /** throws {@link EnvironmentFailureException} when image does not exist */ - private File getImagePath(File datasetRoot, TileImageReference params) + private File getImagePath(File datasetRoot, String datasetCode, TileImageReference params) throws EnvironmentFailureException { - HCSDatasetLoader imageAccessor = new HCSDatasetLoader(datasetRoot); + IHCSDatasetLoader imageAccessor = HCSDatasetLoaderFactory.create(datasetRoot, datasetCode); Location wellLocation = params.getWellLocation(); Location tileLocation = params.getTileLocation(); int channel = 1; // NOTE: we assume that there is only one channel @@ -56,9 +57,9 @@ public class SplittingImagesDownloadServlet extends AbstractImagesDownloadServle **/ @Override protected final ResponseContentStream createImageResponse(TileImageReference params, - File datasetRoot) throws IOException, EnvironmentFailureException + File datasetRoot, String datasetCode) throws IOException, EnvironmentFailureException { - File imageFile = getImagePath(datasetRoot, params); + File imageFile = getImagePath(datasetRoot, datasetCode, params); BufferedImage image = ImageChannelsUtils.mergeImageChannels(params, imageFile); return createResponseContentStream(image, imageFile); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java index a78d64eb95b1b63af69b859762d8dab16b31dfd0..3ae25a3a1087a40460720a36274c2731ddbb0549 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java @@ -22,9 +22,11 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -import ch.systemsx.cisd.bds.hcs.HCSDatasetLoader; import ch.systemsx.cisd.bds.hcs.Location; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; +import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference; +import ch.systemsx.cisd.openbis.dss.etl.HCSDatasetLoaderFactory; +import ch.systemsx.cisd.openbis.dss.etl.IHCSDatasetLoader; import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDatasetDownloadServlet.Size; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtil; @@ -57,9 +59,10 @@ public class ImageChannelsUtils * be merged. * @throw {@link EnvironmentFailureException} when image does not exist */ - public static List<File> getImagePaths(File datasetRoot, TileImageReference params) + public static List<File> getImagePaths(File datasetRoot, String datasetCode, + TileImageReference params) { - HCSDatasetLoader imageAccessor = new HCSDatasetLoader(datasetRoot); + IHCSDatasetLoader imageAccessor = HCSDatasetLoaderFactory.create(datasetRoot, datasetCode); Location wellLocation = params.getWellLocation(); Location tileLocation = params.getTileLocation(); List<File> paths = new ArrayList<File>(); @@ -152,14 +155,16 @@ public class ImageChannelsUtils * @param chosenChannel starts from 1 * @throw {@link EnvironmentFailureException} when image does not exist */ - public static File getImagePath(HCSDatasetLoader imageAccessor, Location wellLocation, + public static File getImagePath(IHCSDatasetLoader imageAccessor, Location wellLocation, Location tileLocation, int chosenChannel) { - String imagePath = - imageAccessor.tryGetStandardNodeAt(chosenChannel, wellLocation, tileLocation); - if (imagePath != null) + AbsoluteImageReference image = + imageAccessor.tryGetImage(chosenChannel, wellLocation, tileLocation); + if (image != null) { - return new File(imagePath); + // TODO 2010-05-31, Tomasz Pylak: add support for tiff paged images and channels + // splitting + return new File(image.getImageAbsolutePath()); } else { throw EnvironmentFailureException.fromTemplate( diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ScreeningImageReportingPlugin.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ScreeningImageReportingPlugin.java deleted file mode 100644 index 0d41b216824912a5031e8a4159c39cd6c032b395..0000000000000000000000000000000000000000 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ScreeningImageReportingPlugin.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2009 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.generic.server.plugins; - -import static ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.SimpleTableModelBuilder.asNum; -import static ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.SimpleTableModelBuilder.asText; - -import java.io.File; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; - -import ch.systemsx.cisd.bds.DataStructureLoader; -import ch.systemsx.cisd.bds.IDataStructure; -import ch.systemsx.cisd.bds.hcs.Geometry; -import ch.systemsx.cisd.bds.hcs.IHCSImageFormattedData; -import ch.systemsx.cisd.bds.hcs.Location; -import ch.systemsx.cisd.bds.storage.INode; -import ch.systemsx.cisd.bds.v1_0.IDataStructureV1_0; -import ch.systemsx.cisd.common.exceptions.NotImplementedException; -import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.AbstractDatastorePlugin; -import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IReportingPluginTask; -import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.SimpleTableModelBuilder; -import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtil; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ImageTableCell; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.StringTableCell; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; -import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; - -/** - * Reporting plugin which shows all images in wells of a plate dataset. - * - * @author Tomasz Pylak - */ -public class ScreeningImageReportingPlugin extends AbstractDatastorePlugin implements - IReportingPluginTask -{ - // -------- column headers used to describe images for a plate - - private static final String IMAGE = "Thumbnail"; - - private static final String CHANNEL = "Channel"; - - private static final String TILE = "Tile"; - - private static final String COLUMN = "Column"; - - private static final String ROW = "Row"; - - private static final String DATASET_CODE = "Dataset Code"; - - private static final String IMAGE_PATH = "Image Path"; - - // ---------- - - private static final long serialVersionUID = 1L; - - public ScreeningImageReportingPlugin(Properties properties, File storeRoot) - { - super(properties, storeRoot); - } - - public TableModel createReport(List<DatasetDescription> datasets) - { - SimpleTableModelBuilder builder = new SimpleTableModelBuilder(); - addReportHeaders(builder); - DataStructureLoader loader = new DataStructureLoader(storeRoot); - for (DatasetDescription dataset : datasets) - { - IDataStructureV1_0 structure = createDatasetAccessor(loader, dataset); - IHCSImageFormattedData imageAccessor = getImageAccessor(structure); - addReportRows(builder, dataset, imageAccessor); - structure.close(); - } - return builder.getTableModel(); - } - - private void addReportHeaders(SimpleTableModelBuilder builder) - { - // Note: we rely on that column order at the openBIS server side! - builder.addHeader(DATASET_CODE); - builder.addHeader(ROW); - builder.addHeader(COLUMN); - builder.addHeader(TILE); - builder.addHeader(CHANNEL); - builder.addHeader(IMAGE); - builder.addHeader(IMAGE_PATH); - } - - private void addReportRows(SimpleTableModelBuilder builder, DatasetDescription dataset, - IHCSImageFormattedData imageAccessor) - { - Geometry plateGeometry = imageAccessor.getPlateGeometry(); - Geometry wellGeometry = imageAccessor.getWellGeometry(); - for (int channel = 1; channel <= imageAccessor.getChannelCount(); channel++) - { - for (Location wellLocation : new GeometryIterable(plateGeometry)) - { - for (Location tileLocation : new GeometryIterable(wellGeometry)) - { - INode img = - imageAccessor.tryGetStandardNodeAt(channel, wellLocation, tileLocation); - if (img != null) - { - - String imageStoreRelativePath = getStoreRelativePath(img.getPath()); - ISerializableComparable image = - createImageCell(dataset, new File(img.getPath())); - String datasetCode = dataset.getDatasetCode(); - int tileNumber = - tileLocation.getX() + (tileLocation.getY() - 1) - * wellGeometry.getColumns(); - List<ISerializableComparable> row = - Arrays.<ISerializableComparable> asList(asText(datasetCode), - asNum(wellLocation.getY()), asNum(wellLocation.getX()), - asNum(tileNumber), asNum(channel), image, - asText(imageStoreRelativePath)); - builder.addRow(row); - } - } - } - } - } - - private static class GeometryIterable implements Iterable<Location> - { - private final Geometry geometry; - - public GeometryIterable(Geometry geometry) - { - this.geometry = geometry; - } - - public Iterator<Location> iterator() - { - return new Iterator<Location>() - { - private int x = 0; - - private int y = 1; - - public boolean hasNext() - { - return x < geometry.getColumns() || y < geometry.getRows(); - } - - public Location next() - { - if (x < geometry.getColumns()) - { - x++; - } else - { - x = 1; - y++; - } - return new Location(x, y); - } - - public void remove() - { - throw new NotImplementedException(); - } - }; - } - } - - private IHCSImageFormattedData getImageAccessor(IDataStructureV1_0 structure) - { - return (IHCSImageFormattedData) structure.getFormattedData(); - } - - private IDataStructureV1_0 createDatasetAccessor(DataStructureLoader loader, - DatasetDescription dataset) - { - IDataStructure dataStructure = loader.load(dataset.getDataSetLocation(), false); - return (IDataStructureV1_0) dataStructure; - } - - private static ISerializableComparable createImageCell(DatasetDescription dataset, File file) - { - if (ImageUtil.isImageFile(file)) - { - String code = dataset.getDatasetCode(); - String location = dataset.getDataSetLocation(); - return new ImageTableCell(code, location, file.getPath(), 100, 60); - } - return new StringTableCell(file.getName()); - } -} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ScreeningPlateImageParamsReportingPlugin.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ScreeningPlateImageParamsReportingPlugin.java index 0af088f7920fdb593eb6b32bab52f07c1e5af41b..4ea9ea4d3fcf049f02461d47ee4c625633e9bf9d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ScreeningPlateImageParamsReportingPlugin.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ScreeningPlateImageParamsReportingPlugin.java @@ -25,7 +25,8 @@ import java.util.List; import java.util.Properties; import ch.systemsx.cisd.bds.hcs.Geometry; -import ch.systemsx.cisd.bds.hcs.HCSDatasetLoader; +import ch.systemsx.cisd.openbis.dss.etl.HCSDatasetLoaderFactory; +import ch.systemsx.cisd.openbis.dss.etl.IHCSDatasetLoader; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.AbstractDatastorePlugin; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.IReportingPluginTask; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.SimpleTableModelBuilder; @@ -71,7 +72,8 @@ public class ScreeningPlateImageParamsReportingPlugin extends AbstractDatastoreP for (DatasetDescription dataset : datasets) { File datasetFile = new File(storeRoot, dataset.getDataSetLocation()); - HCSDatasetLoader imageAccessor = new HCSDatasetLoader(datasetFile); + IHCSDatasetLoader imageAccessor = + HCSDatasetLoaderFactory.create(datasetFile, dataset.getDatasetCode()); addReportRows(builder, dataset, imageAccessor); imageAccessor.close(); } @@ -90,7 +92,7 @@ public class ScreeningPlateImageParamsReportingPlugin extends AbstractDatastoreP } private void addReportRows(SimpleTableModelBuilder builder, DatasetDescription dataset, - HCSDatasetLoader imageAccessor) + IHCSDatasetLoader imageAccessor) { Geometry plateGeometry = imageAccessor.getPlateGeometry(); Geometry wellGeometry = imageAccessor.getWellGeometry(); 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 57b039f014d23561a9afaf48d54df3587d0cf8e8..89215b2f40e1cb2b61100a975c27ad669a60383c 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 @@ -32,13 +32,15 @@ import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter; import com.csvreader.CsvReader; import ch.systemsx.cisd.bds.hcs.Geometry; -import ch.systemsx.cisd.bds.hcs.HCSDatasetLoader; import ch.systemsx.cisd.bds.hcs.Location; import ch.systemsx.cisd.common.api.RpcServiceInterfaceVersionDTO; import ch.systemsx.cisd.common.api.server.RpcServiceNameServer; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.io.ConcatenatedFileInputStream; +import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference; +import ch.systemsx.cisd.openbis.dss.etl.HCSDatasetLoaderFactory; +import ch.systemsx.cisd.openbis.dss.etl.IHCSDatasetLoader; import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDssServiceRpc; import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelsUtils; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.DatasetFileLines; @@ -75,8 +77,9 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements // Register the service with the name server RpcServiceInterfaceVersionDTO ifaceVersion = - new RpcServiceInterfaceVersionDTO("screening-dss", "/rmi-datastore-server-screening-api-v1", - getMajorVersion(), getMinorVersion()); + new RpcServiceInterfaceVersionDTO("screening-dss", + "/rmi-datastore-server-screening-api-v1", getMajorVersion(), + getMinorVersion()); HttpInvokerServiceExporter nameServiceExporter = ServiceProvider.getRpcNameServiceExporter(); RpcServiceNameServer nameServer = (RpcServiceNameServer) nameServiceExporter.getService(); @@ -166,7 +169,8 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements private static ImageDatasetMetadata extractImageMetadata(IImageDatasetIdentifier dataset, File datasetRoot) { - HCSDatasetLoader imageAccessor = new HCSDatasetLoader(datasetRoot); + IHCSDatasetLoader imageAccessor = + HCSDatasetLoaderFactory.create(datasetRoot, dataset.getDatasetCode()); File imageFile = getAnyImagePath(imageAccessor, dataset); Geometry wellGeometry = imageAccessor.getWellGeometry(); int channelsNumber = imageAccessor.getChannelCount(); @@ -176,7 +180,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements image.getHeight()); } - private static File getAnyImagePath(HCSDatasetLoader imageAccessor, + private static File getAnyImagePath(IHCSDatasetLoader imageAccessor, IImageDatasetIdentifier dataset) { Geometry plateGeometry = imageAccessor.getPlateGeometry(); @@ -184,12 +188,11 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements { for (int col = 1; col <= plateGeometry.getColumns(); col++) { - String imagePath = - imageAccessor.tryGetStandardNodeAt(1, new Location(col, row), new Location( - 1, 1)); - if (imagePath != null) + AbsoluteImageReference image = + imageAccessor.tryGetImage(1, new Location(col, row), new Location(1, 1)); + if (image != null) { - return new File(imagePath); + return new File(image.getImageAbsolutePath()); } } } @@ -223,14 +226,14 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences) { - Map<String, HCSDatasetLoader> imageLoadersMap = + Map<String, IHCSDatasetLoader> imageLoadersMap = getImageDatasetsMap(sessionToken, imageReferences); List<File> imageFiles = new ArrayList<File>(); try { for (PlateImageReference imageReference : imageReferences) { - HCSDatasetLoader imageAccessor = + IHCSDatasetLoader imageAccessor = imageLoadersMap.get(imageReference.getDatasetCode()); assert imageAccessor != null : "imageAccessor not found for: " + imageReference; File imageFile = tryGetImageFile(imageAccessor, imageReference); @@ -243,20 +246,20 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements return new ConcatenatedFileInputStream(true, imageFiles); } - private static void closeDatasetLoaders(Collection<HCSDatasetLoader> loaders) + private static void closeDatasetLoaders(Collection<IHCSDatasetLoader> loaders) { - for (HCSDatasetLoader loader : loaders) + for (IHCSDatasetLoader loader : loaders) { loader.close(); } } // throws exception if some datasets cannot be found - private Map<String/* image or feature vector dataset code */, HCSDatasetLoader> getImageDatasetsMap( + private Map<String/* image or feature vector dataset code */, IHCSDatasetLoader> getImageDatasetsMap( String sessionToken, List<PlateImageReference> imageReferences) { - Map<String/* dataset code */, HCSDatasetLoader> imageDatasetsMap = - new HashMap<String, HCSDatasetLoader>(); + Map<String/* dataset code */, IHCSDatasetLoader> imageDatasetsMap = + new HashMap<String, IHCSDatasetLoader>(); for (PlateImageReference imageReference : imageReferences) { if (imageDatasetsMap.containsKey(imageReference.getDatasetCode()) == false) @@ -265,7 +268,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements tryFindImageDataset(sessionToken, imageReference.getDatasetCode()); if (imageDataset != null) { - HCSDatasetLoader imageAccessor = createImageLoader(imageDataset.getCode()); + IHCSDatasetLoader imageAccessor = createImageLoader(imageDataset.getCode()); imageDatasetsMap.put(imageReference.getDatasetCode(), imageAccessor); } else { @@ -277,7 +280,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements return imageDatasetsMap; } - private File tryGetImageFile(HCSDatasetLoader imageAccessor, PlateImageReference imageRef) + private File tryGetImageFile(IHCSDatasetLoader imageAccessor, PlateImageReference imageRef) { Location wellLocation = asLocation(imageRef.getWellPosition()); Location tileLocation = @@ -310,12 +313,10 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements return new Location(wellPosition.getWellColumn(), wellPosition.getWellRow()); } - private HCSDatasetLoader createImageLoader(String datasetCode) + private IHCSDatasetLoader createImageLoader(String datasetCode) { - HCSDatasetLoader loader; File datasetRoot = getRootDirectoryForDataSet(datasetCode); - loader = new HCSDatasetLoader(datasetRoot); - return loader; + return HCSDatasetLoaderFactory.create(datasetRoot, datasetCode); } private ExternalData tryFindImageDataset(String sessionToken, String datasetCode) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java index 8c8f91858cecde34ddb2c0442f653c12191b1667..dc5aa32e0e11d336f1db7c6feb316b8c77e12c51 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java @@ -58,7 +58,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Plate; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateSingleImageReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; /** @@ -138,12 +137,6 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl geneMaterialId, experimentIdentifier); } - public List<PlateSingleImageReference> listPlateImages(String sessionToken, TechId plateId) - { - Session session = getSession(sessionToken); - return PlateContentLoader.listPlateImages(session, businessObjectFactory, plateId); - } - public TableModel loadImageAnalysisForExperiment(String sessionToken, TechId experimentId) { Session session = getSession(sessionToken); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java index 537045c43db1bfca6c3ac9d387e8a88303007d31..a8b44548a209a753c22e576af84c3e60ae25dee5 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java @@ -41,7 +41,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Plate; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateSingleImageReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; /** @@ -98,12 +97,6 @@ final class ScreeningServerLogger extends AbstractServerLogger implements IScree return null; } - public List<PlateSingleImageReference> listPlateImages(String sessionToken, TechId plateId) - { - logAccess(sessionToken, "loadAllImages", "PLATE(%s)", plateId.getId()); - return null; - } - public TableModel loadImageAnalysisForExperiment(String sessionToken, TechId experimentId) { logAccess(sessionToken, "loadImageAnalysisForExperiment", "EXPERIMENT(%s)", experimentId diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/DatasetReportsLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/DatasetReportsLoader.java index 0c31b7d73a80f1a6ba875ed5dd9d56472230c294..abde749fb22b5e2dd29283b3fc8d5f863c9039f0 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/DatasetReportsLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/DatasetReportsLoader.java @@ -25,7 +25,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IntegerTableCell; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRow; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImageParameters; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateSingleImageReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; /** @@ -42,40 +41,6 @@ public class DatasetReportsLoader ScreeningConstants.PLATE_IMAGE_ANALYSIS_REPORT_KEY, datastoreCode, datasets); } - public static List<PlateSingleImageReference> loadPlateImages(List<String> datasets, - String datastoreCode, IExternalDataTable externalDataTable) - { - TableModel imageParamsReport = - externalDataTable.createReportFromDatasets( - ScreeningConstants.PLATE_IMAGE_REPORT_KEY, datastoreCode, datasets); - return asPlateImages(imageParamsReport); - } - - private static List<PlateSingleImageReference> asPlateImages(TableModel imagePathsReport) - { - List<PlateSingleImageReference> paths = new ArrayList<PlateSingleImageReference>(); - List<TableModelRow> rows = imagePathsReport.getRows(); - for (TableModelRow row : rows) - { - paths.add(asImagePath(row.getValues())); - } - return paths; - } - - private static PlateSingleImageReference asImagePath(List<ISerializableComparable> values) - { - PlateSingleImageReference path = new PlateSingleImageReference(); - int col = 0; - path.setDatasetCode(asText(values.get(col++))); - path.setWellRow(asNum(values.get(col++))); - path.setWellCol(asNum(values.get(col++))); - path.setTile(asNum(values.get(col++))); - path.setChannel(asNum(values.get(col++))); - path.setImageUrl(asText(values.get(col++))); - path.setImagePath(asText(values.get(col++))); - return path; - } - public static List<PlateImageParameters> loadPlateImageParameters(List<String> datasets, String datastoreCode, IExternalDataTable externalDataTable) { diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java index 26050512c808437ab9df3055d4f1f5ad80ac19e1..b94e4c7bcb33cbe80fd14f8c915fe51846b25bfc 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java @@ -45,7 +45,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReferen import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImageParameters; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateSingleImageReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellMetadata; @@ -57,15 +56,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellMetadata; */ public class PlateContentLoader { - /** - * loads all images from all existing image datasets for the specified plate. - */ - public static List<PlateSingleImageReference> listPlateImages(Session session, - IScreeningBusinessObjectFactory businessObjectFactory, TechId plateId) - { - return new PlateContentLoader(session, businessObjectFactory).loadAllImages(plateId); - } - public static TableModel loadImageAnalysisForPlate(Session session, IScreeningBusinessObjectFactory businessObjectFactory, TechId plateId) { @@ -160,24 +150,6 @@ public class PlateContentLoader externalDataTable); } - private List<PlateSingleImageReference> loadAllImages(TechId plateId) - { - IExternalDataTable externalDataTable = createExternalDataTable(); - List<ExternalDataPE> datasets = loadDatasets(plateId, externalDataTable); - List<ExternalDataPE> imageDatasets = ScreeningUtils.filterImageDatasets(datasets); - List<PlateSingleImageReference> imagePaths = new ArrayList<PlateSingleImageReference>(); - if (imageDatasets.size() > 0) - { - List<String> datasetCodes = extractCodes(imageDatasets); - // NOTE: we assume that all datasets for one plate come from the same datastore - String dataStoreCode = extractDataStoreCode(imageDatasets); - imagePaths = - DatasetReportsLoader.loadPlateImages(datasetCodes, dataStoreCode, - externalDataTable); - } - return imagePaths; - } - private String extractDataStoreCode(List<ExternalDataPE> imageDatasets) { assert imageDatasets.size() > 0; diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java index 88adf7a5d942405ed0e71b1591d892b0bdde7434..e10407ac39a6d0420d445b6ec96288f7f9edbc25 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java @@ -38,7 +38,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages; -import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateSingleImageReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent; /** @@ -73,15 +72,6 @@ public interface IScreeningServer extends IServer TechId geneMaterialId, @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) ExperimentIdentifier experimentIdentifier); - /** - * loads all images from all existing image datasets (in BDS-HCS format) for the specified - * plate. - */ - @Transactional(readOnly = true) - @RolesAllowed(RoleSet.OBSERVER) - public List<PlateSingleImageReference> listPlateImages(String sessionToken, - @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) TechId plateId); - /** * Loads all analysis results from all existing image-analysis datasets connected with the * specified experiment. It is assumed that all datasets are CSV files with the same headers. diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/PlateSingleImageReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/PlateSingleImageReference.java deleted file mode 100644 index 484331f65f08c6fcf7705ece01fec1b08a8c00eb..0000000000000000000000000000000000000000 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/PlateSingleImageReference.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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.plugin.screening.shared.basic.dto; - -import java.io.Serializable; - -import com.google.gwt.user.client.rpc.IsSerializable; - -/** - * Reference to a single image acquired for a plate. - * - * @author Tomasz Pylak - */ -public class PlateSingleImageReference implements IsSerializable, Serializable -{ - private static final long serialVersionUID = 1L; - - private String datasetCode; - - private int wellRow; - - private int wellCol; - - private int tile; - - private int channel; - - // url to fetch the image from DSS using HTTP, the hostname and servlet name is not included - private String imageUrl; - - // path in the DSS store - private String imagePath; - - public int getWellRow() - { - return wellRow; - } - - public void setWellRow(int wellRow) - { - this.wellRow = wellRow; - } - - public int getWellCol() - { - return wellCol; - } - - public void setWellCol(int wellCol) - { - this.wellCol = wellCol; - } - - public int getTile() - { - return tile; - } - - public void setTile(int tile) - { - this.tile = tile; - } - - public int getChannel() - { - return channel; - } - - public void setChannel(int channel) - { - this.channel = channel; - } - - public String getDatasetCode() - { - return datasetCode; - } - - public void setDatasetCode(String datasetCode) - { - this.datasetCode = datasetCode; - } - - public String getImageUrl() - { - return imageUrl; - } - - public void setImageUrl(String imageUrl) - { - this.imageUrl = imageUrl; - } - - public String getImagePath() - { - return imagePath; - } - - public void setImagePath(String imagePath) - { - this.imagePath = imagePath; - } -} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ScreeningConstants.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ScreeningConstants.java index e626d39f107f1e98e0155a08e785ce7bca7a175c..40d8d451d4fe92ba5b3cfbed259ab3081052d0c6 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ScreeningConstants.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ScreeningConstants.java @@ -27,14 +27,14 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; */ public class ScreeningConstants { + // name of the data source (configured in service.properties) which allows to access imaging db + public static final String IMAGING_DATA_SOURCE = "imaging-db"; + // name of the property which stores material (gene) inhibited by the material stored in a well public static final String INHIBITOR_PROPERTY_CODE = "INHIBITOR_OF"; // ---- required DSS plugins - // id of the DSS screening reporting plugin to get the images - public static final String PLATE_IMAGE_REPORT_KEY = "plate-image-reporter"; - // id of the DSS screening reporting plugin to get the images parameters public static final String PLATE_IMAGE_PARAMS_REPORT_KEY = "plate-image-params-reporter"; diff --git a/screening/source/sql/postgresql/001/schema-001.sql b/screening/source/sql/postgresql/001/schema-001.sql index 11f5df79d0cd95e60481487e8f984723a84c1975..5385d12e09badaa1cb0c295aa6186671d329f463 100644 --- a/screening/source/sql/postgresql/001/schema-001.sql +++ b/screening/source/sql/postgresql/001/schema-001.sql @@ -59,7 +59,10 @@ CREATE INDEX SPOTS_CONT_IDX ON SPOTS(CONT_ID); CREATE TABLE DATA_SETS ( ID BIGSERIAL NOT NULL, - PERM_ID CODE NOT NULL, + PERM_ID CODE NOT NULL, + -- All images paths are relative to the IMAGES_DIRECTORY folder. + -- The folder path itself is relative to the dataset root directory. + IMAGES_DIRECTORY FILE_PATH, FIELDS_WIDTH INTEGER, FIELDS_HEIGHT INTEGER, diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingUploadDAOTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingUploadDAOTest.java index 1d94d01c45116ea9ced5a15671d067e436a752ce..9f7992d56c9233232222d6e6333303490b47cef3 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingUploadDAOTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingUploadDAOTest.java @@ -109,13 +109,13 @@ public class ImagingUploadDAOTest extends AbstractDBTest private void testGetImage(final long datasetId, final long channelId1, final long channelId2) { ImgImageDTO image1 = - dao.getImage(channelId1, datasetId, new Location(X_WELL_COLUMN, Y_WELL_ROW), + dao.tryGetImage(channelId1, datasetId, new Location(X_WELL_COLUMN, Y_WELL_ROW), new Location(X_TILE_COLUMN, Y_TILE_ROW)); assertEquals(PATH1, image1.getFilePath()); assertEquals(ColorComponent.BLUE, image1.getColorComponent()); ImgImageDTO image2 = - dao.getImage(channelId2, datasetId, new Location(X_WELL_COLUMN, Y_WELL_ROW), + dao.tryGetImage(channelId2, datasetId, new Location(X_WELL_COLUMN, Y_WELL_ROW), new Location(X_TILE_COLUMN, Y_TILE_ROW)); assertEquals(PATH2, image2.getFilePath()); assertEquals(ColorComponent.RED, image2.getColorComponent()); @@ -186,7 +186,7 @@ public class ImagingUploadDAOTest extends AbstractDBTest final Integer fieldsWidth = 1; final Integer fieldsHeight = 2; final ImgDatasetDTO dataset = - new ImgDatasetDTO(permId, fieldsHeight, fieldsWidth, containerId); + new ImgDatasetDTO(permId, ".", fieldsHeight, fieldsWidth, containerId); final long datasetId = dao.addDataset(dataset); final ImgDatasetDTO loadedDataset = dao.tryGetDatasetByPermId(DS_PERM_ID);