Skip to content

Experiment

The Experiment in EasyDiffraction includes both the measured diffraction data and all the other relevant parameters that describe the experimental setup and related conditions. This can include information about the instrumental resolution, peak shape, background, etc.

EasyDiffraction allows you to:

  • Load an existing experiment from a file (CIF format). Both the metadata and measured data are expected to be in CIF format.
  • Manually define a new experiment by specifying its type, other necessary experimental parameters, as well as load measured data. This is useful when you want to create an experiment from scratch or when you have a measured data file in a non-CIF format (e.g., .xye, .xy).

Below, you will find instructions on how to define and manage experiments in EasyDiffraction. It is assumed that you have already created a project object, as described in the Project section as well as defined its sample_models, as described in the Sample Model section.

Adding an Experiment from CIF

This is the most straightforward way to define an experiment in EasyDiffraction. If you have a crystallographic information file (CIF) for your experiment, that contains both the necessary information (metadata) about the experiment as well as the measured data, you can add it to your project using the add_experiment_from_cif method of the project instance. In this case, the name of the experiment will be taken from CIF.

# Load an experiment from a CIF file
project.add_experiment_from_cif('data/hrpt_300K.cif')

Accessing the experiment after loading it will be done through the experiments object of the project instance. The name of the model will be the same as the data block id in the CIF file. For example, if the CIF file contains a data block with the id hrpt,

data_hrpt

_expt_type.beam_mode  "constant wavelength"
...

you can access it in the code as follows:

# Access the experient by its name
project.experiments['hrpt']

Defining an Experiment Manually

If you do not have a CIF file or prefer to define the experiment manually, you can use the add method of the experiments object of the project instance. In this case, you will need to specify the name of the experiment, which will be used to reference it later. Along with the name, you need to provide the following parameters, essential for defining the experiment, which define the type of experiment:

  • sample_form: The form of the sample (powder, single crystal).
  • beam_mode: The mode of the beam (constant wavelength, time-of-flight).
  • radiation_probe: The type of radiation used (neutron, X-ray).
  • scattering_type: The type of scattering (bragg, total).

Important

It is important to mention that once an experiment is added, you cannot change these parameters. If you need to change them, you must create a new experiment or redefine the existing one.

If you have a measured data file, you can also specify:

  • data_path: The path to the measured data file (e.g., .xye, .xy). Supported formats are described in the Measured Data Category section.

Here is an example of how to add an experiment with all components needed to define the experiment explicitly set:

# Add an experiment with default parameters, based on the specified type.
# The experiment name is used to reference it later.
project.experiments.add(name='hrpt',
                        sample_form='powder',
                        beam_mode='constant wavelength',
                        radiation_probe='neutron',
                        scattering_type='bragg',
                        data_path='data/hrpt_lbco.xye')

To add an experiment of default type, you can simply do:

# Add an experiment of default type
# The experiment name is used to reference it later.
project.experiments.add(name='hrpt',
                        data_path='data/hrpt_lbco.xye')

You can now change the default parameters of the experiment, categorized into the groups based on the type of experiment.

The add method creates a new experiment of the specified type with default parameters. You can then modify its parameters to match your specific experimental setup. All parameters are grouped into the following categories, which makes it easier to manage the experiment:

  1. Instrument Category: Defines the instrument configuration, including wavelength, two-theta offset, and resolution parameters.
  2. Peak Category: Specifies the peak profile type and its parameters, such as broadening and asymmetry.
  3. Background Category: Defines the background type and allows you to add background points.
  4. Linked Phases Category: Links the sample model defined in the previous step to the experiment, allowing you to specify the scale factor for the linked phase.
  5. Measured Data Category: Contains the measured data. The expected format depends on the experiment type, but generally includes columns for 2θ angle or TOF and intensity.

1. Instrument Category

# Modify the default instrument parameters
project.experiments['hrpt'].instrument.setup_wavelength = 1.494
project.experiments['hrpt'].instrument.calib_twotheta_offset = 0.6

2. Peak Category

# Select the desired peak profile type
project.experiments['hrpt'].peak_profile_type = 'pseudo-voigt'

# Modify default peak profile parameters
project.experiments['hrpt'].peak.broad_gauss_u = 0.1
project.experiments['hrpt'].peak.broad_gauss_v = -0.1
project.experiments['hrpt'].peak.broad_gauss_w = 0.1
project.experiments['hrpt'].peak.broad_lorentz_x = 0
project.experiments['hrpt'].peak.broad_lorentz_y = 0.1

3. Background Category

# Select the desired background type
project.experiments['hrpt'].background_type = 'line-segment'

