Git Product home page Git Product logo

Comments (6)

AlexCoul avatar AlexCoul commented on June 11, 2024

from opm.

ptbrown1729 avatar ptbrown1729 commented on June 11, 2024

One comment on my fork: right now the DAQ acquisition is all run in the main thread. So to avoid freezing the GUI this will need to run on a separate thread. I don't know if the way Doug is doing this in his control code can be used in napari-micromanager to accomplish this. But either way, that is one important problem I did not try to solve yet

from opm.

ianhi avatar ianhi commented on June 11, 2024

I just today implemented a way for users of pymmcore-plus to register an acquistion engine to be use by pymmcore-plus. (https://github.com/tlambert03/pymmcore-plus/pull/102) see docs here: https://pymmcore-plus.readthedocs.io/en/latest/examples/mda.html#registering-a-new-mda-engine

If you implement a custom acquisition engine (basically a blocking for loop with signals emitted) then you should be able to register it with the core instance and take advantage of core.run_mda running in a thread and thus not blocking the GUI.

Something like this:

from useq import MDASequence
from pymmcore_plus import CMMCorePlus

from pymmcore_plus.mda import MDAEngine, PMDAEngine
from pymmcore_plus.mda.events import QMDASignaler # qt version best when integrating with QT
# or
# from pymmcore_plus.mda.events import MDASignaler

core = CMMCorePlus.instance()
core.loadSystemConfiguration()

# from scratch
class from_scratch_engine(PMDAEngine):
    # in this class you need to integrate everything
    ...


# inheriting
# not perfectly designed for inheritance, but still handy.
class my_acq_engine(MDAEngine):
    def __init__(self) -> None:
        super().__init__(CMMCorePlus.instance())
        # any other setup you want to do

    def run(self, seq: MDASequence):
        # implement your own loop here
        # You should occasinally check self._canceled or self._paused
        ...


acq_eng = my_acq_engine()
core.register_mda_engine(acq_eng)

seq = ...

# this will run in a thread!
core.run_mda(seq)

I know that the MDAEngine isn't ideal for inheritance but it sitll would help get you started. You would need to override the run method: https://github.com/tlambert03/pymmcore-plus/blob/8f320b4d14571b942e75cd7f6e7079ae8f415249/pymmcore_plus/mda/_engine.py#L68

There's also some information about using threads in this example: https://pymmcore-plus.readthedocs.io/en/latest/examples/integration-with-qt.html though it needs to be updated to include the decorator used here: https://github.com/tlambert03/napari-micromanager/pull/114

Adapting the OPM control code to take advantage of these changes might help clean up the intermittent acquisition errors in my custom Napari based control code.

What errors were these? Do they look anything like: https://github.com/tlambert03/pymmcore-plus/issues/43 ?

from opm.

dpshepherd avatar dpshepherd commented on June 11, 2024

hi @ianhi ,

Interesting! I am not super familiar with callbacks, etc... Hopefully I'll have some time once the semester is over to look into this more.

The hacky code that I wrote runs into a weird memory type error. The basic outline is:

  • Launch RemoteMMCore before starting Napari
  • Start Napari with a set of widgets using magic-gui defined components
  • press button in GUI that calls function decorated as a thread_worker using Napari threading logic
    • loop n times (n>20)
    • open a "with" block accessing the RemoteMMCore
    • modify some hardware
    • run an acquisition using startSequenceAcquisition

Once you do that enough time (say 20 loop iterations), Python crashes and says that it is out of memory. Except I can't find any logs or other indication that memory is actually being used up.

If one acquires the same amount of data is acquired in one acquisition (no looping), no memory error occurs.

I know this is a bit vague and I haven't had the bandwidth to troubleshoot, so I don't have much more to say right now.

Edit: added more information that the function is decorated and called as a Napari thread_worker from the Napari GUI.

from opm.

ianhi avatar ianhi commented on June 11, 2024

Interesting! I am not super familiar with callbacks, etc... Hopefully I'll have some time once the semester is over to look into this more.

I'm thinking taht we will probably need a more concrete example (and a better inheritance model) to make this easier for people. When you do have the time to look into feel free to ask for guidance - can definitely be confusing. It will essnetially boil down to making calls like: self.events.frameReady.emit(img, Event) every time you take a new time.

Once you do that enough time (say 20 loop iterations), Python crashes and says that it is out of memory. Except I can't find any logs or other indication that memory is actually being used up.

yikes. Definitely sounds like something that would be fixed by switching away from RemoteMMCore. Where does that code live? I have a look an maybe suggest what the simplest (hopefully crash free) replacement would be.

The other thing if you're using sequenceAcquistion (especially with multiple cameras) you should definitely read this: micro-manager/mmCoreAndDevices#171

from opm.

dpshepherd avatar dpshepherd commented on June 11, 2024

The other thing if you're using sequenceAcquistion (especially with multiple cameras) you should definitely read this: micro-manager/mmCoreAndDevices#171

Yeah, we had to figure all that out because when I started the lab, we controlled a lot of scopes with Beanshell scripts to control the core instead of Python.

Excited to see where this all this goes!

from opm.

Related Issues (6)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.