spec2nexus.plugin#

An extensible plugin architecture is used to handle the different possible control line control lines (such as #F, #E, #S, …) in a SPEC data file.

A SPEC control line provides metadata about the SPEC scan or SPEC data file.

Plugins can be used to parse or ignore certain control lines in SPEC data files. Through this architecture, it is possible to support custom control lines, such as #U (SPEC standard control line for any user data). One example is support for the UNICAT-style of metadata provided in the scan header.

Plugins are now used to handle all control lines in spec2nexus.spec. Any control line encountered but not recognized will be placed as text in a NeXus NXnote group named unrecognized_NNN (where NNN is from 1 to the maximum number of unrecognized control lines).

Supplied spec plugin modules#

These plugin modules are supplied:

spec_common

SPEC data file standard control lines

fallback

Fallback handling for any SPEC data file control lines not recognized by other handlers

apstools_specwriter

#MD : Bluesky metadata from apstools SpecWriterCallback.

unicat

#H & #V - Metadata in SPEC data files as defined by APS UNICAT

uim

#UIM : Image header information from EPICS areaDetector

uxml

#UXML: UXML structured metadata

XPCS

SPEC data file control lines unique to the APS XPCS instrument

Writing a custom plugin#

While spec2nexus provides a comprehensive set of plugins to handle the common SPEC control line control lines, custom control lines are used at many facilities to write additional scan data and scan metadata into the SPEC data file. Custom plugins are written to process these additions. See the How to write a custom control line handling plugin module for spec section for details.

Overview of the supplied spec plugins#

Plugins for these control lines 1 are provided in spec2nexus:

SPEC_File

#F -- original data file name (starts a file header block)

SPEC_Epoch

#E -- the UNIX epoch (seconds from 00:00 GMT 1/1/70)

SPEC_Date

#D -- date/time stamp

SPEC_Comment

#C -- any comment either in the scan header or somewhere in the scan

SPEC_Geometry

#G -- diffractometer geometry (numbered rows: #G0, #G1, ...)

SPEC_NormalizingFactor

#I -- intensity normalizing factor

SPEC_CounterNames

#J -- names of counters (each separated by two spaces) (new with SPEC v6)

SPEC_CounterMnemonics

#j -- mnemonics of counter (new with SPEC v6)

SPEC_Labels

#L -- data column labels

SPEC_Monitor

#M -- counting against this constant monitor count (see #T)

SPEC_NumColumns

#N -- number of columns of data [ num2 sets per row ]

SPEC_PositionerNames

#O -- positioner names (numbered rows: #O0, #O1, ...)

SPEC_PositionerMnemonics

#o -- positioner mnemonics (new with SPEC v6)

SPEC_Positioners

#P -- positioner values at start of scan (numbered rows: #P0, #P1, ...)

SPEC_HKL

#Q -- \(Q\) (\(hkl\)) at start of scan

SPEC_Scan

#S -- SPEC scan

SPEC_CountTime

#T -- counting against this constant number of seconds (see #M)

SPEC_UserReserved

#U -- Reserved for user-defined information

SPEC_TemperatureSetPoint

#X -- Temperature Set Point (desired temperature)

SPEC_DataLine

(scan_data) -- scan data line

SPEC_MCA

#@MCA -- MCA data formatting declaration (ignored for now)

SPEC_MCA_Array

@A -- MCA Array data

SPEC_MCA_Calibration

#@CALIB -- coefficients to compute a scale based on the MCA channel number

SPEC_MCA_ChannelInformation

#@CHANN -- MCA channel information

SPEC_MCA_CountTime

#@CTIME -- MCA count times

SPEC_MCA_RegionOfInterest

#@ROI -- MCA ROI (Region Of Interest) channel information

UnrecognizedControlLine

unrecognized control line

UNICAT_MetadataMnemonics

#H -- UNICAT metadata names (numbered rows: #H0, #H1, ...)

UNICAT_MetadataValues

#V -- UNICAT metadata values (numbered rows: #V0, #V1, ...)

UIM_generic

#UIM -- various image header information

XPCS_VA

#VA

XPCS_VD

#VD

XPCS_VE

#VE

1

Compare this list with Control lines (keys) defined by SPEC

source code documentation#

Python plugin support for handling SPEC control lines (such as #S, #D, …).

ControlLineBase()

Base class for SPEC data file control line handler plugins.

install_user_plugin(plugin_file)

Install plugin(s) from a Python file.

REGISTRATION SUPPORT (internal use only)

PluginMounter(name, bases, attrs)

(internal) Register and initiate all plugins subclassed from PluginBase.

# from: https://gist.github.com/will-hart/5899567 # a simple Python plugin loading system # see: http://stackoverflow.com/questions/14510286/plugin-architecture-plugin-manager-vs-inspecting-from-plugins-import

class spec2nexus.plugin_core.ControlLineBase[source]#

Base class for SPEC data file control line handler plugins.

Define a subclass of ControlLineBase for each different type of control line. Refer to the supplied plugins (such as spec2nexus.plugins.spec_common) for examples. In each such class, it is necessary to:

  • define a string value for the key (class attribute)

  • override the definition of process()

As each subclass is imported, the metaclass keyword argument above automatically registers the plugin handler and its associated control line key.

It is optional to:

PARAMETERS

key str :

regular expression to match a control line key, up to the first space

scan_attributes_defined [str] :

list of scan attributes defined in this class

returns:

None

process(text, spec_obj, *args, **kwargs)

required: Handle this line from a SPEC data file.

postprocess(header, *args, **kws)

optional: More processing deferred until after data file has been read.

writer(h5parent, writer, scan[, nxclass])

optional: Describe how to store this data in a NeXus HDF5 file.

match_key(text)

Test if this handler's key matches text.

EXAMPLE of match_key method:

Declaration of the match_key method is optional in a subclass. This is used to test a given line from a SPEC data file against the key of each ControlLineBase.

If this method is defined in the subclass, it will be called instead of match_key(). This is the example used by SPEC_DataLine:

def match_key(self, text):
    try:
        float( text.strip().split()[0] )
        return True
    except ValueError:
        return False
match_key(text)[source]#

Test if this handler’s key matches text.

Parameters

text (str) – first word on the line, up to but not including the first whitespace

Returns

key or None

Applies a regular expression match using each handler’s key as the regular expression to match with text.

postprocess(header, *args, **kws)[source]#

optional: More processing deferred until after data file has been read.

process(text, spec_obj, *args, **kwargs)[source]#

required: Handle this line from a SPEC data file.

PARAMETERS

text str:

?raw text?

spec_obj obj:

Instance of SpecDataFile, SpecDataFileHeader, or SpecDataFileScan

writer(h5parent, writer, scan, nxclass=None, *args, **kws)[source]#

optional: Describe how to store this data in a NeXus HDF5 file.

exception spec2nexus.plugin_core.DuplicateKeyError[source]#

Cannot add more than one plugin for the same control key.

class spec2nexus.plugin_core.PluginMounter(name, bases, attrs)[source]#

(internal) Register and initiate all plugins subclassed from PluginBase.

_enroll(plugin)

Add the plugin to the plugin list and perform any registration logic.

Acts as a metaclass which creates anything inheriting from PluginBase. A plugin mount point derived from: http://martyalchin.com/2008/jan/10/simple-plugin-framework/

spec2nexus.plugin_core.install_user_plugin(plugin_file)[source]#

Install plugin(s) from a Python file.

Potentially dangerous since this is an import of a user-created file.