Geometry#

Geometry, in the context of a SPEC data file, refers to the geometry of the diffractometer used for the measurements, its configuration, and information about the orientation of a specific crystalline sample on the diffractometer.

When a diffractometer geometry is used, any of the control lines in the next table may be present in a scan.

control line

array

description

#G0

G[]

geo mode, sector, etc

#G1

U[]

lattice constants, orientation reflections

#G2

unused

#G3

UB[]

orientation matrix

#G4

Q[]

lambda, frozen angles, cut points, etc

#Q

hkl values at start of scan

Information provided by each of these control lines is encoded in a very compact format, with just a sequence of values provided. The content of some lines depends on the specific diffractometer geometry used for the measurements. The name of the diffractometer geometry is not reported in the data file. To identify the diffractometer geometry, it is necessary to examine the number and names of the first motors defined in the #O control lines, and compare the number of items in the various #G control lines with the SPEC standard macros to match. The spec2nexus code has a small database 1 with this information to make a best efforts identification of the specific diffractometer geometry name.

Since SPEC uses specific engineering units when diffractometers are used, it is possible to add appropriate units: 2

  • motors (angles): @units="degrees" for motors

  • wavelength: @units="angstrom"

  • crystal dimensions: @units="angstrom"

1#G0 0 0 1 0 0 1 0 0 0 0 0 0 50 0 0.1 0 68 68 50 -1 1 1 3.13542 3.13542 0 463.6 838.8
2#G1 5.139 5.139 5.139 90 90 90 1.222647462 1.222647462 1.222647462 90 90 90 2 2 0 0 0 2 60 30 90 0 0 0 60 30 0 0 0 0 0.8265814273 0.8265814273
3#G3 -7.940607166e-18 1.138130079e-16 1.222647462 0.8645423114 -0.8645423114 0 0.8645423114 0.8645423114 -2.668317968e-16
4#G4 3.986173683 4.00012985 0 0.8265814273 0 0 0 90 0.15 0 0 0 86 0 0 0 -180 -180 -180 -180 -180 -180 -180 -180 -180 0
5#Q 3.98617 4.00013 0

It is possible to infer the diffractometer geometry in many cases by content in the #G0 and #G4 control lines, which includes the number and names of the motors in the geometry. With the control lines above and these motor names as shown below, the geometry is inferred as fourc.

1#O0  2-theta     theta       chi       phi   antheta  an2theta    z-axis     m_1_8

The hkl values at the start of the scan are written to /SCAN/Q as shown here:

1Q:NX_FLOAT64[3] = [3.98617, 4.00013, 0.0]
2   @description = "hkl at start of scan"

The uninterpreted information from the #G control lines is written to /SCAN/G as shown here:

 1G:NXnote
 2   @NX_class = "NXnote"
 3   @description = "SPEC geometry arrays, meanings defined by SPEC diffractometer support"
 4   G0:NX_FLOAT64[27] = [0.0, 0.0, 1.0, '...', 838.8]
 5     @spec_name = "G0"
 6   G1:NX_FLOAT64[32] = [5.139, 5.139, 5.139, '...', 0.8265814273]
 7     @spec_name = "G1"
 8   G3:NX_FLOAT64[9] = [-7.940607166e-18, 1.138130079e-16, 1.222647462, '...', -2.668317968e-16]
 9     @spec_name = "G3"
10   G4:NX_FLOAT64[26] = [3.986173683, 4.00012985, 0.0, '...', 0.0]
11     @spec_name = "G4"

The interpreted information from the G[] array is written to /SCAN/instrument/diffractometer (and linked to /SCAN/instrument/geometry_parameters). Text description of each parameter is provided when available.

If it was possible to determine the name of the diffractometer geometry, that name will be reported in the name field. In SPEC, some of the geometries have variants. The variant is appended to the name as: {GEOMETRY}.{VARIANT}. In the example below, the name is fourc.default.

The wavelength of the scan, if available in the #G lines, is written to the /SCAN/instrument/monochromator/wavelength field, 3 where /SCAN/instrument/monochromator is a NXmonochromator [#NXmonochromator] group.

