Skip to content
Snippets Groups Projects
Commit cb8abe1f authored by felmer's avatar felmer
Browse files

LMS-1888 API extended

SVN: 18876
parent 8835f531
No related branches found
No related tags found
No related merge requests found
Showing with 392 additions and 13 deletions
......@@ -340,6 +340,19 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences,
boolean convertToPng)
{
Size thumbnailSizeOrNull = null;
return loadImages(sessionToken, imageReferences, thumbnailSizeOrNull, convertToPng);
}
public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences,
ImageSize thumbnailSizeOrNull)
{
return loadImages(sessionToken, imageReferences, convertToSize(thumbnailSizeOrNull), true);
}
public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences,
Size sizeOrNull, boolean convertToPng)
{
checkDatasetsAuthorizationForIDatasetIdentifier(sessionToken, imageReferences);
final Map<String, IHCSImageDatasetLoader> imageLoadersMap =
......@@ -351,12 +364,13 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
imageLoadersMap.get(imageReference.getDatasetCode());
assert imageAccessor != null : "imageAccessor not found for: " + imageReference;
IContent content =
tryGetImageContent(imageAccessor, imageReference, null, convertToPng);
tryGetImageContent(imageAccessor, imageReference, sizeOrNull, convertToPng);
imageContents.add(content);
}
return new ConcatenatedContentInputStream(true, imageContents);
}
public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences)
{
return loadImages(sessionToken, imageReferences, true);
......@@ -370,11 +384,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
IHCSImageDatasetLoader imageAccessor = createImageLoader(datasetCode, rootDir);
List<PlateImageReference> imageReferences =
createPlateImageReferences(imageAccessor, dataSetIdentifier, wellPositions, channel);
Size size = null;
if (thumbnailSizeOrNull != null)
{
size = new Size(thumbnailSizeOrNull.getWidth(), thumbnailSizeOrNull.getHeight());
}
Size size = convertToSize(thumbnailSizeOrNull);
List<IContent> imageContents = new ArrayList<IContent>();
for (PlateImageReference imageReference : imageReferences)
{
......@@ -384,6 +394,15 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
return new ConcatenatedContentInputStream(true, imageContents);
}
public List<PlateImageReference> listPlateImageReferences(String sessionToken,
IDatasetIdentifier dataSetIdentifier, List<WellPosition> wellPositions, String channel)
{
String datasetCode = dataSetIdentifier.getDatasetCode();
File rootDir = getRootDirectoryForDataSet(datasetCode);
IHCSImageDatasetLoader imageAccessor = createImageLoader(datasetCode, rootDir);
return createPlateImageReferences(imageAccessor, dataSetIdentifier, wellPositions, channel);
}
public void saveImageTransformerFactory(String sessionToken,
List<IDatasetIdentifier> dataSetIdentifiers, String channel,
IImageTransformerFactory transformerFactory)
......@@ -555,7 +574,16 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
{
return new Location(wellPosition.getWellColumn(), wellPosition.getWellRow());
}
private Size convertToSize(ImageSize thumbnailSizeOrNull)
{
if (thumbnailSizeOrNull == null)
{
return null;
}
return new Size(thumbnailSizeOrNull.getWidth(), thumbnailSizeOrNull.getHeight());
}
private IHCSImageDatasetLoader createImageLoader(String datasetCode)
{
File datasetRoot = getRootDirectoryForDataSet(datasetCode);
......
......@@ -100,6 +100,14 @@ public class DssServiceRpcScreeningLogger extends AbstractServerLogger implement
return null;
}
public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences,
ImageSize thumbnailSizeOrNull)
{
logAccess(sessionToken, "load_images", "IMAGE_REFERENCES(%s) SIZE(%s)", imageReferences,
thumbnailSizeOrNull);
return null;
}
public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences)
{
logAccess(sessionToken, "load_images", "IMAGE_REFERENCES(%s)", imageReferences);
......@@ -114,6 +122,14 @@ public class DssServiceRpcScreeningLogger extends AbstractServerLogger implement
return null;
}
public List<PlateImageReference> listPlateImageReferences(String sessionToken,
IDatasetIdentifier dataSetIdentifier, List<WellPosition> wellPositions, String channel)
{
logAccess(sessionToken, "list_plate_image_references", "DATA_SET(%s) CHANNEL(%s)",
dataSetIdentifier, channel);
return null;
}
public void saveImageTransformerFactory(String sessionToken,
List<IDatasetIdentifier> dataSetIdentifiers, String channel,
IImageTransformerFactory transformerFactory)
......
......@@ -133,6 +133,24 @@ public interface IDssServiceRpcScreening extends IRpcService
@AuthorizationGuard(guardClass = DatasetIdentifierPredicate.class) List<PlateImageReference> imageReferences,
boolean convertToPng);
/**
* Provide images (PNG encoded) for a given list of image references (given by data set code,
* well position, channel and tile). The result is encoded into one stream, which consist of
* multiple blocks in a format: (<block-size><block-of-bytes>)*, where block-size is the block
* size in bytes encoded as one long number. The number of blocks is equal to the number of
* specified references and the order of blocks corresponds to the order of image references. If
* <code>size</code> is specified, the images will be scaled conserving aspect ratio in order to
* fit into specified size. Otherwise images of original size are delivered.
*
* @since 1.4
*/
@MinimalMinorVersion(4)
@DataSetAccessGuard
public InputStream loadImages(
String sessionToken,
@AuthorizationGuard(guardClass = DatasetIdentifierPredicate.class) List<PlateImageReference> imageReferences,
ImageSize size);
/**
* Provide images for a given list of image references (given by data set code, well position,
* channel and tile). The result is encoded into one stream, which consist of multiple blocks in
......@@ -147,11 +165,10 @@ public interface IDssServiceRpcScreening extends IRpcService
@AuthorizationGuard(guardClass = DatasetIdentifierPredicate.class) List<PlateImageReference> imageReferences);
/**
* Provide images for a specified data set, a list of well positions (empty list means all
* wells), a channel, and an optional thumb nail size. Images of all tiles are delivered. If
* thumb nail size isn't specified the original image is delivered otherwise a thumb nail image
* with same aspect ratio as the original image but which fits into specified size will be
* delivered.
* Provide images for specified data set, list of well positions (empty list means all wells),
* channel, and optional thumb nail size. Images of all tiles are delivered. If thumb nail size
* isn't specified the original image is delivered otherwise a thumb nail image with same aspect
* ratio as the original image but which fits into specified size will be delivered.
* <p>
* The result is encoded into one stream, which consist of multiple blocks in a format:
* (<block-size><block-of-bytes>)*, where block-size is the block size in bytes encoded as one
......@@ -167,7 +184,18 @@ public interface IDssServiceRpcScreening extends IRpcService
String sessionToken,
@AuthorizationGuard(guardClass = SingleDataSetIdentifierPredicate.class) IDatasetIdentifier dataSetIdentifier,
List<WellPosition> wellPositions, String channel, ImageSize thumbnailSizeOrNull);
/**
* Lists plate image references for specified data set, list of well positions (empty list means
* all wells), and channel.
*/
@MinimalMinorVersion(4)
@DataSetAccessGuard
public List<PlateImageReference> listPlateImageReferences(
String sessionToken,
@AuthorizationGuard(guardClass = SingleDataSetIdentifierPredicate.class) IDatasetIdentifier dataSetIdentifier,
List<WellPosition> wellPositions, String channel);
/**
* Saves the specified transformer factory for the specified channel and the experiment to
* which the specified data sets belong.
......
/*
* 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.client.api.v1;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateImageReference;
/**
* Interface of classes handling bytes PNG-encoded plate images.
*
* @author Franz-Josef Elmer
*/
public interface IPlateImageHandler
{
/**
* Handles specified image file bytes for specified plate image reference.
*/
public void handlePlateImage(PlateImageReference plateImageReference, byte[] imageFileBytes);
}
......@@ -265,6 +265,19 @@ public interface IScreeningOpenbisServiceFacade
List<WellPosition> wellPositions, String channel, ImageSize thumbnailSizeOrNull)
throws IOException;
/**
* Loads PNG-encoded images for specified data set, list of well positions (empty
* list means all wells), channel, and optional thumb nail size. Images of all tiles are
* delivered. If thumb nail size isn't specified the original image is delivered otherwise a
* thumb nail image with same aspect ratio as the original image but which fits into specified
* size will be delivered.
*
* @param plateImageHandler Handles delivered images.
*/
public void loadImages(IDatasetIdentifier datasetIdentifier, List<WellPosition> wellPositions,
String channel, ImageSize thumbnailSizeOrNull, IPlateImageHandler plateImageHandler)
throws IOException;
/**
* Saves the specified transformer factory for the specified channel and the experiment to
* which the specified data sets belong.
......
/*
* 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.client.api.v1;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.text.JTextComponent;
import org.apache.log4j.PropertyConfigurator;
import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.IDatasetIdentifier;
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;
/**
* A test class which shows how to use API.
*
* @author Tomasz Pylak
*/
public class ScreeningClientApiTester
{
private static final class Form extends JPanel
{
private final JPanel panel;
private final Component parent;
private final String title;
Form(Component parent, String title)
{
super(new BorderLayout());
this.parent = parent;
this.title = title;
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
add(panel, BorderLayout.CENTER);
}
JTextComponent createTextField(String fieldName, int width, boolean passwordField)
{
JTextComponent result = passwordField ? new JPasswordField(width) : new JTextField(width);
addField(fieldName, result);
return result;
}
void addField(String fieldName, JComponent field)
{
JPanel fieldPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel(fieldName + ":");
Dimension preferredSize = label.getPreferredSize();
label.setPreferredSize(new Dimension(100, preferredSize.height));
fieldPanel.add(label, BorderLayout.WEST);
fieldPanel.add(field, BorderLayout.CENTER);
panel.add(fieldPanel);
}
void showForm()
{
JOptionPane.showMessageDialog(parent, this, title, JOptionPane.QUESTION_MESSAGE);
}
}
private static final class TesterFrame extends JFrame
{
private static final long serialVersionUID = 1L;
private IScreeningOpenbisServiceFacade facade;
private JPanel content;
TesterFrame()
{
setTitle("Screening API Tester");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
content = new JPanel();
content.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(content);
contentPane.add(scrollPane);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu callApiMenu = new JMenu("Call API");
menuBar.add(callApiMenu);
JMenuItem loadImagesByDataSetMenu = new JMenuItem("Load images by data set code");
callApiMenu.add(loadImagesByDataSetMenu);
loadImagesByDataSetMenu.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
loadImagesByDataSetCode();
}
});
}
void setUp(String[] args)
{
setVisible(true);
if (args.length == 3)
{
facade = ScreeningOpenbisServiceFacadeFactory.tryCreate(args[0], args[1], args[2]);
} else
{
Form form = new Form(this, "Connection to openBIS");
JTextField url = new JTextField(20);
JTextField user = new JTextField(20);
JTextField password = new JPasswordField(20);
form.addField("Base URL", url);
form.addField("User ID", user);
form.addField("Password", password);
form.showForm();
facade = ScreeningOpenbisServiceFacadeFactory.tryCreate(user.getText(), user.getText(), url.getText());
if (facade == null)
{
throw new RuntimeException("Couldn't connect openBIS.");
}
JOptionPane.showMessageDialog(this, "Successfully connected to openBIS.");
}
}
private void loadImagesByDataSetCode()
{
Form form = new Form(this, "Parameters for Loading Images by Data Set");
JTextComponent dataSetField = form.createTextField("Data Set", 20, false);
JTextComponent wellsField = form.createTextField("Wells", 20, false);
JTextComponent channelField = form.createTextField("Channel", 20, false);
form.showForm();
String dataSetCode = dataSetField.getText();
List<IDatasetIdentifier> datasetIdentifiers = facade.getDatasetIdentifiers(Arrays.asList(dataSetCode));
if (datasetIdentifiers.isEmpty())
{
JOptionPane.showMessageDialog(this, "Unkown data set: " + dataSetCode);
}
List<WellPosition> wellPositions = WellPosition.parseWellPositions(wellsField.getText());
try
{
content.removeAll();
final JPanel imagePanel = new JPanel();
imagePanel.setLayout(new BoxLayout(imagePanel, BoxLayout.Y_AXIS));
content.add(imagePanel, BorderLayout.CENTER);
facade.loadImages(datasetIdentifiers.get(0), wellPositions, channelField.getText(), new ImageSize(
200, 100), new IPlateImageHandler()
{
public void handlePlateImage(PlateImageReference plateImageReference,
byte[] imageFileBytes)
{
System.out.println(new Date() + " handle " + plateImageReference);
JLabel image =
new JLabel(plateImageReference.toString(), new ImageIcon(
imageFileBytes), SwingConstants.LEFT);
imagePanel.add(image);
validate(imagePanel);
}
});
} catch (Exception ex)
{
ex.printStackTrace();
JOptionPane.showMessageDialog(this, ex.toString());
}
}
private void validate(JComponent component)
{
component.invalidate();
getContentPane().validate();
}
}
public static void main(String[] args) throws IOException
{
configureLogging();
TesterFrame testerFrame = new TesterFrame();
try
{
testerFrame.setUp(args);
} catch (Throwable ex)
{
ex.printStackTrace();
JOptionPane.showMessageDialog(testerFrame, ex.toString());
}
}
private static void configureLogging()
{
Properties props = new Properties();
props.put("log4j.appender.STDOUT", "org.apache.log4j.ConsoleAppender");
props.put("log4j.appender.STDOUT.layout", "org.apache.log4j.PatternLayout");
props.put("log4j.appender.STDOUT.layout.ConversionPattern", "%d %-5p [%t] %c - %m%n");
props.put("log4j.rootLogger", "INFO, STDOUT");
PropertyConfigurator.configure(props);
}
}
......@@ -566,6 +566,35 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa
return result;
}
public void loadImages(IDatasetIdentifier dataSetIdentifier, List<WellPosition> wellPositions,
String channel, ImageSize thumbnailSizeOrNull, IPlateImageHandler plateImageHandler)
throws IOException
{
DssServiceRpcScreeningHolder dssServiceHolder =
dssServiceCache.createDssService(dataSetIdentifier.getDatastoreServerUrl());
IDssServiceRpcScreening service = dssServiceHolder.getService();
List<PlateImageReference> plateImageReferences =
service.listPlateImageReferences(sessionToken, dataSetIdentifier, wellPositions,
channel);
InputStream stream =
service.loadImages(sessionToken, plateImageReferences, thumbnailSizeOrNull);
ConcatenatedFileOutputStreamWriter imagesWriter =
new ConcatenatedFileOutputStreamWriter(stream);
int index = 0;
long size;
do
{
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
size = imagesWriter.writeNextBlock(outputStream);
if (size > 0)
{
plateImageHandler.handlePlateImage(plateImageReferences.get(index),
outputStream.toByteArray());
}
index++;
} while (size >= 0);
}
public void saveImageTransformerFactory(List<IDatasetIdentifier> dataSetIdentifiers, String channel,
IImageTransformerFactory transformerFactory)
{
......
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