# Add background points
project.experiments['hrpt'].background.add(x=10, y=170)
project.experiments['hrpt'].background.add(x=30, y=170)
project.experiments['hrpt'].background.add(x=50, y=170)
project.experiments['hrpt'].background.add(x=110, y=170)
project.experiments['hrpt'].background.add(x=165, y=170)

4. Linked Phases Category

# Link the sample model defined in the previous step to the experiment
project.experiments['hrpt'].linked_phases.add(id='lbco', scale=10.0)

5. Measured Data Category

If you do not have a CIF file for your experiment, you can load measured data from a file in a supported format. The measured data will be automatically converted into CIF format and added to the experiment. The expected format depends on the experiment type.

Supported data file formats:

If no standard deviations are provided, they are automatically calculated as the square root of measured intensities.

Optional comments with # are possible in data file headers.

Here are some examples:

example1.xye

# 2theta  intensity    su
   10.00     167      12.6
   10.05     157      12.5
   10.10     187      13.3
   10.15     197      14.0
   10.20     164      12.5
  ...
  164.65     173      30.1
  164.70     187      27.9
  164.75     175      38.2
  164.80     168      30.9
  164.85     109      41.2

example2.xy

# 2theta  intensity
   10.00     167    
   10.05     157    
   10.10     187    
   10.15     197    
   10.20     164    
  ...
  164.65     173    
  164.70     187    
  164.75     175    
  164.80     168    
  164.85     109  

example3.xy

10  167.3    
10.05  157.4    
10.1  187.1    
10.15  197.8    
10.2  164.9    
...
164.65  173.3    
164.7  187.5    
164.75  175.8    
164.8  168.1    
164.85  109     

Listing Defined Experiments

To check which experiments have been added to the project, use:

# Show defined experiments
project.experiments.show_names()

Expected output:

Defined experiments 🔬
['hrpt']

Viewing an Experiment as CIF

To inspect an experiment in CIF format, use:

# Show experiment as CIF
project.experiments['hrpt'].show_as_cif()

Example output:

Experiment 🔬 'hrpt' as cif
╒═════════════════════════════════════════════╕
│ data_hrpt                                   │
│                                             │
│ _expt_type.beam_mode  "constant wavelength" │
│ _expt_type.radiation_probe  neutron         │
│ _expt_type.sample_form  powder              │
│ _expt_type.scattering_type  bragg           │
│                                             │
│ _instr.2theta_offset  0.6                   │
│ _instr.wavelength  1.494                    │
│                                             │
│ _peak.broad_gauss_u  0.1                    │
│ _peak.broad_gauss_v  -0.1                   │
│ _peak.broad_gauss_w  0.1                    │
│ _peak.broad_lorentz_x  0                    │
│ _peak.broad_lorentz_y  0.1                  │
│                                             │
│ loop_                                       │
│ _pd_phase_block.id                          │
│ _pd_phase_block.scale                       │
│ lbco 10.0                                   │
│                                             │
│ loop_                                       │
│ _pd_background.line_segment_X               │
│ _pd_background.line_segment_intensity       │
│ 10 170                                      │
│ 30 170                                      │
│ 50 170                                      │
│ 110 170                                     │
│ 165 170                                     │
│                                             │
│ loop_                                       │
│ _pd_meas.2theta_scan                        │
│ _pd_meas.intensity_total                    │
│ _pd_meas.intensity_total_su                 │
│ 10.0 167.0 12.6                             │
│ 10.05 157.0 12.5                            │
│ 10.1 187.0 13.3                             │
│ 10.15 197.0 14.0                            │
│ 10.2 164.0 12.5                             │
│ ...                                         │
│ 164.65 173.0 30.1                           │
│ 164.7 187.0 27.9                            │
│ 164.75 175.0 38.2                           │
│ 164.8 168.0 30.9                            │
│ 164.85 109.0 41.2                           │
╘═════════════════════════════════════════════╛

Saving an Experiment

Saving the project, as described in the Project section, will also save the experiment. Each experiment is saved as a separate CIF file in the experiments subdirectory of the project directory. The project file contains references to these files.

EasyDiffraction supports different types of experiments, and each experiment is saved in a dedicated CIF file with experiment-specific parameters.

Below are examples of how different experiments are saved in CIF format.

pd-neut-cwl

This example represents a constant-wavelength neutron powder diffraction experiment:

data_hrpt

_expt_type.beam_mode        "constant wavelength"
_expt_type.radiation_probe  neutron
_expt_type.sample_form      powder
_expt_type.scattering_type  bragg

_instr.wavelength    1.494
_instr.2theta_offset 0.6225(4)

