NXcanSAS v1.1

From canSAS

THIS PAGE IS WORK IN PROGRESS

Latest News

2024-09 : Proposals for NXcanSAS v1.1 in development

Overview

Since its release in 2017, the NXcanSAS format has served the community well, but mostly in the role of an HDF equivalent to the CanSAS1D XML format. However, as is evident in its founding discussions, far greater functionality was originally envisaged. Advances in instrumentation and science are now starting to push at the boundaries of NXcanSAS v1.0. One such area is what may be termed Magnetic-SANS which encompasses a number of different SANS techniques involving manipulation of the neutron spin. To meet the needs of this area revisions (in the form of additions) are required to NXcanSAS v1.0 and, ideally, NeXus.

NXcanSAS is currently implemented by Mantid and SasView.

Since January 2024 the ISIS Mantid Team have been implementing a Magnetic-SANS reduction workflow. It is now at the testing stage and the output file format will form part of this.

The Magnetic-SANS Problem

To reliably and unambigulously interpret Magnetic-SANS data it is necessary to know the spin history of the neutrons during the measurement. It makes sense to store this in the reduced output file as metadata which, in turn, requires NXcanSAS to:

  • have a way to include the polarization (aka spin state) information with the SANS data;
  • have a way to denote the polarization vector as this defines the geometry and physical interpretation of the scattering cross section;
  • have a way to identify the type of Magnetic-SANS technique that generated the data, and;
  • to include metadata relating to the spin manipulating devices (order encountered, type, etc) used during the measurement of the data.

NXcanSAS v1.0 and NeXus provide for some, but alas not all, of this information.

v1.1 Sub-group

  • Dirk Honecker (ISIS)
  • Steve King (ISIS & CanSAS Data Formats WG)
  • Annika Stellhorn (ESS)
  • Lucas Wilkins (ISIS Data Scientist)

Proposals

Throughout these proposals, all references to polarization and its derivative forms shall be deemed to use American English (ie, spelt with a "z")!

In general, NXcanSAS classes, <SASsomething>, are assumed to be of the NeXus type, <NXsomething>.

Mandatory and Recommended refer to whether the information must be present in a Magnetic-SANS NXcanSAS file, or if it is only encouraged.

For NXcanSAS v1.1

PROPOSAL 1: (Mandatory) That the polarization simply be included as additional, optional, data axes within <SASdata/>. This functionality is already part of v1.0, but perhaps had not been envisaged for this particular use case!

Aside: This proposal does mean that every Q point will have associated polarization information (if the file contains Magnetic-SANS data), but this can be leveraged to address other requirements (see below), and the overhead is tiny. It also means the polarization data is directly available to a file reader. An alternative that was considered was something like <SASdata name="title" polarization="value"/>, but this was rejected because it would a) require processing of "value" and b) require introducing something to denote the different types of Magnetic-SANS measurement.

PROPOSAL 2: (Mandatory) That the additional polarization axes be labelled Pin and Pout for before and after the sample, respectively. The units of each are "none".

Aside: This was the proposal that generated the most discussion in the sub-group! In the Magnetic-SANS literature Pin and Pout are variously called P_i / P_f, P_0 / P, or P / P'. Concerns were also expressed that any use of "P" risked confusion with pressure (amongst other quantities). However, examination of axis labels already in use in CanSAS1D and NXcanSAS showed a preference for concise labels without underscores (eg, Q, I, T, Idev, Qdev, Tdev, and Lambda) and it was not clear what else one might call polarization or what label other than P-something made sense! This proposal is thus a compromise that was reached, rather than a unanimous endorsement! The sub-group is open to alternative suggestions.

PROPOSAL 3: (Mandatory) That each polarization axis is restricted to one of the following values: +1 when the polarization is parallel to the polarizer; -1 when the polarization is antiparallel to the polarizer; and 0 when there is no polarisation.

Note: The values of the polarisation axes define the type of Magnetic-SANS data stored in the file: eg, PA-SANS: [Pin, Pout]; Polarizer Pol-SANS: [Pin, 0]; Analyzer Pol-SANS: [0, Pout]. When both polarization axes would take the value 0 - ie, a conventional, unpolarised, SANS measurement - the polarization axes need not be specified.

