Calibration validation#

The evidence for the calibration has two separate gates, as for strain:

  1. Controlled numerical correctness. The tests pass for the controlled cases that are described below.

  2. Empirical Igor parity. A calibration is made in Igor and repeated in lauelab with the same inputs, and the results are compared. This gate remains pending: the development environment has no runnable Igor installation and no exported Igor calibration. DetectorCalibration.provenance() returns "empirical_igor_parity": "pending".

The controlled tests do not establish empirical parity.

Controlled cases#

tests/calibration_cases.py contains the controlled cases, which are ported from Igor:

  • MakeFakeCalibrationData, with its 25 pixel positions for detector 0, its 25 pixel positions for the side detectors, and its sample rotation of -135 degrees about x.

  • GeoReferenceOrientation, which defines the reference detectors.

  • CalibrationErrorRPinternal and the azimuth term of CalibrationErrorRPrho, ported line by line and not vectorized, so that they check the vectorized residuals independently.

The tests check that:

  • The vectorized residuals give Igor’s error.

  • The fit recovers detector 0 together with the sample rotation.

  • The fit recovers the side detectors with a fixed sample rotation.

  • A fit that starts with the detector rotated by 0.66 degree and translated by 3.4 mm recovers detector 0 of the 2023-04-06 geometry file.

  • least_squares and BFGS on Igor’s scalar error reach the same minimum.

  • The native geometry reader reads a written geometry file back.

Export an Igor calibration#

Keep these items from one Igor calibration of detector 0:

  • The frame.

  • FullPeakList and FullPeakIndexed with their wave notes. The note of FullPeakIndexed contains rotation_matrix0.

  • The Emeasured wave.

  • The geometry file that was loaded before the calibration and the geometry file that was written after it.

  • The CalibrationList wave after OptimizeAll, with its wave note (rhox, rhoy, rhoz, azimuth, errStart, err).

To compare the Igor calibration with lauelab:

  1. Read rotation_matrix0 with matrix_from_igor().

  2. Compare the starting error, the refined \(R\) and \(P\), the sample rotation and the calculated_keV column.

  3. Only then compare values that are derived from them.

Choose tolerances from the measurement precision and record the justification. Never edit the exported values by hand.