Mapping Draft‎ > ‎

Functional Mapping

Status Report, 24 February 2014


Graeme Winter, Tobias Richter, Jonathan Sloan, Herbert J. Bernstein

For the past two years or thereabouts Herbert Bernstein and colleagues at Diamond Light Source have been working on the problem of storing the raw data from MX experiments in HDF5 containers. Rather than simply mapping the storage of the CIF tokens into HDF5, a significant effort has been made to create a NeXus application definition (see associated documents) where those ideas from CIF that are already well defined are adopted, and when new concepts need mapping or a more sophisticated mapping is required new NeXus definitions are made. The objective of this project is therefore to create an invertible mapping from the existing imgCIF specification to an idiomatically consistent NeXus HDF5 representation of the same data.

Motivation for this project has come with advances in detector development. Current instruments can record ~ 100 six-megapixel images per second, which (using the imgCIF byte-offset compression) typically results in a data rate of 600 MB/s. The data rate is not itself a great problem, however the file creation rate is. New generation detectors are likely to be able to operate in the 1000 images/s regime, increasing the load on the file system metadata by an order of magnitude. The only practical way to address this is to define a new container format which will work gracefully when storing many hundreds of images in a single file object: HDF5 / NeXus meets this requirement.

The concordance document (see associated documents) defines a mapping to meet this requirement, from imgCIF to HDF5 / NeXus allowing for (i) an exactly invertible transformation ensuring that the imgCIF key values are not lost and (ii) the data to be separated into linked files, so one HDF5 data set can be spread across multiple file system objects created by the detector, each storing e.g. 1000 image frames. This concordance document adopts NeXus idioms where possible and defines (within a namespace) those concepts that are not currently supported.

Following from this, and to some extent in parallel, efforts have been ongoing at Diamond to implement this mapping as a part of CBFlib and tools minicbf2nexus, cbf2nexus and nexus2cbf. These efforts (described as a functional mapping in the attached documentation) have aimed at producing an idiomatically correct and functionally complete NeXus file from a sequence of CBF or miniCBF files. The output files from this process have been independently inspected by James Parkhurst from Diamond Light Source, a key developer on the DIALS project and lead author of the dxtbx - the diffraction experiment toolbox. He found (after some conversation with Jonathan Sloan) that these files contain all of the necessary metadata required to process data as X-ray diffraction, indicating that this mapping is indeed functional.

Subsequent inspection has, however, identified some shortcomings in this mapping where some of the requirements defined above are not met: these shortcomings will be described below. It is important to note that this file does describe a general diffraction experiment containing many image frames in a single file with sufficient metadata to be independently useful (i.e. without the need for any instrument specific documentation) and so meets many of the requirements of the project. The shortcomings identified are as follows:

  • the mapping is not exactly reversible i.e. the precise text of the original CIF document cannot be recovered,
  • datasets that are split across multiple HDF5 files (like Dectris proposes for Eiger) cannot easily be visualised during data collection,
  • a handful of name conflicts need to be resolved.

The first of these shortcomings results from the fact that the freely chosen names in the CIF file, for example the axis names, are lost when the transformation is performed. While this does not impair the analysis of the file in the majority of cases, it does mean that the original file cannot be reproduced and also some non-file-based communication may fail (for example: a beamline scientist reporting that a given axis name has misbehaved during an experiment.) It is therefore desirable that this information is added in accordance with the concordance document, so that the information is not lost. In the majority of cases this information is not critical to the analysis of the data, so in principle the authors of the analysis software may ignore it. The example files that are now available are therefore relevant for these software developers to inspect.

The live display of data written is hampered by the fact that at the moment HDF5 file that are opened for writing cannot currently be read by another process. That is one of the reasons for Dectris proposing to split large detector array datasets into multiple files. So at every interval of N frames a new dataset would be written into a new file. An overarching NeXus file with the metadata would have links to these files. The individual sub-dataset files would be closed and hence readable shortly after collection. However if the metadata file were kept open for writing the entire time visualisation would be hampered by missing metadata (like axis information). The general NeXus standpoint was that this problem should be addresses in the HDF5 library. Diamond is currently working with the HDF5 group to make files readable during writing and transparent linking of multiple datasets into a single one. The alternative solution of putting metadata into the sub-datasets files would require the detector to collect and write metadata at high speed and partition metadata in a needlessly complex way. It is important to note that the HDF5 / NeXus data from the cbf2nexus commands contain all of the data in a single file, which may represent a different format.

While it may be possible to support more than one "dialect" of the MX NeXus definition (e.g. a single-file and multi-file dialect) this is undesirable and a decade or so of experience of working with CBF and miniCBF indicates that we should do everything possible to avoid this outcome. We therefore intend to resolve this conflict before widespread sharing of example data files with the community.

Finally, a small number of name conflicts have been identified where names defined within the concordance document (e.g. "poise" to define the orientation and placement of an axis) need to be corrected in the functional mapping where different names have been used. This is agreed to be a part of a tidying up process, rather than a fundamental issue, and is clearly identified in the associated documentation. There are also a small number of places where the choice of names is influenced by the wider understanding of terms within the crystallographic community - for example the use of "goniometer" to also describe a rotation axis for the positioning of a detector. While it is a correct use of a term it has specific meaning within the community as a sample goniometer and hence may cause confusion: we have yet to decide on the most effective solution for this.

In summary we have:

  • a functional application definition
  • code to translate from CBF to NeXus and back again in a functional way
  • concordance document describing how to literally preserve everything in the file (this is largely there)
  • issues relating to accessing data during data collection best addressed in the HDF5 libraries






Jonathan Sloan has developed a functional mapping that serves as a
prototype of the full mapping.

Proposed Changes

The following is a preliminary analysis of the steps necessary to achieve compatibility of the functional mapping and the full concordance.
Functional mapping of CBF to Nexus from JS of DLS in cbf2nexus:

The CBFlib 0.9.4 release will include a "functional mapping" version of the 
mapping from CBF to NeXus as a prototype for the full mapping in the 
concordance document.  The functional mapping omits some details
from the CBF in the NeXus file, such as user-selected category
key names that are not always needed for successful image processing.
Experience with this mapping has suggested some proposed future
changes both the the functional mapping and to the full mapping
to ensure eventual compatibility between them.  This document details
the differences and the suggest resolution.  

Note:  In general CBF category keys are not carried in the functional
mapping, but are all carried in the full mapping.  In order to avoid
name space conflicts, when a key from a CBF category is moved
to nexus, in general it is prefixed with "CBF_category_name__", as in
"CBF_axis__".  The exception to this rule is when no namespace
conflicts can occur.  See the discussion on NXpoise, below.

In many cases, the full mapping will be adjusted to be an extension of
the functional mapping.  The older, deprecated mappings will still be
accepted by the code for the reverse direction.

