Giter Site home page Giter Site logo

micro-manager / pycro-manager Goto Github PK

View Code? Open in Web Editor NEW
158.0 158.0 50.0 41.06 MB

Python control of micro-manager for customized data acquisition

Home Page: https://pycro-manager.readthedocs.io/en/latest/

License: BSD 3-Clause "New" or "Revised" License

Shell 0.01% Python 12.31% Java 6.69% Jupyter Notebook 80.91% C++ 0.07%

pycro-manager's Introduction

Micro-Manager

Micro-Manager is an application to control microscope hardware, such as cameras, xy-stages, filter wheels, etc. It includes a hardware abstraction layer written in C++ and a user interface written in Java (Swing).

Go to micro-manager.org for documentation and binary downloads.

For support, see Micro-Manager Community.

The Micro-Manager community welcomes you! For our governance structures, go here

Source code

This repository contains the Java projects that make up the Micro-Manager "MMStudio" GUI application. The device control layer is written in C++ and found in a separate repository, mmCoreAndDevices, which is currently a git submodule of this repository.

To checkout both repositories together:

git clone --recurse-submodules https://github.com/micro-manager/micro-manager.git

If you will be making changes to the code, make sure to enable pre-commit hooks as described in doc/pre-commit.md.

Branches

  • main - the main branch of development (Micro-Manager 2.x)
  • svn-mirror - git-svn mirror of the Micro-Manager 1.4 Subversion repository

Other branches are not official.

Developer information

For license information, please see doc/copyright.txt.

For build instructions, please see the doc/how-to-build.md.

Additional information is available on the Micro-Manager website at https://micro-manager.org

Contributing

Start here: https://micro-manager.org/Building_and_debugging_Micro-Manager_source_code

pycro-manager's People

Contributors

binli123 avatar binyangoptics avatar carlkesselman avatar chrisweisiger avatar ckolluru avatar dpshepherd avatar friendly-mm-pr-robot[bot] avatar github-actions[bot] avatar henrypinkard avatar ianhi avatar ieivanov avatar ilyasdc avatar impact27 avatar ischoegl avatar jacopoabramo avatar marktsuchida avatar mdanderson03 avatar mutterer avatar nanthony21 avatar nicost avatar oeway avatar raymonddunn avatar rmeit avatar talonchandler avatar tommasogritti avatar wl-stepp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pycro-manager's Issues

Incorrect arguments exception

I am running this simple code to move the stage in XY:

from pycromanager import Bridge

bridge = Bridge()
core = bridge.get_core()

core.set_relative_xy_position(core.get_xy_stage_device(), 100.0, 0)

I am getting the following error:

Exception: Incorrect arguments.
Expected double, double or java.lang.String, double, double
Got <class 'str'>, <class 'int'>, <class 'int'>

This worked OK a few commits ago (late June). Any ideas?

Can't create display settings

I am trying to modify the display settings for one of micromanager windows. If I understood the doc correctly, this is the way of creating display settings:

from pycromanager import Bridge
bridge = Bridge(convert_camel_case=False)
mmStudio = bridge.get_studio()
displayManager = mmStudio.displays()
dsb = displayManager.displaySettingsBuilder()
display_settings = dsb.build()

But running this, I get:

Exception: java.lang.IllegalAccessException: Class org.micromanager.internal.zmq.ZMQServer can not access a member of class org.micromanager.display.internal.DefaultDisplaySettings$Builder with modifiers "public"

PS: I find it easier to work with acquisitionSettings. The code I use is:

    from pycromanager import Bridge
    bridge = Bridge(convert_camel_case=False)
    acquisition_manager = mmStudio.acquisitions()
    settings = bridge.construct_java_object(
        'org.micromanager.acquisition.SequenceSettings')
    settings.intervalMs = int(interval  * 1000)
    settings.numFrames = numFrames
    settings.prefix = experiment_name
    settings.root = save_dir
    settings.save = True
    settings.shouldDisplayImages = True
    settings.comment = comments
    acquisition_manager.runAcquisitionWithSettings(settings, False)

Is there a reason why I couldn't do something similar with display settings?

Access to static Java classes

There's currently no way to access static fields of a class without creating an instance of that class. The solution is most likely to create a parallel function to construct_java_object, construct_java_class, which just gets you a Python version of the class plus static methods + fields. This will require changes in core.py as well as in ZMQServer.java

