diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseHelper.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseHelper.java index 31e5069afa5a9f3b680208a3c8a5356040650203..9dc994cc37ad6880ec22344578b3ffa8dca8005b 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseHelper.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseHelper.java @@ -23,6 +23,8 @@ import java.util.Map; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.dss.etl.dataaccess.IImagingQueryDAO; import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.Channel; +import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ChannelColor; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelColor; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgChannelDTO; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgContainerDTO; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgExperimentDTO; @@ -92,8 +94,7 @@ public class ImagingDatabaseHelper * in the DB. */ public static ExperimentWithChannelsAndContainer getOrCreateExperimentWithChannelsAndContainer( - IImagingQueryDAO dao, HCSContainerDatasetInfo info, - List<Channel> channels) + IImagingQueryDAO dao, HCSContainerDatasetInfo info, List<Channel> channels) { ImagingDatabaseHelper helper = new ImagingDatabaseHelper(dao); synchronized (IImagingQueryDAO.class) @@ -289,9 +290,16 @@ public class ImagingDatabaseHelper private Map<String, Long> createChannels(ChannelOwner channelOwner, List<Channel> channels) { + int colorIndex = 0; Map<String, Long> map = new HashMap<String, Long>(); for (Channel channel : channels) { + if (channel.tryGetChannelColor() == null) + { + ChannelColor channelColor = ChannelColor.createFromIndex(colorIndex); + channel.setChannelColor(channelColor); + colorIndex++; + } ImgChannelDTO channelDTO = createChannel(channel, channelOwner); addChannel(map, channelDTO); } @@ -313,8 +321,8 @@ public class ImagingDatabaseHelper return nameMap; } - private ImgChannelDTO updateExperimentChannel(Channel channel, - long expId, Map<String, ImgChannelDTO> existingChannels) + private ImgChannelDTO updateExperimentChannel(Channel channel, long expId, + Map<String, ImgChannelDTO> existingChannels) { ImgChannelDTO channelDTO = makeChannelDTO(channel, ChannelOwner.createExperiment(expId)); @@ -358,8 +366,7 @@ public class ImagingDatabaseHelper channelName, existingChannels.keySet()); } - private ImgChannelDTO createChannel(Channel channel, - ChannelOwner channelOwner) + private ImgChannelDTO createChannel(Channel channel, ChannelOwner channelOwner) { ImgChannelDTO channelDTO = makeChannelDTO(channel, channelOwner); long channelId = dao.addChannel(channelDTO); @@ -367,12 +374,15 @@ public class ImagingDatabaseHelper return channelDTO; } - private static ImgChannelDTO makeChannelDTO(Channel channel, - ChannelOwner channelOwner) + private static ImgChannelDTO makeChannelDTO(Channel channel, ChannelOwner channelOwner) { + ChannelColor channelColor = channel.tryGetChannelColor(); + assert channelColor != null : "channel color should be specified at this point"; + ImageChannelColor imageChannelColor = ImageChannelColor.valueOf(channelColor.name()); + return new ImgChannelDTO(channel.getCode(), channel.tryGetDescription(), channel.tryGetWavelength(), channelOwner.tryGetDatasetId(), - channelOwner.tryGetExperimentId(), channel.getLabel()); + channelOwner.tryGetExperimentId(), channel.getLabel(), imageChannelColor); } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseVersionHolder.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseVersionHolder.java index c3522838478e6a338d98b54773de3e945f99393d..0601f6bdab0774a72b4407b73cb86c9ec58ce84e 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseVersionHolder.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseVersionHolder.java @@ -28,7 +28,7 @@ public class ImagingDatabaseVersionHolder implements IDatabaseVersionHolder public String getDatabaseVersion() { - return "011"; // changed in S105 + return "012"; // changed in S106 } } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/IImagingQueryDAO.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/IImagingQueryDAO.java index ae5b3d5b9be7175068fe289d9ae31b4c0c8e17e5..7e5fd32086497b5900dca6bab4781b268296c691 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/IImagingQueryDAO.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/IImagingQueryDAO.java @@ -69,8 +69,8 @@ public interface IImagingQueryDAO extends TransactionQuery, IImagingReadonlyQuer @Select("insert into EXPERIMENTS (PERM_ID) values (?{1}) returning ID") public long addExperiment(String experimentPermId); - @Select("insert into CHANNELS (LABEL, CODE, DESCRIPTION, WAVELENGTH, DS_ID, EXP_ID) values " - + "(?{1.label}, ?{1.code}, ?{1.description}, ?{1.wavelength}, ?{1.datasetId}, ?{1.experimentId}) returning ID") + @Select("insert into CHANNELS (LABEL, CODE, DESCRIPTION, WAVELENGTH, DS_ID, EXP_ID, COLOR) values " + + "(?{1.label}, ?{1.code}, ?{1.description}, ?{1.wavelength}, ?{1.datasetId}, ?{1.experimentId}, ?{1.dbChannelColor}) returning ID") public long addChannel(ImgChannelDTO channel); @Select("insert into CONTAINERS (PERM_ID, SPOTS_WIDTH, SPOTS_HEIGHT, EXPE_ID) values " @@ -105,7 +105,7 @@ public interface IImagingQueryDAO extends TransactionQuery, IImagingReadonlyQuer // updates @Update("update CHANNELS " - + "set DESCRIPTION = ?{1.description}, WAVELENGTH = ?{1.wavelength} " + + "set DESCRIPTION = ?{1.description}, WAVELENGTH = ?{1.wavelength}, COLOR = ?{1.dbChannelColor} " + "where ID = ?{1.id}") public void updateChannel(ImgChannelDTO channel); } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/Channel.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/Channel.java index 845f51b144947cf3754b2426896f42835f9bfb0d..189ff38116c6bfef83c3b2738de970be3f971140 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/Channel.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/Channel.java @@ -20,13 +20,28 @@ public final class Channel extends AbstractHashable private Integer wavelength; - /** Constructs a channel with a specified code and label. */ + private ChannelColor channelColorOrNull; + + /** + * Constructs a channel with a specified code and label. The channel will be presented in a + * default color. + */ public Channel(String code, String label) + { + this(code, label, null); + } + + /** + * Constructs a channel with a specified code and label. The channel will be presented in a + * specified color. + */ + public Channel(String code, String label, ChannelColor channelColorOrNull) { assert code != null : "code is null"; assert label != null : "label is null"; this.label = label; this.code = code; + this.channelColorOrNull = channelColorOrNull; } public String getCode() @@ -49,6 +64,16 @@ public final class Channel extends AbstractHashable return label; } + /** + * @return color for the specified channel which will be used to display merged channels images. + * null only during dataset registration wheb default color should be used, afterwards + * never null. + */ + public ChannelColor tryGetChannelColor() + { + return channelColorOrNull; + } + /** Sets the description of the channel.Optional. */ public void setDescription(String description) { @@ -60,4 +85,11 @@ public final class Channel extends AbstractHashable { this.wavelength = wavelength; } + + /** Sets the color in which this channel will be displayed. */ + public void setChannelColor(ChannelColor channelColor) + { + this.channelColorOrNull = channelColor; + } + } \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/ChannelColor.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/ChannelColor.java new file mode 100644 index 0000000000000000000000000000000000000000..0a10cf74204457afb80fbb0b4cc9d82472cf340e --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/ChannelColor.java @@ -0,0 +1,38 @@ +package ch.systemsx.cisd.openbis.dss.etl.dto.api.v1; + +/** + * Allowed colors in which channels can be presented. + * + * @author Tomasz Pylak + */ +public enum ChannelColor +{ + BLUE(0), GREEN(1), RED(2), RED_GREEN(3), RED_BLUE(4), GREEN_BLUE(5); + + // If no mapping between channels and colors has been provided then channels get consecutive + // colors. This field determines the order in which colors are assigned. + // It is important for backward compatibility as well. + private final int orderIndex; + + private ChannelColor(int orderIndex) + { + this.orderIndex = orderIndex; + } + + public int getColorOrderIndex() + { + return orderIndex; + } + + public static ChannelColor createFromIndex(int colorIndex) + { + for (ChannelColor color : values()) + { + if (color.getColorOrderIndex() == colorIndex) + { + return color; + } + } + throw new IllegalStateException("Invalid color index: " + colorIndex + "!"); + } +} \ No newline at end of file diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleImageDataConfig.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleImageDataConfig.java index 7f92f26718906ca535cb6114d49e7a275f1ced2c..1ff5f95da8eb40b5b74ca83632315190fbb0775b 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleImageDataConfig.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/api/v1/SimpleImageDataConfig.java @@ -76,12 +76,29 @@ abstract public class SimpleImageDataConfig } /** - * Creates channel description for a given code. The channel label will be equal to the code. - * Can be overridden in subclasses. + * <p> + * Creates channel description for a given code. Can be overridden in subclasses. + * </p> + * By default rhe channel label will be equal to the code. Channel color returned by + * {@link #getChannelColor(String)} will be used. */ public Channel createChannel(String channelCode) { - return new Channel(channelCode, channelCode); + ChannelColor channelColor = getChannelColor(channelCode); + return new Channel(channelCode, channelCode, channelColor); + } + + /** + * Returns color for the specified channel. It will be used to display merged channels images. + * <p> + * Can be overridden in subclasses. It is ignored if {@link #createChannel(String)} is + * overridden as well. + * </p> + * By default returns null (the arbitrary color will be set). + */ + public ChannelColor getChannelColor(String channelCode) + { + return null; } // --- auxiliary structures ---------------------------------------------- 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 f26648c429a4e0059b8435d5fecfaff4a7b3eb54..425a2d6faabf39648777073099d7ca70c45566d0 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 @@ -172,7 +172,8 @@ public class SimpleImageDataSetRegistrator List<Channel> channels = new ArrayList<Channel>(); for (String channelCode : channelCodes) { - channels.add(simpleImageConfig.createChannel(channelCode)); + Channel channel = simpleImageConfig.createChannel(channelCode); + channels.add(channel); } return channels; } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java index 460320b878eca1ea2c2a859971964bdb785eed8e..1dc3935f1472e1d011fa4d1733a6aa61bccb3a61 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java @@ -32,6 +32,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.d import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto.LogicalImageReference; import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.utils.GuiUtils; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetImagesReference; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannel; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetParameters; /** @@ -148,12 +149,11 @@ class ChannelChooser for (DatasetImagesReference overlayDataset : overlayDatasets) { ImageDatasetParameters imageParams = overlayDataset.getImageParameters(); - List<String> channelsCodes = imageParams.getChannelsCodes(); - List<String> channelsLabels = imageParams.getChannelsLabels(); for (int i = 0; i < imageParams.getChannelsNumber(); i++) { - String channelCode = channelsCodes.get(i); - String channelLabel = channelsLabels.get(i); + ImageChannel channel = imageParams.getChannels().get(i); + String channelCode = channel.getCode(); + String channelLabel = channel.getLabel(); LabeledItem<ImageDatasetChannel> item = createLabeledItem(overlayDataset, channelCode, channelLabel); items.add(item); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageChannel.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageChannel.java new file mode 100644 index 0000000000000000000000000000000000000000..e51a89aeb830e3bdc2983812ffe2771bd92471d8 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageChannel.java @@ -0,0 +1,87 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; + +import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder; + +/** + * A channel in which the image has been acquired. + * <p> + * Each channel has its <code>code</code> which uniquely identifies it in one experiment or dataset. + * + * @author Tomasz Pylak + */ +public class ImageChannel implements ISerializable +{ + private static final long serialVersionUID = ServiceVersionHolder.VERSION; + + private String code; + + private String label; + + private String description; + + private Integer wavelength; + + private ImageChannelColor channelColor; + + // GWT only + @SuppressWarnings("unused") + private ImageChannel() + { + } + + public ImageChannel(String code, String label, String description, Integer wavelength, + ImageChannelColor channelColor) + { + this.code = code; + this.label = label; + this.description = description; + this.wavelength = wavelength; + this.channelColor = channelColor; + } + + public String getCode() + { + return code; + } + + public String tryGetDescription() + { + return description; + } + + public Integer tryGetWavelength() + { + return wavelength; + } + + public String getLabel() + { + return label; + } + + /** + * @return color for the specified channel which will be used to display merged channels images. + */ + public ImageChannelColor getChannelColor() + { + return channelColor; + } + +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageChannelColor.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageChannelColor.java new file mode 100644 index 0000000000000000000000000000000000000000..e1fd8c8af465c1c59d06a8af262d42b39dbfb180 --- /dev/null +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageChannelColor.java @@ -0,0 +1,27 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; + +/** + * Allowed colors in which channels can be presented. + * + * @author Tomasz Pylak + */ +public enum ImageChannelColor +{ + BLUE, GREEN, RED, RED_GREEN, RED_BLUE, GREEN_BLUE; +} diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageDatasetParameters.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageDatasetParameters.java index dddc6de6a39aa526799f5399413eb1b2d75dbe8c..78b70ff5e6242f4568b353e30e32862dea2c6655 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageDatasetParameters.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ImageDatasetParameters.java @@ -16,6 +16,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -44,9 +45,7 @@ public class ImageDatasetParameters implements ISerializable private int tileColsNum; - private List<String> channelsCodes; - - private List<String> channelsLabels; + private List<ImageChannel> channels; private Map<String/* channel code */, String/* signature */> channelsTransformerFactorySignatures = new HashMap<String, String>(); @@ -104,19 +103,29 @@ public class ImageDatasetParameters implements ISerializable this.datasetCode = datasetCode; } - public void setChannelsCodes(List<String> channelsCodes) + public List<String> getChannelsCodes() { - this.channelsCodes = channelsCodes; + List<String> channelCodes = new ArrayList<String>(); + for (ImageChannel channel : channels) + { + channelCodes.add(channel.getCode()); + } + return channelCodes; } - public List<String> getChannelsCodes() + public List<String> getChannelsLabels() { - return channelsCodes; + List<String> channelLabels = new ArrayList<String>(); + for (ImageChannel channel : channels) + { + channelLabels.add(channel.getLabel()); + } + return channelLabels; } public int getChannelsNumber() { - return channelsCodes.size(); + return channels.size(); } public boolean isMultidimensional() @@ -129,14 +138,14 @@ public class ImageDatasetParameters implements ISerializable this.isMultidimensional = isMultidimensional; } - public void setChannelsLabels(List<String> channelsLabels) + public void setChannels(List<ImageChannel> channels) { - this.channelsLabels = channelsLabels; + this.channels = channels; } - public List<String> getChannelsLabels() + public List<ImageChannel> getChannels() { - return channelsLabels; + return channels; } public void addTransformerFactorySignatureFor(String channelCode, String signatureOrNull) @@ -148,5 +157,4 @@ public class ImageDatasetParameters implements ISerializable { return channelsTransformerFactorySignatures.get(channelCode); } - } diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java index 72422a5d8f02c05efcecb393d72f2bc1b9550596..a127fd776492d681289777686c9e27e2da04c440 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java @@ -20,6 +20,8 @@ import java.util.ArrayList; import java.util.List; import ch.systemsx.cisd.common.utilities.MD5ChecksumCalculator; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannel; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelColor; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelStack; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetParameters; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; @@ -160,21 +162,29 @@ public class HCSDatasetLoader implements IImageDatasetLoader params.setIsMultidimensional(dataset.getIsMultidimensional()); params.addTransformerFactorySignatureFor(ScreeningConstants.MERGED_CHANNELS, mergedChannelTransformerFactorySignatureOrNull); - List<String> channelsCodes = new ArrayList<String>(); - List<String> channelsLabels = new ArrayList<String>(); - for (ImgChannelDTO channel : channels) + + List<ImageChannel> convertedChannels = new ArrayList<ImageChannel>(); + for (ImgChannelDTO channelDTO : channels) { - String channelCode = channel.getCode(); - channelsCodes.add(channelCode); - channelsLabels.add(channel.getLabel()); - params.addTransformerFactorySignatureFor(channelCode, - tryGetSignature(channel.getSerializedImageTransformerFactory())); + ImageChannel channel = convert(channelDTO); + convertedChannels.add(channel); + + String transformationSignature = + tryGetSignature(channelDTO.getSerializedImageTransformerFactory()); + params.addTransformerFactorySignatureFor(channelDTO.getCode(), transformationSignature); } - params.setChannelsCodes(channelsCodes); - params.setChannelsLabels(channelsLabels); + params.setChannels(convertedChannels); return params; } + private static ImageChannel convert(ImgChannelDTO channelDTO) + { + ImageChannelColor imageChannelColor = + ImageChannelColor.valueOf(channelDTO.getDbChannelColor()); + return new ImageChannel(channelDTO.getCode(), channelDTO.getLabel(), + channelDTO.getDescription(), channelDTO.getWavelength(), imageChannelColor); + } + private String tryGetSignature(byte[] bytesOrNull) { if (bytesOrNull == null) diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelDTO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelDTO.java index eaae5838b523ee5536a82afd1125cd0f6834c5a9..3393eabfa401566ef923f43aad9dda78f05dfde8 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelDTO.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelDTO.java @@ -18,6 +18,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess; import net.lemnik.eodsql.ResultColumn; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelColor; + /** * @author Tomasz Pylak */ @@ -43,6 +45,10 @@ public class ImgChannelDTO extends AbstractImageTransformerFactoryHolder @ResultColumn("EXP_ID") private Long experimentIdOrNull; + /** Value for the {@link ImageChannelColor} enum. Not null. */ + @ResultColumn("COLOR") + private String channelColor; + // GWT only @SuppressWarnings("unused") private ImgChannelDTO() @@ -51,7 +57,8 @@ public class ImgChannelDTO extends AbstractImageTransformerFactoryHolder } public ImgChannelDTO(String code, String descriptionOrNull, Integer wavelengthOrNull, - Long datasetIdOrNull, Long experimentIdOrNull, String label) + Long datasetIdOrNull, Long experimentIdOrNull, String label, + ImageChannelColor channelColor) { assert (datasetIdOrNull == null && experimentIdOrNull != null) || (datasetIdOrNull != null && experimentIdOrNull == null); @@ -61,6 +68,7 @@ public class ImgChannelDTO extends AbstractImageTransformerFactoryHolder this.wavelengthOrNull = wavelengthOrNull; this.datasetIdOrNull = datasetIdOrNull; this.experimentIdOrNull = experimentIdOrNull; + this.channelColor = channelColor.name(); } public String getCode() @@ -124,4 +132,14 @@ public class ImgChannelDTO extends AbstractImageTransformerFactoryHolder this.experimentIdOrNull = experimentId; } + /** Can be converted to {@link ImageChannelColor}. */ + public String getDbChannelColor() + { + return channelColor; + } + + public void setDbChannelColor(String channelColor) + { + this.channelColor = channelColor; + } } diff --git a/screening/source/sql/postgresql/012/data.sql b/screening/source/sql/postgresql/012/data.sql new file mode 100644 index 0000000000000000000000000000000000000000..f08222c48c2932180be40863f775e14dac5267bc --- /dev/null +++ b/screening/source/sql/postgresql/012/data.sql @@ -0,0 +1,275 @@ +-- Note that these data has to be loaded manually into the openBIS Core database. + +-- TODO: this sql should be converted to a generic sql without refering to technical ids. +-- Now the ids should be updated if some new records will be added in the generic data. + +-- +-- PostgreSQL database dump +-- + +SET statement_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = off; +SET check_function_bodies = false; +SET client_min_messages = warning; +SET escape_string_warning = off; + +SET search_path = public, pg_catalog; + +-- +-- Data for Name: controlled_vocabularies; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY controlled_vocabularies (id, code, description, registration_timestamp, pers_id_registerer, is_managed_internally, is_internal_namespace, dbin_id, modification_timestamp, is_chosen_from_list, source_uri) FROM stdin; +2 PLATE_GEOMETRY The geometry or dimensions of a plate 2008-06-17 16:38:30.723292+02 1 t t 1 2009-11-27 16:02:26.451046+01 t \N +3 MICROSCOPE Microscope used in an experiment. 2009-11-29 23:55:18.978884+01 1 f f 1 2009-12-17 01:50:54.68+01 t \N +\. + + +-- +-- Data for Name: controlled_vocabulary_terms; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY controlled_vocabulary_terms (id, code, registration_timestamp, covo_id, pers_id_registerer, label, description, ordinal) FROM stdin; +3 384_WELLS_16X24 2008-06-17 16:38:30.723292+02 2 1 384 Wells, 16x24 \N 1 +4 96_WELLS_8X12 2008-06-17 16:38:31.101031+02 2 1 96 Wells, 8x12 \N 2 +5 1536_WELLS_32X48 2008-06-17 16:38:31.101031+02 2 1 1536 Wells, 32x48 \N 3 +6 BD_PATHWAY_855 2009-11-29 23:55:18.978884+01 3 1 \N \N 1 +7 MD_IMAGEXPRESS_MICROLIVE 2009-11-29 23:55:18.978884+01 3 1 \N \N 2 +8 MD_IMAGEXPRESS_MICRO_2 2009-11-29 23:55:18.978884+01 3 1 \N \N 3 +\. + + +-- +-- Data for Name: data_set_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY data_set_types (id, code, description, dbin_id, modification_timestamp) FROM stdin; +3 HCS_IMAGE_ANALYSIS_DATA Data derived from analysis of HCS images 1 2009-11-27 16:02:26.451046+01 +2 HCS_IMAGE HCS raw images acquired by microscopes 1 2009-11-27 16:02:26.451046+01 +4 HCS_ANALYSIS_PER_GENE Image analysis data aggregated per gene. 1 2009-12-16 16:59:50.743029+01 +\. + + +-- +-- Data for Name: material_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY material_types (id, code, description, dbin_id, modification_timestamp) FROM stdin; +1 VIRUS Virus 1 2009-11-27 16:02:26.451046+01 +2 CELL_LINE Cell Line or Cell Culture. The growing of cells under controlled conditions. 1 2009-11-27 16:02:26.451046+01 +3 GENE Gene 1 2009-11-27 16:02:26.451046+01 +4 SIRNA siRNA nucleotide 1 2009-11-27 16:02:26.451046+01 +5 CONTROL Control of a control layout 1 2009-11-27 16:02:26.451046+01 +6 BACTERIUM Bacterium 1 2009-11-27 16:02:26.451046+01 +7 COMPOUND Compound 1 2009-11-27 16:02:26.451046+01 +\. + + +-- +-- Data for Name: property_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY property_types (id, code, description, label, daty_id, registration_timestamp, pers_id_registerer, covo_id, is_managed_internally, is_internal_namespace, dbin_id, maty_prop_id) FROM stdin; +3 NUCLEOTIDE_SEQUENCE A sequence of nucleotides Nucleotide Sequence 1 2008-02-28 13:03:03.358532+01 1 \N f f 1 \N +4 REFSEQ NCBI Reference Sequence code, applicable to sequences of type: DNA, RNA, protein RefSeq 1 2008-02-28 13:03:03.358532+01 1 \N f f 1 \N +13 MICROSCOPE Microscope 7 2009-11-29 23:57:05.85618+01 1 3 f f 1 \N +7 INHIBITOR_OF Inhibitor Of Inhibitor Of 8 2009-11-27 16:02:45.060699+01 1 \N f f 1 3 +11 SIRNA siRNA siRNA 8 2009-11-29 23:56:19.39967+01 1 \N f f 1 4 +12 CONTROL Control Control 8 2009-11-29 23:56:37.355313+01 1 \N f f 1 5 +6 PLATE_GEOMETRY Plate Geometry Plate Geometry 7 2008-06-17 16:38:30.723292+02 1 2 t t 1 \N +15 NUMBER_OF_CHANNEL Channels 3 2009-12-17 10:56:17.239319+01 1 \N f f 1 \N +16 LIBRARY_ID Library id Id from the master plate library 1 2008-02-28 13:03:03.358532+01 1 \N f f 1 \N +\. + + +-- +-- Data for Name: data_set_type_property_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY data_set_type_property_types (id, dsty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, section, ordinal) FROM stdin; +\. + + +-- +-- Data for Name: experiment_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY experiment_types (id, code, description, dbin_id, modification_timestamp) FROM stdin; +2 COMPOUND_HCS Compound High Content Screening 1 2009-11-27 16:02:26.451046+01 +1 SIRNA_HCS Small Interfering RNA High Content Screening 1 2009-11-27 16:02:26.451046+01 +\. + + +-- +-- Data for Name: experiment_type_property_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY experiment_type_property_types (id, exty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, section, ordinal) FROM stdin; +1 1 1 t t 1 2008-06-17 16:38:49.023295+02 \N 1 +2 2 1 t t 1 2008-06-17 16:38:49.301922+02 \N 1 +5 1 13 f f 1 2009-12-17 10:54:01.261178+01 \N 2 +\. + + +-- +-- Data for Name: file_format_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY file_format_types (id, code, description, dbin_id) FROM stdin; +7 PNG \N 1 +8 CSV files with values separated by comma or semicolon 1 +9 JPG \N 1 +\. + + +-- +-- Data for Name: filters; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY filters (id, dbin_id, name, description, registration_timestamp, pers_id_registerer, modification_timestamp, expression, is_public, grid_id) FROM stdin; +9 1 Infection index \N 2009-12-16 21:19:19.012657+01 1 2009-12-16 22:41:56.863+01 float(row.col('colIndex_5')) > float(${threshold}) t data-set-reporting-gridplate-image-analysis-merger +8 1 Total number of cells \N 2009-12-16 21:18:05.161964+01 1 2009-12-16 22:42:31.707+01 int(row.col('colIndex_3')) > int(${threshold}) t data-set-reporting-gridplate-image-analysis-merger +7 1 Number of infected cells \N 2009-12-16 21:17:40.765083+01 1 2009-12-16 22:42:46.052+01 int(row.col('colIndex_4')) > int(${threshold}) t data-set-reporting-gridplate-image-analysis-merger +\. + + +-- +-- Data for Name: material_type_property_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY material_type_property_types (id, maty_id, prty_id, is_mandatory, registration_timestamp, pers_id_registerer, is_managed_internally, section, ordinal) FROM stdin; +10 4 7 t 2009-11-27 16:02:45.060699+01 1 f \N 4 +9 5 1 f 2008-02-28 13:03:03.358532+01 1 f \N 1 +8 4 1 f 2008-02-28 13:03:03.358532+01 1 f \N 3 +6 4 3 t 2008-02-28 13:03:03.358532+01 1 f \N 1 +12 4 16 f 2008-02-28 13:03:03.358532+01 1 f \N 1 +5 3 1 f 2008-02-28 13:03:03.358532+01 1 f \N 2 +3 7 1 t 2008-02-28 13:03:03.358532+01 1 f \N 1 +2 6 1 t 2008-02-28 13:03:03.358532+01 1 f \N 1 +1 1 1 t 2008-02-28 13:03:03.358532+01 1 f \N 1 +\. + + +-- +-- Data for Name: sample_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY sample_types (id, code, description, dbin_id, is_listable, generated_from_depth, part_of_depth, modification_timestamp, is_auto_generated_code, generated_code_prefix) FROM stdin; +3 PLATE Cell Plate 1 t 2 0 2009-11-27 16:02:26.451046+01 f S +7 SIRNA_WELL \N 1 f 0 1 2009-11-27 19:42:03.483115+01 f O +8 CONTROL_WELL \N 1 f 0 1 2009-11-27 19:42:25.791288+01 f C +9 LIBRARY \N 1 f 0 0 2009-11-27 19:42:25.791288+01 f L +\. + + +-- +-- Data for Name: sample_type_property_types; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY sample_type_property_types (id, saty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, is_displayed, section, ordinal) FROM stdin; +8 7 11 f f 1 2009-11-29 23:57:38.268212+01 t \N 1 +9 8 12 f f 1 2009-11-29 23:57:49.098187+01 t \N 1 +10 3 6 f f 1 2009-11-30 01:28:20.972263+01 t \N 1 +\. + +-- +-- PostgreSQL database dump complete +-- + +-------------------------------------------------- +-- update sequences values +-------------------------------------------------- + +select setval('controlled_vocabulary_id_seq', 100); +select setval('cvte_id_seq', 100); +select setval('property_type_id_seq', 100); +select setval('file_format_type_id_seq', 100); +select setval('filter_id_seq', 100); +select setval('experiment_type_id_seq', 100); +select setval('sample_type_id_seq', 100); +select setval('data_set_type_id_seq', 100); +select setval('material_type_id_seq', 100); +select setval('etpt_id_seq', 100); +select setval('stpt_id_seq', 100); +select setval('mtpt_id_seq', 100); + + +-------------------------------------------------- +-- create a gene property and assign it to sirna well +-------------------------------------------------- + +insert into property_types( + id, + code, description, label, + daty_id, + pers_id_registerer, + dbin_id, + maty_prop_id) +values( + nextval('PROPERTY_TYPE_ID_SEQ'), + 'GENE','Inhibited gene','Gene', + (select id from data_types where code = 'MATERIAL'), + (select id from persons where user_id ='system'), + (select id from database_instances where is_original_source = 'T'), + (select id from material_types where code = 'GENE') + ); + +insert into sample_type_property_types( + id, + saty_id, + prty_id, + is_mandatory, + pers_id_registerer, + ordinal +) values( + nextval('stpt_id_seq'), + (select id from sample_types where code = 'SIRNA_WELL'), + (select id from property_types where code = 'GENE'), + false, + (select id from persons where user_id ='system'), + (select max(ordinal)+1 from sample_type_property_types + where saty_id = (select id from sample_types where code = 'SIRNA_WELL')) + ); + + +-------------------------------------------------- +-- Create gene property: gene_symbols +-------------------------------------------------- + + + insert into property_types + (id + ,code + ,description + ,label + ,daty_id + ,pers_id_registerer + ,dbin_id) + values + (nextval('PROPERTY_TYPE_ID_SEQ') + ,'GENE_SYMBOLS' + ,'Gene symbols' + ,'Gene symbols' + ,(select id from data_types where code ='VARCHAR') + ,(select id from persons where user_id ='system') + ,(select id from database_instances where is_original_source = 'T') + ); + + insert into material_type_property_types( + id, + maty_id, + prty_id, + is_mandatory, + pers_id_registerer, + ordinal + ) values( + nextval('mtpt_id_seq'), + (select id from material_types where code = 'GENE'), + (select id from property_types where code = 'GENE_SYMBOLS'), + false, + (select id from persons where user_id ='system'), + (select max(ordinal)+1 from material_type_property_types + where maty_id = (select id from material_types where code = 'GENE')) + ); + diff --git a/screening/source/sql/postgresql/012/schema-012.sql b/screening/source/sql/postgresql/012/schema-012.sql new file mode 100644 index 0000000000000000000000000000000000000000..c798e6d3ba6a294b6e578ac27d2d90bbc3cac884 --- /dev/null +++ b/screening/source/sql/postgresql/012/schema-012.sql @@ -0,0 +1,285 @@ + +/* ---------------------------------------------------------------------- */ +/* Domains */ +/* ---------------------------------------------------------------------- */ + +CREATE DOMAIN TECH_ID AS BIGINT; + +CREATE DOMAIN CODE AS VARCHAR(40); + +CREATE DOMAIN NAME AS VARCHAR(80); + +CREATE DOMAIN DESCRIPTION AS VARCHAR(200); + +CREATE DOMAIN FILE_PATH as VARCHAR(1000); + +CREATE DOMAIN COLOR_COMPONENT AS VARCHAR(40) CHECK (VALUE IN ('RED', 'GREEN', 'BLUE')); + +CREATE DOMAIN CHANNEL_COLOR AS VARCHAR(20) CHECK (VALUE IN ('BLUE', 'GREEN', 'RED', 'RED_GREEN', 'RED_BLUE', 'GREEN_BLUE')); + +CREATE DOMAIN BOOLEAN_CHAR AS BOOLEAN DEFAULT FALSE; + +/* ---------------------------------------------------------------------- */ +/* Tables */ +/* ---------------------------------------------------------------------- */ + +CREATE TABLE EXPERIMENTS ( + ID BIGSERIAL NOT NULL, + PERM_ID CODE NOT NULL, + IMAGE_TRANSFORMER_FACTORY BYTEA, + + PRIMARY KEY (ID), + UNIQUE (PERM_ID) +); + +CREATE TABLE CONTAINERS ( + ID BIGSERIAL NOT NULL, + PERM_ID CODE NOT NULL, + + SPOTS_WIDTH INTEGER, + SPOTS_HEIGHT INTEGER, + + EXPE_ID TECH_ID NOT NULL, + + PRIMARY KEY (ID), + UNIQUE (PERM_ID), + CONSTRAINT FK_SAMPLE_1 FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE INDEX CONTAINERS_EXPE_IDX ON CONTAINERS(EXPE_ID); + +CREATE TABLE SPOTS ( + ID BIGSERIAL NOT NULL, + + -- position in the container, one-based + X INTEGER, + Y INTEGER, + CONT_ID TECH_ID NOT NULL, + + PRIMARY KEY (ID), + CONSTRAINT FK_SPOT_1 FOREIGN KEY (CONT_ID) REFERENCES CONTAINERS (ID) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE INDEX SPOTS_CONT_IDX ON SPOTS(CONT_ID); +-- allows to select one spot of the container quicker +CREATE INDEX SPOTS_COORDS_IDX ON SPOTS(CONT_ID, X, Y); + +CREATE TABLE DATA_SETS ( + ID BIGSERIAL NOT NULL, + PERM_ID CODE NOT NULL, + + ---- image dataset specific fields (should be refactored) + FIELDS_WIDTH INTEGER, + FIELDS_HEIGHT INTEGER, + -- transformation for merged channels on the dataset level, overrides experiment level transformation + IMAGE_TRANSFORMER_FACTORY BYTEA, + -- a redundant information if there are timepoint or depth stack data for any spots in this dataset + IS_MULTIDIMENSIONAL BOOLEAN_CHAR NOT NULL, + + -- Which image library should be used to read the image? + -- If not specified, some heuristics are used, but it is slower and does not try with all the available libraries. + IMAGE_LIBRARY_NAME NAME, + -- Which reader in the library should be used? Valid only if the library name is specified. + -- Should be specified when library name is specified. + IMAGE_LIBRARY_READER_NAME NAME, + ---- END image dataset specific fields + + CONT_ID TECH_ID, + + PRIMARY KEY (ID), + UNIQUE (PERM_ID), + CONSTRAINT FK_DATA_SET_1 FOREIGN KEY (CONT_ID) REFERENCES CONTAINERS (ID) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE INDEX DATA_SETS_CONT_IDX ON DATA_SETS(CONT_ID); + +CREATE TABLE CHANNELS ( + ID BIGSERIAL NOT NULL, + + CODE NAME NOT NULL, + LABEL NAME NOT NULL, + DESCRIPTION DESCRIPTION, + WAVELENGTH INTEGER, + IMAGE_TRANSFORMER_FACTORY BYTEA, + COLOR CHANNEL_COLOR NOT NULL, + + DS_ID TECH_ID, + EXP_ID TECH_ID, + + PRIMARY KEY (ID), + CONSTRAINT FK_CHANNELS_1 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT FK_CHANNELS_2 FOREIGN KEY (EXP_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT CHANNELS_DS_EXP_ARC_CK CHECK ((DS_ID IS NOT NULL AND EXP_ID IS NULL) OR (DS_ID IS NULL AND EXP_ID IS NOT NULL)), + + CONSTRAINT CHANNELS_UK_1 UNIQUE(CODE, DS_ID), + CONSTRAINT CHANNELS_UK_2 UNIQUE(CODE, EXP_ID) +); + +CREATE INDEX CHANNELS_DS_IDX ON CHANNELS(DS_ID); + +CREATE TABLE CHANNEL_STACKS ( + ID BIGSERIAL NOT NULL, + + -- x and y are kind of a two dimensional sequence number, some use case may only use x and leave y alone + X INTEGER, + Y INTEGER, + -- We use the fixed dimension meters here. + Z_in_M REAL, + -- We use the fixed dimension seconds here. + T_in_SEC REAL, + SERIES_NUMBER INTEGER, + + -- For all channel stacks of a well (HCS) or image dataset (microscopy) there should be exactly + -- one record with is_representative = true + is_representative BOOLEAN_CHAR NOT NULL DEFAULT 'F', + + DS_ID TECH_ID NOT NULL, + SPOT_ID TECH_ID, + + PRIMARY KEY (ID), + CONSTRAINT FK_CHANNEL_STACKS_1 FOREIGN KEY (SPOT_ID) REFERENCES SPOTS (ID) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT FK_CHANNEL_STACKS_2 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE INDEX CHANNEL_STACKS_DS_IDX ON CHANNEL_STACKS(DS_ID); +CREATE INDEX CHANNEL_STACKS_SPOT_IDX ON CHANNEL_STACKS(SPOT_ID); +CREATE INDEX CHANNEL_STACKS_DIM_IDX ON CHANNEL_STACKS(X, Y, Z_in_M, T_in_SEC); + +CREATE TABLE IMAGES ( + ID BIGSERIAL NOT NULL, + + PATH FILE_PATH NOT NULL, + PAGE INTEGER, + COLOR COLOR_COMPONENT, + + PRIMARY KEY (ID) +); + +CREATE TABLE ACQUIRED_IMAGES ( + ID BIGSERIAL NOT NULL, + + IMG_ID TECH_ID NOT NULL, + THUMBNAIL_ID TECH_ID, + IMAGE_TRANSFORMER_FACTORY BYTEA, + + CHANNEL_STACK_ID TECH_ID NOT NULL, + CHANNEL_ID TECH_ID NOT NULL, + + PRIMARY KEY (ID), + CONSTRAINT FK_IMAGES_1 FOREIGN KEY (CHANNEL_STACK_ID) REFERENCES CHANNEL_STACKS (ID) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT FK_IMAGES_2 FOREIGN KEY (CHANNEL_ID) REFERENCES CHANNELS (ID) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT FK_IMAGES_3 FOREIGN KEY (IMG_ID) REFERENCES IMAGES (ID) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT FK_IMAGES_4 FOREIGN KEY (THUMBNAIL_ID) REFERENCES IMAGES (ID) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE INDEX IMAGES_CHANNEL_STACK_IDX ON ACQUIRED_IMAGES(CHANNEL_STACK_ID); +CREATE INDEX IMAGES_CHANNEL_IDX ON ACQUIRED_IMAGES(CHANNEL_ID); +CREATE INDEX IMAGES_IMG_IDX ON ACQUIRED_IMAGES(IMG_ID); +CREATE INDEX IMAGES_THUMBNAIL_IDX ON ACQUIRED_IMAGES(THUMBNAIL_ID); + +CREATE TABLE EVENTS ( + LAST_SEEN_DELETION_EVENT_ID TECH_ID NOT NULL +); + +/* ---------------------------------------------------------------------- */ +/* FEATURE VECTORS */ +/* ---------------------------------------------------------------------- */ + +CREATE TABLE FEATURE_DEFS ( + ID BIGSERIAL NOT NULL, + + CODE NAME NOT NULL, + LABEL NAME NOT NULL, + DESCRIPTION DESCRIPTION, + + DS_ID TECH_ID NOT NULL, + + PRIMARY KEY (ID), + CONSTRAINT FK_FEATURE_DEFS_1 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT FEATURE_DEFS_UK_1 UNIQUE(CODE, DS_ID) +); + +CREATE INDEX FEATURE_DEFS_DS_IDX ON FEATURE_DEFS(DS_ID); + +CREATE TABLE FEATURE_VOCABULARY_TERMS ( + ID BIGSERIAL NOT NULL, + + CODE NAME NOT NULL, + SEQUENCE_NUMBER INTEGER NOT NULL, + FD_ID TECH_ID NOT NULL, + + PRIMARY KEY (ID), + CONSTRAINT FK_FEATURE_VOCABULARY_TERMS_1 FOREIGN KEY (FD_ID) REFERENCES FEATURE_DEFS (ID) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE INDEX FEATURE_VOCABULARY_TERMS_FD_IDX ON FEATURE_VOCABULARY_TERMS(FD_ID); + +CREATE TABLE FEATURE_VALUES ( + ID BIGSERIAL NOT NULL, + + -- we use the fixed dimension meters here + Z_in_M REAL, + -- we use the fixed dimension seconds here + T_in_SEC REAL, + -- Serialized 2D matrix with values for each spot. + -- Contains floats which can be NaN. + -- It is never a case that the whole matrix contains NaN - in such a case we save nothing. + -- If feature definition has some connected vocabulary terms then the matrix + -- stores FEATURE_VOCABULARY_TERMS.SEQUENCE_NUMBER of the terms (should be casted from float to int). + -- If the term is null the Float.NaN is stored. + VALUES BYTEA NOT NULL, + + FD_ID TECH_ID NOT NULL, + + PRIMARY KEY (ID), + CONSTRAINT FK_FEATURE_VALUES_1 FOREIGN KEY (FD_ID) REFERENCES FEATURE_DEFS (ID) ON DELETE CASCADE ON UPDATE CASCADE + -- This constaint does not make any sense. Leave it out for now. + -- CONSTRAINT FEATURE_VALUES_UK_1 UNIQUE(Z_in_M, T_in_SEC) +); + +CREATE INDEX FEATURE_VALUES_FD_IDX ON FEATURE_VALUES(FD_ID); +CREATE INDEX FEATURE_VALUES_Z_AND_T_IDX ON FEATURE_VALUES(Z_in_M, T_in_SEC); + + +/* ---------------------------------------------------------------------- */ +/* FUNCTIONS AND TRIGGERS */ +/* ---------------------------------------------------------------------- */ + +CREATE OR REPLACE FUNCTION DELETE_UNUSED_IMAGES() RETURNS trigger AS $$ +BEGIN + delete from images where id = OLD.img_id or id = OLD.thumbnail_id; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER UNUSED_IMAGES AFTER DELETE ON ACQUIRED_IMAGES + FOR EACH ROW EXECUTE PROCEDURE DELETE_UNUSED_IMAGES(); + +------------------------------------------------------------------------------------ +-- Purpose: Create trigger CHANNEL_STACKS_CHECK which checks if both spot_id and dataset.cont_id +-- are both null or not null. +------------------------------------------------------------------------------------ + +CREATE OR REPLACE FUNCTION CHANNEL_STACKS_CHECK() RETURNS trigger AS $$ +DECLARE + v_cont_id CODE; +BEGIN + + select cont_id into v_cont_id from data_sets where id = NEW.ds_id; + + -- Check that if there is no spot than there is no dataset container as well + if v_cont_id IS NULL then + if NEW.spot_id IS NOT NULL then + RAISE EXCEPTION 'Insert/Update of CHANNEL_STACKS failed, as the dataset container is not set, but spot is (spot id = %).',NEW.spot_id; + end if; + else + if NEW.spot_id IS NULL then + RAISE EXCEPTION 'Insert/Update of CHANNEL_STACKS failed, as the dataset container is set (id = %), but spot is not set.',v_cont_id; + end if; + end if; + RETURN NEW; +END; +$$ LANGUAGE 'plpgsql'; + +CREATE TRIGGER CHANNEL_STACKS_CHECK BEFORE INSERT OR UPDATE ON CHANNEL_STACKS + FOR EACH ROW EXECUTE PROCEDURE CHANNEL_STACKS_CHECK(); \ No newline at end of file diff --git a/screening/source/sql/postgresql/012/upload-screening-metadata.sh b/screening/source/sql/postgresql/012/upload-screening-metadata.sh new file mode 100755 index 0000000000000000000000000000000000000000..1a8a1969f1ef9d83fafdeb766696b9c5eef14fe7 --- /dev/null +++ b/screening/source/sql/postgresql/012/upload-screening-metadata.sh @@ -0,0 +1,2 @@ +DB=$1 +psql -U postgres -d openbis_$DB -f data.sql diff --git a/screening/source/sql/postgresql/migration/migration-011-012.sql b/screening/source/sql/postgresql/migration/migration-011-012.sql new file mode 100644 index 0000000000000000000000000000000000000000..4197da7db0dba79e3d371c83c5bcc9516c6d3cb0 --- /dev/null +++ b/screening/source/sql/postgresql/migration/migration-011-012.sql @@ -0,0 +1,22 @@ +-- Migration from 011 to 012 +CREATE DOMAIN CHANNEL_COLOR AS VARCHAR(20) CHECK (VALUE IN ('BLUE', 'GREEN', 'RED', 'RED_GREEN', 'RED_BLUE', 'GREEN_BLUE')); + +ALTER TABLE channels ADD COLUMN color CHANNEL_COLOR; + +update channels upd_ch +set color = + ( select + CASE + WHEN (upd_ch.id - min(id)) % 6 = 0 THEN 'BLUE' + WHEN (upd_ch.id - min(id)) % 6 = 1 THEN 'GREEN' + WHEN (upd_ch.id - min(id)) % 6 = 2 THEN 'RED' + WHEN (upd_ch.id - min(id)) % 6 = 3 THEN 'RED_GREEN' + WHEN (upd_ch.id - min(id)) % 6 = 4 THEN 'RED_BLUE' + WHEN (upd_ch.id - min(id)) % 6 = 5 THEN 'GREEN_BLUE' + END color + from channels cc + where upd_ch.exp_id = cc.exp_id or upd_ch.ds_id = cc.ds_id + group by cc.exp_id, cc.ds_id + ); + +ALTER TABLE channels ALTER COLUMN color SET NOT NULL; diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ChannelColorTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ChannelColorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9f14f9af3b0a3748c5b107cb9ad7941f51e35b8c --- /dev/null +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ChannelColorTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.dss.etl.dataaccess; + +import java.util.Arrays; +import java.util.List; + +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.common.test.AssertionUtil; +import ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.ChannelColor; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelColor; + +/** + * @author Tomasz Pylak + */ +public class ChannelColorTest extends AssertJUnit +{ + @Test + public void testEnumsEqual() + { + List<ChannelColor> values1 = Arrays.asList(ChannelColor.values()); + List<ImageChannelColor> values2 = Arrays.asList(ImageChannelColor.values()); + AssertionUtil.assertEnumsEqual(values1, values2); + } +} diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingQueryDAOTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingQueryDAOTest.java index f4702198da5d214f7a929fb4cb7447410ade5bc5..00ac1faf50d3d2f92d2c2ebd3d56a287f21f4c72 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingQueryDAOTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingQueryDAOTest.java @@ -31,6 +31,7 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import ch.systemsx.cisd.bds.hcs.Location; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelColor; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.AbstractDBTest; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ColorComponent; import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgAcquiredImageDTO; @@ -54,6 +55,8 @@ public class ImagingQueryDAOTest extends AbstractDBTest private static final String CHANNEL_LABEL = "Channel Label"; + private static final ImageChannelColor CHANNEL_COLOR = ImageChannelColor.RED; + private static final int PAGE = 1; private static final int Y_TILE_ROW = 2; @@ -299,6 +302,7 @@ public class ImagingQueryDAOTest extends AbstractDBTest assertEquals("DSCHANNEL", datasetChannel.getCode()); assertEquals(CHANNEL_LABEL, datasetChannel.getLabel()); + assertEquals(CHANNEL_COLOR.name(), datasetChannel.getDbChannelColor()); assertEquals(datasetChannelId, datasetChannel.getId()); assertEquals(datasetChannel, dao.tryGetChannelForDataset(datasetId, "dsChannel")); @@ -308,6 +312,7 @@ public class ImagingQueryDAOTest extends AbstractDBTest ImgChannelDTO experimentChannel = experimentChannels.get(0); assertEquals("EXPCHANNEL", experimentChannel.getCode()); assertEquals(CHANNEL_LABEL, experimentChannel.getLabel()); + assertEquals(CHANNEL_COLOR.name(), experimentChannel.getDbChannelColor()); assertEquals(experimentChannelId, experimentChannel.getId()); assertEquals(experimentChannel, dao.tryGetChannelForExperiment(experimentId, "expChannel")); @@ -400,7 +405,7 @@ public class ImagingQueryDAOTest extends AbstractDBTest { final ImgChannelDTO channel = new ImgChannelDTO(DS_CHANNEL, CHANNEL_DESCRIPTION, WAVELENGTH, datasetId, null, - CHANNEL_LABEL); + CHANNEL_LABEL, CHANNEL_COLOR); return dao.addChannel(channel); } @@ -408,7 +413,7 @@ public class ImagingQueryDAOTest extends AbstractDBTest { final ImgChannelDTO channel = new ImgChannelDTO(EXP_CHANNEL, CHANNEL_DESCRIPTION, WAVELENGTH, null, experimentId, - CHANNEL_LABEL); + CHANNEL_LABEL, CHANNEL_COLOR); return dao.addChannel(channel); } diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java index 3306e9b6d49da7fc4607126ffb6b281278da5b0c..eb2a160d7cbf03b2cfae696c68449ef8f914a765 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java @@ -47,6 +47,7 @@ import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackR import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.RequestedImageSize; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtilTest; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannel; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetParameters; /** @@ -165,7 +166,8 @@ public class ImageChannelsUtilsTest extends AssertJUnit { one(loader).getImageParameters(); ImageDatasetParameters imgParams = new ImageDatasetParameters(); - imgParams.setChannelsCodes(Arrays.asList(CHANNEL)); + imgParams.setChannels(Arrays.asList(new ImageChannel(CHANNEL, CHANNEL, null, + null, null))); will(returnValue(imgParams)); RequestedImageSize requestedSize = diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java index 55da96f177bbdf02f68d05bbf0596163cf87139f..cd6cb792052dee44963a18c47beeed4cf55b6fd4 100644 --- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java +++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java @@ -79,6 +79,8 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IFeatureVecto import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ImageSize; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateImageReference; import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.WellPosition; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannel; +import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelColor; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetParameters; import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants; import ch.systemsx.cisd.openbis.plugin.screening.shared.dto.PlateFeatureValues; @@ -169,7 +171,8 @@ public class DssServiceRpcScreeningTest extends AssertJUnit imageParameters.setTileRowsNum(1); imageParameters.setTileColsNum(2); imageParameters.setDatasetCode(DATASET_CODE); - imageParameters.setChannelsCodes(Arrays.asList(CHANNEL_CODE)); + imageParameters.setChannels(Arrays.asList(new ImageChannel(CHANNEL_CODE, CHANNEL_CODE, + null, null, null))); context.checking(new Expectations() { { @@ -384,7 +387,8 @@ public class DssServiceRpcScreeningTest extends AssertJUnit { one(dao).tryGetChannelForExperimentPermId(EXPERIMENT_PERM_ID, channel); ImgChannelDTO channelDTO = - new ImgChannelDTO("dapi", null, null, new Long(42), null, "dapi"); + new ImgChannelDTO("dapi", null, null, new Long(42), null, "dapi", + ImageChannelColor.BLUE); channelDTO.setSerializedImageTransformerFactory(SerializationUtils .serialize(transformerFactory)); will(returnValue(channelDTO));