Skip to content

Feature/uc symmetry constraint

Jonathan Fisher requested to merge feature/uc-symmetry-constraint into develop

UC symmetry constraints + refactor of UB/offset refinement. This replaces the out-of-date branch feature/constraints. Major changes include

  • Removal of some dead/obsolete code (e.g. PeakFit which has been replaced by Profile3d)
  • Minor changes to UnitCell API, add methods with parameters in their name. This has to do with the constraint fitting (more on that below).
  • Because of the way fitting is reimplemented for UnitCell, it was necessary to change the propagation of error calculation. The good news is that the error calculation is even more accurate than before!
  • Once the symmetry of the UC has been determined by autoindexing, the symmetry constraints are automatically applied during refinement.
  • New class FitParameters and corresponding changes to Minimizer API. This makes fitting much more convenient, especially when there are constraints.
  • Because of changes to the Minimizer API, I had to modify all of the places where fitting is done.
  • Class UBFunctor has been removed. The functionality is split between the UBSolution and UBMinimizer.
  • UBSolution has been reworked to decouple UB, source, sample, and detector. Because of the new Minimizer API it is no longer necessary to store all of the offsets in a single flat array/vector.
  • UBMinimizer interface has been updated to reflect the changes in UBSolution, making things much more readable. E.g. instead of old style minimizer.refineParameter(10+nSampleAxes+i, true) it is simply minimizer.refineDetector(i, true)
  • DialogRefineUnitCell has been updated to reflect these changes.
  • Changes to implementation details of AutoIndexer which gives dramatic speedup when there is a large number of peaks.

Some details about the UnitCell::parameters method: internally we store the unit cell in terms of a basis matrix. By QR factorization (or Busing-Levy convention if you prefer), this is equivalent to storing an orthogonal matrix U (giving overall orientation) and the 6 lattice constants A, B, C, D, E, F (the independent components of the metric tensor). The symmetry constraints are linear in these 6 components, so this gives a much better coordinate system to use when fitting, as opposed to the components of the basis matrix, on which the constraints are nonlinear.

Ever UnitCell stores a NiggliCharacter which is the result of Niggli reduction. This structure contains a member C which is the matrix of constraints on the parameters A, B, C, D, E, F. For example, if there is a constraint A=B, then C will have a row which reads (1, -1, 0, 0, 0, 0) etc. Using the Eigen LU factorization routine, we can come up with a matrix K whose columns give a basis of solutions to the contraint matrix C. For example, if the contraints are A=B, D=0, E=0, F=0 (corresponding to Niggli condition 11) then C will be

C = 
| 1 -1  0 0 0 0 |
| 0  0  0 1 0 0 |
| 0  0  0 0 1 0 |
| 0  0  0 0 0 1 |

Then the matrix K giving the solution is

K = 
| 1  0 |
| 1  0 |
| 0  1 |
| 0  0 | 
| 0  0 |
| 0  0 |

Then any linear combination of the columns of K yields a solution to the Niggli contraints, e.g.

A * K.col(0) + C * K.col(1) = (A, A, C, 0, 0, 0)

The UnitCell methods which have parameters in their names refer to this expansion in terms of the matrix K.

Edited by eric pellegrini

Merge request reports