Note:  The functional mapping has adopted the practice of putting most axis
definitions in a pose:NXcollection group under the relevant equipment.  This
resolves the issue of namespace conflicts between axis names and other fields.
The full mapping has resolved that issue by prefixing axis names with
"CBF_axis_".  Both practices will be retained as a deprecated options,
but the default will be a variation of the functional mapping practice.
All axes will be protected from namespace conflicts with by gatherings
them into poise:NXpoise groups under the relevant equipment.  The proposed
NeXus base class name "NXpoise" is under discussion.  The class name
"NXgoniometer" may be used instead, provided the potential confusion for
crystallographers in seeing an "NXgoniometer" under NXDetector can be
resolved.  Until a new NXpoise base class or similar is approved, a 
temporary poise:NXcollection group will be used as a third, 
to-be-deprecated option.  In this document both the proposed revised 
functional mapping and proposed revised full mapping with both be presented using
poise:NXpoise groups.

================================

ARRAY_DATA category

Current functional mapping:

    _array_data.array_id
    _array_data.binary_id
    _array_data.data  DATAARRAY
    
    -->
    
      /entry:NXentry
        /data:NXdata
          /data-->/entry/instrument/detector/data
        /instrument:NXinstrument
          /detector:NXdetector
            /data=DATAARRAY
            

omitting both ARRAYID and BINARYID, which are generated internally
for the functional mapping. In the full mapping they are explicitly 
recorded, and the data in NXdetector is the primary copy.

Current Full Mapping:
 
    _array_data.array_id  ARRAYID
    _array_data.binary_id BINARYID
    _array_data.data      DATAARRAY

    -->
    
      /CBF_diffrn_scan__SCANID:NXentry
        /instrument:NXinstrument
          /CBF_diffrn_detector__DETECTORNAME:NXdetector
            /data_ARRAYID_BINARYID=DATAARRAY
              @CBF_array_id="ARRAYID"
              @CBF_binary_id="BINARYID"
        /data:NXdata
            /data_ARRAYID_BINARYID-->
              /CBF_diffrn_scan__SCANID/instrument/CBF_diffrn_detector__DETECTORNAME/data_ARRAYID_BINARYID
  
This is essentially the same mapping, just with names preserved.
No changes are proposed in either mapping.

================================

ARRAY_ELEMENT_SIZE category

Current functional mapping:

  The current functional mapping does not use this
category, but infers the pixel sizes from the
ARRAY_STRUCTURE_LIST category.  This is not always
correct.


Current Full Mapping:
              
    _array_element_size.size SIZE -->
      /CBF_diffrn_scan__SCANID:NXentry
        /instrument:NXinstrument
          /CBF_diffrn_detector__DETECTORNAME:NXdetector
            /?_pixel_size_ARRAYID=SIZE
              @units="m"
    where "?" is "x", "y", "z" for
    _array_element_size.index == 1,2, or 3 respectively
    
Proposed functional mapping:

    _array_element_size.size SIZE -->
      /entry:NXentry
        /instrument:NXinstrument
          /detector:NXdetector
            /?_pixel_size=SIZE
              @units="m"
    where "?" is "x", "y", "z" for
    _array_element_size.index == 1,2, or 3 respectively

    
This is essentially the same mapping, just with names preserved.
    
================================

ARRAY_INTENSITIES category 

    Note on the handling of ARRAY_INTENSITIES
    
    In CBF, ARRAY_INTENSITIES is a set of properties of arrays
    of data, mapping in the concordance to attributes of
    each data array.
    
    In the current functional mapping, each of the ARRAY_INTENSITIES
    is treated as a property of the detector and mapped to
    a a field in NXdetector.  This is workable when there
    is a single uniform set of ARRAY_INTENSITIES properties
    applicable to all the data in NXdetector, but limiting in
    more general cases of multiple data arrays for a single
    detector.
    
Current functional mapping:

    _array_intensities.array_id ARRAYID
    _array_intensities.binary_id BINARYID
    _array_intensities.details DETAILS
    _array_intensities.gain GAIN
    _array_intensities.gain_esd GAINESD
    _array_intensities.linearity LINEARITY
    _array_intensities.offset OFFSET
    _array_intensities.scaling SCALING
    _array_intensities.overload OVERLOAD
    _array_intensities.undefined_value UNDEFVAL
    _array_intensities.pixel_fast_bin_size FBINSIZE
    _array_intensities.pixel_slow_bin_size SBINSIZE
    _array_intensities.pixel_binning_method METHOD


    -->
    
      /entry:NXentry
        /data:NXdata
          /data=DATAARRAY
          /offset --> /entry/instrument/detector/offset
          /scaling_factor --> /entry/instrument/detector/scaling_factor
        /instrument:NXinstrument
          /detector:NXdetector
            /offset=[OFFSET]
            /saturation_value=[OVERLOAD]
            /scaling_factor=[SCALING]            
            /undefined_value=[UNDEFVAL]
            
    with no explicit mapping of ARRAYID, BINARYID, DETAILS, GAIN, 
    GAINESD, LINEARITY, FBINSIZE, SBINSIZE, METHOD.   ARRAYID
    and BINARYID are used implicitly to organize the arrays
    and LINEARITY is used as a filter, supporting only 
    "linear".  The current functional mapping also overrides
    the value of scaling with the value 1/gain.  This is not
    necessarily correct.
    
    We propose to deprecate this mapping changing to the following
    functional mapping and full mapping. Because all the 
    properties are attributes, they are all seen via the link.
    We propose to add a new _diffrn_detector_element.gain_setting
    tag to carry a NeXus-style text gain setting and keep the
    gain distinct from the scaling.  We proposed to drop the
    prefixes on "linearity" and "gain" and "details" and add
    them to the NeXus definitions.
    
    
Proposed functional mapping:
    
    _array_intensities.array_id ARRAYID
    _array_intensities.binary_id BINARYID
    _array_intensities.details DETAILS
    _array_intensities.gain GAIN
    _array_intensities.gain_esd GAINESD
    _array_intensities.linearity LINEARITY
    _array_intensities.offset OFFSET
    _array_intensities.scaling SCALING
    _array_intensities.overload OVERLOAD
    _array_intensities.undefined_value UNDEFVAL
    _array_intensities.pixel_fast_bin_size FBINSIZE
    _array_intensities.pixel_slow_bin_size SBINSIZE
    _array_intensities.pixel_binning_method METHOD


    -->
      /entry:NXentry
        /data:NXdata
          /data-->/entry/instrument/detector/data
        /instrument:NXinstrument
          /detector:NXdetector
            /data=DATAARRAY
              @CBF_array_id="ARRAYID"
              @details="DETAILS"
              @gain=[GAIN]          
              @gain_esd=[GAINESD]
              @CBF_array_intensities__linearity="LINEARITY"          
              @offset=[OFFSET]
              @saturation_value=[OVERLOAD]
              @scaling_factor=[SCALING]
              @underfined_value=[UNDEFVAL]
              @CBF_array_intensities__pixel_fast_bin_size=[FBINSIZE]
              @CBF_array_intensities__pixel_slow_bin_size=[SBINSIZE]
              @CBF_array_intensities__pixel_binning_method="METHOD"

            
    with only the BINARYID being handled implicitly and all linearity
    options being supported.
    