Aside: Other options considered were: "0" / "1" (eg, denoting a flipper is off / on), but this carries the risk that a coding error could be interpreted as off or not polarized), and "+" / "-", "p" / "m" (eg, denoting plus / minus), or "p" / "a" (eg, denoting parallel / antiparallel), but which require translation into a number or boolean for use in a program. It was noted that ORSO have opted for "p" / "m" in their emerging NR data format but their reasoning was not known.

PROPOSAL 4: (Mandatory) That the definition of the polarization be "For a magnetically saturated sample with collinear magnetic moments aligned along the polarization axis z, the non-spin-flip component with higher intensity is defined as the <minus, minus> spin state, but denoted here as [-1, -1]". This definition is to be incorporated in all relevant documentation relating to the production and use of NXcanSAS files.

Aside: A definition of the spin states is mandatory if the data is to have any meaning at all! This definition is a less ambiguous statement of the Moon-Riste-Koehler definition "for a polariser in the Northern hemisphere with the field aligned to the Earth's magnetic field, the transmitted beam is defined as - / minus." And in other literature the <minus, minus> state is said to transmit higher intensity than the <plus, plus> state.

Note: The astute reader will realise that this definition must invert in the Southern hemisphere! Data reduction software for polarized-SANS data measured at facilities there would need to correctly compensate when writing NXcanSAS files.

PROPOSAL 5a: (Recommended) That the wavelength-dependent neutron transmissions and associated uncertainties of polarizers, flippers or analyzers be written as separate <SAStransmission_spectrum/> blocks with appropriate names (eg, <SAStransmission_spectrum name="polarizer">) and the labels T and Tdev, respectively. In the case of hyperpolarization cells (ie, SEOP, MEOP & DNP) the transmission of the empty cell should also be recorded (eg, <SAStransmission_spectrum name="polarizer_empty">).

Aside: This proposal simply makes use of existing functionality in NXcanSAS v1.0, replicating how TOF-SANS CanSAS1D / NXcanSAS files presently incorporate the sample or background transmissions.

PROPOSAL 5b: (Recommended) That the fixed-wavelength neutron transmissions and associated uncertainties of polarizers, flippers or analyzers be written as the single values @T and @Tdev , respectively, under the relevant sub-class in <SASinstrument/>. In the case of hyperpolarization cells (ie, SEOP, MEOP & DNP) the transmission of the empty cell should also be recorded (eg, @T_empty and @Tdev_empty).

Aside: This proposal represents an addition to NXcanSAS. It is also noted that neither NXpolarizer or NXflipper provide for transmission values.

Note: It is noted that NeXus uses PARAMETER_error for uncertainties, but that NXcanSAS has generally opted for PARAMETERdev. Here PARAMETER_dev is proposed for readability.

PROPOSAL 6a: (Recommended) That the wavelength-dependent efficiency and associated uncertainties of polarizers, flippers or analyzers be written as separate <SASefficiency_spectrum/> blocks with appropriate names (eg, <SASefficiency_spectrum name="polarizer">) and the labels Eff and Effdev, respectively.

Aside: This proposal represents an addition to NXcanSAS, but is a simple and logical extension from <SAStransmission_spectrum/> (see Proposal 5a).

PROPOSAL 6b: (Recommended) That the fixed-wavelength efficiency and associated uncertainty of polarizers, flippers or analyzers be written as the single values @Eff and @Effdev, respectively, under the relevant sub-class in <SASinstrument/>.

Aside: This proposal represents an addition to NXcanSAS. It is noted that whilst NXpolarizer does provide for an efficiency value, NXflipper does not.

PROPOSAL 7a: (Recommended) That the magnitude (@magnetic_field / @electric_field) and direction (@direction) of a magnetic/electric field across the sample be written under <SASsample/>.

Aside: This proposal represents an addition to NXcanSAS, but is entirely consistent with NXsample.

Note: @direction in NeXus is defined as "Any of these values: x | y | z"; ie, just a single axis. For some experiments (eg, if using the ISIS 3D Vector Field Magnet) this would be too limiting, leading to Proposal 7b.

PROPOSAL 7b: (Recommended) That wherever @direction may be used, an optional alternative (@direction_spherical) be permitted. This would record the two angles required to describe the field direction in spherical coordinates.

Aside: @direction_spherical would follow the axes coordinate system of Mantid and SasView, where the neutrons travel horizontally in the direction of -z. Thus, the first angle, θ (theta), would record the angle of the field above (if positive) or below (if negative) the x-z plane. And the second angle, ψ (psi), would record the rotation of the field in the x-y plane with zero degrees at the 3 O'clock position. A positive angle corresponds to a counter-clockwise rotation.

