Note
This documentation is for OMERO 5.2. This version is now in maintenance mode and will only be updated in the event of critical bugs or security concerns. OMERO 5.3 is expected before the end of 2016.
Using the Ice Java language mapping from ZeroC, OMERO provides access to your data within an OMERO.blitz server from Java code.
To make use of the OMERO Java API and interact with OMERO.blitz from your code, a client application needs the Java bindings available on the classpath.
The required .jar files can be obtained in a number of ways:
To access all the functionality available in omero_client.jar or to use the importer, you will need more jar files. To see all the current requirements, take a look at the builds on jenkins, or alternatively examine the dependencies in the ivy.xml files (e.g. components/insight/ivy.xml)
LoginCredentials cred = new LoginCredentials(userName, password, host, port);
// Alternative using args array:
// args = new String[] { "--omero.host=" + hostName, "--omero.port=" + port,
// "--omero.user=" + userName, "--omero.pass=" + password };
// LoginCredentials cred = new LoginCredentials(args);
//Create a simple Logger object which just writes
//to System.out or System.err
Logger simpleLogger = new SimpleLogger();
Gateway gateway = new Gateway(simpleLogger);
ExperimenterData user = gateway.connect(cred);
//for every subsequent call to the server you'll need the
//SecurityContext for a certain group; in this case create
//a SecurityContext for the user's default group.
SecurityContext ctx = new SecurityContext(user.getGroupId());
gateway.disconnect();
The BrowseFacility offers methods for browsing within the data hierarchy. A list of examples follows, indicating how to load Project, Dataset, Screen, etc.
If a Project contains Datasets, the Datasets will automatically be loaded.
BrowseFacility browse = gateway.getFacility(BrowseFacility.class);
Collection<ProjectData> projects = browse.getProjects(ctx);
Iterator<ProjectData> i = projects.iterator();
ProjectData project;
Set<DatasetData> datasets;
Iterator<DatasetData> j;
DatasetData dataset;
while (i.hasNext()) {
project = i.next();
String name = projet.getName();
long id = project.getId();
datasets = project.getDatasets();
j = datasets.iterator();
while (j.hasNext()) {
dataset = j.next();
// Do something here
// If images loaded.
// dataset.getImages();
}
}
BrowseFacility browse = gateway.getFacility(BrowseFacility.class);
Collection<DatasetData> datasets = browse.getDatasets(ctx);
Iterator<DatasetData> i = datasets.iterator();
DatasetData dataset;
Set<ImageData> images;
Iterator<ImageData> j;
ImageData image;
while (i.hasNext()) {
dataset = i.next();
images = dataset.getImages();
j = images.iterator();
while (j.hasNext()) {
image = j.next();
//Do something
}
}
BrowseFacility browse = gateway.getFacility(BrowseFacility.class);
Collection<ImageData> images = browse.getImagesForDatasets(ctx, Arrays.asList(datasetId));
Iterator<ImageData> j = images.iterator();
ImageData image;
while (j.hasNext()) {
image = j.next();
// Do something
}
BrowseFacility browse = gateway.getFacility(BrowseFacility.class);
ImageData image = browse.getImage(ctx, imageId);
The model is as follows: Image-Pixels i.e. to access valuable data about the image you need to use the pixels object. We now only support one set of pixels per image (it used to be more!).
PixelsData pixels = image.getDefaultPixels();
int sizeZ = pixels.getSizeZ(); // The number of z-sections.
int sizeT = pixels.getSizeT(); // The number of timepoints.
int sizeC = pixels.getSizeC(); // The number of channels.
int sizeX = pixels.getSizeX(); // The number of pixels along the X-axis.
int sizeY = pixels.getSizeY(); // The number of pixels along the Y-axis.
Note that the wells are not loaded.
BrowseFacility browse = gateway.getFacility(BrowseFacility.class);
Collection<ScreenData> screens = browse.getScreens(ctx);
Iterator<ScreenData> i = screens.iterator();
ScreenData screen;
Set<PlateData> plates;
Iterator<PlateData> j;
PlateData plate;
while (i.hasNext()) {
screen = i.next();
plates = screen.getPlates();
j = plates.iterator();
while (j.hasNext()) {
plate = j.next();
}
}
Given a plate ID, load the wells.
BrowseFacility browse = gateway.getFacility(BrowseFacility.class);
Collection<WellData> wells = browse.getWells(ctx, plateId);
Iterator<WellData> i = wells.iterator();
WellData well;
while (i.hasNext()) {
well = i.next();
//Do something
}
This is useful when you need for example the pixels intensity.
RawDataFacility rdf = gateway.getFacility(RawDataFacility.class);
PixelsData pixels = image.getDefaultPixels();
int sizeZ = pixels.getSizeZ();
int sizeT = pixels.getSizeT();
int sizeC = pixels.getSizeC();
Plane2D p;
for (int z = 0; z < sizeZ; z++)
for (int t = 0; t < sizeT; t++)
for (int c = 0; c < sizeC; c++) {
p = rdf.getPlane(ctx, pixels, z, t, c);
}
RawDataFacility rdf = gateway.getFacility(RawDataFacility.class);
PixelsData pixels = image.getDefaultPixels();
int sizeZ = pixels.getSizeZ();
int sizeT = pixels.getSizeT();
int sizeC = pixels.getSizeC();
int x = 0;
int y = 0;
int width = pixels.getSizeX()/2;
int height = pixels.getSizeY()/2;
Plane2D p;
for (int z = 0; z < sizeZ; z++) {
for (int t = 0; t < sizeT; t++) {
for (int c = 0; c < sizeC; c++) {
p = rdf.getTile(ctx, pixels, z, t, c, x, y, width, height);
}
}
}
This is useful when you need the pixels intensity.
PixelsData pixels = image.getDefaultPixels();
int sizeT = pixels.getSizeT();
int sizeC = pixels.getSizeC();
long pixelsId = pixels.getId();
RawPixelsStorePrx store = gateway.getPixelsStore(ctx);
store.setPixelsId(pixelsId, false);
for (int t = 0; t < sizeT; t++) {
for (int c = 0; c < sizeC; c++) {
byte[] plane = store.getStack(c, t);
//Do something
}
}
store.close();
This is useful when you need the pixels intensity.
PixelsData pixels = image.getDefaultPixels();
long pixelsId = pixels.getId();
//offset values in each dimension XYZCT
List<Integer> offset = new ArrayList<Integer>();
int n = 5;
for (int i = 0; i < n; i++) {
offset.add(i, 0);
}
List<Integer> size = new ArrayList<Integer>();
size.add(pixels.getSizeX());
size.add(pixels.getSizeY());
size.add(pixels.getSizeZ());
size.add(pixels.getSizeC());
size.add(pixels.getSizeT());
//indicate the step in each direction, step = 1,
//will return values at index 0, 1, 2.
//step = 2, values at index 0, 2, 4 etc.
List<Integer> step = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
step.add(i, 1);
}
RawPixelsStorePrx store = gateway.getPixelsStore(ctx);
store.setPixelsId(pixelsId, false);
byte[] values = store.getHypercube(offset, size, step);
//Do something
store.close();
DataManagerFacility dm = gateway.getFacility(DataManagerFacility.class);
//Using IObject directly
Dataset dataset = new DatasetI();
dataset.setName(omero.rtypes.rstring("new Name 1"));
dataset.setDescription(omero.rtypes.rstring("new description 1"));
//Using the model object (recommended)
DatasetData datasetData = new DatasetData();
datasetData.setName("new Name 2");
datasetData.setDescription("new description 2");
ProjectDatasetLink link = new ProjectDatasetLinkI();
link.setChild(dataset);
link.setParent(new ProjectI(info.getProjectId(), false));
IObject r = dm.saveAndReturnObject(ctx, link);
//With model object
link = new ProjectDatasetLinkI();
link.setChild(datasetData.asDataset());
link.setParent(new ProjectI(info.getProjectId(), false));
r = dm.saveAndReturnObject(ctx, link);
Using the Gateway:
ImportCallback cb = new ImportCallback();
TransferFacility tf = gateway.getFacility(TransferFacility.class);
// the uploadImage method will automatically create a dataset with
// the same name as the directory, the image file is located in
tf.uploadImage(ctx, new File("/pathTo/image.dv"), cb);
//wait for the upload to finish
while (!cb.isFinished()) {
try {
Thread.sleep(250);
} catch (InterruptedException e) {}
}
Using the Java API directly:
String paths = new String[] {"/pathTo/image1.dv", "/pathTo/image2.dv"};
ImportConfig config = new ome.formats.importer.ImportConfig();
config.email.set("");
config.sendFiles.set(true);
config.sendReport.set(false);
config.contOnError.set(false);
config.debug.set(false);
config.hostname.set("localhost");
config.port.set(4064);
config.username.set("root");
config.password.set("omero");
// the imported image will go into 'orphaned images' unless
// you specify a particular existing dataset like this:
// config.targetClass.set("omero.model.Dataset");
// config.targetId.set(1L);
OMEROMetadataStoreClient store;
try {
store = config.createStore();
store.logVersionInfo(config.getIniVersionNumber());
OMEROWrapper reader = new OMEROWrapper(config);
ImportLibrary library = new ImportLibrary(store, reader);
ErrorHandler handler = new ErrorHandler(config);
library.addObserver(new LoggingImportMonitor());
ImportCandidates candidates = new ImportCandidates(reader, paths, handler);
reader.setMetadataOptions(new DefaultMetadataOptions(MetadataLevel.ALL));
library.importCandidates(config, candidates);
store.logout();
} catch (Exception e) {
e.printStackTrace();
}
DataManagerFacility dm = gateway.getFacility(DataManagerFacility.class);
TagAnnotation tag = new TagAnnotationI();
tag.setTextValue(omero.rtypes.rstring("new tag 1"));
tag.setDescription(omero.rtypes.rstring("new tag 1"));
//Using the model object (recommended)
TagAnnotationData tagData = new TagAnnotationData("new tag 2");
tagData.setTagDescription("new tag 2");
ProjectAnnotationLink link = new ProjectAnnotationLinkI();
link.setChild(tag);
link.setParent(new ProjectI(info.getProjectId(), false));
IObject r = dm.saveAndReturnObject(ctx, link);
//With model object
link = new ProjectAnnotationLinkI();
link.setChild(tagData.asAnnotation());
link.setParent(new ProjectI(info.getProjectId(), false));
r = dm.saveAndReturnObject(ctx, link);
To attach a file to an object e.g. an image, few objects need to be created:
int INC = 262144;
DataManagerFacility dm = gateway.getFacility(DataManagerFacility.class);
//To retrieve the image see above.
File file = File.createTempFile("temp-file-name_", ".tmp");
String name = file.getName();
String absolutePath = file.getAbsolutePath();
String path = absolutePath.substring(0,
absolutePath.length()-name.length());
//create the original file object.
OriginalFile originalFile = new OriginalFileI();
originalFile.setName(omero.rtypes.rstring(name));
originalFile.setPath(omero.rtypes.rstring(path));
originalFile.setSize(omero.rtypes.rlong(file.length()));
final ChecksumAlgorithm checksumAlgorithm = new ChecksumAlgorithmI();
checksumAlgorithm.setValue(omero.rtypes.rstring(ChecksumAlgorithmSHA1160.value));
originalFile.setHasher(checksumAlgorithm);
originalFile.setMimetype(omero.rtypes.rstring(fileMimeType)); // or "application/octet-stream"
//Now we save the originalFile object
originalFile = (OriginalFile) dm.saveAndReturnObject(ctx, originalFile);
//Initialize the service to load the raw data
RawFileStorePrx rawFileStore = gateway.getRawFileService(ctx);
rawFileStore.setFileId(originalFile.getId().getValue());
//Open file and read stream.
FileInputStream stream = new FileInputStream(file);
long pos = 0;
int rlen;
byte[] buf = new byte[INC];
ByteBuffer bbuf;
while ((rlen = stream.read(buf)) > 0) {
rawFileStore.write(buf, pos, rlen);
pos += rlen;
bbuf = ByteBuffer.wrap(buf);
bbuf.limit(rlen);
}
stream.close();
originalFile = rawFileStore.save();
rawFileStore.close();
//now we have an original File in DB and raw data uploaded.
//We now need to link the Original file to the image using
//the File annotation object. That's the way to do it.
FileAnnotation fa = new FileAnnotationI();
fa.setFile(originalFile);
fa.setDescription(omero.rtypes.rstring(description)); // The description set above e.g. PointsModel
fa.setNs(omero.rtypes.rstring(NAME_SPACE_TO_SET)); // The name space you have set to identify the file annotation.
//save the file annotation.
fa = (FileAnnotation) dm.saveAndReturnObject(ctx, fa);
//now link the image and the annotation
ImageAnnotationLink link = new ImageAnnotationLinkI();
link.setChild(fa);
link.setParent(image.asImage());
//save the link back to the server.
link = (ImageAnnotationLink) dm.saveAndReturnObject(ctx, link);
// o attach to a Dataset use DatasetAnnotationLink;
long userId = gateway.getLoggedInUser().getId();
List<String> nsToInclude = new ArrayList<String>();
nsToInclude.add(NAME_SPACE_TO_SET);
List<String> nsToExclude = new ArrayList<String>();
ParametersI param = new ParametersI();
param.exp(omero.rtypes.rlong(userId)); //load the annotation for a given user.
IMetadataPrx proxy = gateway.getMetadataService(ctx);
List<Annotation> annotations = proxy.loadSpecifiedAnnotations(
FileAnnotation.class.getName(), nsToInclude, nsToExclude, param);
//Do something with annotations.
First load the annotations, cf. above.
Iterator<Annotation> j = annotations.iterator();
Annotation annotation;
FileAnnotationData fa;
RawFileStorePrx store = null;
File file = File.createTempFile("temp-file-name_", ".tmp");
store = gateway.getRawFileService(ctx);
int index = 0;
FileOutputStream stream = new FileOutputStream(file);
OriginalFile of;
while (j.hasNext()) {
annotation = j.next();
if (annotation instanceof FileAnnotation && index == 0) {
fa = new FileAnnotationData((FileAnnotation) annotation);
//The id of the original file
of = getOriginalFile(fa.getFileID());
store.setFileId(fa.getFileID());
int offset = 0;
long size = of.getSize().getValue();
//name of the file
String fileName = of.getName().getValue();
try {
for (offset = 0; (offset+INC) < size;) {
stream.write(store.read(offset, INC));
offset += INC;
}
} finally {
stream.write(store.read(offset, (int) (size-offset)));
stream.close();
}
index++;
}
}
store.close();
In the following example, we create a table with 2 columns.
/**
* Creates a number of empty rows.
*
* @param rows The number of rows.
* @return See above.
*/
private Column[] createColumns(int rows)
{
Column[] newColumns = new Column[2];
newColumns[0] = new LongColumn("Uid", "", new long[rows]);
newColumns[1] = new LongColumn("MyLongColumn", "",
new long[rows]);
return newColumns;
}
int rows = 1;
String name = UUID.randomUUID().toString();
Column[] columns = createColumns(rows);
//create a new table.
SharedResourcesPrx store = gateway.getSharedResources(ctx);
TablePrx table = store.newTable(1, name);
//initialize the table
table.initialize(columns);
//add data to the table.
rows = 2;
Column[] newRow = createColumns(rows);
LongColumn uids = (LongColumn) newRow[0];
LongColumn myLongs = (LongColumn) newRow[1];
for (int i = 0; i < rows; i++) {
uids.values[i] = i;
myLongs.values[i] = i;
}
table.addData(newRow);
OriginalFile file = table.getOriginalFile(); //if you need to interact with the table
file = new OriginalFileI(file.getId(), false);
table = store.openTable(file);
//read headers
Column[] cols = table.getHeaders();
for (int i = 0; i < cols.length; i++) {
String colName = cols[i].name;
}
//Depending on size of table, you may only want to read some blocks.
long[] columnsToRead = new long[cols.length];
for (int i = 0; i < cols.length; i++) {
columnsToRead[i] = i;
}
//The number of columns we wish to read.
long[] rowSubset = new long[(int) (table.getNumberOfRows()-1)];
for (int j = 0; j < rowSubset.length; j++) {
rowSubset[j] = j;
}
Data data = table.slice(columnsToRead, rowSubset); // read the data.
cols = data.columns;
for (int j = 0; j < cols.length; j++) {
Column c = cols[j];
}
table.close();
To learn about the model see the ROI Model documentation. Note that annotations can be linked to ROI or shape.
In this example, we create an ROI with a rectangular shape and attach it to an image.
DataManagerFacility dm = gateway.getFacility(DataManagerFacility.class);
ROIFacility roifac = gateway.getFacility(ROIFacility.class);
//To retrieve the image see above.
ROIData data = new ROIData();
data.setImage(image);
//Create a rectangle.
RectangleData rectangle = new RectangleData(10, 10, 10, 10);
rectangle.setZ(0);
rectangle.setT(0);
data.addShapeData(rectangle);
//Create an ellipse.
EllipseData ellipse = new Ellipse(10, 10, 10, 10);
ellipse.setZ(0);
ellipse.setT(0);
ellipse.setText("ellipse text");
data.addShapeData(ellipse);
// Save ROI and shape
ROIData roiData = roifac.saveROIs(ctx, image.getId(), Arrays.asList(data)).iterator().next();
//now check that the shape has been added.
//Retrieve the shape on plane (z, t) = (0, 0)
List<ShapeData> shapes = roiData.getShapes(0, 0);
Iterator<ShapeData> i = shapes.iterator();
while (i.hasNext()) {
ShapeData shape = i.next();
// plane info
int z = shape.getZ();
int t = shape.getT();
long id = shape.getId();
if (shape instanceof RectangleData) {
RectangleData rectData = (RectangleData) shape;
// Handle rectangle
} else if (shape instanceof EllipseData) {
EllipseData ellipseData = (EllipseData) shape;
// Handle ellipse
} else if (shape instanceof LineData) {
LineData lineData = (LineData) shape;
// Handle line
} else if (shape instanceof PointData) {
PointData pointData = (PointData) shape;
// Handle point
}
}
ROIFacility roifac = gateway.getFacility(ROIFacility.class);
//Retrieve the roi linked to an image
List<ROIResult> roiresults = roifac.loadROIs(ctx, image.getId());
ROIResult r = roiresults.iterator().next();
if (r == null) return;
List<Roi> rois = r.rois;
List<Shape> list;
Iterator<Roi> j = rois.iterator();
while (j.hasNext()) {
roi = j.next();
list = roi.copyShapes();
// Do something
}
DataManagerFacility dm = gateway.getFacility(DataManagerFacility.class);
ROIFacility roifac = gateway.getFacility(ROIFacility.class);
//Retrieve the roi linked to an image
List<ROIResult> roiresults = roifac.loadROIs(ctx, image.getId());
ROIResult r = roiresults.iterator().next();
List<Roi> rois = r.rois;
List<Shape> list;
Iterator<Roi> j = rois.iterator();
while (j.hasNext()) {
roi = j.next();
list = roi.copyShapes();
// remove the first shape.
if (list.size() > 0) {
roi.removeShape(list.get(0));
// update the roi.
dm.saveAndReturnObject(ctx, roi).saveAndReturnObject(roi);
}
}
It is possible to delete Projects, datasets, images, ROIs etc. and objects linked to them depending on the specified options (see Deleting in OMERO).
In the following example, we create an image and delete it.
DataManagerFacility dm = gateway.getFacility(DataManagerFacility.class);
//First create an image.
ImageData image = new ImageData();
image.setName("image1");
image.setDescription("descriptionImage1");
IObject object = dm.saveAndReturnObject(ctx, image.asIObject());
Response rsp = dm.deleteObject(ctx, object);
PixelsData pixels = image.getDefaultPixels();
long pixelsId = pixels.getId();
RenderingEnginePrx proxy = null;
proxy = gateway.getRenderingService(ctx, pixelsId);
proxy.lookupPixels(pixelsId);
if (!(proxy.lookupRenderingDef(pixelsId))) {
proxy.resetDefaultSettings(true);
proxy.lookupRenderingDef(pixelsId);
}
proxy.load();
//Now can interact with the rendering engine.
proxy.setActive(0, Boolean.valueOf(false));
PlaneDef pDef = new PlaneDef();
pDef.z = 0;
pDef.t = 0;
pDef.slice = omero.romio.XY.value;
//render the data uncompressed.
int[] uncompressed = proxy.renderAsPackedInt(pDef);
byte[] compressed = proxy.renderCompressed(pDef);
//Create a buffered image
ByteArrayInputStream stream = new ByteArrayInputStream(compressed);
BufferedImage image = ImageIO.read(stream);
proxy.close();
ThumbnailStorePrx store = gateway.getThumbnailService(ctx);
PixelsData pixels = image.getDefaultPixels();
store.setPixelsId(pixels.getId())
//retrieve a 96x96 thumbnail.
byte[] array = store.getThumbnail(
omero.rtypes.rint(96), omero.rtypes.rint(96));
ByteArrayInputStream stream = new ByteArrayInputStream(array);
//Create a buffered image to display
ImageIO.read(stream);
store.close();
The following example shows how to create an Image from an Image already in OMERO. Similar approach can be applied when uploading an image.
//See above how to load an image.
PixelsData pixels = image.getDefaultPixels();
int sizeZ = pixels.getSizeZ();
int sizeT = pixels.getSizeT();
int sizeC = pixels.getSizeC();
int sizeX = pixels.getSizeX();
int sizeY = pixels.getSizeY();
long pixelsId = pixels.getId();
//Read the pixels from the source image.
RawPixelsStorePrx store = gateway.getPixelsStore(ctx);
store.setPixelsId(pixelsId, false);
List<byte[]> planes = new ArrayList<byte[]>();
for (int z = 0; z < sizeZ; z++) {
for (int t = 0; t < sizeT; t++) {
planes.add(store.getPlane(z, 0, t));
}
}
//Better to close to free space.
store.close();
//Now we are going to create the new image.
IPixelsPrx proxy = gateway.getPixelsService(ctx);
//Search for PixelsType object matching the source image.
List<IObject> l = proxy.getAllEnumerations(PixelsType.class.getName());
Iterator<IObject> i = l.iterator();
PixelsType type = null;
String original = pixels.getPixelType();
while (i.hasNext()) {
PixelsType o = (PixelsType) i.next();
String value = o.getValue().getValue();
if (value.equals(original)) {
type = o;
break;
}
}
if (type == null)
throw new Exception("Pixels Type not valid.");
//Create new image.
String name = "newImageFrom"+image.getId();
RLong idNew = proxy.createImage(sizeX, sizeY, sizeZ, sizeT, Arrays.asList(0), type, name,
"From Image ID: "+image.getId());
if (idNew == null)
throw new Exception("New image could not be created.");
IContainerPrx proxyCS = entryUnencrypted.getContainerService();
List<Image> results = proxyCS.getImages(Image.class.getName(),
Arrays.asList(idNew.getValue()), new ParametersI());
ImageData newImage = new ImageData(results.get(0));
//Link the new image and the dataset hosting the source image.
DatasetImageLink link = new DatasetImageLinkI();
link.setParent(new DatasetI(datasetId, false));
link.setChild(new ImageI(newImage.getId(), false));
gateway.getUpdateService(ctx).saveAndReturnObject(link);
//Write the data.
store = gateway.getPixelsStore(ctx);
store.setPixelsId(newImage.getDefaultPixels().getId(), false);
int index = 0;
for (int z = 0; z < sizeZ; z++) {
for (int t = 0; t < sizeT; t++) {
store.setPlane(planes.get(index++), z, 0, t);
}
}
//Save the data.
store.save();
store.close();
For the details behind writing, configuring, and executing a client, please see Working with OMERO.