[chimerax-users] Remote control / Threading in ChimeraX
Tom Goddard
goddard at sonic.net
Wed Jan 4 12:41:57 PST 2023
Hi Albert,
ChimeraX is not designed to run arbitrary Python code multithreaded. There are many reasons. First the Qt window toolkit is not thread safe -- all Qt GUI calls have to be done in the main thread. Violating that often results in a crash. But even without the GUI, imagine the main thread is looping over the list of open models while a second thread decides to add a model to that list -- this could break the looping thread many ways. Python has a global interpreter lock which means it only can run one thread at a time. Still if you pause one thread and then change the state of the ChimeraX session in another thread, the first thread could throw errors in countless ways when it resumes at an arbitrary point in the code with the data structures changed. In general very little software is thread safe because it is very difficult to implement. Usually that is only done by making threads not modify any data structures used by other threads.
Here are two solutions. 1) Have your listener thread run the Python code it receives in the main thread rather than the listener thread. There is a ChimeraX function that takes a function and queues it to be run in the main thread.
session.ui.thread_safe(func, args...)
Here is the code if you want to see how it works
https://github.com/RBVI/ChimeraX/blob/2e33222fabb48edec76df6e82a10efedb54a8a25/src/bundles/ui/src/gui.py#L360
A second solution is to use the ChimeraX remotecontrol communication for everything. That mechanism just runs ChimeraX commands, but you can run Python code using it by just sending the command "open script27.py" where you put the Python you want to run in a file script27.py.
Tom
> On Jan 4, 2023, at 4:40 AM, Albert Smith-Penzel via ChimeraX-users <chimerax-users at cgl.ucsf.edu> wrote:
>
> Hello,
>
> I am working on a Python project that uses ChimeraX (currently running 1.5 to interactively view dynamics data by mapping it onto a molecule. All the figures/movies in this paper, https://www.nature.com/articles/s41467-021-27417-y, were made possible by Chimera! Also thanks to Tom Goddard for explaining to me how some of those figures could be made awhile ago (https://rbvi.github.io/chimerax-recipes/spherical_harmonics/spherical_harmonics.html ).
>
> So we’re controlling ChimeraX remotely; we launch a session and then can send commands from Python over to Chimera and edit images from within our python code (while still allowing us to interact via the ChimeraX interface). The basic way this works is as follows
>
> launch chimeraX from our code, including a short python script
> python script imports our libraries, launches “cmxr” (chimeraX remote)
> cmxr uses multiprocessing.connection.Listener to listen for commands/data coming from Client in our python code
> !!!The Listener runs in a thread (threading.Thread) so that we continue to be able to interact normally with ChimeraX (launching the Listener without using a thread freezes ChimeraX while waiting for commands, rendering it unusable)
> Then, we just tell it to run some function(s) that we’ve imported into ChimeraX, and provide some data, atom ids, etc. over the Client/Listener connection
>
> There are a few things that I can’t figure how to make work via this process. We’ve had a few long-standing workarounds, but I’ve always been a little disturbed that we can’t get this all to work from python alone. At the moment, when we launch ChimeraX, we also enable remote control via curl, and some commands are then sent that way (remotecontrol rest start port XXXX)
>
> In particular, if I want to send commands that would normally be executed at ChimeraX’s command line, in principle I should be able to use chimerax.core.commands.run. If I execute “run” from a simple python script, everything works, but if I run it from within a thread (as required by our Listener setup), then ChimeraX freezes. So, we send these commands via curl on the remotecontrol instead.
>
> Second, is there a right way to open models/surfaces from the ChimeraX python shell? At the moment, we also open pdbs via curl commands. For pdbs, maybe I just don’t know the right python command. However, I am re-implementing spherical harmonics referenced above. Once I have prepared the surface (“s”), if I add it to session.models, it crashes chimeraX if it is being added within the listener thread, and if there are no models already open. If another model is already open, then it works just fine, and if I load the same modules/execute the same commands from within the python shell provided in ChimeraX, it also works (regardless of other models being open). It seems like maybe ChimeraX isn’t able to fully initialize the session from within a thread.
>
> I’ve grouped these problems together because I guess mainly they have to do with being unable to do some actions from within threads, and if there’s an explanation/workaround for dealing with that.
>
> Thanks for your help!
>
> Cheers,
> Albert
>
>
>
> –––––––––––––––––––––––––––––––––––
> Albert Smith-Penzel, Ph.D.
> DFG Project Leader
> Institute for Medical Physics and Biophysics
> Leipzig University
> 04107 Leipzig, Germany
> E-mail: albert.smith-penzel at uni-leipzig.de <mailto:albert.smith-penzel at medizin.uni-leipzig.de>
>
>
>
>
>
> _______________________________________________
> ChimeraX-users mailing list
> ChimeraX-users at cgl.ucsf.edu
> Manage subscription:
> https://www.rbvi.ucsf.edu/mailman/listinfo/chimerax-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.rbvi.ucsf.edu/pipermail/chimerax-users/attachments/20230104/33628785/attachment.html>
More information about the ChimeraX-users
mailing list