We're Hiring!

Default rendering settings when script creates an image

General and open developer discussion about using OMERO APIs from C++, Java, Python, Matlab and more! Please new questions at https://forum.image.sc/tags/omero
Please note:
Historical discussions about OMERO. Please look for and ask new questions at https://forum.image.sc/tags/omero

If you are having trouble with custom code, please provide a link to a public repository, ideally GitHub.

Default rendering settings when script creates an image

Postby a.herbert » Thu Aug 04, 2011 11:08 am

Hi,

I am using the Gateway API to create new images. I have scripts that work on multi-channel images and create new images using createImageFromNumpySeq().

I would like to know the best way to set up the default rendering settings for the image. I have managed to do this using the following code:

Code: Select all
def cloneImage(conn, img):
    """
    Clone the image into the same dataset in OMERO.
   
    @param conn:   The BlitzGateway connection
    @param img:    The OMERO ImageWrapper object
    """
    imageName = os.path.basename(img.getName())
    print "Image Id = %s" % img.getId()
    print "Image name = %s" % imageName
    print "Dimensions = x%s,y%s,z%s,c%s,t%s" % (
        img.getSizeX(), img.getSizeY(), img.getSizeZ(), img.getSizeC(), img.getSizeT() )

    renderingEngine = conn.createRenderingEngine()
    updateService = conn.getUpdateService()

    pixels = img.getPrimaryPixels()
   
    Z = range(img.getSizeZ())
    C = range(img.getSizeC())
    T = range(img.getSizeT())

    # Store original channel colours and names
    colors = []
    cNames = []
    for index, c in enumerate(img.getChannels()):
        colors.append(c.getColor().getRGB())
        cNames.append(str(c.getLabel()))

    # Use a tile generator to join up multiple frame image and upload to OMERO
    def tileGen():
        for z in Z:
            for c in C:
                for t in T:
                    # ACTUAL PROCESSING WOULD BE DONE HERE
                    yield pixels.getPlane(z, c, t)
   
    newImg = conn.createImageFromNumpySeq(tileGen(),
        img.getName(), len(Z), len(C), len(T),
        img.getDescription(), dataset=img.getDataset())

    print "New Image Id = %s" % newImg.getId()
   
    # Apply colors from the original image to the new one
    newImg._prepareRenderingEngine()
    for c, color in enumerate(colors):
        r,g,b = color
        newImg._re.setRGBA(c, r, g, b, 255)
    newImg._re.saveCurrentSettings()
    newImg._re.close()

    # Apply the original channel names
    pixelsId = newImg.getId()
    renderingEngine.lookupPixels(pixelsId)
    if not renderingEngine.lookupRenderingDef(pixelsId):
        renderingEngine.resetDefaults() 
    renderingEngine.load()
    pixels = renderingEngine.getPixels()
    for i, c in enumerate(pixels.iterateChannels()):
        lc = c.getLogicalChannel()
        lc.setName(rstring(cNames[i]))
        updateService.saveObject(lc)
       
    # Apply the original pixel size - Need to get the object again to refresh state
    newImg = conn.getObject("Image", newImg.getId())
    pixels = newImg.getPrimaryPixels()
    pixels.setPhysicalSizeX(rdouble(img.getPixelSizeX()))
    pixels.setPhysicalSizeY(rdouble(img.getPixelSizeY()))
    pixels.setPhysicalSizeZ(rdouble(img.getPixelSizeZ()))
    pixels.save()


This sets the rendering colours, channel names and physical size using the original image.

However the colours are not set as the defaults and are only applied to the user who owns the connection object:

  • If the owner opens the image in OMERO Insight and, using the rendering controls, resets the image to defaults the channel colours get reset
  • Other users do not see the applied colours

Is there a way to set the default channel colours for all users?

Thanks,

Alex
a.herbert
 
Posts: 53
Joined: Tue Jan 11, 2011 1:35 pm

Re: Default rendering settings when script creates an image

Postby wmoore » Thu Aug 04, 2011 12:45 pm

Hi Alex,

There are a couple of things going on here:

If you view another user's images in a "collaborative" group, you will see the 'default' rendering settings on the image (not the owners settings). In Insight, under the right-hand "Preview" tab, the 'viewed by' button will let you browse and apply other user's rendering settings.
In a "read-only" group, where you can't save your own rendering settings, all users will only see the owner's settings. We could extend this approach to "collaborative" groups too, but we'd need to be sure this was behavior that most users would want.

Having just asked Chris about this...
It seems the right solution would be to set the colors on the Channels of the new image.
E.g. channel.red, green, blue are 0-255.
Most images don't have these values set - we use wavelength metadata to choose 'default' rendering settings. But if set, then by default, these colors should be used for all users.

I haven't tried this myself just now, but should be something like
Code: Select all
    for i, c in enumerate(pixels.iterateChannels()):
        c.red = 255
        c.green = 0
        c.blue = 0
        updateService.saveObject(c)


Hope that works!

Will.
User avatar
wmoore
Team Member
 
Posts: 674
Joined: Mon May 18, 2009 12:46 pm

Re: Default rendering settings when script creates an image

Postby a.herbert » Thu Aug 04, 2011 2:10 pm

Hi Will,

I tried setting the RGB colour values directly into the channel. This did not work. So I tried settings the metadata instead. I was already setting the channel name into the logical channel object. I just added the emission and excitation wavelength from the original image. The new image then renders as expected.

