Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to decode java object returned by using javabridge? #200

Open
vbmade2000 opened this issue Feb 17, 2022 · 10 comments
Open

How to decode java object returned by using javabridge? #200

vbmade2000 opened this issue Feb 17, 2022 · 10 comments

Comments

@vbmade2000
Copy link

vbmade2000 commented Feb 17, 2022

I am trying to call some methods in python package python-bioformats that uses javabridge to call a java lib called Bioformats.

When I call one of those methods, it returns following.
<Java object at 0x246ef80>

How can I check what this object is and how can I use it in python? Docs in Bioformats says it should be HashTable. If it is, I have no idea how to iterate it.

@LeeKamentsky
Copy link
Owner

Hi Malhar - glad you're using bioformats and javabridge. Look at this page for hints on how to do what you want: https://github.com/LeeKamentsky/python-javabridge/blob/master/docs/highlevel.rst

In particular, you probably want to use javabridge.JWrapper. If you use it in something like a Jupyter notebook, you can use code completion to look at the available methods, I think.

The tests might give you a good idea of how to use it:
https://github.com/LeeKamentsky/python-javabridge/blob/master/javabridge/tests/test_wrappers.py

Hope this helps. Please close the issue if it does.

@vbmade2000
Copy link
Author

Hey @LeeKamentsky . I appreciate your reply. The issue is my script doesn't use javabridge directly but through another package called python-bioformat. So, I am not sure if your comments apply in my case.

@LeeKamentsky
Copy link
Owner

They do. python-bioformats uses Javabridge under the hood.

@vbmade2000
Copy link
Author

Yeah that is why I am not sure how to apply what you said, to my problem.

@LeeKamentsky
Copy link
Owner

Post the code you're using to access bioformats that returns your Java object.

@vbmade2000
Copy link
Author

Here is my code.

if __name__ == "__main__":
    javabridge.start_vm(class_path=bioformats.JARS)
    tif_file_path = "/tmp/xyz.tif"
    try:
       with get_image_reader('my_image_key', tif_file_path) as reader:
           r = reader.rdr
           print(f"Metadata: {r.getMetadata()}")
    except Exception as e:
        print(e)
    javabridge.kill_vm()

It prints Metadata: <Java object at 0x26fdf40>.
Now, I don't know how to use this Java object. It has only a single method called addr().

Here is how python-bioformat implements it, in case it helps.
https://github.com/CellProfiler/python-bioformats/blob/c03fb0988caf686251707adc4332d0aff9f02941/bioformats/formatreader.py#L122

@LeeKamentsky
Copy link
Owner

Try something like this:

from javabridge.wrappers import JWrapper
if __name__ == "__main__":
    javabridge.start_vm(class_path=bioformats.JARS)
    tif_file_path = "/tmp/xyz.tif"
    try:
       with get_image_reader('my_image_key', tif_file_path) as reader:
           r = reader.rdr
           metadata = JWrapper(r.getMetadata())
           print(metadata.toString())
           print(metadata.getClass().toString())
    except Exception as e:
        print(e)
    javabridge.kill_vm()

For my TIFF file, this printed

{XResolution=1.0, PhotometricInterpretation=BlackIsZero, MetaDataPhot
ometricInterpretation=Monochrome, ImageLength=2048, BitsPerSample=16, Resolutio
nUnit=None, Compression=Deflate (Zlib), SamplesPerPixel=1, NumberOfChannels=1, 
Software=tifffile.py, MetaMorph=no, ImageWidth=2048, YResolution=1.0}
class java.util.Hashtable

So it's a hashtable and you can do things to look inside it like metadata.keySet() and such.

@vbmade2000
Copy link
Author

It alt least show some meaningful but still unable to iterate the HashTable. I use following code.

           m = JWrapper(r.getGlobalMetadata())
            keys = m.keySet()
           for k in keys.iterator():
               print(k)

It throws java.util.Hashtable$Enumerator@74a2a94c is not a Collection and does not support __iter__. I understand this message but then how to iterate it. If I iterate m then it throws following which is same issue but with long message.


{PhotometricInterpretation=BlackIsZero, MetaDataPhotometricInterpretation=Monochrome, <prop id="number-of-planes" type="int" value="1"/>, Comment=<MetaData>
<PlaneInfo>
</PlaneInfo>
<SetInfo>
</SetInfo>
</MetaData>
, NewSubfileType=2, ImageLength=2048, BitsPerSample=16, Compression=Uncompressed, SamplesPerPixel=1, NumberOfChannels=1, Software=MetaSeries, MetaMorph=no, ImageWidth=2048, Orientation=1st row -> top; 1st column -> left, DateTime=20210204 11:17:35.363, <custom-prop id="Z Thickness" type="float" value="3.98"/>} is not a Collection and does not support __iter__

@vbmade2000
Copy link
Author

Tried this one.

m = JWrapper(r.getGlobalMetadata())
while m.elements().hasMoreElements():
     print(m.elements().nextElement())

It prints BlackIsZero infinitely.

Also, tried following.

while m.keys().hasMoreElements():
    print(m.keys().nextElement())

It prints PhotometricInterpretation infinitely.

@vbmade2000
Copy link
Author

Got success with following code.

           m = JWrapper(r.getMetadata())
            entry_set = m.entrySet()
            entry_set_iterator = entry_set.iterator()
            while entry_set_iterator.hasNext():
                entry = entry_set_iterator.next()
                print(entry.getKey())
                print(entry.getValue())
                print("-----------------")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants