Bug Report: Score Always (seems to be) Zero for Imported Aligned Particles
NOTE: the refinement code is very complex, this is a sub-issue for #556. This will be part of a series of issues related to adding GPU refinement in cisTEM.
Summary
Particle scores remain zero throughout refinement for imported aligned particles, eliminating frequency-dependent reconstruction weighting and potentially degrading reconstruction quality.
Affected Versions
- Current master branch
- Likely affects all versions with the current refine3d/reconstruct3d implementation
Severity
High - Silently degrades reconstruction quality by disabling frequency-dependent particle weighting
Description
The Problem
When particles are imported from other packages (Relion, Frealign) or cisTEM with pre-existing alignments, their scores are initialized to 0.0 and never recalculated during subsequent refinements. This causes the frequency-dependent weighting term in reconstruction to always equal 1.0, effectively disabling this important quality control mechanism.
Root Cause Analysis
1. Import Initialization
File: src/gui/ImportRefinementPackageWizard.cpp
For Relion imports (lines 369-370):
temp_refinement...score = 0.0; // Hardcoded to zero
temp_refinement...image_is_active = 1; // Marked as aligned
For cisTEM imports (lines 424-425):
temp_refinement...score = input_params_file.ReturnScore(particle_counter);
temp_refinement...image_is_active = (int)input_params_file.ReturnImageIsActive(particle_counter);
2. Refinement Logic Bug
File: src/programs/refine3d/refine3d.cpp
The score calculation logic (lines 1548-1555) only calculates scores when NOT doing parameter searches:
if (number_of_search_dimensions > 0 && (do_global_search || do_local_refinement)) {
// Calculate logP but NOT score
output_parameters.logp = ReturnLogLikelihood(...);
// score remains unchanged (0.0)
} else {
// This branch never executes for aligned particles
output_parameters.score = ReturnLogLikelihoodWithoutSearch(...);
}
Since imported aligned particles (image_is_active = 1) undergo local refinement, they always have number_of_search_dimensions > 0, preventing score calculation.
3. Score Clamping
Additionally, any negative scores are clamped to zero (lines 1601-1602):
if (output_parameters.score < 0.0)
output_parameters.score = 0.0;
This prevents scores from ever recovering once they're zero.
Impact on Reconstruction
The reconstruction weighting formula in src/programs/reconstruct3d/reconstruct3d.cpp:
weight = particle_weight * exp((score - avg_score) * score_weight_conversion * freq²)
With all scores = 0 and avg_score = 0:
- The exponential term becomes
exp(0) = 1.0
- No frequency-dependent quality weighting is applied
- All particles contribute equally regardless of their actual quality
- Poor quality particles at high frequencies are not down-weighted
Reproduction Steps
- Import a refinement package from Relion or another package with aligned particles
- Run Manual or Auto refinement
- Check output star file - all scores will be 0.0
- Reconstruction uses uniform weighting instead of quality-based weighting
Proposed Solutions
Solution 1: Calculate Score During Refinement (Recommended)
Modify refine3d.cpp to calculate scores even during parameter searches. This preserves the existing workflow while fixing the bug.
Solution 2: Use LogP for Weighting
Replace score-based weighting with logP-based weighting in reconstruction. LogP (log-likelihood) is always calculated and represents the actual goodness-of-fit.
Solution 3: Force Global Search on Import
Set image_is_active = 0 for imported particles to force initial global search and score calculation.
Workaround
Currently, there is no user-accessible workaround. The only way to get proper scores is to:
- Import particles as unaligned (
image_is_active = 0)
- Run Ab Initio refinement to generate initial alignments with scores
Related Issues
- Excluded particles (
image_is_active = -1) are incorrectly refined as aligned particles
- Variable naming confusion between
local_global_refine and adaptive refinement strategies
Test Cases
- Import Relion star file → Check scores in database → Should be non-zero after refinement
- Import cisTEM star file with scores → Scores should be preserved or recalculated
- Run refinement on aligned particles → Scores should be updated
- Verify reconstruction weights vary with frequency when scores are non-zero
References
- Original Frealign score: Negative of weighted cross-correlation
- LogP calculation:
-0.5 * (variance_difference + log(2π)) * number_of_pixels
- Frequency-dependent weighting: Critical for high-resolution reconstruction quality
Bug Report: Score Always (seems to be) Zero for Imported Aligned Particles
NOTE: the refinement code is very complex, this is a sub-issue for #556. This will be part of a series of issues related to adding GPU refinement in cisTEM.
Summary
Particle scores remain zero throughout refinement for imported aligned particles, eliminating frequency-dependent reconstruction weighting and potentially degrading reconstruction quality.
Affected Versions
Severity
High - Silently degrades reconstruction quality by disabling frequency-dependent particle weighting
Description
The Problem
When particles are imported from other packages (Relion, Frealign) or cisTEM with pre-existing alignments, their scores are initialized to 0.0 and never recalculated during subsequent refinements. This causes the frequency-dependent weighting term in reconstruction to always equal 1.0, effectively disabling this important quality control mechanism.
Root Cause Analysis
1. Import Initialization
File:
src/gui/ImportRefinementPackageWizard.cppFor Relion imports (lines 369-370):
For cisTEM imports (lines 424-425):
temp_refinement...score = input_params_file.ReturnScore(particle_counter); temp_refinement...image_is_active = (int)input_params_file.ReturnImageIsActive(particle_counter);2. Refinement Logic Bug
File:
src/programs/refine3d/refine3d.cppThe score calculation logic (lines 1548-1555) only calculates scores when NOT doing parameter searches:
Since imported aligned particles (
image_is_active = 1) undergo local refinement, they always havenumber_of_search_dimensions > 0, preventing score calculation.3. Score Clamping
Additionally, any negative scores are clamped to zero (lines 1601-1602):
This prevents scores from ever recovering once they're zero.
Impact on Reconstruction
The reconstruction weighting formula in
src/programs/reconstruct3d/reconstruct3d.cpp:weight = particle_weight * exp((score - avg_score) * score_weight_conversion * freq²)With all scores = 0 and avg_score = 0:
exp(0) = 1.0Reproduction Steps
Proposed Solutions
Solution 1: Calculate Score During Refinement (Recommended)
Modify
refine3d.cppto calculate scores even during parameter searches. This preserves the existing workflow while fixing the bug.Solution 2: Use LogP for Weighting
Replace score-based weighting with logP-based weighting in reconstruction. LogP (log-likelihood) is always calculated and represents the actual goodness-of-fit.
Solution 3: Force Global Search on Import
Set
image_is_active = 0for imported particles to force initial global search and score calculation.Workaround
Currently, there is no user-accessible workaround. The only way to get proper scores is to:
image_is_active = 0)Related Issues
image_is_active = -1) are incorrectly refined as aligned particleslocal_global_refineand adaptive refinement strategiesTest Cases
References
-0.5 * (variance_difference + log(2π)) * number_of_pixels