Switch from default multiprocessing to default threading

Acquisition hooks, image processors, and acquisition events all operate on different threads so that they can operate asynchronously whenever possible. Right now this is implemented using python's multiprocessing module, to ensure that global interpreter lock issues don't slow down CPU bounded computations. However, multiprocessing has several unfortunate downsides, particularly on windows (like #94). So the default behavior should instead switch to using threading, and process based parallelism for high compute applications will have to explicitly turn it on

Faster Java-Python transport layer

The ZeroMQ library that pycro-manager uses to pass data and messages between Java and Python has a speed limitation somewhere on the order of 100-200 MB/s. The prevents image processors from being useful in acquisitions with the fastest data rates. It is possible that a faster library could be used in the transport layer, or that there are other bottlenecks in message passing that could be fixed to improve performance

Bridge.get_studio raises exception

Here is the traceback:

Traceback (most recent call last):
  File "C:/Users/nicke/Documents/git/pycro-manager/pycromanager/core.py", line 459, in <module>
    s = b.get_studio()
  File "C:/Users/nicke/Documents/git/pycro-manager/pycromanager/core.py", line 205, in get_studio
    return self.construct_java_object('org.micromanager.Studio')
  File "C:/Users/nicke/Documents/git/pycro-manager/pycromanager/core.py", line 150, in construct_java_object
    valid_method_spec = _check_method_args(methods_with_name, args)
  File "C:/Users/nicke/Documents/git/pycro-manager/pycromanager/core.py", line 398, in _check_method_args
    ', '.join([str(type(a)) for a in fn_args]) ))
Exception: Incorrect arguments. 
Expected  
Got 

This appears to be an issue with the logic in _check_method_args_ but I'm not sure.

ForkingPickler can't pickle

Hi,
I was trying out the pycro-manager with democamera config in microanager-gamma (14May nightly build) in a jupyter notebook with the following codes as documented.

from pycromanager import Acquisition, multi_d_acquisition_events

with Acquisition(directory=r'C:\Users\biswajitpradha\Reseach\analysis\PycroManager\data', name='acquisition_name') as acq:
    events = multi_d_acquisition_events(
                                    num_time_points=4, time_interval_s=0,
                                    channel_group='channel', channels=['DAPI', 'FITC'],
                                    z_start=0, z_end=6, z_step=0.4,
                                    order='tcz')

But it showed an error:

AttributeError: Can't pickle local object 'Acquisition.__init__.<locals>.event_sending_fn'

full error pic:
image

Do you know what's going wrong here?

Thanks, Biswajit

Access to class methods

Some part of the API call directly to classes, which the bridge doesn't let me do (as far as I know). For example:

import org.micromanager.data.Datastore;
import org.micromanager.data.internal.DefaultDatastore;
DefaultDatastore.setPreferredSaveMode(mmStudio_,
    Datastore.SaveMode.SINGLEPLANE_TIFF_SERIES);

Here, I want to call a function in DefaultDatastore and I want to access an enumeration in Datastore. The solution I found which I don't feel like is very nice is:

# Construct object as we can't access classes
datastore = bridge.construct_java_object(
    'org.micromanager.data.internal.DefaultDatastore',
    args=(mmStudio,))
# Use getPreferredSaveMode as we can't access the enum in Datastore.SaveMode
save_mode = mmStudio.data().getPreferredSaveMode().SINGLEPLANE_TIFF_SERIES
# Add interface because interface is listed as
# org.micromanager.data.Datastore$SaveMode
save_mode._interfaces.append('org.micromanager.data.Datastore.SaveMode')
datastore.setPreferredSaveMode(mmStudio, save_mode)

Is there a better way of doing that?

PS: _check_method_args doesn't recognise:
'org.micromanager.data.Datastore.SaveMode' as
'org.micromanager.data.Datastore$SaveMode'

irregular lagging when calling snap_image function

Wondering is normal to see the snap_image function lagging frequently when running it in a for loop.

If I run the following code:

for i in range(1000):
    start = time.time()
    core.snap_image()
    tagged_image = core.get_tagged_image()
    print('execution time', str(time.time()-start))

I get most of the small execution time (e.g. 0.01), but sometimes goes much bigger (e.g. 10).

