Project

General

Profile

Creating a new Leginon node

Added by Morgan Beeby over 9 years ago

Dear Anchi,

I wondered if could give me some quick orienting pointers for writing a new node for Leginon?

Specifically, I want to create a node that controls a liquid nitrogen pump controlled via a serial port on the Leginon main computer for tomography. I'm not sure where to start, however.

Ideally this would be a node that is called automatically at the end of every tilt series. I am a competent Python programmer so am sure I could put this all together with a couple of tips on where to start.

many thanks,

Morgan


Replies (8)

RE: Creating a new Leginon node - Added by Anchi Cheng over 9 years ago

Morgan,

We have a Conditioner class of node that you can use to call before every tilt series with a timeout I think will work well for you. We use that for Krios auto nitrogen filler.

I completed the wiki for Creating_a_new_Leginon_node with the example of pumping buffer tank. You can look at that and follow the example.

Since the buffer cycling is in 3.1 release as part of conditioner.py module, you can not just take your 3.1 files and add a new subclass of Conditioner.py in a new module, though. You should copy source:trunk/leginon/conditioner.py and source:trunk/leginon/gui/wx/Conditioner.py to your installation.

"Buffer Cycling" node itself is not used in any application we distribute generally, so you will be o.k. without also copying other files I made for this example listed in #2929

When you use your new node, set the timeout to be a reasonable time for the pumping so that it does not need to pump too often. 0 second will make it pump each time FixConditionEvent is sent, even if it is only 2 minutes later when a tilt series failed or aborted quickly.

RE: Creating a new Leginon node - Added by Morgan Beeby over 9 years ago

Anchi,

Excellent. This looks as if it'll be a great help. I hope to get to this next week.

thanks!

Morgan

RE: Creating a new Leginon node - Added by Morgan Beeby over 9 years ago

Hi Anchi,

Finally getting to this...

I've built our refilling contraption, and have standalone python code to operate it successfully. The final step is to integrate it into Leginon.

I have followed your buffer_cycle example based on the conditioner class. However, when I try running my modified tomography application, I get the following error:

AttributeError: 'AutoRefill' object has no attribute 'onPlayer'.

This looks like some sort of inheritance problem, but I'm following your instructions very closely. Even if I define my own 'onPlayer' attribute within the subclass I get this error. I wondered if you have any thoughts about possible troubleshooting directions?

In my application I have bound it only to 'tomography' node (on FixConditionEvent).

thanks for you help,

Morgan

RE: Creating a new Leginon node - Added by Anchi Cheng over 9 years ago

Any chance you can send me the code. It is hard to guess from here.

RE: Creating a new Leginon node - Added by Morgan Beeby over 9 years ago

Hi Anchi,

Sure. Sorry, should have done that initially.

leginonAutoRefill.py is the conditioner subclass; LeginonAutoRefill.py is for the GUI panel class. Both are in the correct directories on my installation. Please excuse any/all sloppyness!

thanks,

Morgan

RE: Creating a new Leginon node - Added by Anchi Cheng over 9 years ago

HI, Morgan,

Your code is pretty good. I have no problem following it.

Unfortunately, I didn't spotted any problem in your code. After commented out your runAutoRefill() in _fixCondition method, it worked for me without giving me the error.

There is one possibility that the error does not come from your object but somehow from Its parent class Conditioner that you accidentally access.

In 3.1 release, onPlayer was defined in a subclass AutoNitrogenFiller written for Krios and is in the conditioner module. If you didn't replace the 3.1 conditioner.py fully with the conditioner.py in trunk with revision r18566 where I moved onPlayer to the base class Conditioner, calls to onPlayer to
Conditioner class would indeed not exist.

Let's say that somehow your node registration does not point to your new node but Conditioner, which in the old code was the buffer cycling, then onPlayer would not exist for it.

Therefore, please check two things:

1. Check allnodes.py. Your registration should look like this:

from leginonAutoRefill import AutoRefill
noderegistry.registerNodeClass(AutoRefill,classtype)

2. Check to see if you did replace the 3.1 conditioner.py with the new conditioner.py in trunk as mentioned earlier.

By the way, may I suggest that you name your module and class something that reflects that it uses serial port ? It is used in Leginon, it seems not necessary to have the word leginon in its module name....

RE: Creating a new Leginon node - Added by Morgan Beeby over 9 years ago

Hi Anchi,

Thanks for this. I don't have access to the microscope for a couple of days but will try then. I think I've addressed all of your points -- but if it works for you, I must have done something odd.

And, yes, renaming is a good idea. I'll do that...

thanks,

Morgan

RE: Creating a new Leginon node - Added by Morgan Beeby over 9 years ago

Hi Anchi,

I re-did everything and it works beautifully. Many thanks!

Morgan

    (1-8/8)