docs: the phenix label line, and why the MTZ carries no DANO

Two measurements, neither of which changes what we write.

phenix's "Multiple equally suitable arrays" is a tie between the two
INTENSITY arrays, IMEAN and I(+)/I(-); iotbx scores F and F(+)/F(-) below
them, so writing amplitudes as well is not what causes it. ctruncate's own
output ties in the same place, so this is what phenix does with a CCP4 merged
file rather than something rugnux does to a user. Column order, dataset and
project names, and dropping the amplitudes all leave the tie exactly where it
was; only removing one of the two intensity arrays clears it, and removing the
Bijvoet columns would take the SHELX route with it. So the file stays as it is
and the page now carries the label line per program, both formats, including
the quoting the anomalous one needs. A program that asks iotbx for anomalous
data by preference - hyss, find_peaks_holes, molprobity, the autosol import -
needs nothing at all, which is now said as well.

The page also said the MTZ form of that message names no choices. It names
both, exactly as the mmCIF form does; corrected.

DANO/SIGDANO stay out. Against a ctruncate file, DANO is F(+)-F(-) and SIGDANO
is the quadrature sum of the two sigmas, bit-identical on every reflection, so
the pair is a restatement of columns we already write - and the quadrature sum
is the convention whether or not the mates share a scale model. Every consumer
in the documented routes takes the Bijvoet columns directly, CCP4's own bp3 and
afro ask for them in preference to F/DANO, and adding the pair costs 12.5% of
the merged file while changing nothing phenix or Phaser sees. fft's anomalous
Fourier is the one caller with no other spelling; the ctruncate command that
makes it is now on the page.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N
This commit is contained in:
2026-09-02 14:12:45 +02:00
co-authored by Claude Opus 5
parent 4af23e9b27
commit 0eb9fb8a8b
+57 -9
View File
@@ -63,6 +63,23 @@ and the wavelength, on a dataset of its own behind the reserved `HKL_base` — s
the file is given the right edge. The Bijvoet columns are present on any rotation merge, with or
without `-A`; a stills merge has no Bijvoet split and the file then stops after `F SIGF FreeR_flag`.
There is deliberately **no `DANO`/`SIGDANO`** pair, the anomalous difference columns a CCP4 merged
file usually carries. They are a restatement rather than a measurement: checked column against
column on a `ctruncate` file, `DANO` is `F(+) F(-)` to the last bit and `SIGDANO` is
`√(σ(+)² + σ()²)` to the last bit, on every reflection — the quadrature sum is the convention
whether or not the two mates came from one scale model, and no correlation correction is applied by
anybody. Every program in the phasing routes below reads the Bijvoet columns directly and forms the
difference itself, and CCP4's own phasing engines prefer them: `bp3` and `afro` want `F+/SF+/F-/SF-`
and tell a user holding `F`/`DANO` to convert *to* that form, and `mtz2sca` ranks `I(+/-)` over
`F(+/-)` over `F/DANO`. Where the pair is genuinely wanted — `fft`'s anomalous-difference Fourier
takes a `DANO` label and has no other spelling — one command makes it, with the `ISYM` column that
belongs beside it:
```
ctruncate -hklin myrun.mtz -hklout myrun_ct.mtz \
-colin '/*/*/[IMEAN,SIGIMEAN]' -colano '/*/*/[I(+),SIGI(+),I(-),SIGI(-)]'
```
## The unmerged export
`<prefix>_unmerged.mtz` holds every integrated observation, before scaling and merging, in the column
@@ -134,20 +151,51 @@ independently determined orientation matrix agrees with rugnux's to well under a
The reflection files are inputs to other suites, and the handover has a few conventions worth one
line each. These are the minimum commands that get each program running on rugnux output.
**phenix.** The merged files carry both the mean intensity and the Bijvoet pairs, and phenix
refuses to choose between two equally usable intensity arrays — `Sorry: Multiple equally suitable
arrays of observed xray data found.` (from the mmCIF the message at least lists the choices; from
the MTZ it names none, which is where a user is genuinely stuck). It is one behaviour surfacing in
both formats; only the label vocabulary differs, following each format's own column names — the
MTZ label fails on the mmCIF with `Sorry: No matching array`:
**phenix.** The merged files carry both the mean intensity and the Bijvoet pairs, and a phenix
program that has not said which it wants stops on the pair of them — from the MTZ and from the
mmCIF alike, each listing its own format's labels:
```
phenix.xtriage myrun.mtz xray_data.obs_labels=IMEAN,SIGIMEAN
phenix.xtriage myrun.cif xray_data.obs_labels=intensity_meas
Sorry: Multiple equally suitable arrays of observed xray data found.
Possible choices:
myrun.mtz:IMEAN,SIGIMEAN
myrun.mtz:I(+),SIGI(+),I(-),SIGI(-)
```
Two things are worth knowing before reading that as a fault in the file. The tie is between the two
**intensity** arrays and nothing else: iotbx scores `F`/`SIGF` and `F(+)`/`F(-)` below them, so they
are never in the running and writing amplitudes as well as intensities is not what causes this. And
**ctruncate's own output ties in the same place** — put any merged data through CCP4's truncate step
and phenix asks the same question of the result, because a mean intensity array and an anomalous one
score equally whenever the calling program has expressed no preference. The only file change that
removes the tie is dropping one of the two, and dropping the Bijvoet columns would take the anomalous
signal — and the whole [SHELX route](#experimental-phasing-with-shelx) — with it.
So the answer is a label. The parameter name differs by program, which is the part that catches
people out:
```
phenix.xtriage myrun.mtz xray_data.obs_labels=IMEAN
phenix.xtriage myrun.mtz "xray_data.obs_labels=I(+)" # the Bijvoet array instead
phenix.refine model.pdb myrun.mtz miller_array.labels.name=IMEAN
```
(phenix.refine takes a different parameter name for the same choice.)
`IMEAN` on its own is enough — the match is on a substring — and `IMEAN,SIGIMEAN` and the
fully-qualified `scaling.input.xray_data.obs_labels=` work equally. Quote the anomalous one: the
parentheses are shell syntax otherwise. The same behaviour appears on the mmCIF in that format's own
vocabulary, and a label from one format does not work on the other (`Sorry: No matching array`):
```
phenix.xtriage myrun.cif xray_data.obs_labels=intensity_meas
phenix.xtriage myrun.cif xray_data.obs_labels=pdbx_I_plus
```
**A program that states a preference needs none of this.** `phenix.hyss`, `phenix.find_peaks_holes`,
`phenix.molprobity` and the data import behind `phenix.autosol` ask for anomalous data by preference,
which breaks the tie for them. `phenix.hyss myrun.mtz n_sites=6 scattering_type=S` opens the file
with no labels given, reports `Miller array info: myrun.mtz:I(+),SIGI(+),I(-),SIGI(-)`, and forms the
anomalous differences itself.
**The R-free convention.** `FreeR_flag` is **0 = work, 1 = free** (the phenix/CNS convention;
5 % free by default). phenix.refine detects that on its own. **REFMAC5 does not**: its default