execution time 0.011862993240356445
execution time 0.011394023895263672
execution time 0.012370824813842773
execution time 0.011996030807495117
execution time 0.01181483268737793
execution time 0.01213693618774414
execution time 0.012043952941894531
execution time 0.012295961380004883
execution time 0.012087106704711914
execution time 0.011587858200073242
execution time 0.011800050735473633
execution time 0.011947154998779297
execution time 10.005636215209961 <--------------------
execution time 5.281268358230591
execution time 0.011175155639648438
execution time 0.012015819549560547

If I remove the get_tagged_image call, the issue remains.

Any solution to this? Maybe using continuous acquisition mode and the circular buffer would solve this? Do you have any example which start_continuous_sequence_acquisition and we call get_tagged_image as we want?

Edit: It seems better with start_continuous_sequence_acquisition and stop_sequence_acquisition. Here is my code:

core.start_continuous_sequence_acquisition()
for i in range(100):
    image = core.get_tagged_image()
    display_or_save(image)
core.stop_sequence_acquisition()

Still wondering whether this is the right way to do stuff and why it becomes laggy with snap_image.

Bridge.get_core() raises Exception

Here is the traceback

Traceback (most recent call last):
  File "C:/Users/nicke/Documents/git/pycro-manager/pycromanager/core.py", line 463, in <module>
    c = b.get_core()
  File "C:/Users/nicke/Documents/git/pycro-manager/pycromanager/core.py", line 198, in get_core
    self.core = self.construct_java_object('mmcorej.CMMCore')
  File "C:/Users/nicke/Documents/git/pycro-manager/pycromanager/core.py", line 165, in construct_java_object
    convert_camel_case=self._convert_camel_case)
  File "C:/Users/nicke/Documents/git/pycro-manager/pycromanager/core.py", line 233, in __init__
    exec('setattr(self, method_name_modified, MethodType(fn, self))')
  File "<string>", line 1, in <module>
NameError: name 'MethodType' is not defined

This appears to be caused by the usage exec. I'm not sure I understand the reasoning for using exec but I would caution against it if it's not absolutely necessary.

Acquisition doesn't acquire images

With micromanager I can acquire a stack of 10 images:
mm_interface
I would like to do the same with pycromanager. I replaced the acquisition engine as instructed in #41 and run this code:

from pycromanager import Acquisition, multi_d_acquisition_events

if __name__ == '__main__': #this is important, don't forget it

    with Acquisition(directory='C:/Users/Quentin.Peter/Desktop/tmp0', name='acquisition_name') as acq:
        events = multi_d_acquisition_events(10)
        acq.acquire(events)

A folder is created (C:/Users/Quentin.Peter/Desktop/tmp0/acquisition_name_1/Full resolution) and the following windows appears:
interface

But then nothing happens. The python code is stuck in Acquisition.await_completion. If I try to close the window, it asks if I want to Finish acquisition? and I I press OK, the python code finishes.

java.lang.NullPointerException error when calling dataset.has_image

Hi, I am following the example by doing:

from pycromanager import Acquisition
with Acquisition('./test-pycromanager-dataset', 'test1', tile_overlap=10) as acq:

        acq.acquire({'row': 0, 'col': 0})
        acq.acquire({'row': 1, 'col': 0})
        acq.acquire({'row': 0, 'col': 1})

        dataset = acq.get_dataset()
        dataset.has_image(row=0, col=0, resolution_level=1)
        dataset.read_image(row=0, col=0, resolution_level=1)

And the acquisition seems to be working and I can get the files on disk, but I am getting the following error:

Exception                                 Traceback (most recent call last)
<ipython-input-1-79df877bec01> in <module>
      7 
      8         dataset = acq.get_dataset()
----> 9         dataset.has_image(row=0, col=0, resolution_level=1)
     10         dataset.read_image(row=0, col=0, resolution_level=1)

~/miniconda3/lib/python3.7/site-packages/pycromanager/data.py in has_image(self, channel, z, time, position, channel_name, resolution_level, row, col, **kwargs)
    506                 axes.put(key, kwargs[key])
    507             if row is not None and col is not None:
--> 508                 return self._remote_storage.has_tile_by_row_col(axes, resolution_level, row, col)
    509             else:
    510                 return self._remote_storage.has_image(axes, resolution_level)