Proposed full mapping:

    _array_intensities.array_id ARRAYID
    _array_intensities.binary_id BINARYID
    _array_intensities.details DETAILS
    _array_intensities.gain GAIN
    _array_intensities.gain_esd GAINESD
    _array_intensities.linearity LINEARITY
    _array_intensities.offset OFFSET
    _array_intensities.scaling SCALING
    _array_intensities.overload OVERLOAD
    _array_intensities.undefined_value UNDEFVAL
    _array_intensities.pixel_fast_bin_size FBINSIZE
    _array_intensities.pixel_slow_bin_size SBINSIZE
    _array_intensities.pixel_binning_method METHOD


    -->

      /CBF_diffrn_scan__SCANID:NXentry
        /data:NXdata
          /data-->
            /CBF_diffrn_scan__SCANID/instrument/CBF_diffrn_detector__DETECTORNAME/data_ARRAYID_BINARYID
        /instrument:NXinstrument
          /CBF_diffrn_detector__DETECTORNAME:NXdetector
            /data_ARRAYID_BINARYID=DATAARRAY
              @CBF_array_id="ARRAYID"
              @CBF_binary_id="BINARYID"
              @details="DETAILS"
              @gain=[GAIN]          
              @gain_esd=[GAINESD]
              @linearity="LINEARITY"          
              @offset=[OFFSET]
              @saturation_value=[OVERLOAD]
              @scaling_factor=[SCALING]
              @undefined_value=[UNDEFVAL]
              @CBF_array_intensities__pixel_fast_bin_size=[FBINSIZE]
              @CBF_array_intensities__pixel_slow_bin_size=[SBINSIZE]
              @CBF_array_intensities__pixel_binning_method="METHOD"

This is essentially the same mapping, just with names preserved.
The same attributes could be used as fields in the case of a single
data array, but in that case links for all the fields would be needed
from NXdata to NXdetector, so it is preferable to use attributes even
in the case of a single data array.  The reverse mapping will support
both uses.

================================

ARRAY_STRUCTURE category

    _array_structure.id
    _array_structure.encoding_type
    _array_structure.compression_type
    _array_structure.byte_order

    Data items in the ARRAY STRUCTURE category record the 
    organization and encoding of array data that may be stored 
    in the ARRAY DATA category.
    
    Note that this is essentially a type that may apply to 
    multiple binary images, and corresponds to some of the 
    detailed HDF5 information about an array. 
    
    The information in this category is the byte order, the 
    compression information, and the encoding, which is carried 
    in and retrievable from the HDF5 types, properties lists, etc.
    
    At present NeXus does not expose this information, so it is
    only used implicitly in the mappings.

================================

ARRAY_STRUCTURE_LIST category

Current functional mapping:

    _array_structure_list.array_id    ARRAYID
    _array_structure_list.index       INDEX
    _array_structure_list.dimension   DIM
    _array_structure_list.precedence  PRECEDENCE
    _array_structure_list.direction   DIR
    _array_structure_list.axis_set_id AXISSET

    _array_structure_list_axis.axis_set_id  AXISSETID
    _array_structure_list_axis.axis_id      AXISID
    _array_structure_list_axis.angle         ANGLE
    _array_structure_list_axis.angle_increment  ANGLEINC
    _array_structure_list_axis.displacement  DISP
    _array_structure_list_axis.displacement_increment  DISPINC

    
    -->
    
    /entry:Nentry
      /data:NXdata
        /axes=["","y","x"]  where the axis names are internally regenerated
        /x-indices=PRECEDENCE (for x axis)
        /y_indices=PRECEDENCE (for y axis)
        /x=[DISP,DISP+DISPINC,...] using x displacement or angle and increment
          @depends_on=...   determined from AXIS definitions
          @equipment="detector"
          @offset=[...] determined from AXIS definitions
          @offset_units="mm"
          @transformation_type="..." from AXIS definitions
          @units="mm"
          @vector=[...] determined from AXIS definitions
        /y=[DISP,DISP+DISPINC,...] using y displacement or angle and increment
          @depends_on=...   determined from AXIS definitions
          @equipment="detector"
          @offset=[...] determined from AXIS definitions
          @offset_units="mm"
          @transformation_type="..." from AXIS definitions
          @units="mm"
          @vector=[...] determined from AXIS definitions
          
    which supports only simple single-axis axis-sets and loses both single
    axis and axis-set names.  It currently treats the displacement increments as
    the pixel size.  This is not always correct.
    
Proposed full mapping:  

    _array_structure_list.axis_set_id AXISSETID
    _array_structure_list.array_id ARRAYID
    _array_structure_list.dimension DIM
    _array_structure_list.direction DIR
    _array_structure_list.index INDEX
    _array_structure_list.precedence PRECEDENCE
    _array_structure_list_axis.axis_id AXISID
    _array_structure_list_axis.axis_set_id AXISSETID
    _array_structure_list_axis.angle ANGLE
    _array_structure_list_axis.angle_increment ANGLEINC
    _array_structure_list_axis.displacement DISP
    _array_structure_list_axis.fract_displacement  FRACTDISP
    _array_structure_list_axis.displacement_increment DISPINC
    _array_structure_list_axis.fract_displacement_increment FRACTINC
    _array_structure_list_axis.angular_pitch  ANGPITCH
    _array_structure_list_axis.reference_angle REFANG
    _array_structure_list_axis.reference_displacement REFDISP 

    -->
    
      /CBF_diffrn_scan__SCANID:NXentry
        /instrument:NXinstrument
          /CBF_diffrn_detector__DETECTORNAME:NXdetector
            /CBF_array_structure_list_axis__AXISSETID=[]
              @CBF_array_structure_list_axis__id="AXISSETID"
              @CBF_array__id="ARRAYID"
              @CBF_array_structure_list__dimension=DIM
              @CBF_array_structure_list__direction="DIR"
              @CBF_array_structure_list__index=INDEX
              @CBF_array_structure_list__precedence=PRECEDENCE
            /poise:NXpoise
              /AXISID=[DISP,DISP+DISPINC,...]   (or using angles where appropriate)
                @depends_on=...   determined from AXIS definitions
                @equipment="detector"
                @offset=[...] determined from AXIS definitions
                @offset_units="mm"
                @transformation_type="..." from AXIS definitions
                @units="mm"
                @vector=[...] determined from AXIS definitions
                @CBF_array_structure_list_axis__axis_id="AXISID"
                @CBF_array_structure_list_axis__axis_set_id="AXISSETID"
                @CBF_array_structure_list_axis__angle=ANGLE
                @CBF_array_structure_list_axis__angle_increment=ANGLEINC
                @CBF_array_structure_list_axis__displacement=DISP
                @CBF_array_structure_list_axis__displacement=FRACTDISP
                @CBF_array_structure_list_axis__displacement_increment=DISPINC
                @CBF_array_structure_list_axis__fract_displacement_increment=FRACTINC
                @CBF_array_structure_list_axis__angular_pitch=ANGPITCH
                @CBF_array_structure_list_axis__radial_pitch=RADPITCH
                @CBF_array_structure_list_axis__reference_angle=REFANG
                @CBF_array_structure_list_axis__reference_displacement=REFDISP
                
     with the parent category for the axis set and axis determined by the equipment 
     of the axes.
              
Proposed functional mapping:
    
    To avoid creating multiple dialects -- one for the simple detector pixel geometries
    and another for the complex geometries such as spiral scans, we propose to upgrade
    the functional mapping to support full use of axis sets and the include this
    upgraded functional mapping in the full mapping.  
    
    _array_structure_list.axis_set_id AXISSETID
    _array_structure_list.array_id ARRAYID
    _array_structure_list.dimension DIM
    _array_structure_list.direction DIR
    _array_structure_list.index INDEX
    _array_structure_list.precedence PRECEDENCE
    _array_structure_list_axis.axis_id AXISID
    _array_structure_list_axis.axis_set_id AXISSETID
    _array_structure_list_axis.angle ANGLE
    _array_structure_list_axis.angle_increment ANGLEINC
    _array_structure_list_axis.displacement DISP
    _array_structure_list_axis.fract_displacement  FRACTDISP
    _array_structure_list_axis.displacement_increment DISPINC
    _array_structure_list_axis.fract_displacement_increment FRACTINC
    _array_structure_list_axis.angular_pitch  ANGPITCH
    _array_structure_list_axis.reference_angle REFANG
    _array_structure_list_axis.reference_displacement REFDISP 

    -->
    
    /entry:Nentry
      /instrument:NXinstrument
        /detector:NXdetector
          /axes=["frame_number","y","x"]  where the names are the
                string "frame_number"
                followed by the actual original axis-set names.  
                Use of internally-generated names is likely to 
                cause confusion and errors.
             @CBF_axis_sets=["AXISSET1_AXIS1:AXISSET1_AXIS2:...",
             "AXISSET2_AXIS1:AXISSET2_AXIS2:...",...] 
                 where the names are the actual names of the axes in the axis sets
                 as given on the NeXus side of the mapping
          /poise:NXpoise
            /AXISID=[DISP,DISP+DISPINC,...]
              @depends_on=...   determined from AXIS definitions
              @equipment="detector"
              @offset=[...] determined from AXIS definitions
              @offset_units="mm"
              @transformation_type="..." from AXIS definitions
              @units="mm"
              @vector=[...] determined from AXIS definitions


================================

AXIS category

Current functional mapping

    _axis.id                  AXISID
    _axis.type                AXISTYPE
    _axis.equipment           AXISEQUIPMENT
    _axis.equipment_component AXISEQUIPCOMP
    _axis.depends_on          AXISDEPENDSON
    _axis.rotation_axis       AXISROTAXIS
    _axis.rotation            AXISROTATION
    _axis.vector[1]           AXISV1
    _axis.vector[2]           AXISV2
    _axis.vector[3]           AXISV3
    _axis.offset[1]           AXISO1
    _axis.offset[2]           AXISO2
    _axis.offset[3]           AXISO3
    _axis.system              AXISSYSTEM
    
    -->
    
    {   /entry:NXentry
          /instrument:NXinstrument
            /detector:NXdetector
for AXISEQUIPMENT=="detector"}
    {   /entry:NXentry
          /sample:NXsample
for AXISEQUIPMENT=="goniometer"}
             /pose:NXcollection
               /AXISID=[]
                 @units="mm"  if AXISTYPE=="translation" 
                 or @units="degrees"  if AXISTYPE=="rotation"
                 @equipment="AXISEQUIPMENT"
                 @offset=offsetxform([O1,O2,O3])
                 @offset_units="mm"
                 @transformation_type="AXISTYPE"
                 @vector=coordxform([V1,V2,V3])

  each axis is placed with its equipment.  The functional mapping avoids name
  conflicts by wrapping the associated axis definitions in a POSE
  NXcollection.  We propose to formalize that and use a more appropriate name
  by creating a new NXpoise class to contain arbitrarily named collections
  of axes to be associated with an enclosing NXdetector or NXgoniometer group.
  
  All axes are converted from the CBF coordinate frame to the NeXus MxStas
  coordinate frame.
  
  The current functional mapping discards all axes other than those for
  axis types "translation" and "rotation".  This is a serious omission
  because the general axes are needed to recover the original CBF laboratory
  coordinates from the NeXus McStas coordinates.  (CBF files do not necessarily
  have Y point upwards).
  
  This mapping does not handle the equipment_component, rotation_axis and
  rotation tags added for FEL work.
  
  This functional mapping avoid the need for prefixing axis names by use of
  pose:NXcollection to isolate the names, and put the goniometer axes
  under NXsample, rather than under NXgoniometer.
  

We propose to conform the full mapping to the functional mapping, but extend
the functional mapping to support general axes and FEL tags, and move the
general axes up one leveel.            


Proposed Full Mapping

    _axis.id                  AXISID
    _axis.type                AXISTYPE
    _axis.equipment           AXISEQUIPMENT
    _axis.equipment_component AXISEQUIPCOMP
    _axis.depends_on          AXISDEPENDSON
    _axis.rotation_axis       AXISROTAXIS
    _axis.rotation            AXISROTATION
    _axis.vector[1]           AXISV1
    _axis.vector[2]           AXISV2
    _axis.vector[3]           AXISV3
    _axis.offset[1]           AXISO1
    _axis.offset[2]           AXISO2
    _axis.offset[3]           AXISO3
    _axis.system              AXISSYSTEM
    
    -->
    { /CBF_diffrn_scan__SCANID:NXentry
      /CBF_scan_id="SCANID"
      /instrument:NXinstrument
        /CBF_diffrn_detector__DETECTORNAME:NXdetector
    for AXISEQUIPMENT=="detector"}
    {  /CBF_diffrn_scan__SCANID:NXentry
         /sample:NXsample
    for AXISEQUIPMENT=="goniometer"}
    {  /CBF_diffrn_scan__SCANID:NXentry
         /coordinate_system:NXcoordinate_system
    for AXISEQUIPMENT=="general"}
         /poise:NXpoise
           /AXISID=[]
          /poise:NXpoise
            /AXISID=[]
              @units="mm"  if AXISTYPE=="translation" 
              or @units="degrees"  if AXISTYPE=="rotation"
              @transformation_type="AXISTYPE"
              @equipment_component="AXISEQUIPCOMP"
              @depends_on="AXISDEPENDSON"
              @rotation_axis="AXISROTAXIS"
              @rotation=AXISROTATION
              @rotation_units="degrees"
              @offset=offsetxform([O1,O2,O3])
              @offset_inits="mm"
              @vector=coordxform([V1,V2,V3])
    
 Proposed functional mapping
 
    _axis.id                  AXISID
    _axis.type                AXISTYPE
    _axis.equipment           AXISEQUIPMENT
    _axis.equipment_component AXISEQUIPCOMP
    _axis.depends_on          AXISDEPENDSON
    _axis.rotation_axis       AXISROTAXIS
    _axis.rotation            AXISROTATION
    _axis.vector[1]           AXISV1
    _axis.vector[2]           AXISV2
    _axis.vector[3]           AXISV3
    _axis.offset[1]           AXISO1
    _axis.offset[2]           AXISO2
    _axis.offset[3]           AXISO3
    _axis.system              AXISSYSTEM
    
    -->

    { /CBF_diffrn_scan__SCANID:NXentry
      /CBF_scan_id="SCANID"
      /instrument:NXinstrument
        /CBF_diffrn_detector__DETECTORNAME:NXdetector
    for AXISEQUIPMENT=="detector"}
    {  /CBF_diffrn_scan__SCANID:NXentry
         /sample:NXsample
    for AXISEQUIPMENT=="goniometer"}
    {  /CBF_diffrn_scan__SCANID:NXentry
         /coordinate_system:NXcoordinate_system
    for AXISEQUIPMENT=="general"}
         /poise:NXpoise
           /AXISID=[]
              @units="mm"  if AXISTYPE=="translation" 
              or @units="degrees"  if AXISTYPE=="rotation"
              @transformation_type="AXISTYPE"
              @equipment_component="AXISEQUIPCOMP"
              @depends_on="AXISDEPENDSON"
              @rotation_axis="AXISROTAXIS"
              @rotation=AXISROTATION
              @rotation_units="degrees"
              @offset=offsetxform([O1,O2,O3])
              @offset_inits="mm"
              @vector=coordxform([V1,V2,V3])


================================

DIFFRN category

    _diffrn.id is not carried in the functional mapping
    
    in the full mapping
    
    _diffrn.id DIFFRNID -->
    
    /CBF_diffrn_scan__SCANID:NXentry
      /CBF_diffrn_id="DIFFRNID"

================================
      
    _diffrn.crystal_id is not carried in the functional mapping
    
    and is only carried in the full mapping in the /CBF_cbf group
    for completeness, it should be handled 
    
Proposed full mapping:

    _diffrn.crystal_id CRYSTALID -->
    
    /CBF_diffrn_scan__SCANID:NXentry
      /CBF_diffrn__CRYSTAL_ID:NXsample
        /CBF_crystal_id="CRYSTALID"
        
Proposed functional mapping:

    _diffrn.crystal_id CRYSTALID -->
    
    /entry:NXentry
      /sample:NXsample
        /CBF_crystal_id="CRYSTALID"

      

================================

DIFFRN source category

Current functional mapping:

    _diffrn_source.current 	CURRENT
    _diffrn_source.details 	DETAILS
    _diffrn_source.diffrn_id 	DIFFRNID
    _diffrn_source.power 	    POWER
    _diffrn_source.size 	    SIZE
    _diffrn_source.source 	SOURCE
    _diffrn_source.take-off_angle 	TOANGLE
    _diffrn_source.target 	TARGET
    _diffrn_source.type 	    TYPE
    _diffrn_source.voltage 	VOLTAGE
    
    --> 
    
    /entry:NXentry
      /instrument:NXinstrument
        /source:NXsource
          /current=CURRENT
            @units="mA"
          /power=POWER
            @units="kW"
          /type="TYPE"
          /target_material="TARGET"
          /name="TYPE"
          /voltage=VOLTAGE
            @units="kV"
            
 not currently supported in the full mapping
 
 Proposed full mapping (to conform)

    _diffrn_source.current 	CURRENT
    _diffrn_source.details 	DETAILS
    _diffrn_source.diffrn_id 	DIFFRNID
    _diffrn_source.power 	    POWER
    _diffrn_source.size 	    SIZE
    _diffrn_source.source 	SOURCE
    _diffrn_source.take-off_angle 	TOANGLE
    _diffrn_source.target 	TARGET
    _diffrn_source.type 	    TYPE
    _diffrn_source.voltage 	VOLTAGE
    
    --> 
    
    /CBF_diffrn_scan__SCANID:NXentry
      /instrument:NXinstrument
        /source:NXsource
          /current=CURRENT
            @units="mA"
          /details="DETAILS"
          /power=POWER
            @units="kW"
          /size="SIZE"
          /source="SOURCE"
          /take_off_angle=TOANGLE
            @units="degrees"
          /target_material="TARGET"
          /name="TYPE"
          /voltage=VOLTAGE
            @units="kV"
 
    

================================
  
DIFFRN category

    _diffrn_radiation.diffrn_id  is not carried in the functional mapping.
    Rather the wavelength spectrum is mapped independently of _diffrn_radiation
    
    in the full mapping,
    
    _diffrn_radiation.diffrn_id DIFFRNID -->
      /CBF_diffrn_scan__SCANID:NXentry
        /CBF_scan_id="SCANID"
        /CBF_diffrn_id="DIFFRNID"


================================
DIFFRN_RADIATION and DIFFRN_RADIATION_WAVELENGTH categories

Current functional mapping

    _diffrn_radiation.collimation    COLLIMATION
    _diffrn_radiation.diffrn_id      DIFFRNID
    _diffrn_radiation.div_x_source   DIVX
    _diffrn_radiation.div_y_source   DIVY
    _diffrn_radiation.div_x_y_source DIVXY
    _diffrn_radiation.filter_edge'   ABSEDGE
    _diffrn_radiation.inhomogeneity  HWIDTH
    _diffrn_radiation.monochromator  MONOCHROMATOR
    _diffrn_radiation.polarisn_norm  POLNANG
    _diffrn_radiation.polarisn_ratio POLRAT
    _diffrn_radiation.polarizn_source_norm   POLSNANG
    _diffrn_radiation.polarizn_source_ratio  POLSRAT
    _diffrn_radiation.probe          RADIATION
    _diffrn_radiation.type           SIEGBAHNTYPE
    _diffrn_radiation.xray_symbol    IUPACXRAYSYMB
    _diffrn_radiation.wavelength_id  ID
    _diffrn_radiation_wavelength.id  ID
    _diffrn_radiation_wavelength.wavelength    WAVELENGTH
    _diffrn_radiation_wavelength.wt            WEIGHT
    
    
    -->
    
    /entry:NXentry
      /sample:NXsample
        /beam:NXbeam/collimation=COLLIMATION
        /incident_divergence_x=DIVX
          @units="degrees"
        /incident_divergence_y=DIVY
          @units="degrees"
        /incident_divergence_xy=DIVXY
          @units="degrees^2"
        /beam_size_x=HWIDTH   (not correct)
          @units="mm"
        /beam_size_y=HWIDTH   (not correct)
          @units="mm"
        /incident_wavelength=[wavelength]
          @units="A"
        /weight=[wt]
        /incident_polarisation_stokes=[I,Q,U,V]
      /instrument:NXinstrument
        /monochromator:NXmonochromator
          /description="MONOCHROMATOR"
        /source:NXsource
          /probe="RADIATION"

    where I (the intensity = |Ex|^2+|Ey|^2) = 1.0
          Q (|Ex|^2-|Ey|^2) = POLSRAT*cos(2*POLSNANG*PI/180)
          U (2Re(ExEy*)) = POLSRAT*sin(2*POLSNANG*PI/180)
          V (-2Im(ExEy*)) = 0.0
              
This polarization mapping is not quite right because it does not account for the
differences between the CBF laboratory coordinate system and the McStas
coordinate system, and the intensity is being forced to 1, which, while
understandable, is not right for the 4-parameter Stokes vector, where the
first element is explicitly the intensity.

I propose to resolve this as follows:

1.  Convert the angle POLSNANG to the McStas value for the functional
mapping.
2.  Change the concordance to also use the Stokes vector with the
corrected POLSNANG.
3.  If the incident beam intensity is provided in the CBF, scale the Stokes
vector by that amount, but if it is not provided, use the current default of 1.
When an intensity is provided, it is provided frame-by-frame, in
_diffrn_scan_frame_monitor.value.  Therefore, I propose to index
the Stokes vectors by frame as well by the slow index.
4.  Add Stokes vector tags to the CBF dictionary, frame by frame.
5.  When mapping from a NeXus file with a Stokes vector populate _both_ the
overall 2-parameter polarization derived from an average of the
frame-by-frame Stokes vectors and the individual Stokes vectors
for each frame.



Proposed full mapping:

    _diffrn_radiation.collimation    COLLIMATION
    _diffrn_radiation.diffrn_id      DIFFRNID
    _diffrn_radiation.div_x_source   DIVX
    _diffrn_radiation.div_y_source   DIVY
    _diffrn_radiation.div_x_y_source DIVXY
    _diffrn_radiation.filter_edge'   ABSEDGE
    _diffrn_radiation.inhomogeneity  HWIDTH
    _diffrn_radiation.monochromator  MONOCHROMATOR
    _diffrn_radiation.polarisn_norm  POLNANG
    _diffrn_radiation.polarisn_ratio POLRAT
    _diffrn_radiation.polarizn_source_norm   POLSNANG
    _diffrn_radiation.polarizn_source_ratio  POLSRAT
    _diffrn_radiation.polarizn_Stokes_I  SVECI
    _diffrn_radiation.polarizn_Stokes_Q  SVECQ
    _diffrn_radiation.polarizn_Stokes_U  SVECU
    _diffrn_radiation.polarizn_Stokes_V  SVECV
    _diffrn_radiation.probe          RADIATION
    _diffrn_radiation.type           SIEGBAHNTYPE
    _diffrn_radiation.xray_symbol    IUPACXRAYSYMB
    _diffrn_radiation.wavelength_id  ID
    _diffrn_radiation_wavelength.id  ID
    _diffrn_radiation_wavelength.wavelength    WAVELENGTH
    _diffrn_radiation_wavelength.wt            WEIGHT
    _diffrn_scan_frame.polarizn_Stokes_I STOKESI
    _diffrn_scan_frame.polarizn_Stokes_Q STOKESQ
    _diffrn_scan_frame.polarizn_Stokes_U STOKESU
    _diffrn_scan_frame.polarizn_Stokes_V STOKESV
    _diffrn_scan_frame.frame_number FRAMENO
    
    -->

       /CBF_diffrn_scan__SCANID:NXentry
         /CBF_scan_id="SCANID"
         /sample:NXsample
           /beam:NXbeam
             /incident_divergence_x=DIVX
               @units="degrees"
             /incident_divergence_y=DIVY
               @units="degrees"
             /incident_divergence_xy=DIXXY
               @units="degrees^2"
             /CBF_diffrn_radiation_wavelength__wavelength_id=[WAVELENGTH_ID]
             /incident_wavelength=[WAVELENGTH]
               @units="A"
             /weight=[WEIGHT]
             /incident_polarisation_stokes_average=[SVECI,SVECQ,SVECU,SVECV]
               @units="Watts/meter^2"
             /incident_polarisation_stokes=[STOKESI,STOKESQ,STOKESU,STOKESV]
               @units="Watts/meter^2"
             /CBF_diffrn_radiation__polarisn_norm=POLNANG
               /@units="deg"
             /CBF_diffrn_radiation__polarisn_ratio=POLRAT    
             /CBF_diffrn_radiation__polarisn_source_norm=POLSNANG
               /@units="deg"
             /CBF_diffrn_radiation__polarizn_source_ratio=POLSRAT

             /CBF_diffrn_radiation__filter_edge=ABSEDGE
                /@units="angstroms"
             /CBF_diffrn_radiation__inhomogeneity=HWIDTH
                /@units="mm"
         /instrument:NXinstrument
           /monchromator:NXmonochromator
             /description="MONOCHROMATOR"
           /source:NXsource
             /probe="RADIATION"
             /CBF_diffrn_radiation__type="SIEGBAHNTYPE"
             /CBF_diffrn_radiation__xray_symbol="IUPACXRAYSYMB"

         With the incident_polarisation_stokes array indexed by FRAMENO
================================

DIFFRN_DETECTOR category

Current functional mapping:

    _diffrn_detector.diffrn_id DIFFRNID 
    _diffrn_detector.id DETECTORNAME 
    _diffrn_detector.details DETAILS
    _diffrn_detector.detector DETECTOR
    _diffrn_detector.dtime DTIME
    _diffrn_detector.number_of_axes NAXES
    _diffrn_detector.type DETTYPE

    --> 
 
    /entry:NXentry
      /instrument:NXinstrument
        /detector:NXdetector
          /description="DETTYPE"
          /details="DETAILS"
          
The following is a revision as of 27 February 2014
to conform more closely to the definitions in the
NeXus NXdetector base class

Proposed full mapping:

    _diffrn_detector.diffrn_id DIFFRNID 
    _diffrn_detector.id DETECTORNAME 
    _diffrn_detector.details DETAILS
    _diffrn_detector.detector DETECTOR
    _diffrn_detector.dtime DTIME
    _diffrn_detector.gain_setting GAINSETTING
    _diffrn_detector.number_of_axes NAXES
    _diffrn_detector.type DETTYPE
    
    --> 
    
      /CBF_diffrn_scan__SCANID:NXentry
        /CBF_scan_id="SCANID"
        /CBF_diffrn_id="DIFFRNID"
          /instrument:NXinstrument/CBF_diffrn_detector__DETECTORNAME:NXdetector
            /details="DETAILS"
            /type="DETECTOR"
            /deadtime=DTIME
            /number_of_axes=NAXES
            /decription="DETTYPE"
            /gain_setting="GAINSETTING"


