API Reference

X-SOCS data processing is implemented in the xsocs.process package. It provides:

  • Merge SPEC+EDF to HDF5: xsocs.process.merge
  • Q Space Conversion: xsocs.process.qspace
  • Fit/COM: xsocs.process.fit

xsocs.process.merge: SPEC+EDF to HDF5

merge_scan_data()

Sample Code

import time

from xsocs.process.merge import merge_scan_data

# output directory (some temporary files will also be written there)
output_dir = '/path/to/output/'

# path to the spec file
spec_f ='/path/to/spec/scan.spec'

# path to the image files, if stored in a different place than the path written
# in the spec file (else, set to None)
img_base = '/path/to/img/dir/'

# the beam energy (note that this value can be changed later when calling the
# img_2_qpeak function)
# Set to None to read it from scan headers
beam_energy = 8000.

# merge_scan_data will take all scans from the spec file that have a matching
# image file. If you only want a subset of those scans you can provide a list
# of scan numbers (i.e : the #S xxx lines in the scan headers)
# for example, if we only want scans 48.1, 54.1 and 68.1 we would write :
# scan_ids = ['48.1', '54.1', '68.1']
scan_ids = None

# this (temporary?) keyword is used to tell the function about the format
# of the spec file. So far there is only two supported values :
# 0 : files created before March 2016 (To Be Confirmed)
# 1 : files creqted after March 2016 (To Be Confirmed)
# At the moment it changed the way the nextNr value in the scan header is
# used to generate the image file name
# (in version 0 we actualy have to take nextNr-1 and pad it to get a 4 digit
# number, while in version 1 we pad the value to to 5 digits)
version = 1

# you can also set the offset and padding with the nr_offset and nr_padding
# keywords to the merge_scan_data function, or ignore them if you want
#  to use the default values specified by "version".
# nr_offset = -1
# nr_padding = 4

# channels (pix.) per degree (used by xrayutilities when converting to
# qspace coordinates)
# (not that this value can also be changed later when calling the
# img_2_qpeak function)
chan_per_deg = [318., 318.]

# direct beam position in the detector coordinates
center_chan = [140, 322]

# Detector image ROI to save as (row, column, height, width), example:
# image_roi = [100, 100, 200, 200]
# Set to None to save the whole image:
image_roi = None

# checks if some of the output files already exist
# set it to True if you dont care about overwriting files
overwrite = False

t_merge = time.time()

merge_scan_data(output_dir,
                spec_f,
                beam_energy=beam_energy,
                chan_per_deg=chan_per_deg,
                center_chan=center_chan,
                scan_ids=scan_ids,
                img_dir=img_base,
                version=version,
                overwrite=overwrite,
                image_roi=image_roi)

t_merge = time.time() - t_merge
print('Total time spent : {0}'.format(t_merge))

xsocs.process.qspace: QSpace conversion

kmap_2_qspace()

Sample Code

from xsocs.process.qspace import kmap_2_qspace, QSpaceConverter

# ========================
# Files
# ========================
# output HDF5 file name, default is qspace.h5 if not set
output_f = 'my_qspace.h5'

# path to the hdf5 "master" file (see id01_spec function)
xsocs_h5 = '/path/to/data.h5'

#========================
# Conversion parameters
#========================

# number of "bins" for the qspace cubes
qspace_dims = (28, 154, 60)

# size of median filter window to apply to each frame
medfilt_dims = None # e.g. (3,3)

# set disp_times to True if you want to output some info in stdout
QSpaceConverter.disp_times = True

# positions (on the sample) to convert to qspace
# if pos_indices will be ignored if rect_roi is provided
# rect_roi = [x_min, x_max, y_min, y_max] (sample positions)
roi = None

# whether to redistribute the intensity to fill the mpx4 gaps
maxipix_correction = False

# data column containing the monitor readings of primary beam intensity
monitor = "cnt1"

# Mask:
# boolean array of equal shape to detector frames to filter out bad pixels
# A non-zero value means that the pixel is masked
mask = None # numpy.ndarray

# set to true if you want to overwrite the output file
# otherwise an exception will be raised if the file already exists
overwrite = False

# number of processes to use
# If None, will use the number of availble core (see multiprocessing.cpu_count)
n_proc = None

kmap_2_qspace(xsocs_h5,
              output_f,
              qspace_dims,
              medfilt_dims=medfilt_dims,
              maxipix_correction=maxipix_correction,
              normalizer=monitor,
              roi=roi,
              mask=mask,
              n_proc=n_proc,
              overwrite=overwrite)

xsocs.process.fit: Fit/COM

PeakFitter

Sample Code

#!/usr/bin/python
# coding: utf-8
"""
This scripts illustrates the API of the gaussian/center-of-mass processing
"""

import sys
import numpy
from xsocs.process.fit import PeakFitter, FitTypes, BackgroundTypes

# path to the hdf5 file written by the kmap_2_qspace function
qspace_f = '/path/to/qspace.h5'

# Name of the text file where to store the resuls
result_file = 'results.txt'

# List of QSpace indices to process
# This selects sample positions for which QSpace are processed.
# If None, all QSpace are processed
indices = None

# Number of processors to use
# If None, all available cores are used.
n_proc = None

# Set-up the processing for a gaussian fit without background subtraction
fitter = PeakFitter(qspace_f,
                    fit_type=FitTypes.GAUSSIAN,
                    indices=indices,
                    n_proc=n_proc,
                    roi_indices=None,  # QSpace ROI
                    background=BackgroundTypes.NONE)

# Run the processing and get the results
results = fitter.peak_fit()

# Check for errors
if fitter.status != fitter.DONE:
    print("Fit process failed")
    sys.exit()

# Prepare columns header and data
# Start with position (x, y) on the sample
headers = ['sample_x', 'sample_y']
values = [results.sample_x, results.sample_y]

# Add one column for each parameter of the fit/COM result
# For each axis of the QSpace
for dimension, axis_name in enumerate(results.qspace_dimension_names):
    # For each fitted/computed parameter of the result
    for parameter_name in results.available_result_names:
        # Add its name to the header and its data to the values
        headers.append(axis_name + '_' + parameter_name)
        values.append(results.get_results(dimension, parameter_name))

# Transpose values from (parameters x points) to (points x parameters)
values = numpy.transpose(numpy.array(values))

# Write results to text file
with open(result_file, 'w') as res_f:
    res_f.write('\t'.join(headers) + '\n')
    for row_values in values:
        res_f.write('\t'.join(str(v) for v in row_values) + '\n')