~/miniconda3/lib/python3.7/site-packages/pycromanager/core.py in <lambda>(instance, signatures_list, *args)
    261                 params, methods_with_name, method_name_modified = _parse_arg_names(methodSpecs, method_name, convert_camel_case)
    262                 return_type = methods_with_name[0]['return-type']
--> 263                 fn = lambda instance, *args, signatures_list=tuple(methods_with_name): instance._translate_call(signatures_list, args)
    264                 fn.__name__ = method_name_modified
    265                 fn.__doc__ = "{}.{}: A dynamically generated Java method.".format(_java_class, method_name_modified)

~/miniconda3/lib/python3.7/site-packages/pycromanager/core.py in _translate_call(self, method_specs, fn_args)
    348 
    349         self._socket.send(message)
--> 350         return self._deserialize(self._socket.receive())
    351 
    352     def _deserialize(self, json_return):

~/miniconda3/lib/python3.7/site-packages/pycromanager/core.py in receive(self, timeout)
     95                 return reply
     96         message = json.loads(reply.decode('utf-8'))
---> 97         self._check_exception(message)
     98         return message
     99 

~/miniconda3/lib/python3.7/site-packages/pycromanager/core.py in _check_exception(self, response)
    100     def _check_exception(self, response):
    101         if ('type' in response and response['type'] == 'exception'):
--> 102             raise Exception(response['value'])
    103 
    104     def close(self):

Exception: java.lang.NullPointerException

Exception: java.lang.RuntimeException: Internal class accidentally exposed