PROPOSAL 8: (Recommended) That the magnitude (@magnetic_field) and direction (@direction, or @direction_spherical if Proposal 7b is adopted) of the magnetic field across polarizers, flippers or analyzers be written under the respective sub-class in <SASinstrument/>.

Aside: This proposal represents an addition to both NXcanSAS and NeXus; there is no provision for the magnetic field in NXpolarizer or NXflipper.

PROPOSAL 9: (Recommended) That the initial polarization (@polarization_initial) and decay time (@decay_time) of hyperpolarization (SEOP, MEOP & DNP) polarizers/analyzers and their respective uncertainties (@polarization_initial_dev and @decay_time_dev), along with the gas pressure (@pressure) and exchange distance (@length), be written under <SASpolarizer/> / <SASanalyzer/>.

Aside: This proposal represents an addition to both NXcanSAS and NeXus; there is no provision for the time-dependent polarisation of a hyperpolarization (ie, SEOP, MEOP & DNP) cell in NXpolarizer.

Note: The decay of polarization in a gas spin-exchange polarizer is a relaxation process with an exponential decay of the form exp(-t / T1) where t is the time and T1 is the relaxation time constant (ie, @decay_time).

PROPOSAL 10: (Mandatory) That the order with which the neutron encounters polarizers, flippers or analyzers be specified as the distance (@distance) from the sample (positive = before; negative = after) and written under the respective sub-class in <SASinstrument/>.

Aside: This proposal represents an addition to NXcanSAS but is essential to distinguish between polarizers and analysers. @distance has previously been used by NeXus but is now deprecated in favour of NXtransformations. So using @distance in NXcanSAS would remove the need to make a NXtransformations a requirement of NXcanSAS and save a lot of work!

PROPOSAL 11: (Mandatory) That to be able to differentiate multiple instances of polarizers, flippers or analyzers, as may be required for some Magnetic-SANS experiments, an identifer (@name) be written under the respective sub-class in <SASinstrument/>.

Aside: This proposal merely extends functionality already permitted for other devices in <SASinstrument>; eg, in <SASdetector>. It would also provide a secondary means of distinguishing between polarizers and analyzers.'

For NeXus

In formulating the proposals for NXcanSAS above it became clear that there were places where the type association between NXcanSAs and NeXus broke down. To remedy this, the following additions to the NeXus standard are proposed:

PROPOSAL NX1: That the NXpolarizer base class be granted the additional parameters @transmission, @transmission_empty, @pressure, @length, @polarization_initial and @decay_time.

Aside: As currently defined, NXpolarizer is very much predicated on a supermirror polarizer. Although it recognises a polarizer may be of type "3He", almost none of the current parameters would describe a 3He MEOP cell. In fact, it would be more sensible to deprecate the type "3He" and introduce either an umbrella type "hyperpolarization", or introduce three new types: "SEOP", "MEOP" and "DNP".

Note: NeXus has no NXanalyzer base class, it is presumed because it would be just be a copy of NXpolarizer with a different name. That works provided it can be made clear what role a given NXpolarizer instance in a file represents. At present this can only be inferred from the position of the device; ie, an analyzer must be after a polarizer. Proposal NX4 would help to further resolve any ambiguity. Or, of course, NeXus could introduce an NXanalyzer base class!

PROPOSAL NX2: That the NXflipper base class be granted the additional parameters @transmission and @efficiency.

Aside: This proposal would give NXflipper the same functionality as NXpolarizer if Proposal NX1 is adopted.

PROPOSAL NX3: That the NXpolarizer and NXflipper base classes be granted the additional parameters @magnetic_field and @direction.

Aside: This proposal would give NXpolarizer and NXflipper the same functionality as NXsample.

Note: @direction in NeXus is defined as "Any of these values: x | y | z"; ie, just a single axis. This is too limiting for modern experiments. Proposal 7b above suggests an alternative for NXcanSAS but it is noted that other solutions may exist in NXtransformations.

PROPOSAL NX4: That the NXpolarizer and NXflipper base classes be granted the additional parameter @description.

Aside: This proposal would give NXpolarizer and NXflipper the same functionality as some other classes in NXinstrument (eg, NXaperture, NXdetector) and allow multiple instances of these devices, as is required for some types of Magnetic-SANS experiment, to be distinguished. It would also provide another way to distinguish whether a polarizer device is being used as a polarizer or an analyzer!.

