Skip to content

In helical reconstruction, psi prior angles are not flipped 180 degrees when needed #1268

@thurberk

Description

@thurberk

In short, in helical analysis, when a helical structure has a direction opposite to the initial model, Relion is not flipping the AnglePsiPrior by 180 degrees, in a Refine3D job.

This has bad consequences if local angular averaging is triggered either by the initial parameters, or during the Relion Refine3D job.

In more detail:
For helical analysis, when Relion is doing non-local angular averaging, it checks Psi angles within the range from AnglePsiPrior, and also within the range from AnglePsiPrior + 180 degrees.
When Relion is doing local angular averaging, it only checks Psi angles within the range from AnglePsiPrior. So, if the AnglePsiPrior is not flipped by 180 degrees for helices that are going the opposite direction, when local averaging is triggered only the wrong direction of the Psi angle is checked.
Currently (in Relion 5 and probably earlier versions) the AnglePsiPrior is not being flipped by 180 degrees, even when most particles in the helix have preferred orientation of Psi ~180 degrees away from the prior.

There is also a closely related issue where the PsiFlipRatio variable is not being updated if the Psi angle is not flipped. In this case, the PsiFlipRatio variable stays at 0.5, for helices that are going the same direction as the model.

Before Relion is updated, the main bad effects can be avoided by avoiding local angular searches. To be explicit, this means: On the Auto-sampling tab of a 3D run, the “Local searches from auto-sampling” should be set small enough that it will not be reached during the run.

I think the fix in the code is thankfully pretty simple as detailed below:

helix.cpp: Lines 4136 to 4145
// Change the polarity of the entire helix if psi_flip_ratio is larger than 0.5
if (psi_flip_ratio > 0.5)
{
for (int id = sid; id <= eid; id++)
{
flipPsiTiltForHelicalSegment(list[id].psi_prior_deg, list[id].tilt_prior_deg,
list[id].psi_prior_deg, list[id].tilt_prior_deg);
list[id].psi_flip_ratio = (1. - psi_flip_ratio);
}
}

Should be:
// Change the polarity of the entire helix if psi_flip_ratio is larger than 0.5
if (psi_flip_ratio > 0.5)
{
for (int id = sid; id <= eid; id++)
{
flipPsiTiltForHelicalSegment(list[id].psi_prior_deg, list[id].tilt_prior_deg,
list[id].psi_prior_deg, list[id].tilt_prior_deg);
flipPsiTiltForHelicalSegment(list[id].psi_deg, list[id].tilt_deg,
list[id].psi_deg, list[id].tilt_deg);
list[id].psi_flip_ratio = (1. - psi_flip_ratio);
}
}
else
{
for (int id = sid; id <= eid; id++)
{
list[id].psi_flip_ratio = psi_flip_ratio;
}
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions