XtalOptimizer: Store 1/lambda (not lambda) + add check for very small lambda + set beam center as one parameter block + fix poni rotation convention (rot2 was likely wrong)
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 14m59s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m29s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 16m2s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m30s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 16m53s
Build Packages / build:rpm (rocky8) (push) Successful in 17m27s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 18m31s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 13m20s
Build Packages / Generate python client (push) Successful in 19s
Build Packages / XDS test (durin plugin) (push) Successful in 12m24s
Build Packages / Create release (push) Skipped
Build Packages / XDS test (neggia plugin) (push) Successful in 10m57s
Build Packages / build:rpm (rocky9) (push) Successful in 14m32s
Build Packages / Build documentation (push) Successful in 38s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 13m46s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 12m55s
Build Packages / DIALS test (push) Successful in 15m2s
Build Packages / Unit tests (push) Successful in 1h2m14s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 14m59s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 15m29s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 16m2s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 16m30s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 16m53s
Build Packages / build:rpm (rocky8) (push) Successful in 17m27s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 18m31s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 13m20s
Build Packages / Generate python client (push) Successful in 19s
Build Packages / XDS test (durin plugin) (push) Successful in 12m24s
Build Packages / Create release (push) Skipped
Build Packages / XDS test (neggia plugin) (push) Successful in 10m57s
Build Packages / build:rpm (rocky9) (push) Successful in 14m32s
Build Packages / Build documentation (push) Successful in 38s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 13m46s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 12m55s
Build Packages / DIALS test (push) Successful in 15m2s
Build Packages / Unit tests (push) Successful in 1h2m14s
This commit is contained in:
@@ -16,18 +16,20 @@ struct XtalResidual {
|
||||
double exp_l,
|
||||
gemmi::CrystalSystem symmetry)
|
||||
: obs_x(x), obs_y(y),
|
||||
lambda(lambda),
|
||||
inv_lambda(1.0/lambda),
|
||||
pixel_size(pixel_size),
|
||||
exp_h(exp_h),
|
||||
exp_k(exp_k),
|
||||
exp_l(exp_l),
|
||||
angle_rad(angle_rad),
|
||||
symmetry(symmetry) {
|
||||
if (std::fabs(lambda) < 1e-6)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"Lambda cannot be close to zero");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool operator()(const T *const beam_x,
|
||||
const T *const beam_y,
|
||||
bool operator()(const T *const beam,
|
||||
const T *const distance_mm,
|
||||
const T *const detector_rot,
|
||||
const T *const rotation_axis,
|
||||
@@ -47,12 +49,12 @@ struct XtalResidual {
|
||||
const T s1 = ceres::sin(rot1);
|
||||
|
||||
// Rx(-rot2): rotation around X-axis with inverted sign (PyFAI left-handed)
|
||||
const T c2 = ceres::cos(-rot2);
|
||||
const T s2 = ceres::sin(-rot2);
|
||||
const T c2 = ceres::cos(rot2);
|
||||
const T s2 = ceres::sin(rot2);
|
||||
|
||||
// Detector coordinates in mm
|
||||
const T det_x = (T(obs_x) - beam_x[0]) * T(pixel_size);
|
||||
const T det_y = (T(obs_y) - beam_y[0]) * T(pixel_size);
|
||||
const T det_x = (T(obs_x) - beam[0]) * T(pixel_size);
|
||||
const T det_y = (T(obs_y) - beam[1]) * T(pixel_size);
|
||||
const T det_z = T(distance_mm[0]);
|
||||
|
||||
// Apply Ry(rot1) first: rotate around Y
|
||||
@@ -62,18 +64,17 @@ struct XtalResidual {
|
||||
|
||||
// Then apply Rx(-rot2): rotate around X
|
||||
const T x = t1_x;
|
||||
const T y = c2 * t1_y - s2 * t1_z;
|
||||
const T z = s2 * t1_y + c2 * t1_z;
|
||||
const T y = c2 * t1_y + s2 * t1_z;
|
||||
const T z = -s2 * t1_y + c2 * t1_z;
|
||||
|
||||
// convert to recip space
|
||||
const T lab_norm = ceres::sqrt(x * x + y * y + z * z);
|
||||
const T inv_norm = T(1) / lab_norm;
|
||||
const T inv_lambda = T(1) / T(lambda);
|
||||
|
||||
T recip_raw[3];
|
||||
recip_raw[0] = x * inv_norm * inv_lambda;
|
||||
recip_raw[1] = y * inv_norm * inv_lambda;
|
||||
recip_raw[2] = (z * inv_norm - T(1.0)) * inv_lambda;
|
||||
recip_raw[0] = x * inv_norm * T(inv_lambda);
|
||||
recip_raw[1] = y * inv_norm * T(inv_lambda);
|
||||
recip_raw[2] = (z * inv_norm - T(1.0)) * T(inv_lambda);
|
||||
|
||||
// Apply goniometer "back-to-start" rotation:
|
||||
// brings observed reciprocal from image orientation into reference crystal frame
|
||||
@@ -178,7 +179,7 @@ struct XtalResidual {
|
||||
}
|
||||
|
||||
const double obs_x, obs_y;
|
||||
const double lambda;
|
||||
const double inv_lambda;
|
||||
const double pixel_size;
|
||||
const double exp_h;
|
||||
const double exp_k;
|
||||
@@ -510,17 +511,16 @@ bool XtalOptimizerInternal(XtalOptimizerData &data,
|
||||
double beta = data.latt.GetUnitCell().beta;
|
||||
|
||||
// Initial guess for the parameters
|
||||
double beam_x = data.geom.GetBeamX_pxl();
|
||||
double beam_y = data.geom.GetBeamY_pxl();
|
||||
double beam[2] = {data.geom.GetBeamX_pxl(), data.geom.GetBeamY_pxl()};
|
||||
double distance_mm = data.geom.GetDetectorDistance_mm();
|
||||
|
||||
double detector_rot[2] = {data.geom.GetPoniRot1_rad(), data.geom.GetPoniRot2_rad()};
|
||||
|
||||
ceres::Problem problem;
|
||||
|
||||
double latt_vec0[3] = {0.0, 0.0, 0.0};
|
||||
double latt_vec1[3] = {0.0, 0.0, 0.0};
|
||||
double latt_vec2[3] = {0.0, 0.0, 0.0};
|
||||
double latt_vec0[3] = {0.0, 0.0, 0.0};
|
||||
double latt_vec1[3] = {0.0, 0.0, 0.0};
|
||||
double latt_vec2[3] = {0.0, 0.0, 0.0};
|
||||
|
||||
double rot_vec[3] = {1, 0, 0};
|
||||
|
||||
@@ -591,7 +591,7 @@ double latt_vec2[3] = {0.0, 0.0, 0.0};
|
||||
continue;
|
||||
|
||||
problem.AddResidualBlock(
|
||||
new ceres::AutoDiffCostFunction<XtalResidual, 3, 1, 1, 1, 2, 3, 3, 3, 3>(
|
||||
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(),
|
||||
@@ -599,8 +599,7 @@ double latt_vec2[3] = {0.0, 0.0, 0.0};
|
||||
h, k, l,
|
||||
data.crystal_system)),
|
||||
nullptr,
|
||||
&beam_x,
|
||||
&beam_y,
|
||||
beam,
|
||||
&distance_mm,
|
||||
detector_rot,
|
||||
rot_vec,
|
||||
@@ -621,10 +620,8 @@ double latt_vec2[3] = {0.0, 0.0, 0.0};
|
||||
problem.SetParameterUpperBound(&distance_mm, 0, distance_mm * (1.0 + dist_range));
|
||||
}
|
||||
|
||||
if (!data.refine_beam_center) {
|
||||
problem.SetParameterBlockConstant(&beam_x);
|
||||
problem.SetParameterBlockConstant(&beam_y);
|
||||
}
|
||||
if (!data.refine_beam_center)
|
||||
problem.SetParameterBlockConstant(beam);
|
||||
|
||||
if (!data.refine_detector_angles) {
|
||||
problem.SetParameterBlockConstant(detector_rot);
|
||||
@@ -684,9 +681,9 @@ double latt_vec2[3] = {0.0, 0.0, 0.0};
|
||||
ceres::Solve(options, &problem, &summary);
|
||||
|
||||
if (data.refine_beam_center) {
|
||||
data.beam_corr_x = data.geom.GetBeamX_pxl() - beam_x;
|
||||
data.beam_corr_y = data.geom.GetBeamY_pxl() - beam_y;
|
||||
data.geom.BeamX_pxl(beam_x).BeamY_pxl(beam_y);
|
||||
data.beam_corr_x = data.geom.GetBeamX_pxl() - beam[0];
|
||||
data.beam_corr_y = data.geom.GetBeamY_pxl() - beam[1];
|
||||
data.geom.BeamX_pxl(beam[0]).BeamY_pxl(beam[1]);
|
||||
}
|
||||
|
||||
if (data.refine_distance_mm)
|
||||
|
||||
Reference in New Issue
Block a user