The following calls have caused this java exception to be reported, I am sure there are many other ways to cause it as well.

  • Any call to a method of `Bridge.get_studio().plugins() in an attempt to access a plugin.
  • Any call to a method of Bridge.get_studio().skin()

As a side note, it may be helpful if a java traceback was included with exceptions.

Read multi-resolution tiles during acquisition

I am following the xy_tilling example, however, it's not clear to me how can I get the image tiles during acquisition for real-time display.

Ideally, I would like to initiate an acquisition with tile size, tile_overlap, but also levels to specify how many resolution to be generated. Right after I call acq.acquire({'row': i, 'col': j}) I would like to access to all the resolution levels for {'row': i, 'col': j}. Is this what you would do?

Snap image is much slower and laggy compared to pymmcore

I am comparing the performance of pycormanager with pymmcore by looping snap and get images, it appears that pycromanager is much more laggy and slower. See the following GIFs:

  1. Using pymmcore, it's very fast and the images shows instantly (source code notebook):
    pymmcore_performance

  2. Using pycromanager, it's much more laggy and the acquisition was blocked for a while the come again(source code notebook):
    pycromanager-performance

The tests were done on the same computer (MacOS 10.14.6), same Jupyter notebook, same micro-manager(2.0.0 gamma1-20200824) and config file, and I can reliably reproduce the result.

Any idea why?

unable to successfully connect micromanager

Hi!
i'm sorry I think it's a basic issue but I couldn't find out how to solve it.
After installing pycromanager and the last version of micromanager, the two initial lines of codes gave this

In [1]:from pycromanager import Bridge
bridge = Bridge()
bridge.get_core()
Out[1]: <pycromanager.core.mmcorej_CMMCore at 0x172fdcfdac8>

then any command to micromanager would not do anything (without throwing any exception)
Thanks!

Add support for sequence acquisitions with external triggering

Pycro-manager by default supports hardware triggered acquisitions where the camera is the master device. An alternative to this are situations where where there is another master device and the camera waits to receive triggers from it. Implementing this situation will require a new acquisition hook that runs after the camera has been told to start waiting for triggered acquisitions. This hook will be used to send a custom command to whatever devices is the master of the triggering setup.

Why not use Py4J

As far as I can tell py4j does the same thing as pycromanager when it comes to general-purpose Java/Python interfacing via sockets. Py4J is fairly mature, well-documented, and is used in other major projects. It also implements handling for things which I don't believe are in pycromanager such as exception handling, multithreading etc.

If pycromanager relied on py4j rather than implementing all the low-level language interfacing from scratch via zmq then that would free up much more development time for functionality that is specific to Micro-Manager.

Full/advanced examples - interact with MM's preview window?

I am currently looking into pycro-manager and was wondering whether it is possible to automate image acquisition while showing the images using micro-manager's own preview windows (MM is already open, which would make this an alternative to matplotlib)

The low level example works well, and I have started to look into MMStudio via Micro-manager Java APIs. While I have located DisplayManager, DataManager, Image, DataStore, DisplayController etc., I have thus far been unable to open a new (or even interact with an existing) preview window.

I realize that pycro-manager is fairly new and some interfaces may not be complete, and it may not be possible to instantiate some objects from Python? There aren't many examples to go from right now so any pointers would be appreciated! Thanks!

PS: Here's the extent of what I've located

# org_micromanager_internal_MMStudio  
studio = bridge.get_studio()

# org_micromanager_display_internal_DefaultDisplayManager
d = studio.displays()

# org_micromanager_display_internal_displaywindow_DisplayController
disp = d.get_active_data_viewer() # <-- a currently open Preview window

# org_micromanager_data_internal_DefaultRewritableDatastore
disp.get_data_provider()

# org_micromanager_data_internal_DefaultDataManager
dd = studio.data()

# org_micromanager_data_internal_DefaultDatastore
dd.create_ram_datastore()

# org_micromanager_data_internal_DefaultRewritableDatastore
dd.create_rewritable_ram_datastore()

# org_micromanager_data_internal_DefaultImage
im = dd.convert_tagged_image(img)

# org_micromanager_data_internal_DefaultCoords
im.get_coords()

Expanded automatic testing

Incorporate some automatic testing framework (pytest?) to run all the examples, and add addition edge case examples of things one might do using Java-Python bridge.

Since almost all of these tests would need to run with micro-manager already running, it would probably be difficult to have github do this automatically, but it should be feasible to have a single script that can be run locally to do it

Feature: Add keep_shutter_open option

It would be nice to add a keep_shutter_open option which will keep the shutter open when acquiring data along any given axis (time, channel, z, custom, etc.). Currently the shutter is closed after every slice of a z stack.

generated method signatures can be misleading for overloaded java methods

The signature for Bridge().get_core().set_roi looks like this (string, int, int1, int2, int3=None)

When it really should look more like (string=None, int, int1, int2, int3), however this wouldn't be allowed by Python. The method still works as expected for both overloads, it is just the signature that can be incorrect.

Unexpected problems on windows due to multiprocessing

Pycro-manager acquisitions use multiple threads in order to asynchronously execute different parts of the acquisition cycle. These correspond to different threads on the Java side as well. Specifically, sending acquisition events, running acquisition hooks, and running image processors should each occur separately, such that one does not block another, and none interferes with the main thread. Right now, this is achieved using python's multiprocessing module, so that each of theses actions occurs in its own dedicated process. However, multiprocessing can behave in non-intuitive ways on windows, leading to unexpected issues (#9, #42).

One alternative to this behavior might be to use python's threading module instead. For acquisition events it would be pretty easy to swap in multiple threads instead of multiple processes, and I doubt there would much (if any) performance hit, but image processors and acquisition hooks run by the same mechanism, and if using both at the same time global interpreter lock blocking could become a problem. Ideally, there could be a change that would cover all three cases, but I've yet to figure out what that could be. It might make sense in the mean time to switch all three cases to using threads to ensure that simple use cases work as expected, and allow swapping in of processes for more performant use cases.

Continuous acquisition (aka Burst mode) not implemented

In Micromanager setting the time point interval to 0 seconds runs the camera in continuous acquisition mode, in which the camera controls the acquisition rate and Micromanager listens for arriving images until the requested total number of images is received.

https://micro-manager.org/wiki/Micro-Manager_User%27s_Guide#Multi-dimensional_acquisition

When time_interval_s = 0, pycromanager instead still triggers acquisition of frames one-by-one. The resulting acquisition rate is low and unpredictable.

It'll be great to implement continuous acquisition mode when time_interval_s = 0. Continuous acquisition can also be run when all acquisition hardware (e.g. light sources or stages) are controlled through electronic signals: https://micro-manager.org/wiki/Hardware-based_Synchronization_in_Micro-Manager

Garbled images in image processor functions using non-square images

Hi,

we had problems running pycromanager acquisitions together with an image processor on non-square images. Images in the image processor function are garbled and have swapped height and width. Modifications made to images in the processor functions are also garbled.

Swapping the order of Height and Width on line 93 of acquire.py produces images that look correct in the image processor function and in micro-manager.

/david

Saving the Image as Tiff

Hi, I am working on a project that is aiming to automate a neutron tomography process. I have just started 1 learning Python as a non-coder by trade and 2 using pycro-manager to work with the EMCCD camera that we use. I have been able to figure out some of the Bridge commands like setting the exposure time, my follow up question that will probably have a lot of time saved just asking here and not sifting through documentation I can only slightly read:

In pyrcromanager as a whole, how would I go about saving the image that I got from core.snap_image() as a tiff to a pre-specified directory?

Also, after saving the image will I need to do anything like close the previous image to then take another picture and save that? I currently cannot access the camera and am trying to get some high level coding done ahead of time.

Thanks

missing interfaces

Some interfaces are missing. For example:

from pycromanager import Bridge
bridge = Bridge(convert_camel_case=False)
mmStudio = bridge.get_studio()
acquisition_manager = mmStudio.acquisitions()
settings = bridge.construct_java_object(
        'org.micromanager.acquisition.SequenceSettings')
settings.numFrames=1
datastore = acquisition_manager.runAcquisitionWithSettings(settings, False)
# I need to add this as I know DataProvider is a superinterface of Datastore
if 'org.micromanager.data.Datastore' in datastore._interfaces:
    datastore._interfaces.append('org.micromanager.data.DataProvider')
mmStudio.displays().closeDisplaysFor(datastore)

Save data according to ome-tiff standard

It would be nice if pycromanager data can be saved according to the OME-TIFF standard. This way data can easily be loaded using tifffile or the Fiji BioFormats reader. Currently, these readers load data from only one file if multi-file tif stack is saved. Further, the data is imported as 3D stack, and not shaped properly.

If implemented, one would need to figure out how to handle custom pycromanager axes.

does it work with multiprocessing?

Hi!

I'm very interested in using PycroManager. I'd like to use python's multiprocessing to do data acquisition with micro-manager. Would it work?

KR,

Josep

`mmc.get_image()` should return the correct shape

Currently, calling mmc.get_image() via pycromanager will return a 1-d array, I think would be nice to return the correct shape (although we can do mmc.get_tagged_image but that may be slightly slower than mmc.get_image). This would be also nice since using pymmcore directly in Python would return the correct shape.

Acquisition class doesn't work without z stage

I am trying to acquire 10 frames:

from pycromanager import Acquisition, multi_d_acquisition_events

if __name__ == '__main__': #this is important, don't forget it

    with Acquisition(directory='C:/Users/Quentin.Peter/Desktop/tmp0', name='acquisition_name') as acq:
        events = multi_d_acquisition_events(10)
        acq.acquire(events)

But I get

Traceback (most recent call last):

  File "C:\ProgramData\Anaconda3\lib\site-packages\pycromanager\untitled0.py", line 5, in <module>
    with Acquisition(directory='C:/Users/Quentin.Peter/Desktop/tmp0', name='acquisition_name') as acq:

  File "C:\ProgramData\Anaconda3\lib\site-packages\pycromanager\acquire.py", line 181, in __init__
    tile_overlap is not None, x_overlap, y_overlap)

  File "C:\ProgramData\Anaconda3\lib\site-packages\pycromanager\core.py", line 261, in <lambda>
    fn = lambda instance, *args, signatures_list=tuple(methods_with_name): instance._translate_call(signatures_list, args)

  File "C:\ProgramData\Anaconda3\lib\site-packages\pycromanager\core.py", line 348, in _translate_call
    return self._deserialize(self._socket.receive())

  File "C:\ProgramData\Anaconda3\lib\site-packages\pycromanager\core.py", line 97, in receive
    self._check_exception(message)

  File "C:\ProgramData\Anaconda3\lib\site-packages\pycromanager\core.py", line 102, in _check_exception
    raise Exception(response['value'])

Exception: java.lang.RuntimeException: Problem communicating with core to get Z stage limits
org.micromanager.acqj.api.Acquisition.initialize(Acquisition.java:205)
org.micromanager.acqj.api.Acquisition.initialize(Acquisition.java:183)
org.micromanager.remote.RemoteAcquisition.<init>(RemoteAcquisition.java:33)
org.micromanager.remote.RemoteAcquisitionFactory.createAcquisition(RemoteAcquisitionFactory.java:36)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.micromanager.internal.zmq.ZMQServer.runMethod(ZMQServer.java:270)
org.micromanager.internal.zmq.ZMQServer.parseAndExecuteCommand(ZMQServer.java:325)
org.micromanager.internal.zmq.ZMQServer.lambda$initialize$1(ZMQServer.java:83)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)

The acquisiton is sucessful if I use mmcore directly.

Allow for multiple acquisitions within a Python session

With the current implementation, acquisitions require a __main__ module to spawn a task in multiprocessing. While it is possible to launch acquisition scripts from within a Python environment (e.g. IPython), only the first acquisition is successful; subsequent attempts raise an exception, e.g. running an acquisition script pycrotest.py results in

In [1]: %run pycrotest.py # this is successful

In [2]: %run pycrotest.py # this fails
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~\GitLab\umanager\examples\pycrotest.py in <module>
      6     #cwd = Path.cwd()
      7     exposures = np.linspace(100, 1000, 10)
----> 8     with pm.Acquisition(directory='.', name='pycrotest') as acq:
      9         events = []
     10         for idx, exposure in enumerate(exposures):

~\miniconda3\envs\crio\lib\site-packages\pycromanager\acquire.py in __init__(self, directory, name, image_process_fn, pre_hardware_hook_fn, post_hardware_hook_fn, post_camera_hook_fn, show_display, tile_overlap, magellan_acq_index, process, debug)
    227                                                          name='Event sending')
    228                     # if multiprocessing else threading.Thread(target=event_sending_fn, args=(), name='Event sending')
--> 229             self.event_process.start()
    230
    231

~\miniconda3\envs\crio\lib\multiprocessing\process.py in start(self)
    119                'daemonic processes are not allowed to have children'
    120         _cleanup()
--> 121         self._popen = self._Popen(self)
    122         self._sentinel = self._popen.sentinel
    123         # Avoid a refcycle if the target function holds an indirect

~\miniconda3\envs\crio\lib\multiprocessing\context.py in _Popen(process_obj)
    222     @staticmethod
    223     def _Popen(process_obj):
--> 224         return _default_context.get_context().Process._Popen(process_obj)
    225
    226 class DefaultContext(BaseContext):

~\miniconda3\envs\crio\lib\multiprocessing\context.py in _Popen(process_obj)
    324         def _Popen(process_obj):
    325             from .popen_spawn_win32 import Popen
--> 326             return Popen(process_obj)
    327
    328     class SpawnContext(BaseContext):

~\miniconda3\envs\crio\lib\multiprocessing\popen_spawn_win32.py in __init__(self, process_obj)
     43
     44     def __init__(self, process_obj):
---> 45         prep_data = spawn.get_preparation_data(process_obj._name)
     46
     47         # read end of pipe will be duplicated by the child process

~\miniconda3\envs\crio\lib\multiprocessing\spawn.py in get_preparation_data(name)
    181     # or through direct execution (or to leave it alone entirely)
    182     main_module = sys.modules['__main__']
--> 183     main_mod_name = getattr(main_module.__spec__, "name", None)
    184     if main_mod_name is not None:
    185         d['init_main_from_name'] = main_mod_name

AttributeError: module '__main__' has no attribute '__spec__'

As an aside, it would be great if pycro-manager could support acquisition tasks defined within functions or objects instead of having everything tied to __main__.

Translate Python variable types to Java data types for Micro-Manager Core?

First of all, it's great to find this project! - I successfully tested the interface (following your Controlling Micro-Manager Core tutorial) for a machine vision camera we're using, and most things appear to work really smoothly.

While testing, I tried to get/set the ROI / region of interest from pycromanager. While the methods core.get_roi and core.set_roi exist as expected (considering snake_case vs CamelCase), only the latter works. The former results in an error:

[...]

In [10]: a = b = c = d = 0

In [11]: core.get_roi(a, b, c, d)
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-71-df0daa3b1c10> in <module>
----> 1 core.get_roi(a, b, c, d)

~\miniconda3\envs\crio\lib\site-packages\pycromanager\core.py in <lambda>(instance, signatures_list, *args)
    261                 params, methods_with_name, method_name_modified = _parse_arg_names(methodSpecs, method_name, convert_camel_case)
    262                 return_type = methods_with_name[0]['return-type']
--> 263                 fn = lambda instance, *args, signatures_list=tuple(methods_with_name): instance._translate_call(signatures_list, args)
    264                 fn.__name__ = method_name_modified
    265                 fn.__doc__ = "{}.{}: A dynamically generated Java method.".format(_java_class, method_name_modified)

~\miniconda3\envs\crio\lib\site-packages\pycromanager\core.py in _translate_call(self, method_specs, fn_args)
    341         #args that are none are placeholders to allow for polymorphism and not considered part of the spec
    342         # fn_args = [a for a in fn_args if a is not None]
--> 343         valid_method_spec = _check_method_args(method_specs, fn_args)
    344         #args are good, make call through socket, casting the correct type if needed (e.g. int to float)
    345         message = {'command': 'run-method', 'hash-code': self._hash_code, 'name': valid_method_spec['name'],

~\miniconda3\envs\crio\lib\site-packages\pycromanager\core.py in _check_method_args(method_specs, fn_args)
    467
    468     if valid_method_spec is None:
--> 469         raise Exception('Incorrect arguments. \nExpected {} \nGot {}'.format(
    470             ' or '.join([', '.join(method_spec['arguments']) for method_spec in method_specs]),
    471             ', '.join([str(type(a)) for a in fn_args]) ))

Exception: Incorrect arguments.
Expected  or java.lang.String or int[], int[], int[], int[] or java.lang.String, int[], int[], int[], int[]
Got <class 'int'>, <class 'int'>, <class 'int'>, <class 'int'>

I am admittedly not very familiar with Micro-Manager, and loosely followed a Beanshell example, so I may be overlooking something obvious. Regardless, the error stack points at get_roi requiring a conversion from Python to Java data types (call by reference vs call by value?). Looking at the source code, this may be part of the TODO comment ...

java.lang.ClassCastException

I was trying to run some of the tests but I ran into this error.
I've seen this error on multi_d_acq and magellan_acq, though it may also appear on other tests.

Traceback here:

Traceback (most recent call last):
  File "C:/Users/nicke/Documents/git/pycro-manager/test/multi_d_acq.py", line 5, in <module>
    with Acquisition(directory='/Users/henrypinkard/megllandump', name='tcz_acq') as acq:
  File "C:\Users\nicke\Documents\git\pycro-manager\pycromanager\acquire.py", line 146, in __init__
    acq_manager = self.bridge.construct_java_object('org.micromanager.remote.RemoteAcquisitionFactory', args=[core])
  File "C:\Users\nicke\Documents\git\pycro-manager\pycromanager\core.py", line 173, in construct_java_object
    serialized_object = self._master_socket.receive()
  File "C:\Users\nicke\Documents\git\pycro-manager\pycromanager\core.py", line 87, in receive
    self._check_exception(message)
  File "C:\Users\nicke\Documents\git\pycro-manager\pycromanager\core.py", line 92, in _check_exception
    raise Exception(response['value'])
Exception: java.lang.ClassCastException: java.lang.Package cannot be cast to java.lang.Comparable

As a sidenote, it would be nice to move towards having tests formatted to run in something like PyTest so that testing can be done more automatically.

Error loading data

Error 'Dataset' object has no attribute '_remote_storage' received after a call to

dataset = Dataset(r'Y:\Test\Test1_1')
data = dataset.as_array()

for data acquired with

if __name__ == '__main__':

        with Acquisition(directory=r'Y:\Test', name='Test1') as acq:
            events = multi_d_acquisition_events(num_time_points = 100, time_interval_s = 0)
            acq.acquire(events)

Integration with Micro-Manager GUI

Not really a Pycro-Manager issue per se, but an opportunity to add additional useful functionality to Pycro-Manager with some changes to Micro-Manager. Specifically, Acquisitions could be made to work with acquisitions in the micro-manager MDA window in the same way that they now work with those in the Micro-Magellan GUI. This would allow Python acquisition hooks and image processors to run on Micro-Manager MDAs. Full details can be found here: micro-manager/micro-manager#809

Getting pixels from taggedImage

the pix field of a TaggedImage appears to just be a copy of the tags metadata.

>>> a = bridge.get_core().get_tagged_image()
>>> a.pix == a.tags
        True
>>> print(a.pix)
{'Z-Description': 'Demo stage driver',
 'Camera-PixelType': '16bit',
 'Camera-Binning': '1',
 'Core-Shutter': 'Shutter',
 'Camera-FastImage': '0',
 'D-DA-HubID': '',
...

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.