Feature #1056
closedNonorthogonal boxes for helical insert in Manual Picker
0%
Description
Manual picker currently boxes out filaments into orthogonal boxes, which results in the filaments being at all different angles in the boxes. This creates a problem for helical processing because we want the filament to be close to being either vertical or horizontal in the box. It would be nice if the user could pick a few points along the filament, then manual picker used these points to generate a spline along the helical axis, then the filament segments were boxed out parallel to the spline. This is the way phoelix works. My workaround for this is to use Eman's helixboxer to box out the filaments because it allows you to select non-orthogonal, rectangular boxes. I set the width to 1024 pixels so it is big enough to allow for the particles to be selected in stack creation without going out of bounds. I convert the img files to mrc files, transpose them so they are horizontal, and upload them into appion. Then I run them through manual picker and stack creation to cut the filament into small segments. Attached is a word doc with two snapshots of the same filament in manual picker. The first figure illustrates how the particles are picked currently and the second illustrates how I would like it to be done.
Files
Updated by Neil Voss about 14 years ago
- Category changed from Image Processing to Python scripting
- Priority changed from Normal to High
I understand how valuable this feature would be, but I think there is a lot of work needed to get it up and running. The helical picker was a quick add on hack that I added for Arne. In order to get this properly working we would need the following:
Step 1: Track helical angle for particles¶
- track the angle information for each helical pick in the manual picker
- store the angle information for each helical pick in the database
Step 2: Non-orthongonal boxing¶
This is probably best done by:- CTF correction of image
- rotate image so helix is vertical (with usual artifacts)
- extract orthogonal boxes (using EMAN's batch boxer OR custom python script)
- repeat steps 2,3 for each helix
step 1 will be the most involved to implement, but it is required before we can work on step 2. I am not setup to test this right now, maybe this summer, but I would encourage anyone interested to work on this.
Less than ideal workarounds¶
Arne was able to get around this by producing stacks with rotated helices and then aligning them in the alignment part of the pipeline, this is less than ideal, but could get you moving in the short term.
Second, you could produce a stack with EMAN's helixboxer and upload it to the pipeline, but CTF correction would be unavailable.
Lastly, you could CTF correct the images using the pipeline and the program ctfCorrector.py
, which produces CTF-corrected whole image, run helixboxer on the corrected images and then upload those.
Updated by Lauren Fisher about 14 years ago
Hey Neil,
I've been doing some thinking about how to implement helical boxing and this is the procedure I’ve come up with:
1.) Select two end points on helix in manual picker
2.) Calculate and insert intermediate points - Helical Insert
3.) Extract box around each pick that is 2x boxsize (excluding first and last picks) – MakeStack
4.) Calculate approximate rotation angle for each pick by using adjacent points
5.) Rotate box by the inverse of this angle so helix is approximately horizontal
6.) Extract the pick from the rotated box with original boxsize
7.) Run pick through first step of helical alignments, which will find the refined rotation angle to get the helix as close to horizontal as possible
8.) Add first and second rotation angles and repeat steps 3, 5, and 6
9.) Make a stack of final rotated picks
EX: Step 1 – User selects end points:
(x1, y1) = (1192, 756)
(x2, y2) = (2212, 1472)
Step 2 – Calculations done in manualpicker.py:
pixeldistance = hypot[(x1 - x2), (y1 - y2)] = sqrt(1020^2 + 716^2) = 1246
stepsize = helicalstep/(pixeldistance*apix*bin) = 1160/(1246*1.8*8) = 0.0646
t = 0.0
while t < 1.0:
x = (1.0 - t)*x1 + t*x2
y = (1.0 - t)*y1 + t*y2
t += 0.0646
First three picks:
1=(1192, 756), 2=(1258, 802), 3=(1324, 849)
Step 3 – Extract box around pick 2 with 2 x boxsize:
Boxsize = helicalstep/apix = 1160/1.8 = 644
Box2 = 644 * 2 = 1288 pixels
Step 4 – Rotation angle for pick 2:
tan(a) = (opp/adj )*(-1)= ((y3 - y1)/(x3 - x1))*(-1) = ((849-756)/(1324-1192))*(-1)
a = -35.2
Calculating the coordinates and rotation angles is easy….actually applying them is what I don’t fully know how to do. Batchboxer has an optional parameter input called “xform” that rotates and translates the box database before output. I’ve never used batchboxer, but this sounds like what we need…do you know how it works and what it does exactly? The help info for it isn’t actually very helpful. It requires dx, dy, and da. I’m assuming these are the x and y coordinates and the rotation angle? Any ideas?
Thanks!
Updated by Neil Voss about 14 years ago
Hi Lauren, I agree mostly with your post, but there are some show stopper. In the manual picker, when you use the helical insert, the angle is calculated to insert the points, but the information is immediately discarded. And the concept of adjacent points that you suggest in #4 is unavailable to the program, because it only has an unsorted list of (x,y) coordinates (nothing else). You could try to find adjacent points by doing a distance search in the list, but if you have two (or more) intersecting helices this would fail.
Like I said, we just need to treat helical points differently from regular manual picks, because, as you said, there are adjacent points and angles, but currently all that information is lost during the picking process.
It looks like Anchi has created a special label for helical picks, but what we need to do now if put in the angle information.
Updated by Lauren Fisher over 13 years ago
- Status changed from New to Assigned
- Assignee set to Lauren Fisher
Added algorithm for calculating angle of filament in helical insert function in manualpicker.py based on 2 target points selected by user. Added angle in ApParticleData table in appiondata.py, see r15600 and r15602. Added checkbox in runMakeStack.php to apply the rotation angles and align filaments vertically, see r15601. Added makehelicalstack.py which gets called instead of makestack2.py if the "Apply helical rotation angles" box is checked. This script is basically the same as makestack but adds the helical function to extract a 2*boxsize box around each coordinate, rotate it by the appropriate filament angle, then extract 1*boxsize from the center and gather all rotated files back into a final stack so all filaments are roughly aligned vertically. See r15599.
Updated by Neil Voss over 13 years ago
Hi Lauren, I am concerned about creating a separate makestack file (makehelicalstack.py), because you are duplicating a lot of code that may go unsupervised. What do I mean... well lets say we get a new CTF correction method OR we change how ctf correction is done in the pipeline. Now, we have to go and change to makestack files instead of one.
Ideally, we should (1) try to merge you great improvements to makestack into makestack2.py OR (2) move all common subfunctions into appionlib/apMakeStack.py (or something). Option (1) sounds easier, but I dunno (2) may be better in the long run. I would like to get Amber's input on the issue.
Updated by Amber Herold over 13 years ago
Lauren, let's do a code review in person and we can go over some options for ensuring the code is maintainable.
Updated by Lauren Fisher over 13 years ago
I completely agree with Neil. I was just afraid of breaking something in stack creation, which is why I duplicated the code and added the helical stuff to a separate script. My goal is to do a lot of testing this week and then merge the helical stuff into makestack2.py.
Updated by Neil Voss over 13 years ago
Hi Lauren, I do the same thing, sorry to jump to conclusions. Just wanted to make sure.
Updated by Lauren Fisher over 13 years ago
Neil, would you be willing to do the code review for this? I merged the rotation angle stuff into makestack2.py and I don't think I broke anything, but I'm not sure if the way I set it up to write the eman boxfiles is the best way. The helical particles require 2 different boxfiles, 1 to box out a 2*boxsize box around the particle selection then another with the normal boxsize for after it has been rotated. Both of these are different from the standard boxfile for unrotated particles, so there are 3 options within writeParticlesToBoxFile. I'd really like your input if you think there is a cleaner way to do this. Thanks!
Updated by Neil Voss over 13 years ago
- Status changed from Assigned to In Test
Hi Lauren, the code looks pretty clean, but I think it is time to drop EMAN boxer and just do it in python. It would be so much cleaner...
For each image: image = mrc.read(...) rotated = scipy.ndimage.rotate(image, angle=##, reshape=False, order=1) partlist = [] For each particle: part = rotate[x1':x2',y1':y2'] #note: rotated coordinate system, x2' = x1' + boxsize partlist.append(part) apImagicFile.writeImagic(partlist, image1stack) apImagicFile.mergeStacks(image1stack, image2stack, ...)
and then (1) skip the whole proc2d/batchboxer non-sense, (2) do it in one pass, and (3) it would be much faster.
Updated by Neil Voss over 13 years ago
Sorry, if it works, go with it. I just wanna plan a (long overdue) simpler way.
Updated by Lauren Fisher over 13 years ago
Arne is testing it right now, so if it works for him I think we're good to go for now. But should we open a new issue for discontinuing the use of EMAN boxer in the future?
Updated by Lauren Fisher over 13 years ago
- Assignee changed from Lauren Fisher to Arne Moeller
Updated by Neil Voss over 13 years ago
Yeah, let's open a new issue. I would work on it, but I do not have a working Appion setup to test it yet.
Updated by Lauren Fisher over 13 years ago
Arne found a pretty major bug. I didn't have an if statement in manual picker to check if the particles had an angle associated with them or not. So for regular particle picking it was crashing every time because it couldn't find the angle and if you accidentally (or intentionally) selected a point after using helical insert it would crash as well. r15615 should fix this, but I'm not sure if this is the best implementation of the error check. I wanted to check it in in case someone needs to use the beta version of manual picker for standard picking, but I'm going to talk to Jim about setting up a better error check.
Updated by Lauren Fisher over 13 years ago
Jim helped me fix the bug. It now checks if the target is an instance of the leginon TargetPanelTools StatsTarget class and if so, then it sets the angle. We also added a better error check, so if the user clicks helical insert, which assigns angles to the filament picks, then all of the picks must have an angle assigned to them. If a peak is found without an angle (for example if the user accidentally clicked the image before clicking forward) then that peak is automatically removed from the dictionary, not committed to the database, and a warning message is displayed. If no peaks have angles, then it proceeds normally. See r15626
Updated by Anchi Cheng about 9 years ago
- Status changed from In Test to Closed
- Target version changed from Appion/Leginon Future Version to Appion/Leginon 3.1.0