This notebook shows how load an ImageJ macrofile linked to an image and analyze the image the macro. This notebook assumes that a macro file has been linked to the dataset. If more than one macro is linked, the user can select the macro to apply.
Fiji has been installed with few other plugins including the omero_ij plugin to allow to connect to an OMERO server.
The following section shows
First we had Fiji and the plugins to the classpath.
%classpath add jar /srv/conda/vnc/Fiji.app/jars/*
%classpath add jar /srv/conda/vnc/Fiji.app/plugins/*
g = new EasyForm("Enter credentials and continue to the next cell. Do not re-run this cell.")
g.addTextField("Server").onInit({g['Server'] = "wss://workshop.openmicroscopy.org/omero-ws"})
g.addTextField("UserName")
g.addPasswordField("Password")
g
import omero.gateway.Gateway
import omero.gateway.LoginCredentials
import omero.log.SimpleLogger
// Method to connect to OMERO
def connect_to_omero() {
"Connect to OMERO"
credentials = new LoginCredentials()
credentials.getServer().setHostname(g['Server'])
credentials.getUser().setUsername(g['UserName'].trim())
credentials.getUser().setPassword(g['Password'].trim())
simpleLogger = new SimpleLogger()
gateway = new Gateway(simpleLogger)
gateway.connect(credentials)
return gateway
}
// Connect to OMERO
println "connecting..."
gateway = connect_to_omero()
println "connected..."
connecting... connected...
null
ga = new EasyForm("Select the Image to analyze. Do not re-run this cell.")
ga.addTextField("ImageID")
ga
//Connection information
HOST = g['Server']
USERNAME = g['UserName'].trim()
PASSWORD = g['Password'].trim()
//Image to analyze
image_id = ga['ImageID'].toLong()
group_id = "-1"
-1
Macros have been linked to the dataset as File Annotations.
import java.util.ArrayList
import java.util.HashMap
import omero.gateway.SecurityContext
import omero.gateway.facility.BrowseFacility
import omero.gateway.facility.MetadataFacility
import omero.gateway.model.FileAnnotationData
import omero.gateway.model.ImageData
import omero.model.OriginalFile
// Retrieve the macros linked to the dataset
user = gateway.getLoggedInUser()
ctx = new SecurityContext(user.getGroupId())
svc = gateway.getFacility(MetadataFacility)
//Find the dataset
browse = gateway.getFacility(BrowseFacility)
object = browse.findIObject(ctx, "omero.model.Image", image_id)
image = new ImageData(object);
users = new ArrayList(1)
//users.add(new Long(user.getId()))
types = new ArrayList(1)
types.add(FileAnnotationData.class)
annotations = svc.getAnnotations(ctx, image, types, users)
macros = new HashMap()
macroNames = new HashMap()
querySvc = gateway.getQueryService(ctx)
annotations.each { fa ->
of = (OriginalFile) querySvc.get("omero.model.OriginalFile", fa.getFileID());
name = of.getName().getValue()
// load the first annotation with ijm
if (name.endsWith(".ijm")) {
macros.put(fa.getFileID(), of)
macroNames.put(name, fa.getFileID())
}
}
if (macros.size) {
println "No macros linked to the image"
return
}
null
gm = new EasyForm("Select the macro to use. Do not re-run this cell.")
gm.addComboBox("Name", new ArrayList(macroNames.keySet()))
gm
import java.io.File
import java.io.FileOutputStream
import omero.gateway.SecurityContext
//size of the chunk to load
INC = 262144
// Load the macro file linked to the dataset
def load_macro_file(gateway, macro_name) {
fileID = macroNames.get(macro_name)
of = macros.get(fileID)
user = gateway.getLoggedInUser()
ctx = new SecurityContext(user.getGroupId())
store = gateway.getRawFileService(ctx);
file = File.createTempFile(name, ".ijm")
stream = new FileOutputStream(file)
store.setFileId(fileID);
offset = 0;
size = of.getSize().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();
}
return file
}
println "loading macro..."
//Name of the macro
macro_name = gm['Name']
macro_file = load_macro_file(gateway, macro_name)
loading macro...
/tmp/Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv_results.csv3663083204645933358.ijm
import ij.IJ
import org.openmicroscopy.shoola.env.data.model.FileObject
import ij.plugin.frame.RoiManager
// Open the image using Bio-Formats
def open_image_plus(host, username, password, group_id, image_id) {
"Open the image using the Bio-Formats Importer"
StringBuilder options = new StringBuilder()
options.append("location=[OMERO] open=[omero:server=")
options.append(host)
options.append("\nuser=")
options.append(username)
options.append("\nport=")
options.append(443)
options.append("\npass=")
options.append(password)
options.append("\ngroupID=")
options.append(group_id)
options.append("\niid=")
options.append(image_id)
options.append("] ")
options.append("windowless=true view=Hyperstack ")
IJ.runPlugIn("loci.plugins.LociImporter", options.toString())
}
println "Opening image..."
imp = open_image_plus(HOST, USERNAME, PASSWORD, String.valueOf(group_id), String.valueOf(image_id))
println "Image opened"
imp = IJ.getImage()
//Use to identify if it is a new image etc.
file_object = new FileObject(imp)
println "Running macro " + macro_name + " on image: "+image_id
RoiManager.getRoiManager()
IJ.runMacroFile(macro_file.getAbsolutePath())
println "Analysis completed"
Opening image... Image opened Running macro fiji-macro-segment-2.ijm on image: 9539 Label Area Mean StdDev Mode Min Max X Y XM YM Perim. BX BY Width Height Feret Ch FeretX FeretY FeretAngle MinFeret 1 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:1/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.154 144.031 43.207 188 22 188 5.038 4.987 5.034 4.990 2.047 4.792 4.594 0.396 0.713 0.728 1 123 133 67.620 0.393 2 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:1/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.016 175.300 8.070 176 162 186 5.287 5.029 5.287 5.029 0.415 5.227 4.950 0.119 0.158 0.198 1 132 125 126.870 0.119 3 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:1/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.050 153.188 29.139 158 95 189 2.671 5.157 2.667 5.159 1.101 2.455 4.990 0.317 0.356 0.396 1 62 129 143.130 0.275 4 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:1/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.121 126.701 53.092 154 0 189 3.008 5.315 2.999 5.323 1.576 2.851 5.069 0.317 0.515 0.585 1 73 128 118.301 0.317 5 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:1/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.036 164.870 18.575 151 128 189 3.286 5.240 3.288 5.241 0.844 3.208 5.069 0.158 0.356 0.390 1 81 128 113.962 0.158 6 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:2/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.240 121.431 47.835 115 0 189 5.343 5.299 5.352 5.311 3.059 5.069 4.950 0.515 0.752 0.816 2 130 125 112.834 0.515 7 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:2/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.176 142.321 37.955 167 15 189 3.125 5.332 3.135 5.322 2.285 2.851 4.990 0.554 0.634 0.708 2 74 142 63.435 0.514 8 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:2/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.017 180.364 6.932 171 171 189 9.869 5.870 9.870 5.870 0.471 9.781 5.782 0.158 0.158 0.198 2 248 146 126.870 0.158 9 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.031 137.600 40.520 184 57 189 6.451 2.780 6.455 2.782 0.630 6.376 2.653 0.158 0.238 0.286 3 161 67 123.690 0.158 10 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.019 174.250 12.513 186 153 189 4.118 2.845 4.118 2.845 0.471 4.039 2.772 0.158 0.158 0.198 3 102 73 36.870 0.158 11 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.019 167.917 15.180 179 144 187 5.395 4.003 5.396 4.003 0.471 5.306 3.920 0.158 0.158 0.198 3 135 99 126.870 0.158 12 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.025 168.500 14.184 153 148 188 3.740 4.292 3.741 4.291 0.653 3.683 4.158 0.119 0.277 0.280 3 94 105 98.130 0.119 13 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.017 167.091 13.960 142 142 187 2.115 4.347 2.114 4.345 0.494 2.059 4.237 0.119 0.198 0.231 3 52 107 120.964 0.119 14 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.315 143.085 44.116 183 0 189 2.904 4.838 2.923 4.830 3.745 2.534 4.435 0.832 0.792 0.945 3 68 132 56.976 0.692 15 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.198 144.730 36.152 189 49 189 5.155 4.954 5.151 4.941 2.630 4.871 4.514 0.475 0.950 0.958 3 131 138 82.875 0.453 16 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.049 169.645 11.531 156 147 187 4.887 4.965 4.886 4.965 0.877 4.752 4.831 0.238 0.317 0.396 3 120 122 126.870 0.210 17 Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv:c:3/3 - Centrin_PCNT_Cep215_20110506_Fri-1545_0_SIR_PRJ.dv 0.022 164.500 13.642 160 140 183 2.874 5.451 2.874 5.450 0.518 2.812 5.346 0.119 0.198 0.231 3 71 140 59.036 0.119 Analysis completed
null
Depending on the macros run, new images, ROIs or results will be created. Select the output you wish to save back to OMERO.
gr = new EasyForm("Select the output to save. Do not re-run this cell.")
options = ["Image", "ROIs", "Results"]
gr.addCheckBox("Image")
gr.addCheckBox("ROIs")
gr.addCheckBox("Results")
gr
save_image = gr['Image']
save_rois = gr['ROIs']
save_results = gr['Results']
true
Save the rois if any created during the analysis
import org.openmicroscopy.shoola.util.roi.io.ROIReader
import omero.gateway.facility.ROIFacility
exp = gateway.getLoggedInUser()
reader = new ROIReader()
roi_list = reader.readImageJROIFromSources(image_id, imp)
if (roi_list != null && roi_list.size() > 0 && save_rois) {
println "saving ROIs"
roi_facility = gateway.getFacility(ROIFacility)
result = roi_facility.saveROIs(ctx, image_id, exp.getId(), roi_list)
}
saving ROIs
[omero.gateway.model.ROIData (id=1293870), omero.gateway.model.ROIData (id=1293871), omero.gateway.model.ROIData (id=1293872), omero.gateway.model.ROIData (id=1293873), omero.gateway.model.ROIData (id=1293874), omero.gateway.model.ROIData (id=1293875), omero.gateway.model.ROIData (id=1293876), omero.gateway.model.ROIData (id=1293877), omero.gateway.model.ROIData (id=1293878), omero.gateway.model.ROIData (id=1293879), omero.gateway.model.ROIData (id=1293880), omero.gateway.model.ROIData (id=1293881), omero.gateway.model.ROIData (id=1293882), omero.gateway.model.ROIData (id=1293883), omero.gateway.model.ROIData (id=1293884), omero.gateway.model.ROIData (id=1293885), omero.gateway.model.ROIData (id=1293886)]
First we read the measurement using the reader defined about and then attach the CSV file to the image as a File Annotation.
import java.io.File
import java.io.FileInputStream
import java.nio.ByteBuffer
import java.nio.file.Files
import omero.gateway.facility.DataManagerFacility
import omero.gateway.model.FileAnnotationData
import omero.gateway.model.ImageData
import omero.model.ChecksumAlgorithmI
import omero.model.FileAnnotationI
import omero.model.ImageI
import omero.model.OriginalFileI
import omero.model.enums.ChecksumAlgorithmSHA1160
import static omero.rtypes.rlong
import static omero.rtypes.rstring
// Upload the CSV file to OMERO
def upload_csv_to_omero(ctx, file, image_id) {
"Upload the CSV file and attach it to the specified project"
svc = gateway.getFacility(DataManagerFacility)
file_size = file.length()
original_file = new OriginalFileI()
original_file.setName(rstring(file.getName()))
original_file.setPath(rstring(file.getAbsolutePath()))
original_file.setSize(rlong(file_size))
checksum_algorithm = new ChecksumAlgorithmI()
checksum_algorithm.setValue(rstring(ChecksumAlgorithmSHA1160.value))
original_file.setHasher(checksum_algorithm)
original_file.setMimetype(rstring("text/csv"))
original_file = svc.saveAndReturnObject(ctx, original_file)
store = gateway.getRawFileService(ctx)
// Open file and read stream
INC = 262144
pos = 0
buf = new byte[INC]
ByteBuffer bbuf = null
stream = null
try {
store.setFileId(original_file.getId().getValue())
stream = new FileInputStream(file)
while ((rlen = stream.read(buf)) > 0) {
store.write(buf, pos, rlen)
pos += rlen
bbuf = ByteBuffer.wrap(buf)
bbuf.limit(rlen)
}
original_file = store.save()
} finally {
if (stream != null) {
stream.close()
}
store.close()
}
// create the file annotation
namespace = "training.demo"
fa = new FileAnnotationI()
fa.setFile(original_file)
fa.setNs(rstring(namespace))
data_object = new ImageData(new ImageI(image_id, false))
svc.attachAnnotation(ctx, new FileAnnotationData(fa), data_object)
}
tmp_dir = Files.createTempDirectory("Fiji_csv")
path = tmp_dir.resolve(image_id+"_results.csv")
file_path = Files.createFile(path)
file = new File(file_path.toString())
//Save the results
value = reader.readResults(file)
if (value && save_results) { //some results to upload
println "saving Results as CSV"
upload_csv_to_omero(ctx, file, image_id)
}
file.delete()
saving Results as CSV
true
If an image is created by the macro and the option is selected, the image will be imported in a new dataset named "Analysis from Fiji".
import java.lang.reflect.Array
import omero.gateway.SecurityContext
import omero.gateway.facility.BrowseFacility
import omero.gateway.facility.DataManagerFacility
import omero.gateway.model.DatasetData
import ome.formats.importer.ImportConfig
import ome.formats.importer.OMEROWrapper
import ome.formats.importer.ImportLibrary
import ome.formats.importer.ImportCandidates
import ome.formats.importer.cli.ErrorHandler
import ome.formats.importer.cli.LoggingImportMonitor
import loci.formats.in.DefaultMetadataOptions
import loci.formats.in.MetadataLevel
//Upload the generated image
def upload_image(paths, gateway, id) {
"Upload an image to OMERO"
user = gateway.getLoggedInUser()
sessionKey = gateway.getSessionId(user)
config = new ImportConfig()
config.debug.set('false')
config.hostname.set(HOST)
config.port.set(443)
config.sessionKey.set(sessionKey)
dataset = find_dataset(gateway, id)
store = config.createStore()
reader = new OMEROWrapper(config)
library = new ImportLibrary(store, reader)
error_handler = new ErrorHandler(config)
library.addObserver(new LoggingImportMonitor())
candidates = new ImportCandidates(reader, paths, error_handler)
containers = candidates.getContainers()
containers.each() { c ->
c.setTarget(dataset)
}
reader.setMetadataOptions(new DefaultMetadataOptions(MetadataLevel.ALL))
return library.importCandidates(config, candidates)
}
// Find the dataset matching the specified ID
def find_dataset(gateway, dataset_id) {
"Load the Dataset"
browse = gateway.getFacility(BrowseFacility)
user = gateway.getLoggedInUser()
ctx = new SecurityContext(user.getGroupId())
return browse.findIObject(ctx, "omero.model.Dataset", dataset_id)
}
// Check if the macro created a new image
if (file_object.isNewImage() && save_image) {
// Create a Dataset
d = new DatasetData()
d.setName("Analysis from Fiji")
dm = gateway.getFacility(DataManagerFacility)
user = gateway.getLoggedInUser()
ctx = new SecurityContext(user.getGroupId())
d = dm.createDataset(ctx, d, null)
file_to_import = file_object.getFileToImport()
println "importing..."
str2d = new String[1]
str2d[0] = file_to_import.getAbsolutePath()
success = upload_image(str2d, gateway, d.getId())
println "imported"
}
// delete the local copy of the temporary file and directory
dir = new File(tmp_dir.toString())
entries = dir.listFiles()
for (i = 0; i < entries.length; i++) {
entries[i].delete()
}
dir.delete()
// Close the connection
gateway.disconnect()
//Delete macrofile
macro_file.delete()
println "processing done"
importing...
May 25, 2020 11:29:47 AM java.util.prefs.FileSystemPreferences$1 run INFO: Created user preferences directory.
Image:57242
Other imported objects: Fileset:39956
imported processing done
null
// delete the local copy of the temporary file and directory
dir.delete()
// Close the connection
gateway.disconnect()
//Delete macrofile
macro_file.delete()
println "processing done"
processing done
null
Copyright (c) 2021, University of Dundee All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.