micro-manager / pycro-manager

Python control of micro-manager for customized data acquisition
https://pycro-manager.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
162 stars 49 forks source link

Tagged Image Memory Leak #398

Closed jsokoloff23 closed 1 year ago

jsokoloff23 commented 2 years ago

Bug summary

Tagged image remains in memory

Code for reproduction

Reproducible in the demo config:


core.startSequenceAcquisition(500, 0., True)

while core.getRemainingImageCount() > 0 or core.isSequenceRunning():
    if core.getRemainingImageCount() > 0:
    tagged = core.popNextTaggedImage()
    else:
        core.sleep(5)

Expected outcome tagged image is removed from memory each time a new image is popped. This is at least how it works in the Beanshell script and in plugins.

Actual outcome

Tagged image remains in memory until Micro-Manager is closed.

Version Info

henrypinkard commented 2 years ago

Looks like something got mixed up at some point for garbage collecting python views of Java objects. Should be fixed in the new pip version (#399). Thanks for the very good bug report!

jsokoloff23 commented 2 years ago

Thanks for the quick fix! One more (hopefully) quick one: when I run the following code through the shell, I get an attribute error 'org_micromanager_remote_RemoteAcquisitionFactory' object has no attribute 'create_acquisition'

path = 'G:'
name = 'acquisition'
with Acquisition(directory=path, name=name, show_display=False) as acq:
    events = multi_d_acquisition_events(num_time_points = 100)
    acq.acquire(events)

I'm new to this acquisition class (right now I'm just using a script I wrote a while back for acquisitions). Am I doing something wrong or is something weird?

It's maybe worth noting that if I don't establish a Core or Studio object, it seems to work fine,

Thanks for developing pycromanager! I was finally able to bridge our NIDAQ controlled galvo mirror program to the rest of our hardware, allowing for hardware triggering like never before! By the way, my colleague Adam Fries says hi.

Best regards, Jonah Sokoloff Parthasarathy Lab University of Oregon

henrypinkard commented 2 years ago

Hi Adam!

That great to hear its worked well for you!

This code works as expected for me:

from pycromanager import Acquisition, multi_d_acquisition_events, Core

core = Core()

with Acquisition(directory="/Users/henrypinkard/tmp", name="tcz_acq", debug=False, show_display=False) as acq:
    # Generate the events for a single z-stack
    events = multi_d_acquisition_events(
        num_time_points=100,
    )
    acq.acquire(events)

print('done')

Is it possible you're using an older version of pycromanager or micromanager? In general always a good idea to stay up to day with the latest nightly build/pip version

jsokoloff23 commented 2 years ago

I think I figured it out. I use the core with convert_camel_case = False. When create_acquisition() is called on the RemoteAcquisitionFactory java object, the method doesn't exist because the method is actually createAcquisition(). I'm fine with just creating a new core object with convert_camel_case = True.

henrypinkard commented 2 years ago

Oh nice. Yeah that makes sense, and that should be fixable

jsokoloff23 commented 1 year ago

Hey Henry, I'm having the same bug but with image objects. See:

Bug summary

Image object remains in memory

Code for reproduction

Reproducible in the demo config (OutOfMemoryException is thrown if Java environment runs out of memory)


for i in range(20):
    core.start_sequence_acquisition(400, 0, True)
    while core.get_remaining_image_count() > 0 or core.is_sequence_running():
        if core.get_remaining_image_count() > 0:
            tagged = core.pop_next_tagged_image()
            studio.data().convert_tagged_image(tagged)
        else:
            core.sleep(5)

Same thing happens if you assign a variable to studio.data().convert_tagged_image(tagged) (ie image).

Expected outcome Image is removed from memory each time a new image is popped. Loop runs without OutOfMemoryException.

Actual outcome

Image remains in memory until Micro-Manager is closed. Throws OutOfMemoryException

Version Info