Module to process SPEC data files

Introduction

This module defines classes, objects and routines for reading SPEC datafiles into python classes. There are three main classes for the data, SpecDataFile, SpecScan and SpecData and are arranged as follows:

SpecDataFile, contains a single data file. The datafile is indexed upon initializing the class to allow for fast searching of large data files.

To retrieve a scan from the datafile, an item is requested from the object. For example:

>>>sd = SpecDataFile('data.01')
>>>scan = sd[100]

The construct sd[100] will return scan 100 as a SpecScan object. By passing a range of integers, for example:

>>>scans = sd[[100, 101]]

these data will be concatenated into a single object. This is useful, for example, when two scans are used to take the data (one wide, one close) and you need to fit the data.

The SpecScan object contains members for all motors and counters for the scan in question. These can be accessed in two main ways. For example, to obtain the detector counts for the scan as an array:

>>>Det = sd[1000].Detector

or:

>>>scan = sd[1000]
>>>Det = scan.Detector

can be used. For situations where you need machine adjustable code, the construct:

>>>Det = scan.values['Detector']

can be used, where the member ‘values’ is a python dictionary of all scan variables. In addition to the counters and motors, values defined in the header are also included. See the SpecScan class documentation for further information.

For example, to plot (using matplotlib) the theta values against the detector normalized to the monitor one could run the code:

>>>sd = SpecDataFile('data.01')
>>>scan = sd[100]
>>>plot(scan.Theta, scan.Detector / scan.Monitor)

and error-bars can be plotted using:

>>>x = scan.Theta
>>>y = scan.Detector / scan.Monitor
>>>e = sqrt(scan.Detetor) / scan.Monitor
>>>errorbar(x, y, yerr = e)

One can easily perform calculations on the data with this setup. For example, if measurements are taken with a photodiode, often the x-ray flux is the required value. The pyspec.utils contains the function itophotons() which can be used to calculate the flux. For example:

>>>from pyspec.utils import itophotons
>>>x = scan.Theta
>>>y = itophotons(scan.pdiode, scan.energy)
>>>plot(x, y, 'ro')

Finally, the SpecScan class defines some helper routines for plotting, fitting etc. which can be used to help in data analysis. See the documentation on the SpecScan class for more information. These classes form the basis for the SPEC datafile handling. There are three objects, the SpecDataFile the SpecScan and the SpecData.

Plotting Data

There are a number of helper routines which allow for quick plotting of scans. These try to guess the best they can what the last scan was viewing. This is done like CPLOT [1] where the first column in the data file is assumed to be the scan axis and the last column the counter. Data is normalized by a beam intensity monitor which is assumed to be the second from last column. To plot a scan from a spec file:

>>>sd = SpecDataFile('data.01')
>>>scan = sd[100]
>>>scan.plot()

The default behavior can be overridden by a number of keyword arguments passed to the plot function. These allow for the user to easily plot different counters, or to normalize to a different monitor. This is accomplished by the use of the xcol, ycol and mcol keyword arguments. These arguments can be either a column number (negative numbers count from the last column) or a column (counter) name. For example, to plot the Theta axis against mdet1 with Ring as the monitor:

>>>scan.plot(xcol='Theta', ycol='mdet1', mcol = 'Ring')

The scan.plot() function is really the overloaded SpecPlot.show() function, and returns a SpecPlot instance. The possible keyword arguments are defined by this function and are listed below:

class pyspec.spec.SpecPlot(specscan)
show(xcol=None, ycol=None, mcol=None, norm=True, doplot=True, errors=True, check_errorbars=True, fmt='ro', new=True, xint=200, yint=200, notitles=False, log=False, twodtype='contour')

Plot and display the scan

‘xcol’, ‘ycol’ and ‘mcol’ can be either numbers (negative count from end) or string values for the motor names

for 2D plots ‘xcol’ can be a list or array e.g. [0, 1]

‘norm = False’ will suppress normalization of the data ‘doplot = False’ will suppress the plotting of the figure ‘errors = False’ will suppress the plotting of errorbars ‘check_errorbars = True’ will suppress errorbar checking ‘fmt’ is the format string passed onto the plot command ‘new = True’ will create a new figure ‘xint = 200’ will set the x size of the 2D grid to 200 pts ‘yint = 200’ will set the y size of the 2D grid to 200 pts ‘log = True’ will set the y axis to logscale ‘twodtype = ‘contout’‘

Obtaining Information on Data

You can obtain data on the scan, to find out which variables are defined in the class for a give scan. This is accomplished using the str method. Whenever a string is requested of the class, a string containing a formatted output of the information is provided. For example:

>>>print sd[100]
Scan:

     500

Datafile:

     /home/tardis/swilkins/Dropbox/Data/CDI_2011_02_01/CDI_2011_02_01