Units

Parameters with units must specify those units in accordance with NeXus units conventions unless alternative units are permitted by CanSAS1D / NXcanSAS unit conventions. For unitless parameters (eg, transmission, efficiency, polarization) the units must be set to "none".

Pseudo-code Examples

In the following examples, only the base classes and labels specifically relevant to the Magnetic-SANS case are being shown; it would be perfectly valid for additional metadata from the base classes shown (expand the links) to also be included, and in most cases this already happens in existing implementations of NXcanSAS v1.0. Certain Magnetic-SANS experiments may also require multiple instances of certain devices, for example, two flippers.

Question: How do we ensure the nD matrix of Q, I, Pin, Pout is correctly interpreted?

TOF-SANS

<SASroot>
   
   <SASentry> This represents a single sample
       <Title/>
       <Run/>
         
       <SASdata/>
           Pin_indices=0
           Pout_indices=1
           Q_indices=0,1,2
           I_axes=Pin,Pout,Q
              
           I: float[2,2,nQ]
           Pin: int[2]  (restricted to -1, 0, 1)
           Pout: int[2] (restricted to -1, 0, 1)
           Qx: float[nQ]
           Qy: float[nQ]
       <SASdata/>
                 
       <SAStransmission_spectrum name="sample"/>          Transmission data block for the sample (already in NXcanSAS v1.0)
       <SAStransmission_spectrum name="can"/>             Transmission data block for the sample container (already in NXcanSAS v1.0)
       
       <SAStransmission_spectrum name=”polarizer”/>       Transmission data block for the polariser (Recommended)
       <SAStransmission_spectrum name=”polarizer_empty”/> Transmission data block for the empty polariser (Recommended)
       <SAStransmission_spectrum name=”flipper”/>         Transmission data block for the flipper (Recommended)
       <SAStransmission_spectrum name=”analyser”/>        Transmission data block for the analyzer (Recommended)
       <SAStransmission_spectrum name=”analyser_empty”/>  Transmission data block for the empty analyzer (Recommended)
       
       <SASefficiency_spectrum name=”polarizer”/>         Efficiency data block for the polariser (Recommended)
       <SASefficiency_spectrum name=”flipper”/>           Efficiency data block for the flipper (Recommended)
       <SASefficiency_spectrum name=”analyser”/>          Efficiency data block for the analyzer (Recommended)
       
       <SASinstrument>
           <SASsource>
               radiation:
           <\SASsource>
           
           <SAScollimation/>
           
           <SASpolarizer> 
                name: (Mandatory) device identifier
                type: (Recommended) one of: “crystal”, “supermirror”, “3He”
                distance: (Mandatory) position of device in beamline
                polarization_initial: (Recommended) initial polarization of 3He gas in polarizer cell
                polarization_initial_dev: (Recommended) uncertainty on initial polarization of 3He gas in polarizer cell
                decay_time: (Recommended) polarization decay time of 3He gas in polarizer cell
                decay_time_dev: (Recommended) uncertainty on polarization decay time of 3He gas in polarizer cell
                pressure: (Recommended) pressure of 3He gas in the polarizer cell
                length: (Recommended) exchange distance through 3He gas in the polarizer cell
                magnetic_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
           <\SASpolarizer>
              
           <SASflipper>
                name: (Mandatory) device identifier
                type: (Recommended) one of: “coil”, “current-sheet”
                distance: (Mandatory) position of device in beamline
                magnetic_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
           <\SASflipper>
              
           <SASanalyzer>  (optional for polarisation analysis)              
                name: (Mandatory) device identifier
                type: (Recommended) one of: “crystal”, “supermirror”, “3He”
                distance: (Mandatory) position of device in beamline
                polarization_initial: (Recommended) initial polarization of 3He gas in analyzer cell
                polarization_initial_dev: (Recommended) uncertainty on initial polarization of 3He gas in analyzer cell
                decay_time: (Recommended) polarization decay time of 3He gas in analyzer cell
                decay_time_dev: (Recommended) uncertainty on polarization decay time of 3He gas in analyzer cell
                pressure: (Recommended) pressure of 3He gas in the analyzer cell
                length: (Recommended) exchange distance through 3He gas in the analyzer cell
                magnetic_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
           <\SASanalyser>
              
           <SASdetector/> 
              
      </SASinstrument>
         
       <SASsample>
                magnetic_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
                electric_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
               <temperature/> Average value and uncertainty from SE logs
       </SASSsample>
         
       <SASprocess>
           <SASprocessnote>
               Include Mantid workspace history?
           </SASprocessnote>
       </SASprocess>
         
       <SASnote/>

  </SASentry>
   
