XtalOptimizer: Accept std::vector<std::vector<SpotToSave>> for spots input, to distinguish spots between different images
This commit is contained in:
@@ -504,7 +504,7 @@ CrystalLattice AngleAxisAndLengthsToLattice(const double rod[3], const double le
|
||||
}
|
||||
|
||||
bool XtalOptimizerInternal(XtalOptimizerData &data,
|
||||
const std::vector<SpotToSave> &spots,
|
||||
const std::vector<std::vector<SpotToSave>> &spots,
|
||||
const float tolerance) {
|
||||
try {
|
||||
Coord vec0 = data.latt.Vec0();
|
||||
@@ -565,50 +565,60 @@ bool XtalOptimizerInternal(XtalOptimizerData &data,
|
||||
|
||||
const float tolerance_sq = tolerance * tolerance;
|
||||
|
||||
// Add residuals for each point
|
||||
for (const auto &pt: spots) {
|
||||
if (!data.index_ice_rings && pt.ice_ring)
|
||||
for (int i = 0; i < spots.size(); i++) {
|
||||
if (spots[i].empty())
|
||||
continue;
|
||||
|
||||
float angle_rad = 0.0;
|
||||
|
||||
Coord recip = pt.ReciprocalCoord(data.geom);
|
||||
double angle_rad = 0.0;
|
||||
std::optional<RotMatrix> rot_matr;
|
||||
|
||||
if (data.axis) {
|
||||
recip = data.axis->GetTransformationAngle(pt.phi) * recip;
|
||||
angle_rad = pt.phi * M_PI / 180.0;
|
||||
const float angle_deg = data.axis->GetAngle_deg(i) + data.axis->GetWedge_deg() / 2.0;
|
||||
angle_rad = angle_deg * M_PI / 180.0;
|
||||
rot_matr = data.axis->GetTransformationAngle(angle_deg);
|
||||
}
|
||||
|
||||
double h_fp = recip * vec0;
|
||||
double k_fp = recip * vec1;
|
||||
double l_fp = recip * vec2;
|
||||
// Add residuals for each point
|
||||
for (const auto &pt: spots[i]) {
|
||||
if (!data.index_ice_rings && pt.ice_ring)
|
||||
continue;
|
||||
|
||||
double h = std::round(h_fp);
|
||||
double k = std::round(k_fp);
|
||||
double l = std::round(l_fp);
|
||||
Coord recip = pt.ReciprocalCoord(data.geom);
|
||||
|
||||
double norm_sq = (h - h_fp) * (h - h_fp) + (k - k_fp) * (k - k_fp) + (l - l_fp) * (l - l_fp);
|
||||
if (rot_matr)
|
||||
recip = rot_matr.value() * recip;
|
||||
|
||||
if (norm_sq > tolerance_sq)
|
||||
continue;
|
||||
double h_fp = recip * vec0;
|
||||
double k_fp = recip * vec1;
|
||||
double l_fp = recip * vec2;
|
||||
|
||||
problem.AddResidualBlock(
|
||||
new ceres::AutoDiffCostFunction<XtalResidual, 3, 2, 1, 2, 3, 3, 3, 3>(
|
||||
new XtalResidual(pt.x, pt.y,
|
||||
data.geom.GetWavelength_A(),
|
||||
data.geom.GetPixelSize_mm(),
|
||||
angle_rad,
|
||||
h, k, l,
|
||||
data.crystal_system)),
|
||||
nullptr,
|
||||
beam,
|
||||
&distance_mm,
|
||||
detector_rot,
|
||||
rot_vec,
|
||||
latt_vec0,
|
||||
latt_vec1,
|
||||
latt_vec2
|
||||
);
|
||||
double h = std::round(h_fp);
|
||||
double k = std::round(k_fp);
|
||||
double l = std::round(l_fp);
|
||||
|
||||
double norm_sq = (h - h_fp) * (h - h_fp) + (k - k_fp) * (k - k_fp) + (l - l_fp) * (l - l_fp);
|
||||
|
||||
if (norm_sq > tolerance_sq)
|
||||
continue;
|
||||
|
||||
problem.AddResidualBlock(
|
||||
new ceres::AutoDiffCostFunction<XtalResidual, 3, 2, 1, 2, 3, 3, 3, 3>(
|
||||
new XtalResidual(pt.x, pt.y,
|
||||
data.geom.GetWavelength_A(),
|
||||
data.geom.GetPixelSize_mm(),
|
||||
angle_rad,
|
||||
h, k, l,
|
||||
data.crystal_system)),
|
||||
nullptr,
|
||||
beam,
|
||||
&distance_mm,
|
||||
detector_rot,
|
||||
rot_vec,
|
||||
latt_vec0,
|
||||
latt_vec1,
|
||||
latt_vec2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (problem.NumResidualBlocks() < data.min_spots)
|
||||
@@ -722,7 +732,7 @@ bool XtalOptimizerInternal(XtalOptimizerData &data,
|
||||
}
|
||||
}
|
||||
|
||||
bool XtalOptimizer(XtalOptimizerData &data, const std::vector<SpotToSave> &spots) {
|
||||
bool XtalOptimizer(XtalOptimizerData &data, const std::vector<std::vector<SpotToSave>> &spots) {
|
||||
if (!XtalOptimizerInternal(data, spots, 0.3))
|
||||
return false;
|
||||
XtalOptimizerInternal(data, spots, 0.2);
|
||||
|
||||
Reference in New Issue
Block a user