Beam centre: measure the direct beam from the symmetry of the spots, before indexing
The centre in the file is often a placeholder, and nothing measures it until post-refinement has already indexed the sweep - by which time a wrong centre has chosen the lattice. Two exact facts about a rotation sweep give it from spot positions alone, with no cell, no orientation matrix and nothing indexed. Rotating 180 degrees about the spindle and taking -h negates a reflection's component along the spindle and leaves the rest, so with the spindle perpendicular to the beam the Laue condition is preserved and the spots recorded half a turn apart are mirror images along the spindle. Those are Friedel mates, not the same reflection. The same reflection appears twice for a different reason: it meets the Ewald sphere on two crossings, generally not half a turn apart, differing only in the sign of the component perpendicular to both the spindle and the beam. The first observable gives the coordinate along the spindle, the second the coordinate across it. Each candidate pairing votes and the true value accumulates while wrong pairings scatter. Both observables need guarding, because a vote is a comb and the tallest tooth is not always the right one. Along the spindle a false pairing cannot fake the equality of Friedel amplitudes. Across it, the two crossings of one reflection are separated by a sweep angle its own position fixes, which no accidental pair reproduces. The mirror is exact in the laboratory frame, so it is only as good as the rotation axis. Every file here states an ideal axis and none of them has one; a skew about the beam spreads the vote instead of shifting it, and past a milliradian it moves an otherwise correct answer by pixels while every internal statistic still looks healthy. It is therefore fitted, not assumed. A tilt of the axis towards the beam is measured and reported but not applied, being confounded with the detector rotation until that is fitted too. Nothing inside the fit can see a wrong tooth - when the vote flips, every frame pair flips with it - so the answer is checked from outside, by asking whether it depends on where the search began. That, and a floor on the angular span the pairs cover, are what refuse the cases this cannot measure: a sweep barely past half a turn is the dangerous one, not the short one, because at exactly half a turn there is nothing to fit and just past it there is almost nothing. Where the sweep is too short for any of this the radial background profile gives a coarser centre from a handful of images, and where neither can measure it the file's value is kept. The beam-stop projection now takes its own frames rather than sharing the sample, so turning this on cannot change the mask; and both samples keep away from the ends of the sweep, where shutter synchronisation spoils an image. Reading twice as many frames as before costs a few seconds once, and is what makes the answer independent of which frames were drawn. Off by default. Over the 38-crystal rotation battery it serves every dataset, agrees with XDS's refined direct beam to 0.116 px in the median against 0.135 for the value in the file, and changes no space group. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
### 1.0.0-rc.161
|
||||
This is an UNSTABLE release. It includes many experimental features, as well as many AI generated fixes. We recommend using rc.152 for production use.
|
||||
|
||||
* rugnux: New **beam-centre measurement before indexing** (`--estimate-beam-center`), which takes the direct beam from the symmetry of the spots where the sweep reaches at least half a turn, from the radial background profile where it does not, and keeps the value in the file where neither can measure it; the rotation axis' skew about the beam is fitted at the same time (`--no-fit-spindle` keeps the axis from the file).
|
||||
* Lattice search: a reduced cell whose β sits on the Niggli type boundary now keeps its centring instead of falling through to triclinic, so a centred lattice is no longer read as primitive according to which way its refined cell happened to reduce.
|
||||
* rugnux: The second rotation pass now reuses a space group that came from the intensity-based centred-lattice test, as it already did for every other group, instead of re-deciding the symmetry at the refined geometry.
|
||||
* Space-group search: where the search on the well-measured observations (`--search-min-zeta`) and the search on all of them disagree, the answer is now always the one the merge of all the observations supports, instead of whichever of the two found more symmetry.
|
||||
|
||||
@@ -151,6 +151,37 @@ Jungfraujoch uses $|\Delta_\mathrm{Ewald}|$ as an operational proxy for excitati
|
||||
- profile radius estimation (see §11.1),
|
||||
- still partiality option in scaling/merging (§10.2).
|
||||
|
||||
### 1.4 Measuring the direct beam before indexing
|
||||
|
||||
Two exact facts about a rotation sweep let the direct beam be measured from spot positions alone,
|
||||
before anything is indexed (`--estimate-beam-center`).
|
||||
|
||||
**Friedel mates half a turn apart.** Rotating 180° about the spindle $\mathbf{m}$ and taking $-h$
|
||||
negates a reflection's component along $\mathbf{m}$ and leaves the rest. With the spindle
|
||||
perpendicular to the beam this preserves $\mathbf{q}\cdot\mathbf{S}_0$, so $-h$ satisfies the Laue
|
||||
condition at $\varphi+180°$ exactly where $h$ satisfies it at $\varphi$, and the spots recorded half a
|
||||
turn apart are mirror images along the spindle direction. This gives the beam coordinate **along**
|
||||
the spindle. Note these are Friedel mates, not the same reflection.
|
||||
|
||||
**The second crossing.** The same reflection meets the Ewald sphere twice, at two angles that are
|
||||
generally *not* 180° apart, differing only in the sign of the lab component perpendicular to both
|
||||
$\mathbf{m}$ and the beam. This gives the remaining coordinate. The two crossings are separated by a
|
||||
sweep angle fixed by the reflection's own position, so genuine pairs are identified without a cell or
|
||||
an orientation matrix.
|
||||
|
||||
Neither observable requires the reflections to be indexed: each candidate pairing votes for a beam
|
||||
coordinate, and the true value accumulates while wrong pairings scatter.
|
||||
|
||||
The mirror is exact in the **laboratory** frame, so it is sensitive to the spindle's orientation. A
|
||||
skew of the spindle about the beam *spreads* the vote rather than shifting it, and is fitted
|
||||
alongside the centre (`--no-fit-spindle` keeps the axis from the file); a tilt of the spindle towards
|
||||
the beam is measured and reported but not applied. The frames read are sampled away from both ends of
|
||||
the sweep, where shutter synchronisation can spoil an image.
|
||||
|
||||
Where the sweep is shorter than half a turn the spot symmetry cannot be formed, and the centre is
|
||||
taken instead from the centroid of the radial background profile, which needs only a few images.
|
||||
Where neither method can measure the centre, the value from the file is kept.
|
||||
|
||||
---
|
||||
|
||||
## 2. Azimuthal integration (radial profiles)
|
||||
|
||||
@@ -393,6 +393,13 @@ Detector mask:
|
||||
| --- | --- |
|
||||
| `--detect-beam-stop[=N\|off]` | Find the beam stop and its holder in a projection of N images and add them to the pixel mask as bit 9, so nothing shadowed by them is integrated. **On by default** (60 images); `=off` disables. Reflections behind the stop are attenuated but not flagged, so they integrate low with a plausible sigma and no existing rejection catches them |
|
||||
|
||||
Geometry:
|
||||
|
||||
| Option | Description |
|
||||
| --- | --- |
|
||||
| `--estimate-beam-center` | Measure the direct beam before indexing, from the symmetry of the spots where the sweep reaches at least half a turn and from the radial background profile where it does not; the value in the file is kept where neither can measure it. Off by default |
|
||||
| `--no-fit-spindle` | With the above, keep the rotation axis given in the file instead of fitting its skew about the beam |
|
||||
|
||||
Spot finding:
|
||||
|
||||
| Option | Description |
|
||||
|
||||
Reference in New Issue
Block a user