</SASroot>


Fixed-wavelength SANS

<SASroot>
   
   <SASentry> This represents a single sample
       <Title/>
       <Run/>
         
       <SASdata/>
           Pin_indices=0
           Pout_indices=1
           Q_indices=0,1,2
           I_axes=Pin,Pout,Q
              
           I: float[2,2,nQ]
           Pin: int[2]  (restricted to -1, 0, 1)
           Pout: int[2] (restricted to -1, 0, 1)
           Qx: float[nQ]
           Qy: float[nQ]
       <SASdata/>
                                 
       <SASinstrument>
           <SASsource>
               radiation:
           <\SASsource>
           
           <SAScollimation/>
           
           <SASpolarizer> 
                name: (Mandatory) device identifier
                type: (Recommended) one of: “crystal”, “supermirror”, “3He”
                distance: (Mandatory) position of device in beamline
                T: (Recommended) transmission of polarizer
                Tdev: (Recommended) transmission uncertainty of polarizer
                T_empty: (Recommended) transmission of empty 3He cell polarizer
                Tdev_empty: (Recommended) transmission uncertainty of empty 3He cell polarizer
                Eff: (Recommended) efficiency of polarizer
                Effdev: (Recommended) efficiency uncertainty of polarizer
                polarization_initial: (Recommended) initial polarization of 3He gas in polarizer cell
                polarization_initial_dev: (Recommended) uncertainty on initial polarization of 3He gas in polarizer cell
                decay_time: (Recommended) polarization decay time of 3He gas in polarizer cell
                decay_time_dev: (Recommended) uncertainty on polarization decay time of 3He gas in polarizer cell
                pressure: (Recommended) pressure of 3He gas in the polarizer cell
                length: (Recommended) exchange distance through 3He gas in the polarizer cell
                magnetic_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
           <\SASpolarizer>
              
           <SASflipper>
                name: (Mandatory) device identifier
                type: (Recommended) one of: “coil”, “current-sheet”
                distance: (Mandatory) position of device in beamline
                T: (Recommended) transmission of flipper
                Tdev: (Recommended) transmission uncertainty of flipper
                Eff: (Recommended) efficiency of flipper
                Effdev: (Recommended) efficiency uncertainty of flipper
                magnetic_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
           <\SASflipper>
              
           <SASanalyzer>  (optional for polarisation analysis)              
                name: (Mandatory) device identifier
                type: (Recommended) one of: “crystal”, “supermirror”, “3He”
                distance: (Mandatory) position of device in beamline
                T: (Recommended) transmission of analyzer
                Tdev: (Recommended) transmission uncertainty of analyzer
                T_empty: (Recommended) transmission of empty 3He cell analyzer
                Tdev_empty: (Recommended) transmission uncertainty of empty 3He cell analyzer
                Eff: (Recommended) efficiency of analyzer
                Effdev: (Recommended) efficiency uncertainty of analyzer
                polarization_initial: (Recommended) initial polarization of 3He gas in analyzer cell
                polarization_initial_dev: (Recommended) uncertainty on initial polarization of 3He gas in analyzer cell
                decay_time: (Recommended) polarization decay time of 3He gas in analyzer cell
                decay_time_dev: (Recommended) uncertainty on polarization decay time of 3He gas in analyzer cell
                pressure: (Recommended) pressure of 3He gas in the analyzer cell
                length: (Recommended) exchange distance through 3He gas in the analyzer cell
                magnetic_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
           <\SASanalyser>
              
           <SASdetector/> 
              
      </SASinstrument>
         
       <SASsample>
                T: (Recommended) transmission of sample
                Tdev: (Recommended) transmission uncertainty of sample
                magnetic_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
                electric_field: (Recommended) field strength
                    @direction or @direction_spherical: (Recommended) field direction
               <temperature/> Average value and uncertainty from SE logs
       </SASSsample>
         
       <SASprocess>
           <SASprocessnote>
               Include Mantid workspace history?
           </SASprocessnote>
       </SASprocess>
         
       <SASnote/>

  </SASentry>
   
</SASroot>