Scan Command:

     round_roi_scan npbx -0.0075 0.0075 npbz -0.0075 0.0075 0.0012 5 0.5

Scan Constants:

ccdAcquireTime      Lattice             RLattice            ccdAcquirePeriod
scandatum           energy              or0                 or1
ccdNumExposures     or1Lambda           or1Angles           wavelength
scan_command        comments            scan_type           or0Angles
UB                  header              data                ccdNumImages
alphabeta           Qvec                scanno              scan
or0Lambda           ccdNumAcquisitions  omega               azimuth


Motors:

Chi                 MIR_ROLL            ExitSlit            NPBY
XDiff1              Theta               YS                  XDiff2
EXSyh               XDiff               MuT                 Phi
AZS                 MuR                 ZDiff               NPTX
EXSh                TMM                 NPTZ                RDiff
NPTY                SGM                 Gamma               Delta
ExitSlitY           PDiff               BPM_Y               BPM_X
Mu                  DiffSlitVert        MIR_X               XS
EntSlit             YDiff               AYS                 ZS
SExitSlit           MIR_YAW             NIX                 ZDiff3
ZDiff2              ZDiff1

Scan Variables:

kpts                Detector            DELPos              Current
NPBX                Epoch               CCPres              NPBZ
Monitor             SGME                ccdnet3             Seconds
cnptx               sdet2               IONPress            ccdtot2
Monitor2            K                   ccdnet2             mdet1
mdet2               H                   L                   Treg
Tsam                ccdnet5             Ring                sdet1
SGMENC              Shutter             ccdnet1             ccdnet4
THPos               ccdtot3             ccdtot1             ccdtot4
ccdtot5

Spec Data File Class

class pyspec.spec.SpecDataFile(fn, userext=[], **kwargs)

DataFile class for handling spec data files

getAll(*args, **kwargs)

Read all scans into the object

getScan(item, mask=None, setkeys=True, persistent=True, reread=False, **kwargs)

Get a scan from the data file

This routine gets a scan from the data file and loads it into the list of SpecData instances.

setting ‘setkeys = True’ will set attributes to the specdata item of all the motors and counters

The mask can be used to detete bad points. This should be a list of datum (data point numbers) which should be excluded. If the “item” is a list of scans (that will be concatenated or binned together) this should be a list containing either None for no removal of data points or a list of points to remove

Returns the ScanData object corresponding to the scan requested.

getStats(head='---- ')

Returns string with statistics on specfile.

head : string
append string head to status text
index()

Index the datafile

This routine indexes and sorts the byte-offests for all the scans (Lines beginning with ‘#S’)

readHeader()

Read the spec header from the datafile.

Currently supported header items:
‘#O’ (Motor positions)
reload()

Reload the data file

This routine reloads (reindexes) the datafile

reset()

Reset the specfile class

This routine resets the SpecDataFile, as if no scans had been read.

setMode(mode='concatenate')

Set the modee to deal with multiple scans

mode : string
If mode is ‘concatenate’ then concatenate scans together. If mode is ‘bin’ then bin (numerically the scans together.

Spec Scan Class

class pyspec.spec.SpecScan(specfile, item, setkeys=True, mask=None, **kwargs)

Class defining a SPEC scan

This class defines a single spec scan, or a collection of scans either binned or concatenated. The class has members for the data and variables contained in the scan. If the optional ‘setkeys’ is defined (see __init__) then the motor positions and variables will be set as class members. For example, in a typical scan the motor position TTH can be accessed as a class member by SpecScan.TTH

This object has some standard members:

header : [string] Header of spec scan values : [dict] All scan data variables (Motors and Counters) data : [array] All scan data (cols = variables, rows = datum) comments : [string] Comments inserted in scan scandate : [time] Date of start of scan

There are a number of special members. Wherever possible the following members are added to the class:

Qvec : [array] Q Vector alphabeta : [array] array([alpha, beta]) wavelength : [float] incident wavelength omega : [float] omega ((TTH / 2) - TH) azimuth : [float] azimuthal angle

bin(a, binbreak=None)

Bin the scans together adding the column values

a is a SpecScan object of the file to bin.

Note: This routine only bins the “data” portion of the scan. It returns the origional scans motors etc.

fit(funcs, quiet=False)

Overloaded function which calls the current scanplot with scanplot.fit(...)

getSIXCAngles()

This function returns the SIXC angles for the scan as a Nx6 array

getYE(ycol=None, mcol=None)

Return an tuple of two arrays of y and e

plot(*args, **kwargs)

Plot the SpecScan using matplotlib

plotCCD(*args, **kwargs)

Plot the SpecScan CCD images using matplotlib

show(prefix='', nperline=4)

Return string of statistics on SpecScan

Footnotes

[1]CPLOT Certified Scientific Software <http://www.certif.com/>.