Closed henrypinkard closed 4 years ago
I just pushed code that starts (and stops) the zmq server as I think it should. However, the Python side of things does not work for me. I have pygellan 0.1.6 installed (which is what I get from pip install pygellan). I figured that I need to delete the old compiled version of the Magellan plugin, since it starts the ZMQ server by itself (and most likely holds on to the port).
When I do:
from pygellan.acquire import MagellanBridge bridge = MagellanBridge();
I see the following on the Java side: org.json.JSONException: JSONObject["classpath"] not found. in Thread[ZMQ Server master,6,main] [ ] at org.json.JSONObject.get(JSONObject.java:285) [ ] at org.json.JSONObject.getString(JSONObject.java:411) [ ] at org.micromanager.internal.zmq.ZMQServer.parseAndExecuteCommand(ZMQServer.java:86) [ ] at org.micromanager.internal.zmq.ZMQServer.lambda$initialize$1(ZMQServer.java:56) [ ] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [ ] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [ ] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [ ] at java.lang.Thread.run(Thread.java:748)
Ideas?
You probably need to delete the existing Magellan jar, because unless you rebuilt it it is still running one too.
Also you should pull the latest pygellan source code (I didn't want to push a new version to PyPi yet so as not to disrupt existing users). You can either remove the pip installed version and add the source code to your path, or do a pip install -e .
when in the top level folder of pygellan to make the local code called by python
Also I changed the name of MagellanBridge to PygellanBridge, so that'll be one way to verify its working
Forgot to add link to the new example above. Its here: https://github.com/henrypinkard/Pygellan/blob/master/examples/micro-manager_api.py
pip install -e
results in: ERROR: File "setup.py" not found. Directory cannot be installed in editable mode: /Users/nico/git/Pygellan/pygellan
Basically I have no idea how to get this new pygellan code to work in Pycharm.
did you forget the "." ? you'll want
pip install -e .
On second thought I'm not sure you actually need to do that. If you set up your pycharm project with the root folder of the pygellan git repo as the project folder it should just work I think
After lots of environment mangling (have to learn more about Pycharm;) managed to get it to work. Sweet! Managed to do:
from pygellan.acquire import PygellanBridge
bridge = PygellanBridge()
mm = bridge.get_studio()
mmc = bridge.get_core()
mmc.set_exposure("Camera", 100)
mm.live().snap(True)
and all worked (more or less). Questions/issues I encountered:
<pygellan.acquire.JavaObjectShadow object at 0x113fac610>]
Exception ignored in: <function JavaObjectShadow.__del__ at 0x113ee7cb0>
Traceback (most recent call last):
File "/Users/nico/git/Pygellan/pygellan/acquire.py", line 155, in __del__
if reply_json['type'] == 'exception':
KeyError: ('type',)
Nice!
bridge = PygellanBridge(convert_camel_case=False)
should already work in the version you havesending you another PR with some small fixes now on micromanager, and pushing new stuff to pygellan as well
Fixed the bug in the third bullet in new PR
Awesome! Amazing turn-around;)
mmc.getDevicePropertyNames("XY")
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<string>", line 1, in <lambda>
File "/Users/nico/git/Pygellan/pygellan/acquire.py", line 200, in _translate_call
return self._deserialize_return(reply)
File "/Users/nico/git/Pygellan/pygellan/acquire.py", line 213, in _deserialize_return
raise Exception(json_return['value'])
Exception: Internal class accidentally exposed
Any way to deal with that elegantly?
Good catch...I only know how to spell in binary
Another PR coming that exposes all mmcorej classes. It may be that it makes more sense to hard code in explicit conversions to python types for some of these, as I did with TaggedImage and ArrayList. For now they are ShadowClasses
Also fixed the function overloading thing (re-pull Pygellan). Turns out I implemented this a few months ago and forgot, but there was a small bug. What is not implemented though is autocomplete with all versions with different numbers of arguments. For now it just defaults to the one with the longest argument list
Still the same error, I think because mmcorej is now added to the apiClasses, but not mmcorej.StrVector. Adding the line: `apiClasses.add(StrVector.class);` solves this (but does not add the other classes in mmcorej). I guess that somehow the mmcorej package is not visible in the current classloader?
Is there a way from Python to "close" the bridge? It is easy to restart a Python console to accomplish the same thing, but it seems more elegant to close the bridge and start a new one.
new PR for MMCoreJ problems. It wasnt loading them because they were in a jar rather than on the file system (CMMCore still worked because it was added manually as a vestige from before)
pushed code with a destructor that shuts down all sockets and ZMQ. This will happen if the bridge gets garbage collected, or you can trigger it manuall with del bridge
https://github.com/henrypinkard/Pygellan/commit/96a42fc17e8cd1499a3ecbd0404557f98162f787
This version automatically gets all non internal Micromanager classes and as well as plugins (at least from netbeans, haven't tried from built version which might be a good check). I also added a generic mechanism for accessing a plugin by its classpath. Still needs a mechanism for enabling from tools, maybe you can do this more easily than I (line 898 of MMStudio).
You'll need to pull new version of Pygellan. Take a look at this (incomplete) example: