Skip to content
Snippets Groups Projects
Commit eb31b4f8 authored by tpylak's avatar tpylak
Browse files

LMS-1645 dynamix: draft support of timepoints in the GUI

SVN: 17466
parent d1e91dc5
No related branches found
No related tags found
No related merge requests found
Showing
with 284 additions and 74 deletions
......@@ -16,6 +16,8 @@
package ch.systemsx.cisd.openbis.plugin.screening.client.web.client;
import java.util.List;
import ch.systemsx.cisd.openbis.generic.client.web.client.IClientService;
import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientService;
import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
......@@ -29,11 +31,13 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GenericTableRow;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LibraryRegistrationInfo;
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.PlateMaterialsSearchCriteria;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
/**
* Service interface for the <i>screening</i> <i>GWT</i> client.
......@@ -98,6 +102,10 @@ public interface IScreeningClientService extends IClientService
public String prepareExportPlateMetadata(TableExportCriteria<GenericTableRow> exportCriteria)
throws UserFailureException;
/** Lists all images for a given well in the given dataset */
public List<ChannelStackImageReference> listChannelStackImages(String datasetCode,
String datastoreCode, WellLocation wellLocation);
/**
* Registers a new library.
*/
......
......@@ -16,6 +16,8 @@
package ch.systemsx.cisd.openbis.plugin.screening.client.web.client;
import java.util.List;
import com.google.gwt.user.client.rpc.AsyncCallback;
import ch.systemsx.cisd.openbis.generic.client.web.client.IClientServiceAsync;
......@@ -29,11 +31,13 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.GenericTableRow;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleParentWithDerived;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LibraryRegistrationInfo;
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.PlateMaterialsSearchCriteria;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
/**
* Service interface for the <i>screening</i> <i>GWT</i> client.
......@@ -83,6 +87,13 @@ public interface IScreeningClientServiceAsync extends IClientServiceAsync
public void prepareExportPlateMetadata(TableExportCriteria<GenericTableRow> exportCriteria,
AsyncCallback<String> callback);
/**
* @see IScreeningClientService#listChannelStackImages
*/
public void listChannelStackImages(String datasetCode, String datastoreCode,
WellLocation wellLocation,
AsyncCallback<List<ChannelStackImageReference>> abstractAsyncCallback);
/**
* @see IScreeningClientService#registerLibrary(LibraryRegistrationInfo)
*/
......
......@@ -32,6 +32,7 @@ import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Widget;
import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.LinkRenderer;
import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.renderers.SimpleImageHtmlRenderer;
......@@ -44,6 +45,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.D
import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningViewContext;
import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.ChannelChooser.DefaultChannelState;
import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.ChannelChooser.IChanneledViewerFactory;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetImagesReference;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
......@@ -59,53 +61,79 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateMaterials
*/
public class WellContentDialog extends Dialog
{
private static final int ONE_IMAGE_WIDTH_PX = 200;
private static final int ONE_IMAGE_HEIGHT_PX = 120;
private static final int NO_IMAGES_DIALOG_WIDTH_PX = 300;
private static final int NO_IMAGES_DIALOG_HEIGHT_PX = 160;
public static void showContentDialog(final WellData wellData, DefaultChannelState channelState,
final ScreeningViewContext viewContext)
{
final LayoutContainer container = new LayoutContainer();
container.setLayout(new RowLayout());
container.setScrollMode(Scroll.AUTO);
final WellContentDialog contentDialog =
new WellContentDialog(wellData.tryGetMetadata(), getExperiment(wellData),
viewContext);
LayoutContainer descriptionContainer = contentDialog.createContentDescription();
container.add(descriptionContainer);
int dialogWidth;
int dialogHeight;
final WellImages images = wellData.tryGetImages();
if (images != null)
final WellImages imagesOrNull = wellData.tryGetImages();
if (imagesOrNull != null && imagesOrNull.isMultidimensional())
{
int imgW = 200;
int imgH = 120;
LayoutContainer imageViewer =
createImageViewer(images, channelState, viewContext, imgW, imgH);
container.add(imageViewer);
dialogWidth = getDialogWidth(images, imgW);
dialogHeight = getDialogHeight(images, imgH);
showTimepointImageViewer(contentDialog, wellData, imagesOrNull, channelState,
viewContext);
} else
{
dialogWidth = 300;
dialogHeight = 160;
if (imagesOrNull != null)
{
LayoutContainer imageViewer =
createImageViewer(imagesOrNull, channelState, viewContext);
contentDialog.addComponent(imageViewer);
}
contentDialog.setupContentAndShow(wellData);
}
String title = "Well Content: " + wellData.getWellDescription();
setupContentAndShow(contentDialog, container, dialogWidth, dialogHeight, title);
}
private static int getDialogWidth(final WellImages images, int imgW)
private static void showTimepointImageViewer(final WellContentDialog contentDialog,
final WellData wellData, final WellImages images,
final DefaultChannelState channelState, final ScreeningViewContext viewContext)
{
viewContext.getService().listChannelStackImages(images.getDatasetCode(),
images.getDatastoreCode(), images.getWellLocation(),
new AbstractAsyncCallback<List<ChannelStackImageReference>>(viewContext)
{
@Override
protected void process(List<ChannelStackImageReference> channelStackImages)
{
LayoutContainer imageViewer =
createTimepointImageViewer(channelStackImages, images,
channelState, viewContext);
contentDialog.addComponent(imageViewer);
contentDialog.setupContentAndShow(wellData);
}
});
}
private static LayoutContainer createTimepointImageViewer(
List<ChannelStackImageReference> channelStackImages, WellImages images,
DefaultChannelState channelState, IViewContext<?> viewContext)
{
System.out.println("result: " + channelStackImages);
// TODO 2010-08-16, Tomasz Pylak: implement me!
return new LayoutContainer();
}
private static int getDialogWidth(final WellImages images)
{
float imageSizeMultiplyFactor = getImageSizeMultiplyFactor(images);
return (int) (imgW * imageSizeMultiplyFactor) * images.getTileColsNum() + 100;
return (int) (ONE_IMAGE_WIDTH_PX * imageSizeMultiplyFactor) * images.getTileColsNum() + 100;
}
private static int getDialogHeight(final WellImages images, int imgH)
private static int getDialogHeight(final WellImages images)
{
float imageSizeMultiplyFactor = getImageSizeMultiplyFactor(images);
return Math
.max((int) (imgH * imageSizeMultiplyFactor) * images.getTileRowsNum() + 100, 300);
return Math.max((int) (ONE_IMAGE_HEIGHT_PX * imageSizeMultiplyFactor)
* images.getTileRowsNum() + 100, 300);
}
private static SingleExperimentSearchCriteria getExperiment(WellData wellData)
......@@ -129,25 +157,50 @@ public class WellContentDialog extends Dialog
private final ScreeningViewContext viewContext;
private final LayoutContainer dialogContent;
private WellContentDialog(WellMetadata metadataOrNull,
SingleExperimentSearchCriteria experiment, ScreeningViewContext viewContext)
{
this.metadataOrNull = metadataOrNull;
this.experiment = experiment;
this.viewContext = viewContext;
this.dialogContent = new LayoutContainer();
dialogContent.setLayout(new RowLayout());
dialogContent.setScrollMode(Scroll.AUTO);
LayoutContainer descriptionContainer = createContentDescription();
dialogContent.add(descriptionContainer);
}
private static void setupContentAndShow(Dialog dialog, Widget content, int width, int height,
String title)
public void addComponent(LayoutContainer component)
{
dialog.setHeading(title);
dialog.setLayout(new FitLayout());
dialog.setScrollMode(Scroll.AUTO);
dialog.setHideOnButtonClick(true);
dialog.add(content);
dialog.setWidth(width);
dialog.setHeight(height);
dialog.show();
dialogContent.add(component);
}
private void setupContentAndShow(WellData wellData)
{
String title = "Well Content: " + wellData.getWellDescription();
setHeading(title);
setLayout(new FitLayout());
setScrollMode(Scroll.AUTO);
setHideOnButtonClick(true);
add(dialogContent);
final WellImages imagesOrNull = wellData.tryGetImages();
if (imagesOrNull != null)
{
setWidth(getDialogWidth(imagesOrNull));
setHeight(getDialogHeight(imagesOrNull));
} else
{
setWidth(NO_IMAGES_DIALOG_WIDTH_PX);
setHeight(NO_IMAGES_DIALOG_HEIGHT_PX);
}
show();
}
private LayoutContainer createContentDescription()
......@@ -234,8 +287,7 @@ public class WellContentDialog extends Dialog
// -------------
private static LayoutContainer createImageViewer(final WellImages images,
DefaultChannelState channelState, final IViewContext<?> viewContext,
final int imageWidth, final int imageHeight)
DefaultChannelState channelState, final IViewContext<?> viewContext)
{
final float imageSizeMultiplyFactor = getImageSizeMultiplyFactor(images);
final IChanneledViewerFactory viewerFactory = new IChanneledViewerFactory()
......@@ -244,8 +296,8 @@ public class WellContentDialog extends Dialog
{
String sessionId = getSessionId(viewContext);
return createTilesGrid(images, channel, sessionId,
(int) (imageWidth * imageSizeMultiplyFactor),
(int) (imageHeight * imageSizeMultiplyFactor));
(int) (ONE_IMAGE_WIDTH_PX * imageSizeMultiplyFactor),
(int) (ONE_IMAGE_HEIGHT_PX * imageSizeMultiplyFactor));
}
};
return ChannelChooser.createViewerWithChannelChooser(viewerFactory, channelState, images
......@@ -302,20 +354,31 @@ public class WellContentDialog extends Dialog
return container;
}
/** generates URL of an image on Data Store server */
// TODO 2010-08-16, Tomasz Pylak: implement and use me!!!!
@SuppressWarnings("unused")
private static String createDatastoreImageUrl(WellImages images, String channel,
ChannelStackImageReference channelStackRef, int width, int height, String sessionID)
{
URLMethodWithParameters methodWithParameters =
createBasicImageURL(images, channel, sessionID);
methodWithParameters
.addParameter("channelStackId", channelStackRef.getChannelStackTechId());
String linkURL = methodWithParameters.toString();
methodWithParameters.addParameter("mode", "thumbnail" + width + "x" + height);
String imageURL = methodWithParameters.toString();
return SimpleImageHtmlRenderer.createEmbededImageHtml(imageURL, linkURL);
}
/** generates URL of an image on Data Store server */
private static String createDatastoreImageUrl(WellImages images, String channel, int tileRow,
int tileCol, int width, int height, String sessionID)
{
URLMethodWithParameters methodWithParameters =
new URLMethodWithParameters(images.getDownloadUrl() + "/"
+ ScreeningConstants.DATASTORE_SCREENING_SERVLET_URL);
methodWithParameters.addParameter("sessionID", sessionID);
methodWithParameters.addParameter("dataset", images.getDatasetCode());
methodWithParameters.addParameter("channel", channel);
if (channel.equals(ScreeningConstants.MERGED_CHANNELS))
{
methodWithParameters.addParameter("mergeChannels", "true");
}
createBasicImageURL(images, channel, sessionID);
methodWithParameters.addParameter("wellRow", images.getWellLocation().getRow());
methodWithParameters.addParameter("wellCol", images.getWellLocation().getColumn());
methodWithParameters.addParameter("tileRow", tileRow);
......@@ -327,6 +390,22 @@ public class WellContentDialog extends Dialog
return SimpleImageHtmlRenderer.createEmbededImageHtml(imageURL, linkURL);
}
private static URLMethodWithParameters createBasicImageURL(WellImages images, String channel,
String sessionID)
{
URLMethodWithParameters methodWithParameters =
new URLMethodWithParameters(images.getDownloadUrl() + "/"
+ ScreeningConstants.DATASTORE_SCREENING_SERVLET_URL);
methodWithParameters.addParameter("sessionID", sessionID);
methodWithParameters.addParameter("dataset", images.getDatasetCode());
methodWithParameters.addParameter("channel", channel);
if (channel.equals(ScreeningConstants.MERGED_CHANNELS))
{
methodWithParameters.addParameter("mergeChannels", "true");
}
return methodWithParameters;
}
private static String getSessionId(IViewContext<?> viewContext)
{
return viewContext.getModel().getSessionContext().getSessionID();
......
......@@ -50,7 +50,8 @@ class WellData
DatasetImagesReference images = plateImages.tryGetImages();
if (images != null)
{
return new WellImages(images.getImageParameters(), images.getDownloadUrl(), location);
return new WellImages(images.getImageParameters(), images.getDatastoreCode(), images
.getDownloadUrl(), location);
} else
{
return null;
......
......@@ -37,6 +37,8 @@ public class WellImages
private final String datasetCode;
private final String datastoreCode;
private final String downloadUrl;
private final WellLocation location;
......@@ -44,20 +46,23 @@ public class WellImages
// has timepoints or depth stack?
private final boolean isMultidimensional;
public WellImages(PlateImageParameters imageParams, String downloadUrl, WellLocation location)
public WellImages(PlateImageParameters imageParams, String datastoreCode, String downloadUrl,
WellLocation location)
{
this.tileRowsNum = imageParams.getTileRowsNum();
this.tileColsNum = imageParams.getTileColsNum();
this.channelsNames = imageParams.getChannelsNames();
this.isMultidimensional = imageParams.isMultidimensional();
this.datasetCode = imageParams.getDatasetCode();
this.datastoreCode = datastoreCode;
this.downloadUrl = downloadUrl;
this.location = location;
}
public WellImages(DatasetImagesReference images, WellLocation location)
{
this(images.getImageParameters(), images.getDownloadUrl(), location);
this(images.getImageParameters(), images.getDatastoreCode(), images.getDownloadUrl(),
location);
}
public int getTileRowsNum()
......@@ -90,6 +95,11 @@ public class WellImages
return datasetCode;
}
public String getDatastoreCode()
{
return datastoreCode;
}
public boolean isMultidimensional()
{
return isMultidimensional;
......
......@@ -16,6 +16,7 @@
package ch.systemsx.cisd.openbis.plugin.screening.client.web.server;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
......@@ -57,12 +58,14 @@ import ch.systemsx.cisd.openbis.plugin.screening.BuildAndEnvironmentInfo;
import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientService;
import ch.systemsx.cisd.openbis.plugin.screening.shared.IScreeningServer;
import ch.systemsx.cisd.openbis.plugin.screening.shared.ResourceNames;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LibraryRegistrationInfo;
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.PlateMaterialsSearchCriteria;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
/**
* The {@link IScreeningClientService} implementation.
......@@ -280,4 +283,11 @@ public final class ScreeningClientService extends AbstractClientService implemen
final String sessionToken = getSessionToken();
return server.getVocabulary(sessionToken, ScreeningConstants.PLATE_GEOMETRY);
}
public List<ChannelStackImageReference> listChannelStackImages(String datasetCode,
String datastoreCode, WellLocation wellLocation)
{
// TODO 2010-08-16, Tomasz Pylak: implement me!!!!!!!!!!!!
return new ArrayList<ChannelStackImageReference>();
}
}
/*
* 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 com.google.gwt.user.client.rpc.IsSerializable;
/**
* Describes one channel stack which has images for many channels and a specific tile (and
* optionally timepoint and/or depth).
*
* @author Tomasz Pylak
*/
public class ChannelStackImageReference implements IsSerializable
{
// technical id in the imaging db
private long channelStackTechId;
private int tileRow, tileCol;
private Float tOrNull, zOrNull;
// GWT only
@SuppressWarnings("unused")
private ChannelStackImageReference()
{
}
public ChannelStackImageReference(long channelStackTechId, int tileRow, int tileCol,
Float orNull, Float orNull2)
{
this.channelStackTechId = channelStackTechId;
this.tileRow = tileRow;
this.tileCol = tileCol;
tOrNull = orNull;
zOrNull = orNull2;
}
public long getChannelStackTechId()
{
return channelStackTechId;
}
public int getTileRow()
{
return tileRow;
}
public int getTileCol()
{
return tileCol;
}
public Float tryGetTimepoint()
{
return tOrNull;
}
public Float tryGetDepth()
{
return zOrNull;
}
@Override
public String toString()
{
String desc = "";
if (tOrNull != null)
{
desc += ", t=" + tOrNull;
}
if (zOrNull != null)
{
desc += ", z=" + zOrNull;
}
return "tile [" + tileRow + "," + tileCol + "]" + desc;
}
}
......@@ -47,6 +47,11 @@ public class DatasetImagesReference implements IsSerializable
this.imageParameters = imageParameters;
}
public String getDatastoreCode()
{
return dataset.getDatastoreCode();
}
public String getDownloadUrl()
{
return dataset.getDownloadUrl();
......
......@@ -33,32 +33,25 @@ public interface IImagingQueryDAO extends TransactionQuery
public static final int FETCH_SIZE = 1000;
public static final String SQL_IMAGE =
", CHANNEL_STACKS cs, SPOTS s "
"select i.* from CHANNEL_STACKS, SPOTS, ACQUIRED_IMAGES, IMAGES as i "
+ "where "
// where acquired_images.channel.id = ?{channelId}
// and acquired_images.channel_stack.dataset.id = ?{datasetId}
+ "ai.CHANNEL_ID = ?{1} and cs.DS_ID = ?{2} and "
// and acquired_images.channel_stack.x = tileX
// and acquired_images.channel_stack.y = tileY
// and acquired_images.channel_stack.spot.x = wellX
// and acquired_images.channel_stack.spot.y = wellY
+ "cs.x = ?{3.x} and cs.y = ?{3.y} and s.x = ?{4.x} and s.y = ?{4.y} and "
+ "ACQUIRED_IMAGES.CHANNEL_ID = ?{1} and CHANNEL_STACKS.DS_ID = ?{2} and "
+ "CHANNEL_STACKS.x = ?{3.x} and CHANNEL_STACKS.y = ?{3.y} and "
+ "SPOTS.x = ?{4.x} and SPOTS.y = ?{4.y} and "
// joins
+ "ai.CHANNEL_STACK_ID = cs.ID and cs.SPOT_ID = s.ID "
// TODO 2010-07-27, Tomasz Pylak: select the first image if there are many time
// points or depth scans.
// Should be deleted when support for time points will be added!
+ "order by cs.T_in_SEC, cs.Z_in_M limit 1";
// select acquired_images.images.* from acquired_images
@Select("select i.* " + "from ACQUIRED_IMAGES as ai join IMAGES as i on ai.IMG_ID = i.ID "
+ SQL_IMAGE)
+ "ACQUIRED_IMAGES.CHANNEL_STACK_ID = CHANNEL_STACKS.ID and "
+ "CHANNEL_STACKS.SPOT_ID = SPOTS.ID ";
public static final String SQL_NO_MULTIDIMENTIONAL_DATA_COND =
// " and CHANNEL_STACKS.T_in_SEC is NULL and CHANNEL_STACKS.Z_in_M is NULL";
" order by CHANNEL_STACKS.T_in_SEC, CHANNEL_STACKS.Z_in_M limit 1";
@Select(SQL_IMAGE + " and ACQUIRED_IMAGES.IMG_ID = i.ID " + SQL_NO_MULTIDIMENTIONAL_DATA_COND)
public ImgImageDTO tryGetImage(long channelId, long datasetId, Location tileLocation,
Location wellLocation);
// select acquired_images.thumbnail.* from acquired_images
@Select("select i.* "
+ "from ACQUIRED_IMAGES as ai join IMAGES as i on ai.THUMBNAIL_ID = i.ID " + SQL_IMAGE)
@Select(SQL_IMAGE + " and ACQUIRED_IMAGES.THUMBNAIL_ID = i.ID "
+ SQL_NO_MULTIDIMENTIONAL_DATA_COND)
public ImgImageDTO tryGetThumbnail(long channelId, long datasetId, Location tileLocation,
Location wellLocation);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment