scippneutron.io.cif#

CIF file writer.

This module contains tools for writing CIF files with diffraction data. It does not support reading CIF files.

CIF Builder: High-level interface#

This module supports two interfaces for writing files. The high-level interface uses a builder pattern for assembling files. It is implemented by CIF.

To demonstrate the interface, first make some mockup powder diffraction data:

>>> import scipp as sc
>>> tof = sc.array(dims=['tof'], values=[1.2, 1.4, 2.3], unit='us')
>>> intensity = sc.array(
...     dims=['tof'],
...     values=[13.6, 26.0, 9.7],
...     variances=[0.7, 1.1, 0.5],
... )
>>> da = sc.DataArray(intensity, coords={'tof': tof})

Assemble data and metadata using a CIF builder:

>>> from scippneutron.io import cif
>>> cif_ = (
...  cif.CIF('my-data', comment="This is a demo of ScippNeutron's CIF builder.")
...  .with_beamline(beamline='fake', facility='made up')
...  .with_authors(cif.Author(name='Jane Doe', orcid='0000-0000-0000-0001'))
...  .with_reduced_powder_data(da)
... )

When all data has been added, write it to a file:

>>> cif_.save('example.cif')

This results in a file containing

#\#CIF_1.1
# This is a demo of ScippNeutron's CIF builder.
data_my-data

loop_
_audit_conform.dict_name
_audit_conform.dict_version
_audit_conform.dict_location
pdCIF 2.5.0 https://github.com/COMCIFS/Powder_Dictionary/blob/7608b92165f58f968f054344e67662e01d4b401a/cif_pow.dic
coreCIF 3.3.0 https://github.com/COMCIFS/cif_core/blob/fc3d75a298fd7c0c3cde43633f2a8616e826bfd5/cif_core.dic

_audit.creation_date 2024-09-05T13:47:54+00:00
_audit.creation_method 'Written by scippneutron v24.6.1

_audit_contact_author.name 'Jane Doe'
_audit_contact_author.id_orcid 0000-0000-0000-0001

_diffrn_radiation.probe neutron
_diffrn_source.beamline fake
_diffrn_source.facility 'made up'

loop_
_pd_meas.time_of_flight
_pd_proc.intensity_net
_pd_proc.intensity_net_su
1.2 13.6 0.8366600265340756
1.4 26.0 1.0488088481701516
2.3 9.7 0.7071067811865476

Chunks and loops: Low-level interface#

The high-level CIF builder uses Block, Chunk, and Loop to encode data. Those classes can also be used directly to gain more control over the file contents.

To demonstrate, make mockup powder diffraction data:

>>> import scipp as sc
>>> tof = sc.array(dims=['tof'], values=[1.2, 1.4, 2.3], unit='us')
>>> intensity = sc.array(
...     dims=['tof'],
...     values=[13.6, 26.0, 9.7],
...     variances=[0.7, 1.1, 0.5],
... )

Wrap the data in a Loop to write them together as columns.

>>> from scippneutron.io import cif
>>> tof_loop = cif.Loop({
...     'pd_meas.time_of_flight': tof,
...     'pd_meas.intensity_total': sc.values(intensity),
...     'pd_meas.intensity_total_su': sc.stddevs(intensity),
... })

Write the data to file along with some metadata:

>>> block = cif.Block('example', [
...     {
...         'diffrn_radiation.probe': 'neutron',
...         'diffrn_source.beamline': 'some-beamline',
...     },
...     tof_loop,
... ])
>>> cif.save_cif('example.cif', block)

This results in a file containing

#\#CIF_1.1
data_example

_diffrn_radiation.probe neutron
_diffrn_source.beamline some-beamline

loop_
_pd_meas.time_of_flight
_pd_meas.intensity_total
_pd_meas.intensity_total_su
1.2 13.6 0.8366600265340756
1.4 26.0 1.0488088481701516
2.3 9.7 0.7071067811865476

Functions

save_cif(fname, content, *[, comment])

Save data blocks to a CIF file.

Classes

Author(*, name[, address, email, orcid, ...])

Block(name[, content, comment, schema])

A CIF data block.

CIF([name, comment])

A builder for CIF files.

CIFSchema(name, version, location)

Chunk(pairs, /, *[, comment, schema])

A group of CIF key-value pairs.

Loop(columns, *[, comment, schema])

A CIF loop.