Here is my modified code:

Code: Select all
def cloneImage(conn, img):
    """
    Clone the image into the same dataset in OMERO.
   
    @param conn:   The BlitzGateway connection
    @param img:    The OMERO ImageWrapper object
    """
    imageName = os.path.basename(img.getName())
    print "Image Id = %s" % img.getId()
    print "Image name = %s" % imageName
    print "Dimensions = x%s,y%s,z%s,c%s,t%s" % (
        img.getSizeX(), img.getSizeY(), img.getSizeZ(), img.getSizeC(), img.getSizeT() )

    renderingEngine = conn.createRenderingEngine()
    updateService = conn.getUpdateService()

    pixels = img.getPrimaryPixels()
   
    Z = range(img.getSizeZ())
    C = range(img.getSizeC())
    T = range(img.getSizeT())

    # Store original channel details
    cNames = []
    emWave = []
    exWave = []
    for index, c in enumerate(img.getChannels()):
        lc = c.getLogicalChannel()
        cNames.append(str(c.getLabel()))
        emWave.append(lc.getEmissionWave())
        exWave.append(lc.getExcitationWave())
        print "Label = %s " % cNames[-1]
        print "ExW   = %s " % exWave[-1]
        print "EmW   = %s " % emWave[-1]

    # Use a tile generator to join up multiple frame image and upload to OMERO
    def tileGen():
        for z in Z:
            for c in C:
                for t in T:
                    yield pixels.getPlane(z, c, t)
   
    newImg = conn.createImageFromNumpySeq(tileGen(),
        img.getName(), len(Z), len(C), len(T),
        img.getDescription(), dataset=img.getDataset())

    print "New Image Id = %s" % newImg.getId()
   
    # Apply settings from the original image to the new one
    newImg._prepareRenderingEngine()

    pixelsId = newImg.getId()
    renderingEngine.lookupPixels(pixelsId)
    if not renderingEngine.lookupRenderingDef(pixelsId):
        renderingEngine.resetDefaults() 
    renderingEngine.load()
    pixels = renderingEngine.getPixels()
   
    for i, c in enumerate(pixels.iterateChannels()):
        lc = c.getLogicalChannel()
        lc.setEmissionWave(rint(emWave[i]))
        lc.setExcitationWave(rint(exWave[i]))
        lc.setName(rstring(cNames[i]))
        updateService.saveObject(lc)

    renderingEngine.resetDefaults() 

    # Apply the original pixel size - Need to get the object again to refresh state
    newImg = conn.getObject("Image", newImg.getId())
    pixels = newImg.getPrimaryPixels()
    pixels.setPhysicalSizeX(rdouble(img.getPixelSizeX()))
    pixels.setPhysicalSizeY(rdouble(img.getPixelSizeY()))
    pixels.setPhysicalSizeZ(rdouble(img.getPixelSizeZ()))
    pixels.save()


Regards,

Alex
a.herbert
 
Posts: 53
Joined: Tue Jan 11, 2011 1:35 pm

Re: Default rendering settings when script creates an image

Postby wmoore » Thu Aug 04, 2011 2:36 pm

Hi Alex,

Glad you got it working.
I'll look into this a bit more when I have time. It gets more complex if the images don't have channel wavelengths set, since we then use excitation and emission filters on channels!

Cheers,

Will.
User avatar
wmoore
Team Member
 
Posts: 674
Joined: Mon May 18, 2009 12:46 pm

Re: Default rendering settings when script creates an image

Postby a.herbert » Thu Aug 04, 2011 3:44 pm

Hi Will,

If you can let me know the order in which OMERO goes through the meta data to assign colours that would be useful. I can then make sure my script copies all the meta-data that is needed to make the new images 'appear' normal to the user.

So far all my test images have worked since they have the wavelength data. If I find one without then that is when I'll need to add more to my script.

Regards,

Alex
a.herbert
 
Posts: 53
Joined: Tue Jan 11, 2011 1:35 pm

Re: Default rendering settings when script creates an image

Postby wmoore » Thu Aug 04, 2011 4:06 pm

I can't remember the exact code/order, but I believe it's something like

* Emission Wavelength
* Excitation Wavelength
* LightPath/Emission Filter/CutIn
* LightPath/Excitation Filter/CutIn & CutOut
* Possibly also use Laser wavelength?? Channel/LightSourceSettings/LightSource ?

Also, if we have emission data for some channels and not for others, then we assume those are grey (transmitted light).

Will.
User avatar
wmoore
Team Member
 
Posts: 674
Joined: Mon May 18, 2009 12:46 pm

Re: Default rendering settings when script creates an image

Postby cxallan » Thu Aug 11, 2011 7:50 am

wmoore wrote:...

I haven't tried this myself just now, but should be something like
Code: Select all
    for i, c in enumerate(pixels.iterateChannels()):
        c.red = 255
        c.green = 0
        c.blue = 0
        updateService.saveObject(c)


Hope that works!

Will.


The channel colours have the highest priority but all four values (red, green, blue and alpha) must be set, so you will need something like:

Code: Select all
    for i, c in enumerate(pixels.iterateChannels()):
        c.red = 255
        c.green = 0
        c.blue = 0
        c.alpha = 255
        updateService.saveObject(c)
cxallan
Site Admin
 
Posts: 509
Joined: Fri May 01, 2009 8:07 am


Return to Developer Discussion

Who is online

Users browsing this forum: Google [Bot] and 1 guest