Consult the SPEC documentation (https://certif.com) or macros for further descrption of any of the geometry information.

  1instrument:NXinstrument
  2   @NX_class = "NXinstrument"
  3   name:NX_CHAR = [b'fourc.default']
  4   positioners --> /S1/positioners
  5   diffractometer:NXnote
  6     @NX_class = "NXnote"
  7     @description = "SPEC geometry arrays, interpreted"
  8     ALPHA:NX_FLOAT64 = 0.0
  9     AZIMUTH:NX_FLOAT64 = 90.0
 10     BETA:NX_FLOAT64 = 0.0
 11     CUT_AZI:NX_FLOAT64 = 0.0
 12       @description = "azimuthal cut-point flag"
 13     CUT_CHI:NX_FLOAT64 = -180.0
 14       @description = "chi cut point"
 15     CUT_CHIR:NX_FLOAT64 = -180.0
 16       @description = "chiR cut point"
 17     CUT_KAP:NX_FLOAT64 = -180.0
 18       @description = "kap cut point"
 19     CUT_KPHI:NX_FLOAT64 = -180.0
 20       @description = "phi cut point"
 21     CUT_KTH:NX_FLOAT64 = -180.0
 22       @description = "theta cut point"
 23     CUT_PHI:NX_FLOAT64 = -180.0
 24       @description = "phi cut point"
 25     CUT_PHIR:NX_FLOAT64 = -180.0
 26       @description = "phiR cut point"
 27     CUT_TH:NX_FLOAT64 = -180.0
 28       @description = "theta/omega cut point"
 29     CUT_TTH:NX_FLOAT64 = -180.0
 30       @description = "two-theta cut point"
 31     F_ALPHA:NX_FLOAT64 = 0.15
 32       @description = "Frozen values"
 33     F_AZIMUTH:NX_FLOAT64 = 0.0
 34     F_BETA:NX_FLOAT64 = 0.0
 35     F_CHI_Z:NX_FLOAT64 = 0.0
 36     F_OMEGA:NX_FLOAT64 = 0.0
 37     F_PHI:NX_FLOAT64 = 86.0
 38     F_PHI_Z:NX_FLOAT64 = 0.0
 39     F_THETA:NX_FLOAT64 = 0.0
 40     H:NX_FLOAT64 = 3.986173683
 41       @description = "1st Miller index"
 42     K:NX_FLOAT64 = 4.00012985
 43       @description = "2nd Miller index"
 44     L:NX_FLOAT64 = 0.0
 45       @description = "3rd Miller index"
 46     LAMBDA:NX_FLOAT64 = 0.8265814273
 47       @description = "wavelength, Angstrom"
 48     OMEGA:NX_FLOAT64 = 0.0
 49     diffractometer_full:NX_CHAR = [b'fourc.default']
 50       @description = "name of diffractometer (and variant), deduced from scan information"
 51     diffractometer_simple:NX_CHAR = [b'fourc']
 52       @description = "name of diffractometer, deduced from scan information"
 53     diffractometer_variant:NX_CHAR = [b'default']
 54       @description = "name of diffractometer variant, deduced from scan information"
 55     g_aa:NX_FLOAT64 = 5.139
 56       @description = "a lattice constant (real space)"
 57     g_aa_s:NX_FLOAT64 = 1.222647462
 58       @description = "a lattice constant (reciprocal space)"
 59     g_al:NX_FLOAT64 = 90.0
 60       @description = "alpha lattice angle (real space)"
 61     g_al_s:NX_FLOAT64 = 90.0
 62       @description = "alpha lattice angle (reciprocal space)"
 63     g_ana_d:NX_FLOAT64 = 3.13542
 64     g_ana_det_len:NX_FLOAT64 = 50.0
 65     g_ana_sign:NX_FLOAT64 = 1.0
 66     g_bb:NX_FLOAT64 = 5.139
 67       @description = "b lattice constant (real space)"
 68     g_bb_s:NX_FLOAT64 = 1.222647462
 69       @description = "b lattice constant (reciprocal space)"
 70     g_be:NX_FLOAT64 = 90.0
 71       @description = "beta  lattice angle (real space)"
 72     g_be_s:NX_FLOAT64 = 90.0
 73       @description = "beta  lattice angle (reciprocal space)"
 74     g_cc:NX_FLOAT64 = 5.139
 75       @description = "c lattice constant (real space)"
 76     g_cc_s:NX_FLOAT64 = 1.222647462
 77       @description = "c lattice constant (reciprocal space)"
 78     g_frz:NX_FLOAT64 = 1.0
 79       @description = "freeze"
 80     g_ga:NX_FLOAT64 = 90.0
 81       @description = "gamma lattice angle (real space)"
 82     g_ga_s:NX_FLOAT64 = 90.0
 83       @description = "gamma lattice angle (reciprocal space)"
 84     g_h0:NX_FLOAT64 = 2.0
 85       @description = "H of primary reflection"
 86     g_h1:NX_FLOAT64 = 0.0
 87       @description = "H of secondary reflection"
 88     g_haz:NX_FLOAT64 = 0.0
 89       @description = "h azimuthal reference"
 90     g_inci_offset:NX_FLOAT64 = 0.0
 91     g_k0:NX_FLOAT64 = 2.0
 92       @description = "K of primary reflection"
 93     g_k1:NX_FLOAT64 = 0.0
 94       @description = "K of secondary reflection"
 95     g_kappa:NX_FLOAT64 = 50.0
 96       @description = "angle of kappa tilt (in degrees)"
 97     g_kaz:NX_FLOAT64 = 0.0
 98       @description = "k azimuthal reference"
 99     g_l0:NX_FLOAT64 = 0.0
100       @description = "L of primary reflection"
101     g_l1:NX_FLOAT64 = 2.0
102       @description = "L of secondary reflection"
103     g_lambda0:NX_FLOAT64 = 0.8265814273
104       @description = "lambda when or0 was set"
105     g_lambda1:NX_FLOAT64 = 0.8265814273
106       @description = "lambda when or1 was set"
107     g_laz:NX_FLOAT64 = 1.0
108       @description = "l azimuthal reference"
109     g_mode:NX_FLOAT64 = 0.0
110       @description = "spectrometer mode"
111     g_mode_name:NX_CHAR = [b'Omega equals zero']
112       @description = "name of spectrometer mode"
113     g_mon_d:NX_FLOAT64 = 3.13542
114     g_mon_sam_len:NX_FLOAT64 = 68.0
115     g_mon_sign:NX_FLOAT64 = -1.0
116     g_omsect:NX_FLOAT64 = 0.0
117       @description = "omega-mode sector flag"
118     g_picker:NX_FLOAT64 = 0.1
119       @description = "picker-mode factor"
120     g_sam_ana_len:NX_FLOAT64 = 68.0
121     g_sam_sign:NX_FLOAT64 = 1.0
122     g_sect:NX_FLOAT64 = 0.0
123       @description = "sector"
124     g_u00:NX_FLOAT64 = 60.0
125       @description = "angle 0 of primary reflection"
126     g_u01:NX_FLOAT64 = 30.0
127       @description = "angle 1 of primary reflection"
128     g_u02:NX_FLOAT64 = 90.0
129       @description = "angle 2 of primary reflection"
130     g_u03:NX_FLOAT64 = 0.0
131       @description = "angle 3 of primary reflection"
132     g_u04:NX_FLOAT64 = 0.0
133       @description = "angle 4 of primary reflection"
134     g_u05:NX_FLOAT64 = 0.0
135       @description = "angle 5 of primary reflection"
136     g_u10:NX_FLOAT64 = 60.0
137       @description = "angle 0 of secondary reflection"
138     g_u11:NX_FLOAT64 = 30.0
139       @description = "angle 1 of secondary reflection"
140     g_u12:NX_FLOAT64 = 0.0
141       @description = "angle 2 of secondary reflection"
142     g_u13:NX_FLOAT64 = 0.0
143       @description = "angle 3 of secondary reflection"
144     g_u14:NX_FLOAT64 = 0.0
145       @description = "angle 4 of secondary reflection"
146     g_u15:NX_FLOAT64 = 0.0
147       @description = "angle 5 of secondary reflection"
148     g_vmode:NX_FLOAT64 = 0.0
149       @description = "set if vertical mode"
150     g_xtalogic_d1:NX_FLOAT64 = 463.6
151     g_xtalogic_d2:NX_FLOAT64 = 838.8
152     g_zh0:NX_FLOAT64 = 0.0
153       @description = "h zone vec 0"
154     g_zh1:NX_FLOAT64 = 0.0
155       @description = "h zone vec 1"
156     g_zk0:NX_FLOAT64 = 0.0
157       @description = "k zone vec 0"
158     g_zk1:NX_FLOAT64 = 0.0
159       @description = "k zone vec 1"
160     g_zl0:NX_FLOAT64 = 0.0
161       @description = "l zone vec 0"
162     g_zl1:NX_FLOAT64 = 0.0
163       @description = "l zone vec 1"
164     ub_matrix:NX_FLOAT64[3,3] = __array
165       __array = [
166           [-7.940607166e-18, 1.138130079e-16, 1.222647462]
167           [0.8645423114, -0.8645423114, 0.0]
168           [0.8645423114, 0.8645423114, -2.668317968e-16]
169         ]
170       @description = "UB[] matrix"
171   monochromator:NXmonochromator
172     @NX_class = "NXmonochromator"
173     wavelength:NX_FLOAT64 = 0.8265814273
174       @target = "/S1/instrument/monochromator/wavelength"
175       @units = "angstrom"

Crystal sample orientation information (UB matrix, orientation reflections and wavelength) is written to /SCAN/sample (a NXsample 5 group).

 1sample:NXsample
 2   @NX_class = "NXsample"
 3   diffractometer_mode:NX_CHAR = [b'Omega equals zero']
 4   diffractometer_sector:NX_INT64 = 0
 5   ub_matrix:NX_FLOAT64[3,3] = __array
 6     __array = [
 7         [-7.940607166e-18, 1.138130079e-16, 1.222647462]
 8         [0.8645423114, -0.8645423114, 0.0]
 9         [0.8645423114, 0.8645423114, -2.668317968e-16]
10       ]
11   unit_cell:NX_FLOAT64[6] = [5.139, 5.139, 5.139, '...', 90.0]
12   unit_cell_abc:NX_FLOAT64[3] = [5.139, 5.139, 5.139]
13     @units = "angstrom"
14   unit_cell_alphabetagamma:NX_FLOAT64[3] = [90.0, 90.0, 90.0]
15     @units = "degrees"
16   beam:NXbeam
17     @NX_class = "NXbeam"
18     incident_wavelength --> /S1/instrument/monochromator/wavelength
19   or0:NXnote
20     @NX_class = "NXnote"
21     @description = "or0: orientation reflection"
22     chi:NX_FLOAT64 = 90.0
23       @description = "diffractometer angle"
24       @units = "degrees"
25     h:NX_FLOAT64 = 2.0
26     k:NX_FLOAT64 = 2.0
27     l:NX_FLOAT64 = 0.0
28     phi:NX_FLOAT64 = 0.0
29       @description = "diffractometer angle"
30       @units = "degrees"
31     th:NX_FLOAT64 = 30.0
32       @description = "diffractometer angle"
33       @units = "degrees"
34     tth:NX_FLOAT64 = 60.0
35       @description = "diffractometer angle"
36       @units = "degrees"
37     wavelength:NX_FLOAT64 = 0.8265814273
38       @units = "Angstrom"
39   or1:NXnote
40     @NX_class = "NXnote"
41     @description = "or1: orientation reflection"
42     chi:NX_FLOAT64 = 0.0
43       @description = "diffractometer angle"
44       @units = "degrees"
45     h:NX_FLOAT64 = 0.0
46     k:NX_FLOAT64 = 0.0
47     l:NX_FLOAT64 = 2.0
48     phi:NX_FLOAT64 = 0.0
49       @description = "diffractometer angle"
50       @units = "degrees"
51     th:NX_FLOAT64 = 30.0
52       @description = "diffractometer angle"
53       @units = "degrees"
54     tth:NX_FLOAT64 = 60.0
55       @description = "diffractometer angle"
56       @units = "degrees"
57     wavelength:NX_FLOAT64 = 0.8265814273
58       @units = "Angstrom"
1

database of diffractometer geometries in SPEC data files: https://github.com/prjemian/spec2nexus/blob/main/spec2nexus/diffractometer-geometries.dict

2

List of NeXus unit categories: https://manual.nexusformat.org/nxdl-types.html#unit-categories-allowed-in-nxdl-specifications

3

A NeXus field is the same as an HDF5 dataset. The rename is due to historical reasons in NeXus when XML was used as a back-end data file storage format.

4

NXmonochromator: https://manual.nexusformat.org/classes/base_classes/NXmonochromator.html

5

NXsample: https://manual.nexusformat.org/classes/base_classes/NXsample.html