_peak.broad_gauss_u    0.0834
_peak.broad_gauss_v   -0.1168
_peak.broad_gauss_w    0.123
_peak.broad_lorentz_x  0
_peak.broad_lorentz_y  0.0797

loop_
_pd_phase_block.id
_pd_phase_block.scale
lbco 9.0976(3)

loop_
_pd_background.line_segment_X
_pd_background.line_segment_intensity
_pd_background.X_coordinate
 10  174.3  2theta
 20  159.8  2theta
 30  167.9  2theta
 50  166.1  2theta
 70  172.3  2theta
 90  171.1  2theta
110  172.4  2theta
130  182.5  2theta
150  173.0  2theta
165  171.1  2theta

loop_
_pd_meas.2theta_scan
_pd_meas.intensity_total
_pd_meas.intensity_total_su
 10.00  167  12.6
 10.05  157  12.5
 10.10  187  13.3
 10.15  197  14.0
 10.20  164  12.5
 10.25  171  13.0
...
164.60  153  20.7
164.65  173  30.1
164.70  187  27.9
164.75  175  38.2
164.80  168  30.9
164.85  109  41.2

pd-neut-tof

This example demonstrates a time-of-flight neutron powder diffraction experiment:

data_wish

_diffrn_radiation.probe neutron

_pd_instr.2theta_bank 152.827

_pd_instr.dtt1 20773.1(3)
_pd_instr.dtt2    -1.08308
_pd_instr.zero   -13.7(5)

_pd_instr.alpha0 -0.009(1)
_pd_instr.alpha1  0.109(2)
_pd_instr.beta0   0.00670(3)
_pd_instr.beta1   0.0100(3)
_pd_instr.sigma0  0
_pd_instr.sigma1  0
_pd_instr.sigma2 15.7(8)

loop_
_pd_phase_block.id
_pd_phase_block.scale
ncaf 1.093(5)

loop_
_pd_background.line_segment_X
_pd_background.line_segment_intensity
_pd_background.X_coordinate
  9162.3  465(38) time-of-flight
 11136.8  593(30) time-of-flight
 14906.5  546(18) time-of-flight
 17352.2  496(14) time-of-flight
 20179.5  452(10) time-of-flight
 22176.0  468(12) time-of-flight
 24644.7  380(6)  time-of-flight
 28257.2  378(4)  time-of-flight
 34034.4  328(4)  time-of-flight
 41214.6  323(3)  time-of-flight
 49830.9  273(3)  time-of-flight
 58204.9  260(4)  time-of-flight
 70186.9  262(5)  time-of-flight
 82103.2  268(5)  time-of-flight
102712.0  262(15) time-of-flight

loop_
_pd_meas.time_of_flight
_pd_meas.intensity_total
_pd_meas.intensity_total_su
  9001.0  616.523  124.564
  9006.8  578.769  123.141
  9012.6  574.184  120.507
  9018.5  507.739  111.300
  9024.3  404.672  101.616
  9030.1  469.244  107.991
...
103085.0  275.072   60.978
103151.4  214.187   55.675
103217.9  256.211   62.825
103284.4  323.872   73.082
103351.0  242.382   65.736
103417.6  277.666   73.837

sc-neut-cwl

This example represents a single-crystal neutron diffraction experiment:

data_heidi

_diffrn_radiation.probe                 neutron
_diffrn_radiation_wavelength.wavelength 0.793

_pd_calib.2theta_offset 0.6225(4)

_pd_instr.resolution_u  0.0834
_pd_instr.resolution_v -0.1168
_pd_instr.resolution_w  0.123
_pd_instr.resolution_x  0
_pd_instr.resolution_y  0.0797

_pd_instr.reflex_asymmetry_p1 0
_pd_instr.reflex_asymmetry_p2 0
_pd_instr.reflex_asymmetry_p3 0
_pd_instr.reflex_asymmetry_p4 0

loop_
_exptl_crystal.id
_exptl_crystal.scale
tbti 2.92(6)

loop_
_refln.index_h
_refln.index_k
_refln.index_l
_refln.intensity_meas
_refln.intensity_meas_su
 1  1  1   194.5677    2.3253
 2  2  0    22.6319    1.1233
 3  1  1    99.2917    2.5620
 2  2  2   219.2877    3.2522
...
16  8  8    29.3063   12.6552
17  7  7  1601.5154  628.8915
13 13  7  1176.0896  414.6018
19  5  1     0.8334   20.4207
15  9  9    10.9864    8.0650
12 12 10    14.4074   11.3800



Now that the experiment has been defined, you can proceed to the next step: Analysis.