1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 import logging
39 import getopt, sys, os, subprocess
40 import numpy;
41 from struct import *
42
43 import omero.clients
44 import omero_Constants_ice
45 from omero.rtypes import *
46 import omero.util.pixelstypetopython as pixelstypetopython
47 from omero.util.OmeroPopo import EllipseData as EllipseData
48 from omero.util.OmeroPopo import RectData as RectData
49 from omero.util.OmeroPopo import MaskData as MaskData
50 from omero.util.OmeroPopo import WorkflowData as WorkflowData
51 from omero.util.OmeroPopo import ROIData as ROIData
52
53
54 try:
55 import hashlib
56 hash_sha1 = hashlib.sha1
57 except:
58 import sha
59 hash_sha1 = sha.new
60
61
62 COLOURS = {'Red': (255,0,0,255), 'Green': (0,255,0,255), 'Blue': (0,0,255,255), 'Yellow': (255,255,0,255),
63 'White': (255,255,255,255), }
64
65 EXTRA_COLOURS = {'Violet': (238,133,238,255), 'Indigo': (79,6,132,255),
66 'Black': (0,0,0,255), 'Orange': (254,200,6,255), 'Gray': (130,130,130,255),}
67
68 CSV_NS = 'text/csv';
69 CSV_FORMAT = 'text/csv';
70 SU_LOG = logging.getLogger("omero.util.script_utils")
71
72 -def drawTextOverlay(draw, x, y, text, colour='0xffffff'):
73 """
74 Draw test on image.
75 @param draw The PIL Draw class.
76 @param x The x-coord to draw.
77 @param y The y-coord to draw.
78 @param text The text to render.
79 @param colour The colour as a PIL colour string to draw the text in.
80 """
81 draw.text((x,y),text, fill=colour)
82
84 """
85 Draw line on image.
86 @param draw The PIL Draw class.
87 @param x0 The x0-coord of line.
88 @param y0 The y0-coord of line.
89 @param x1 The x1-coord of line.
90 @param y1 The y1-coord of line.
91 @param colour The colour as a PIL colour string to draw the text in.
92 """
93 draw.line([(x0, y0),(x1,y1)], text, fill=colour)
94
96 """
97 Convert an R,G,B value to an int.
98 @param R the Red value.
99 @param G the Green value.
100 @param B the Blue value.
101 @return See above.
102 """
103 RGBInt = (red<<16)+(green<<8)+blue;
104 return int(RGBInt);
105
107 """
108 Convert an RGB value to a PIL colour value.
109 @param RGB the RGB value.
110 @return See above.
111 """
112 hexval = hex(int(RGB));
113 return '#'+(6-len(hexval[2:]))*'0'+hexval[2:];
114
116 """
117 Map a range to a string of numbers
118 @param range See above.
119 @return See above.
120 """
121 first = 1;
122 string = "";
123 for value in range:
124 if(first==1):
125 string = str(value);
126 first = 0;
127 else:
128 string = string + ','+str(value)
129 return string;
130
132 for name in os.listdir(dir):
133 full_name = os.path.join(dir, name)
134
135
136 if not os.access(full_name, os.W_OK):
137 os.chmod(full_name, 0600)
138 if os.path.isdir(full_name):
139 rmdir_recursive(full_name)
140 else:
141 os.remove(full_name)
142 os.rmdir(dir)
143
145 """
146 Returns a hash of the file identified by filename
147
148 @param filename: pathName of the file
149 @return: The hash of the file
150 """
151
152 fileHandle = open(filename)
153 h = hash_sha1()
154 h.update(fileHandle.read())
155 hash = h.hexdigest()
156 fileHandle.close()
157 return hash;
158
160 """
161 Calculate the Sha1 Hash from a data array
162 @param data The data array.
163 @return The Hash
164 """
165 h = hash_sha1()
166 h.update(data)
167 hash = h.hexdigest()
168 return hash;
169
172
173
174 -def createFile(updateService, filename, mimetype=None, origFilePathName=None):
175 """
176 Creates an original file, saves it to the server and returns the result
177
178 @param queryService: The query service E.g. session.getQueryService()
179 @param updateService: The update service E.g. session.getUpdateService()
180 @param filename: The file path and name (or name if in same folder). String
181 @param mimetype: The mimetype (string) or Format object representing the file format
182 @param origFilePathName: Optional path/name for the original file
183 @return: The saved OriginalFileI, as returned from the server
184 """
185
186 originalFile = omero.model.OriginalFileI();
187 if(origFilePathName == None):
188 origFilePathName = filename;
189 path, name = os.path.split(origFilePathName)
190 originalFile.setName(omero.rtypes.rstring(name));
191 originalFile.setPath(omero.rtypes.rstring(path));
192
193 try:
194 v = mimetype.getValue()
195 mt = v.getValue()
196 except:
197
198 mt = mimetype
199 if mt:
200 originalFile.mimetype = omero.rtypes.rstring(mt)
201 originalFile.setSize(omero.rtypes.rlong(os.path.getsize(filename)));
202 originalFile.setSha1(omero.rtypes.rstring(calcSha1(filename)));
203 return updateService.saveAndReturnObject(originalFile);
204
205
206 -def uploadFile(rawFileStore, originalFile, filePath=None):
207 """
208 Uploads an OriginalFile to the server
209
210 @param rawFileStore: The Omero rawFileStore
211 @param originalFile: The OriginalFileI
212 @param filePath: Where to find the file to upload. If None, use originalFile.getName().getValue()
213 """
214 rawFileStore.setFileId(originalFile.getId().getValue());
215 fileSize = originalFile.getSize().getValue();
216 increment = 10000;
217 cnt = 0;
218 if filePath == None:
219 filePath = originalFile.getName().getValue()
220 fileHandle = open(filePath, 'rb');
221 done = 0
222 while(done!=1):
223 if(increment+cnt<fileSize):
224 blockSize = increment;
225 else:
226 blockSize = fileSize-cnt;
227 done = 1;
228 fileHandle.seek(cnt);
229 block = fileHandle.read(blockSize);
230 rawFileStore.write(block, cnt, blockSize);
231 cnt = cnt+blockSize;
232 fileHandle.close();
233
234
235 -def downloadFile(rawFileStore, originalFile, filePath=None):
236 """
237 Downloads an OriginalFile from the server.
238
239 @param rawFileStore: The Omero rawFileStore
240 @param originalFile: The OriginalFileI
241 @param filePath: Where to download the file. If None, use originalFile.getName().getValue()
242 """
243 fileId = originalFile.getId().getValue()
244 rawFileStore.setFileId(fileId)
245 fileSize = originalFile.getSize().getValue()
246 maxBlockSize = 10000
247 cnt = 0
248 if filePath == None:
249 filePath = originalFile.getName().getValue()
250
251 i = 1
252 path, ext = filePath.rsplit(".", 1)
253 while os.path.exists(filePath):
254 filePath = "%s_%s.%s" % (path,i,ext)
255 i +=1
256 fileHandle = open(filePath, 'w')
257 data = '';
258 cnt = 0;
259 fileSize = originalFile.getSize().getValue()
260 while(cnt<fileSize):
261 blockSize = min(maxBlockSize, fileSize)
262 block = rawFileStore.read(cnt, blockSize)
263 cnt = cnt+blockSize
264 fileHandle.write(block)
265 fileHandle.close()
266 return filePath
267
268
269 -def attachFileToParent(updateService, parent, originalFile, description=None, namespace=None):
270 """
271 Attaches the original file (file) to a Project, Dataset or Image (parent)
272
273 @param updateService: The update service
274 @param parent: A ProjectI, DatasetI or ImageI to attach the file to
275 @param originalFile: The OriginalFileI to attach
276 @param description: Optional description for the file annotation. String
277 @param namespace: Optional namespace for file annotataion. String
278 @return: The saved and returned *AnnotationLinkI (* = Project, Dataset or Image)
279 """
280 fa = omero.model.FileAnnotationI();
281 fa.setFile(originalFile);
282 if description:
283 fa.setDescription(omero.rtypes.rstring(description))
284 if namespace:
285 fa.setNs(omero.rtypes.rstring(namespace))
286 if type(parent) == omero.model.DatasetI:
287 l = omero.model.DatasetAnnotationLinkI()
288 elif type(parent) == omero.model.ProjectI:
289 l = omero.model.ProjectAnnotationLinkI()
290 elif type(parent) == omero.model.ImageI:
291 l = omero.model.ImageAnnotationLinkI()
292 else:
293 return
294 parent = parent.__class__(parent.id.val, False)
295 l.setParent(parent);
296 l.setChild(fa);
297 return updateService.saveAndReturnObject(l);
298
299
300 -def uploadAndAttachFile(queryService, updateService, rawFileStore, parent, localName, mimetype, description=None, namespace=None, origFilePathName=None):
301 """
302 Uploads a local file to the server, as an Original File and attaches it to the
303 parent (Project, Dataset or Image)
304
305 @param queryService: The query service
306 @param updateService: The update service
307 @param rawFileStore: The rawFileStore
308 @param parent: The ProjectI or DatasetI or ImageI to attach file to
309 @param localName: Full Name (and path) of the file location to upload. String
310 @param mimetype: The original file mimetype. E.g. "PNG". String
311 @param description: Optional description for the file annotation. String
312 @param namespace: Namespace to set for the original file
313 @param origFilePathName: The /path/to/file/fileName.ext you want on the server. If none, use output as name
314 @return: The originalFileLink child. (FileAnnotationI)
315 """
316
317 filename = localName
318 if origFilePathName == None:
319 origFilePathName = localName
320 originalFile = createFile(updateService, filename, mimetype, origFilePathName);
321 uploadFile(rawFileStore, originalFile, localName)
322 fileLink = attachFileToParent(updateService, parent, originalFile, description, namespace)
323 return fileLink.getChild()
324
325
327 """
328 Add the annotation to an image.
329 @param updateService The update service to create the annotation link.
330 @param image The ImageI object that should be annotated.
331 @param annotation The annotation object
332 @return The new annotationlink object
333 """
334 l = omero.model.ImageAnnotationLinkI();
335 l.setParent(image);
336 l.setChild(annotation);
337 return updateService.saveAndReturnObject(l);
338
340 """
341 Read the OriginalFile with fileId and return it as a string.
342 @param rawFileService The RawFileService service to read the originalfile.
343 @param iQuery The Query Service.
344 @param fileId The id of the originalFile object.
345 @param maxBlockSize The block size of each read.
346 @return The OriginalFile object contents as a string
347 """
348 fileDetails = iQuery.findByQuery("from OriginalFile as o where o.id = " + str(fileId) , None);
349 rawFileService.setFileId(fileId);
350 data = '';
351 cnt = 0;
352 fileSize = fileDetails.getSize().getValue();
353 while(cnt<fileSize):
354 blockSize = min(maxBlockSize, fileSize);
355 block = rawFileService.read(cnt, blockSize);
356 data = data + block;
357 cnt = cnt+blockSize;
358 return data;
359
360 -def readFileAsArray(rawFileService, iQuery, fileId, row, col, separator = ' '):
361 """
362 Read an OriginalFile with id and column separator and return it as an array.
363 @param rawFileService The RawFileService service to read the originalfile.
364 @param iQuery The Query Service.
365 @param fileId The id of the originalFile object.
366 @param row The number of rows in the file.
367 @param col The number of columns in the file.
368 @param sep the column separator.
369 @return The file as an NumPy array.
370 """
371 textBlock = readFromOriginalFile(rawFileService, iQuery, fileId);
372 arrayFromFile = numpy.fromstring(textBlock,sep = separator);
373 return numpy.reshape(arrayFromFile, (row, col));
374
376 """
377 Read the RawImageFlimFile with fileId and return it as an array [c, x, y]
378 @param rawPixelsStore The rawPixelStore service to get the image.
379 @param pixels The pixels of the image.
380 @return The Contents of the image for z = 0, t = 0, all channels;
381 """
382 sizeC = pixels.getSizeC().getValue();
383 sizeX = pixels.getSizeX().getValue();
384 sizeY = pixels.getSizeY().getValue();
385 id = pixels.getId().getValue();
386 pixelsType = pixels.getPixelsType().getValue().getValue();
387 rawPixelsStore.setPixelsId(id , False);
388 cRange = range(0, sizeC);
389 stack = numpy.zeros((sizeC, sizeX, sizeY),dtype=pixelstypetopython.toNumpy(pixelsType));
390 for c in cRange:
391 plane = downloadPlane(rawPixelsStore, pixels, 0, c, 0);
392 stack[c,:,:]=plane;
393 return stack;
394
396 """
397 Download the plane [z,c,t] for image pixels. Pixels must have pixelsType loaded.
398 N.B. The rawPixelsStore must have already been initialised by setPixelsId()
399 @param rawPixelsStore The rawPixelStore service to get the image.
400 @param pixels The pixels of the image.
401 @param z The Z-Section to retrieve.
402 @param c The C-Section to retrieve.
403 @param t The T-Section to retrieve.
404 @return The Plane of the image for z, c, t
405 """
406 rawPlane = rawPixelsStore.getPlane(z, c, t);
407 sizeX = pixels.getSizeX().getValue();
408 sizeY = pixels.getSizeY().getValue();
409 pixelsId = pixels.getId().getValue();
410 pixelType = pixels.getPixelsType().getValue().getValue();
411 convertType ='>'+str(sizeX*sizeY)+pixelstypetopython.toPython(pixelType);
412 convertedPlane = unpack(convertType, rawPlane);
413 numpyType = pixelstypetopython.toNumpy(pixelType)
414 remappedPlane = numpy.array(convertedPlane, numpyType);
415 remappedPlane.resize(sizeY, sizeX);
416 return remappedPlane;
417
418
420 """
421 Reads a local image (E.g. single plane tiff) and returns it as a numpy 2D array.
422
423 @param imagePath Path to image.
424 """
425 import numpy
426 try:
427 from PIL import Image
428 except ImportError:
429 import Image
430
431 i = Image.open(imagePath)
432 a = numpy.asarray(i)
433 if rgbIndex == None:
434 return a
435 else:
436 return a[:, :, rgbIndex]
437
438
439 -def uploadDirAsImages(sf, queryService, updateService, pixelsService, path, dataset = None):
440 """
441 Reads all the images in the directory specified by 'path' and uploads them to OMERO as a single
442 multi-dimensional image, placed in the specified 'dataset'
443 Uses regex to determine the Z, C, T position of each image by name,
444 and therefore determines sizeZ, sizeC, sizeT of the new Image.
445
446 @param path the path to the directory containing images.
447 @param dataset the OMERO dataset, if we want to put images somewhere. omero.model.DatasetI
448 """
449
450 import re
451
452 regex_token = re.compile(r'(?P<Token>.+)\.')
453 regex_time = re.compile(r'T(?P<T>\d+)')
454 regex_channel = re.compile(r'_C(?P<C>.+?)(_|$)')
455 regex_zslice = re.compile(r'_Z(?P<Z>\d+)')
456
457
458
459 imageMap = {}
460 channelSet = set()
461 tokens = []
462
463
464 sizeZ = 1
465 sizeC = 1
466 sizeT = 1
467 zStart = 1
468 tStart = 1
469
470 fullpath = None
471
472 rgb = False
473
474 for f in os.listdir(path):
475 fullpath = os.path.join(path, f)
476 tSearch = regex_time.search(f)
477 cSearch = regex_channel.search(f)
478 zSearch = regex_zslice.search(f)
479 tokSearch = regex_token.search(f)
480
481 if f.endswith(".jpg"):
482 rgb = True
483
484 if tSearch == None:
485 theT = 0
486 else:
487 theT = int(tSearch.group('T'))
488
489 if cSearch == None:
490 cName = "0"
491 else:
492 cName = cSearch.group('C')
493
494 if zSearch == None:
495 theZ = 0
496 else:
497 theZ = int(zSearch.group('Z'))
498
499 channelSet.add(cName)
500 sizeZ = max(sizeZ, theZ)
501 zStart = min(zStart, theZ)
502 sizeT = max(sizeT, theT)
503 tStart = min(tStart, theT)
504 if tokSearch != None:
505 tokens.append(tokSearch.group('Token'))
506 imageMap[(theZ, cName, theT)] = fullpath
507
508 colourMap = {}
509 if not rgb:
510 channels = list(channelSet)
511
512 for i, c in enumerate(channels):
513 if c == 'rfp':
514 colourMap[i] = (255, 0, 0, 255)
515 if c == 'gfp':
516 colourMap[i] = (0, 255, 0, 255)
517 else:
518 channels = ("red", "green", "blue")
519 colourMap[0] = (255, 0, 0, 255)
520 colourMap[1] = (0, 255, 0, 255)
521 colourMap[2] = (0, 0, 255, 255)
522
523 sizeC = len(channels)
524
525
526 imageName = os.path.commonprefix(tokens).strip('0T_')
527 description = "Imported from images in %s" % path
528 SU_LOG.info("Creating image: %s" % imageName)
529
530
531 if rgb:
532 plane = getPlaneFromImage(fullpath, 0)
533 else:
534 plane = getPlaneFromImage(fullpath)
535 pType = plane.dtype.name
536
537 pixelsType = queryService.findByQuery(\
538 "from PixelsType as p where p.value='%s'" % pType, None)
539 if pixelsType == None and pType.startswith("float"):
540 pixelsType = queryService.findByQuery(\
541 "from PixelsType as p where p.value='%s'" % "float", None)
542 if pixelsType == None:
543 SU_LOG.warn("Unknown pixels type for: %s" % pType)
544 return
545 sizeY, sizeX = plane.shape
546
547 SU_LOG.debug("sizeX: %s sizeY: %s sizeZ: %s sizeC: %s sizeT: %s" % (sizeX, sizeY, sizeZ, sizeC, sizeT))
548
549
550
551 channelList = range(sizeC)
552 imageId = pixelsService.createImage(sizeX, sizeY, sizeZ, sizeT, channelList, pixelsType, imageName, description)
553 params = omero.sys.ParametersI()
554 params.addId(imageId)
555 pixelsId = queryService.projection(\
556 "select p.id from Image i join i.pixels p where i.id = :id",\
557 params)[0][0].val
558
559 rawPixelStore = sf.createRawPixelsStore()
560 rawPixelStore.setPixelsId(pixelsId, True)
561 try:
562 for theC in range(sizeC):
563 minValue = 0
564 maxValue = 0
565 for theZ in range(sizeZ):
566 zIndex = theZ + zStart
567 for theT in range(sizeT):
568 tIndex = theT + tStart
569 if rgb:
570 c = "0"
571 else:
572 c = channels[theC]
573 if (zIndex, c, tIndex) in imageMap:
574 imagePath = imageMap[(zIndex, c, tIndex)]
575 if rgb:
576 SU_LOG.debug("Getting rgb plane from: %s" % imagePath)
577 plane2D = getPlaneFromImage(imagePath, theC)
578 else:
579 SU_LOG.debug("Getting plane from: %s" % imagePath)
580 plane2D = getPlaneFromImage(imagePath)
581 else:
582 SU_LOG.debug("Creating blank plane for .", theZ, channels[theC], theT)
583 plane2D = zeros((sizeY, sizeX))
584 SU_LOG.debug("Uploading plane: theZ: %s, theC: %s, theT: %s" % (theZ, theC, theT))
585
586 uploadPlane(rawPixelStore, plane2D, theZ, theC, theT)
587 minValue = min(minValue, plane2D.min())
588 maxValue = max(maxValue, plane2D.max())
589 pixelsService.setChannelGlobalMinMax(pixelsId, theC, float(minValue), float(maxValue))
590 rgba = None
591 if theC in colourMap:
592 rgba = colourMap[theC]
593 try:
594 renderingEngine = sf.createRenderingEngine()
595 resetRenderingSettings(renderingEngine, pixelsId, theC, minValue, maxValue, rgba)
596 finally:
597 renderingEngine.close()
598 finally:
599 rawPixelStore.close()
600
601
602 pixels = pixelsService.retrievePixDescription(pixelsId)
603 i = 0
604 for c in pixels.iterateChannels():
605 lc = c.getLogicalChannel()
606 lc.setName(rstring(channels[i]))
607 updateService.saveObject(lc)
608 i += 1
609
610
611 if dataset:
612 link = omero.model.DatasetImageLinkI()
613 link.parent = omero.model.DatasetI(dataset.id.val, False)
614 link.child = omero.model.ImageI(imageId, False)
615 updateService.saveAndReturnObject(link)
616
617 return imageId
618
619
620
622 """
623 Parses a single line of cecog output and saves as a roi.
624
625 Adds a Rectangle (particle) to the current OMERO image, at point x, y.
626 Uses the self.image (OMERO image) and self.updateService
627 """
628
629 objects = {}
630 roi_ids = []
631
632 import fileinput
633 for line in fileinput.input([filePath]):
634
635 theZ = 0
636 theT = None
637 x = None
638 y = None
639
640 parts = line.split("\t")
641 names = ("frame", "objID", "primaryClassLabel", "primaryClassName", "centerX", "centerY", "mean", "sd", "secondaryClassabel", "secondaryClassName", "secondaryMean", "secondarySd")
642 values = {}
643 for idx, name in enumerate(names):
644 if len(parts) >= idx:
645 values[name] = parts[idx]
646
647 frame = values["frame"]
648 try:
649 frame = long(frame)
650 except ValueError:
651 SU_LOG.debug("Non-roi line: %s " % line)
652 continue
653
654 theT = frame - 1
655 objID = values["objID"]
656 className = values["primaryClassName"]
657 x = float(values["centerX"])
658 y = float(values["centerY"])
659
660 description = ""
661 for name in names:
662 description += ("%s=%s\n" % (name, values.get(name, "(missing)")))
663
664 if theT and x and y:
665 SU_LOG.debug("Adding point '%s' to frame: %s, x: %s, y: %s" % (className, theT, x, y))
666 try:
667 shapes = objects[objID]
668 except KeyError:
669 shapes = []
670 objects[objID] = shapes
671 shapes.append( (theT, className, x, y, values, description) )
672
673 for object, shapes in objects.items():
674
675
676 roi = omero.model.RoiI()
677 roi.setImage(omero.model.ImageI(imageId, False))
678 roi.setDescription(omero.rtypes.rstring("objID: %s" % object))
679
680
681 for shape in shapes:
682
683 theT, className, x, y, values, description = shape
684
685 point = omero.model.PointI()
686 point.cx = rdouble(x)
687 point.cy = rdouble(y)
688 point.theT = rint(theT)
689 point.theZ = rint(0)
690 if className:
691 point.setTextValue(rstring(className))
692
693
694 roi.addShape(point)
695
696 roi = updateService.saveAndReturnObject(point)
697 roi_ids.append(roi.id.val)
698
699 return roi_ids
700
701
702 -def split_image(client, imageId, dir, unformattedImageName = "tubulin_P037_T%05d_C%s_Z%d_S1.tif", dims = ('T', 'C', 'Z')):
703 """
704 Splits the image into component planes, which are saved as local tiffs according to unformattedImageName.
705 E.g. myLocalDir/tubulin_P037_T%05d_C%s_Z%d_S1.tif which will be formatted according to dims, E.g. ('T', 'C', 'Z')
706 Channel will be formatted according to channel name, not index.
707 @param rawPixelsStore The rawPixelStore
708 @param queryService
709 @param c The C-Section to retrieve.
710 @param t The T-Section to retrieve.
711 @param imageName the local location to save the image.
712 """
713
714 unformattedImageName = os.path.join(dir, unformattedImageName)
715
716 session = client.getSession()
717 queryService = session.getQueryService()
718 rawPixelsStore = session.createRawPixelsStore()
719 pixelsService = session.getPixelsService()
720
721 try:
722 from PIL import Image
723 except:
724 import Image
725
726 query_string = "select p from Pixels p join fetch p.image as i join fetch p.pixelsType where i.id='%s'" % imageId
727 pixels = queryService.findByQuery(query_string, None)
728 sizeX = pixels.getSizeX().getValue()
729 sizeY = pixels.getSizeY().getValue()
730 sizeZ = pixels.getSizeZ().getValue()
731 sizeC = pixels.getSizeC().getValue()
732 sizeT = pixels.getSizeT().getValue()
733 rawPixelsStore.setPixelsId(pixels.getId().getValue(), True)
734
735 channelMap = {}
736 cIndex = 0
737 pixels = pixelsService.retrievePixDescription(pixels.id.val)
738 for c in pixels.iterateChannels():
739 lc = c.getLogicalChannel()
740 channelMap[cIndex] = lc.getName().getValue()
741 cIndex += 1
742
743 def formatName(unformatted, z, c, t):
744
745 dimMap = {'T': t, 'C':channelMap[c], 'Z': z}
746 dd = tuple([dimMap[d] for d in dims])
747 return unformatted % dd
748
749
750 zStart = 1
751 tStart = 1
752
753
754 for z in range(sizeZ):
755 for c in range(sizeC):
756 for t in range(sizeT):
757 imageName = formatName(unformattedImageName, z+zStart, c, t+tStart)
758 SU_LOG.debug("downloading plane z: %s c: %s t: %s to %s" % (z, c, t, imageName))
759 plane = downloadPlane(rawPixelsStore, pixels, z, c, t)
760 i = Image.fromarray(plane)
761 i.save(imageName)
762
763
765 """
766 Create a file from the data of type format, setting sha1, ..
767 @param updateService The updateService to create the annotation link.
768 @param filename The name of the file.
769 @param data The data to save.
770 @param format The Format of the file.
771 @return The newly created OriginalFile.
772 """
773 tempFile = omero.model.OriginalFileI();
774 tempFile.setName(omero.rtypes.rstring(filename));
775 tempFile.setPath(omero.rtypes.rstring(filename));
776 tempFile.setMimetype(omero.rtypes.rstring(CSV_FORMAT));
777 tempFile.setSize(omero.rtypes.rlong(len(data)));
778 tempFile.setSha1(omero.rtypes.rstring(calcSha1FromData(data)));
779 return updateService.saveAndReturnObject(tempFile);
780
782 """
783 Attach an array, stored as a csv file to an image. Returns the annotation.
784 @param updateService The updateService to create the annotation link.
785 @param image The image to attach the data to.
786 @param filename The name of the file.
787 @param namespace The namespace of the file.
788 @return
789 """
790 fa = omero.model.FileAnnotationI();
791 fa.setFile(file);
792 fa.setNs(omero.rtypes.rstring(nameSpace))
793 l = omero.model.ImageAnnotationLinkI();
794 l.setParent(image);
795 l.setChild(fa);
796 l = updateService.saveAndReturnObject(l);
797 return l.getChild();
798
799 -def uploadArray(rawFileStore, updateService, queryService, image, filename, namespace, array):
800 """
801 Upload the data to the server, creating the OriginalFile Object and attaching it to the image.
802 @param rawFileStore The rawFileStore used to create the file.
803 @param updateService The updateService to create the annotation link.
804 @param image The image to attach the data to.
805 @param filename The name of the file.
806 @param namespace The name space associated to the annotation.
807 @param data The data to save.
808 @return The newly created file.
809 """
810 data = arrayToCSV(array);
811 file = createFileFromData(updateService, queryService, filename, data);
812 rawFileStore.setFileId(file.getId().getValue());
813 fileSize = len(data);
814 increment = 10000;
815 cnt = 0;
816 done = 0
817 while(done!=1):
818 if(increment+cnt<fileSize):
819 blockSize = increment;
820 else:
821 blockSize = fileSize-cnt;
822 done = 1;
823 block = data[cnt:cnt+blockSize];
824 rawFileStore.write(block, cnt, blockSize);
825 cnt = cnt+blockSize;
826 return attachArrayToImage(updateService, image, file, namespace);
827
829 """
830 Convert the numpy array data to a csv file.
831 @param data the Numpy Array
832 @return The CSV string.
833 """
834 size = data.shape;
835 row = size[0];
836 col = size[1];
837 strdata ="";
838 for r in range(0,row):
839 for c in range(0, col):
840 strdata = strdata + str(data[r,c])
841 if(c<col-1):
842 strdata = strdata+',';
843 strdata = strdata + '\n';
844 return strdata;
845
846
848 """
849 Upload the plane to the server attching it to the current z,c,t of the already instantiated rawPixelStore.
850 @param rawPixelsStore The rawPixelStore which is already pointing to the data.
851 @param plane The data to upload
852 @param z The Z-Section of the plane.
853 @param c The C-Section of the plane.
854 @param t The T-Section of the plane.
855 """
856 byteSwappedPlane = plane.byteswap();
857 convertedPlane = byteSwappedPlane.tostring();
858 rawPixelsStore.setPlane(convertedPlane, z, c, t)
859
860
862 """
863 Upload the plane to the server one row at a time,
864 attching it to the current z,c,t of the already instantiated rawPixelStore.
865 @param rawPixelsStore The rawPixelStore which is already pointing to the data.
866 @param plane The data to upload
867 @param z The Z-Section of the plane.
868 @param c The C-Section of the plane.
869 @param t The T-Section of the plane.
870 """
871 byteSwappedPlane = plane.byteswap()
872
873 rowCount, colCount = plane.shape
874 for y in range(rowCount):
875 row = byteSwappedPlane[y:y+1, :]
876 convertedRow = row.tostring()
877 rawPixelsStore.setRow(convertedRow, y, z, c, t)
878
879
881 """
882 Create the renderingEngine for the pixelsId.
883 @param session The current session to create the renderingEngine from.
884 @return The renderingEngine Service for the pixels.
885 """
886 renderingEngine = session.createRenderingEngine();
887 renderingEngine.lookupPixels(pixelsId);
888 if(renderingEngine.lookupRenderingDef(pixelsId)==0):
889 renderingEngine.resetDefaults();
890 renderingEngine.lookupRenderingDef(pixelsId);
891 renderingEngine.load();
892 return renderingEngine;
893
894
896 """
897 Create the plane rendering def, for z,t
898 @param Z the Z-Section
899 @param T The T-Point.
900 @return The RenderingDef Object.
901 """
902 planeDef = omero.romio.PlaneDef()
903 planeDef.t = t;
904 planeDef.z = z;
905 planeDef.x = 0;
906 planeDef.y = 0;
907 planeDef.slice = 0;
908 return planeDef;
909
911 """
912 Get the rendered Image of the plane for the z, t with the default channels.
913 @param renderingEngine The already instantiated renderEngine.
914 @param z The Z-section.
915 @param t The Timepoint.
916 """
917 planeDef = createPlaneDef(z, t);
918 return renderingEngine.renderAsPackedInt(planeDef);
919
921 """
922 Get the rawPixelsStore for the Image with pixelsId
923 @param pixelsId The pixelsId of the object to retrieve.
924 @return The rawPixelsStore service.
925 """
926 rawPixelsStore = session.createRawPixelsStore();
927 rawPixelsStore.setPixelsId(pixelsId);
928 return rawPixelsStore;
929
931 """
932 Get the rawFileStore for the file with fileId
933 @param fileId The fileId of the object to retrieve.
934 @return The rawFileStore service.
935 """
936 rawFileStore = session.createRawFileStore();
937 rawFileStore.setFileId(fileId);
938 return rawFileStore;
939
941 """
942 Get the plane info for the pixels object returning it in order of z,t,c
943 @param iQuery The query service.
944 @param pixelsId The pixels for Id.
945 @param asOrderedList
946 @return list of planeInfoTimes or map["z:t:c:]
947 """
948 query = "from PlaneInfo as Info where pixels.id='"+str(pixelsId)+"' orderby info.deltaT"
949 infoList = queryService.findAllByQuery(query,None)
950
951 if(asOrderedList):
952 map = {}
953 for info in infoList:
954 key = "z:"+str(info.theZ.getValue())+"t:"+str(info.theT.getValue())+"c:"+str(info.theC.getValue());
955 map[key] = info.deltaT.getValue();
956 return map;
957 else:
958 return infoList;
959
962
963
965 """
966 Simply resests the rendering settings for a pixel set, according to the min and max values
967 The rendering engine does NOT have to be primed with pixelsId, as that is handled by this method.
968
969 @param renderingEngine The OMERO rendering engine
970 @param pixelsId The Pixels ID
971 @param minValue Minimum value of rendering window
972 @param maxValue Maximum value of rendering window
973 @param rgba Option to set the colour of the channel. (r,g,b,a) tuple.
974 """
975
976 renderingEngine.lookupPixels(pixelsId)
977 if not renderingEngine.lookupRenderingDef(pixelsId):
978 renderingEngine.resetDefaults()
979 if rgba == None:
980 rgba=(255,255,255,255)
981
982 if not renderingEngine.lookupRenderingDef(pixelsId):
983 raise "Still No Rendering Def"
984
985 renderingEngine.load()
986 renderingEngine.setChannelWindow(cIndex, float(minValue), float(maxValue))
987 if rgba:
988 red, green, blue, alpha = rgba
989 renderingEngine.setRGBA(cIndex, red, green, blue, alpha)
990 renderingEngine.saveCurrentSettings()
991
992
993 -def createNewImage(pixelsService, rawPixelStore, renderingEngine, pixelsType, gateway, plane2Dlist, imageName, description, dataset=None):
994 """
995 Creates a new single-channel, single-timepoint image from the list of 2D numpy arrays in plane2Dlist
996 with each numpy 2D plane becoming a Z-section.
997
998 @param pixelsService The OMERO pixelsService
999 @param rawPixelStore The OMERO rawPixelsStore
1000 @param renderingEngine The OMERO renderingEngine
1001 @param pixelsType The pixelsType object omero::model::PixelsType
1002 @param gateway The OMERO gateway service
1003 @param plane2Dlist A list of numpy 2D arrays, corresponding to Z-planes of new image.
1004 @param imageName Name of new image
1005 @param description Description for the new image
1006 @param dataset If specified, put the image in this dataset. omero.model.Dataset object
1007
1008 @return The new OMERO image: omero.model.ImageI
1009 """
1010 theC, theT = (0,0)
1011
1012
1013 shape = plane2Dlist[0].shape
1014 sizeY, sizeX = shape
1015 minValue = plane2Dlist[0].min()
1016 maxValue = plane2Dlist[0].max()
1017
1018
1019 channelList = [theC]
1020 sizeZ, sizeT = (len(plane2Dlist),1)
1021 iId = pixelsService.createImage(sizeX, sizeY, sizeZ, sizeT, channelList, pixelsType, imageName, description)
1022 imageId = iId.getValue()
1023 image = gateway.getImage(imageId)
1024
1025
1026 pixelsId = image.getPrimaryPixels().getId().getValue()
1027 rawPixelStore.setPixelsId(pixelsId, True)
1028 for theZ, plane2D in enumerate(plane2Dlist):
1029 minValue = min(minValue, plane2D.min())
1030 maxValue = max(maxValue, plane2D.max())
1031 if plane2D.size > 1000000:
1032 uploadPlaneByRow(rawPixelStore, plane2D, theZ, theC, theT)
1033 else:
1034 uploadPlane(rawPixelStore, plane2D, theZ, theC, theT)
1035 pixelsService.setChannelGlobalMinMax(pixelsId, theC, float(minValue), float(maxValue))
1036 resetRenderingSettings(renderingEngine, pixelsId, theC, minValue, maxValue)
1037
1038
1039 if dataset:
1040 link = omero.model.DatasetImageLinkI()
1041 link.parent = omero.model.DatasetI(dataset.id.val, False)
1042 link.child = omero.model.ImageI(image.id.val, False)
1043 gateway.saveAndReturnObject(link)
1044
1045 return image
1046
1047
1061
1062
1064 """
1065 Get the ROI from the server for the image with the namespace
1066 @param iROIService The iROIService object
1067 @param imageId The imageId to retreive ROI from.
1068 @param namespace The namespace of the ROI.
1069 @return See above.
1070 """
1071 roiOpts = ROIOptions();
1072 if(namespace!=None):
1073 roiOpts.namespace = namespace;
1074 return iROIService.findByImage(imageId, roiOpts);
1075
1077 """
1078 Convert a list to a Comma Separated Value string.
1079 @param list The list to convert.
1080 @return See above.
1081 """
1082 lenList = len(list);
1083 cnt = 0;
1084 str = "";
1085 for item in list:
1086 str = str + item;
1087 if(cnt < lenList-1):
1088 str = str + ",";
1089 cnt = cnt +1;
1090 return str;
1091
1093 """
1094 Convert a csv string to a list of strings
1095 @param csvString The CSV string to convert.
1096 @return See above.
1097 """
1098 list = csvString.split(',');
1099 for index in range(len(list)):
1100 list[index] = list[index].strip();
1101 return list;
1102
1104 """
1105 Register a workflow with the server, if the workflow does not exist create it and returns it,
1106 otherwise it returns the already created workflow.
1107 @param iQuery The query service.
1108 @param iUpdate The update service.
1109 @param namespace The namespace of the workflow.
1110 @param keywords The keywords associated with the workflow.
1111 @return see above.
1112 """
1113 workflow = iQuery.findByQuery("from Namespace as n where n.name = '" + namespace.val+"'", None);
1114 workflowData = WorkflowData();
1115 if(workflow!=None):
1116 workflowData = WorkflowData(workflow);
1117 else:
1118 workflowData.setNamespace(namespace.val);
1119 splitKeywords = keywords.val.split(',');
1120
1121 SU_LOG.debug(workflowData.asIObject())
1122 for keyword in splitKeywords:
1123 workflowData.addKeyword(keyword);
1124 SU_LOG.debug(workflowData.asIObject())
1125 workflow = iUpdate.saveAndReturnObject(workflowData.asIObject());
1126 return WorkflowData(workflow);
1127
1129 """
1130 Finds the ROI with the given namespace linked to the image. Returns a collection of ROIs.
1131 @param roiService The ROI service.
1132 @param image The image the ROIs are linked to .
1133 @param namespace The namespace of the ROI.
1134 @return see above.
1135 """
1136 roiOptions = omero.api.RoiOptions();
1137 roiOptions.namespace = omero.rtypes.rstring(namespace);
1138 results = roiService.findByImage(image, roiOptions);
1139 roiList = [];
1140 for roi in results.rois:
1141 roiList.append(ROIData(roi));
1142 return roiList;
1143