Proposed functional mapping: _diffrn_detector.diffrn_id DIFFRNID _diffrn_detector.id DETECTORNAME _diffrn_detector.details DETAILS _diffrn_detector.detector DETECTOR _diffrn_detector.dtime DTIME _diffrn_detector.gain_setting GAINSETTING _diffrn_detector.number_of_axes NAXES _diffrn_detector.type DETTYPE --> /entry:NXentry /instrument:NXinstrument /detector:NXdetector /description="DETTYPE" /details="DETAILS" /type="DETECTOR" /deadtime=DTIME /number_of_axes=NAXES /gain_setting="GAINSETTING"
================================ DIFFRN_DETECTOR_ELEMENT category Current functional mapping: _diffrn_detector_element.id ELEMENTID _diffrn_detector_element.center[1] CEN1 _diffrn_detector_element.center[2] CEN2 --> /entry:NXentry /instrument:NXinstrument /detector:NXdetector /beam_center_x @units="mm" /beam_center_y @units="mm" references 2 deprecated tags for a beam center. The current tags are given in the full mapping. With the old tags it is not clear which is the fast index and which the slow. Proposed full mapping: _diffrn_detector_element.id ELEMENTID _diffrn_detector_element.detector_id DETECTORNAME _diffrn_detector_element.reference_center_fast RCF _diffrn_detector_element.reference_center_slow RCS _diffrn_detector_element.reference_center_units UNITS --> /CBF_diffrn_scan__SCANID:NXentry /CBF_scan_id="SCANID" /CBF_diffrn_id="DIFFRNID" /instrument:NXinstrument /CBF_diffrn_detector__DETECTORNAME:NXdetector /beam_center_x=[RCS] (converted from UNITS as needed) @units=mm /beam_center_y=[RCF] (converted from UNITS as needed) @units=mm /CBF_diffrn_detector_element__id="ELEMENTID1:ELEMENTID2:..." /CBF_diffrn_detector_element__reference_center_fast=[RCF1,RCF2,...] /CBF_diffrn_detector_element__reference_center_slow=[RCS1,RCS2,...] /CBF_diffrn_detector_element__id="UNITS1:UNITS2:..." inserts ELEMENTID into the colon-separated list of element IDs inserts RCF into the array of reference centers inserts RCS into the array of reference centers inserts ELEMENTID into the colon-separated list of units Proposed functional mapping: _diffrn_detector_element.id ELEMENTID _diffrn_detector_element.detector_id DETECTORNAME _diffrn_detector_element.reference_center_fast RCF _diffrn_detector_element.reference_center_slow RCS _diffrn_detector_element.reference_center_units UNITS --> /entry:NXentry /instrument:NXinstrument /detector:NXdetector /beam_center_x=[RCS] (converted from UNITS as needed) @units=mm /beam_center_y=[RCF] (converted from UNITS as needed) @units=mm ================================ DIFFRN_MEASUREMENT category Current functional mapping: _diffrn_measurement.diffrn_id DIFFRNID _diffrn_measurement.details DETAILS _diffrn_measurement.device DEVICE _diffrn_measurement.device_details DEVDETAILS _diffrn_measurement.device_type DEVTYPE _diffrn_measurement.id GONIOMETER _diffrn_measurement.method METHOD _diffrn_measurement.number_of_axes NUMBER _diffrn_measurement.sample_detector_distance DIST _diffrn_measurement.sample_detector_voffset VOFST _diffrn_measurement.specimen_support SPECSPRT --> /entry:NXentry /method="METHOD" /instrument:NXinstrument /goniometer:NXgoniometer /details="DETAILS" /local_name="DEVICE" /description="DEVDETAILS" /type="DEVTYPE" /detector:NXdetector /distance=DIST @units="mm" Proposed full mapping (to conform to functional mapping): _diffrn_measurement.diffrn_id DIFFRNID _diffrn_measurement.details DETAILS _diffrn_measurement.device DEVICE _diffrn_measurement.device_details DEVDETAILS _diffrn_measurement.device_type DEVTYPE _diffrn_measurement.id GONIOMETER _diffrn_measurement.method METHOD _diffrn_measurement.number_of_axes NUMBER _diffrn_measurement.sample_detector_distance DIST _diffrn_measurement.sample_detector_voffset VOFST _diffrn_measurement.specimen_support SPECSPRT --> /CBF_diffrn_scan__SCANID:NXentry /CBF_scan_id="SCANID /CBF_diffrn_id="DIFFRNID" /instrument:NXinstrument /CBF_diffrn_measurement__GONIOMETER:NXgoniometer /details="DETAILS" /local_name="DEVICE" /description="DEVDETAILS" /type="DEVTYPE" /CBF_diffrn_measurement__method="METHOD" /number_of_axes=NUMBER /CBF_diffrn_measurement__specimen_support="SPECSPRT" /CBF_diffrn_detector__DETECTORNAME:NXdetector /distance=DIST /@units="mm" /CBF_diffrn_measurement__sample_detector_voffset=VOFST /@units="mm" ================================ DIFFRN_MEASUREMENT_AXIS category Current functional mapping: _diffrn_measurement_axis.axis_id AXISID _diffrn_measurement_axis.measurement_device DEVICE _diffrn_measurement_axis.measurement_id GONIOMETER --> /entry:NXentry /sample:NXsample /pose:NXcollection /AXISID=[] Proposed functional mapping _diffrn_measurement_axis.axis_id AXISID _diffrn_measurement_axis.measurement_device DEVICE _diffrn_measurement_axis.measurement_id GONIOMETER --> /entry:NXentry /sample:NXsample /poise:NXpoise /AXISID=[] Proposed full mapping (to conform) _diffrn_measurement_axis.axis_id AXISID _diffrn_measurement_axis.measurement_device DEVICE _diffrn_measurement_axis.measurement_id GONIOMETER --> /CBF_diffrn_scan__SCANID:NXentry /CBF_scan_id="SCANID /CBF_diffrn_id="DIFFRNID" /sample:Nxsample /poise:NXpoise /AXISID=[] /instrument:NXinstrument /CBF_diffrn_measurement__GONIOMETER:NXgoniometer /CBF_diffrn_measurement__device="DEVICE" ======================== Current functional mapping: _diffrn_scan.id SCANID _diffrn_scan.date_end ENDDATETIME _diffrn_scan.date_start STARTDATETIME _diffrn_scan.integration_time AVGCOUNTTIME _diffrn_scan.frame_id_start FRAMESTARTID _diffrn_scan.frame_id_end FRAMEENDID _diffrn_scan.frames FRAMES _diffrn_scan.time_period TIMEPER _diffrn_scan.time_rstrt_incr RSTRTTIME --> /entry:NXentry /instrument:NXinstrument /detector:NXdetector /start_time="STARTDATETIME" /end_time="ENDDATETIME" Current full mapping: _diffrn_scan.id SCANID _diffrn_scan.date_end ENDDATETIME _diffrn_scan.date_start STARTDATETIME _diffrn_scan.integration_time AVGCOUNTTIME _diffrn_scan.frame_id_start FRAMESTARTID _diffrn_scan.frame_id_end FRAMEENDID _diffrn_scan.frames FRAMES _diffrn_scan.time_period TIMEPER _diffrn_scan.time_rstrt_incr RSTRTTIME --> /CBF_diffrn_scan__SCANID:NXentry /CBF_scan_id="SCANID" /end_time=ENDDATETIME /start_time=STARTDATETIME /average_count_time=AVGCOUNTTIME @units="sec" /average_frame_time=TIMEPER @units="sec" /average_frame_restart_time=RSTRTTIME @units="sec" /instrument:NXinstrument /CBF_diffrn_detector__DETECTORNAME:NXdetector /frame_start_number=FRAMESTARTNO /frame_end_number=FRAMEENDNO FRAMESTARTNO is the value of _diffrn_scan_frame.frame_number for which the value of _diffrn_scan_frame.frame_id equals FRAMESTARTID FRAMEENDNO is the value of _diffrn_scan_frame.frame_number for which the value of _diffrn_scan_frame.frame_id equals FRAMEENDID ================================ DIFFRN_SCAN_AXIS category Current functional mapping Data extracted to calculate actual axis settings for each frame. Proposed Full mapping: _diffrn_scan_axis.axis_id AXISID--> _diffrn_scan_axis.angle_start ANGSTART _diffrn_scan_axis.angle_range ANGRANGE _diffrn_scan_axis.angle_increment ANGINC _diffrn_scan_axis.angle_rstrt_incr ANGRSTRT _diffrn_scan_axis.displacement_start DISPSTART _diffrn_scan_axis.displacement_range DISPRANGE _diffrn_scan_axis.displacement_increment DISPINC _diffrn_scan_axis.displacement_increment DISPINC _diffrn_scan_axis.displacement_rstrt_incr DISPRSTRT _diffrn_scan_axis.reference_angle ANG _diffrn_scan_axis.reference_displacement DISP _diffrn_scan_axis.scan_id SCANID --> { /CBF_diffrn_scan__SCANID:NXentry /CBF_scan_id="SCANID" /instrument:NXinstrument /CBF_diffrn_detector__DETECTORNAME:NXdetector for AXISEQUIPMENT=="detector"} { /CBF_diffrn_scan__SCANID:NXentry /sample:NXsample for AXISEQUIPMENT=="goniometer"} { /CBF_diffrn_scan__SCANID:NXentry /coordinate_system:NXcoordinate_system for AXISEQUIPMENT=="general"} /poise:NXpoise /AXISID=[] @diffrn_scan_axis__angle_start=ANGSTART @diffrn_scan_axis__angle_range=ANGRANGE @diffrn_scan_axis__angle_increment=ANGINC @diffrn_scan_axis__angle_rstrt_incr=ANGRSTRT @diffrn_scan_axis__displacement_start=DISPSTART @diffrn_scan_axis__displacement_range=DISPRANGE @diffrn_scan_axis__displacement_increment=DISPINC @diffrn_scan_axis__displacement_rstrt_incr=DISPRSTRT @diffrn_scan_axis__reference_angle=ANG @diffrn_scan_axis__reference_displacement=DISP ================================ Current functional mapping: _diffrn_scan_frame.date DATETIME _diffrn_scan_frame.frame_id ID _diffrn_scan_frame.frame_number FRAMENUMBER _diffrn_scan_frame.integration_time COUNTTIME _diffrn_scan_frame.scan_id SCANID _diffrn_scan_frame.integration_period FRAMETIME _diffrn_scan_frame.time_rstrt_incr RSTRTTIME --> /entry:NXentry /instrument:NXinstrument /detector:NXdetector /frame_start_time=DATETIME /frame_time=[FRAMETIME] which has an erroneous use of integration_period instead of time_period. Proposed full mapping _diffrn_scan_frame.date DATETIME _diffrn_scan_frame.frame_id ID _diffrn_scan_frame.frame_number FRAMENUMBER _diffrn_scan_frame.integration_time COUNTTIME _diffrn_scan_frame.polarizn_Stokes_I STOKESI _diffrn_scan_frame.polarizn_Stokes_Q STOKESQ _diffrn_scan_frame.polarizn_Stokes_U STOKESU _diffrn_scan_frame.polarizn_Stokes_V STOKESV _diffrn_scan_frame.scan_id SCANID _diffrn_scan_frame.time_period FRAMETIME _diffrn_scan_frame.time_rstrt_incr RSTRTTIME --> /CBF_diffrn_scan__SCANID:NXentry /CBF_scan_id="SCANID" /instrument:NXinstrument /CBF_diffrn_detector__DETECTORNAME:NXdetector /CBF_diffrn_scan_frame__date=["DATETIME"] /CBF_diffrn_scan_frame__frame_id=["ID"] /count_time=[COUNTIME] /frame_time=[FRAMETIME] /frame_restart_time=[RSTRTTIME] /sample:NXsample /beam:NXbeam /incident_polarisation_stokes=[STOKESI,STOKESQ,STOKESU,STOKESV] @units="Watts/meter^2" where each array element is inserted at index FRAMENUMBER ================================ DIFFRN_SCAN_FARME_AXIS category Proposed full mapping _diffrn_scan_frame_axis.axis_id AXISID _diffrn_scan_frame_axis.angle ANGLE _diffrn_scan_frame_axis.angle_increment ANGLEINCREMENT _diffrn_scan_frame_axis.angle_rstrt_incr ANGLERSTRTINCREMENT _diffrn_scan_frame_axis.displacement DISP _diffrn_scan_frame_axis.displacement_increment DISPINCREMENT _diffrn_scan_frame_axis.displacement_rstrt_incr DISPRSTRTINCREMENT _diffrn_scan_frame_axis.reference_angle REFANGLE _diffrn_scan_frame_axis.reference_displacement REFDISP { /CBF_diffrn_scan__SCANID:NXentry /CBF_scan_id="SCANID" /instrument:NXinstrument /CBF_diffrn_detector__DETECTORNAME:NXdetector for AXISEQUIPMENT=="detector"} { /CBF_diffrn_scan__SCANID:NXentry /sample:NXsample for AXISEQUIPMENT=="goniometer"} { /CBF_diffrn_scan__SCANID:NXentry /coordinate_system:NXcoordinate_system for AXISEQUIPMENT=="general"} /poise:NXpoise /AXISID=[] @diffrn_scan_frame_axis__angle_start=[ANGSTART] @diffrn_scan_frame_axis__angle_range=[ANGRANGE] @diffrn_scan_frame_axis__angle_increment=[ANGINC] @diffrn_scan_frame_axis__angle_rstrt_incr=[ANGRSTRT] @diffrn_scan_frame_axis__displacement_start=[DISPSTART] @diffrn_scan_frame_axis__displacement_range=[DISPRANGE] @diffrn_scan_frame_axis__displacement_increment=[DISPINC] @diffrn_scan_frame_axis__displacement_rstrt_incr=[DISPRSTRT] @diffrn_scan_frame_axis__reference_angle=[ANG] @diffrn_scan_frame_axis__reference_displacement=[DISP] note that @units="mm" or @units="deg" should also be specified. The dimensions of the array depend on np (the number of frames = the value of _diffrn_scan.frames) either DISP OR ANGLE is inserted as the i-th element counting from 1 in AXISID where i is the value of _diffrn_scan_frame.frame_number for which the value of _diffrn_scan_frame.frame_id agrees with the value of _diffrn_scan_frame_axis.frame_id The remaining tags similarly populate the attribute arrays ================================ DIFFRN_SCAN_FRAME_MONITOR category Proposed full mapping: _diffrn_scan_frame_monitor.id MONID --> _diffrn_scan_frame_monitor.detector_id DETECTORNAME --> _diffrn_scan_frame_monitor.scan_id SCANID --> _diffrn_scan_frame_monitor.frame_id FRAMEID --> _diffrn_scan_frame_monitor.integration_time INTEGRATIONTIME --> _diffrn_scan_frame_monitor.monitor_value MONITORVALUE --> --> /CBF_diffrn_scan__SCANID:NXentry /CBF_scan_id="SCANID" /instrument:NXinstrument /CBF_diffrn_scan_frame_monitor__DETECTORNAME_MONID:NXmonitor @CBF_detector_id="DETECTORNAME" @CBF_diffrn_scan_frame_monitor__id="MONID" /data=[MONITORVALUE] /count_time=[INTEGRATIONTIME] ================================
ċ
mapping-2014-02-20
(7k)
Herbert J. Bernstein,
Feb 23, 2014, 9:21 AM
Comments