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 data file standard control lines |
|
Fallback handling for any SPEC data file control lines not recognized by other handlers |
|
#MD : Bluesky metadata from apstools SpecWriterCallback. |
|
#H & #V - Metadata in SPEC data files as defined by APS UNICAT |
|
#UIM : Image header information from EPICS areaDetector |
|
#UXML: UXML structured metadata |
|
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:
#F -- original data file name (starts a file header block) |
|
#E -- the UNIX epoch (seconds from 00:00 GMT 1/1/70) |
|
#D -- date/time stamp |
|
#C -- any comment either in the scan header or somewhere in the scan |
|
#G -- diffractometer geometry (numbered rows: #G0, #G1, ...) |
|
#I -- intensity normalizing factor |
|
#J -- names of counters (each separated by two spaces) (new with SPEC v6) |
|
#j -- mnemonics of counter (new with SPEC v6) |
|
#L -- data column labels |
|
#M -- counting against this constant monitor count (see #T) |
|
#N -- number of columns of data [ num2 sets per row ] |
|
#O -- positioner names (numbered rows: #O0, #O1, ...) |
|
#o -- positioner mnemonics (new with SPEC v6) |
|
#P -- positioner values at start of scan (numbered rows: #P0, #P1, ...) |
|
#Q -- \(Q\) (\(hkl\)) at start of scan |
|
#S -- SPEC scan |
|
#T -- counting against this constant number of seconds (see #M) |
|
#U -- Reserved for user-defined information |
|
#X -- Temperature Set Point (desired temperature) |
|
(scan_data) -- scan data line |
|
#@MCA -- MCA data formatting declaration (ignored for now) |
|
@A -- MCA Array data |
|
#@CALIB -- coefficients to compute a scale based on the MCA channel number |
|
#@CHANN -- MCA channel information |
|
#@CTIME -- MCA count times |
|
#@ROI -- MCA ROI (Region Of Interest) channel information |
|
unrecognized control line |
|
#H -- UNICAT metadata names (numbered rows: #H0, #H1, ...) |
|
#V -- UNICAT metadata values (numbered rows: #V0, #V1, ...) |
|
#UIM -- various image header information |
|
#VA |
|
#VD |
|
#VE |
source code documentation#
Python plugin support for handling SPEC control lines (such as #S, #D, …).
Base class for SPEC data file control line handler plugins. |
|
|
Install plugin(s) from a Python file. |
REGISTRATION SUPPORT (internal use only)
|
(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]#
Bases:
object
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 asspec2nexus.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:
define
postprocess()
define
writer()
define
match_key()
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 thekey
of eachControlLineBase
.If this method is defined in the subclass, it will be called instead of
match_key()
. This is the example used bySPEC_DataLine
:def match_key(self, text): try: float( text.strip().split()[0] ) return True except ValueError: return False
- key = <object object>#
- known_keys = {'#@CHANN': <spec2nexus.plugins.spec_common.SPEC_MCA_ChannelInformation object>, '#@CTIME': <spec2nexus.plugins.spec_common.SPEC_MCA_CountTime object>, '#@MCA': <spec2nexus.plugins.spec_common.SPEC_MCA object>, '#@ROI': <spec2nexus.plugins.spec_common.SPEC_MCA_RegionOfInterest object>, '#@[cC][aA][lL][iI][bB]': <spec2nexus.plugins.spec_common.SPEC_MCA_Calibration object>, '#C': <spec2nexus.plugins.spec_common.SPEC_Comment object>, '#CCD': <spec2nexus.plugins.XPCS.XPCS_CCD object>, '#D': <spec2nexus.plugins.spec_common.SPEC_Date object>, '#E': <spec2nexus.plugins.spec_common.SPEC_Epoch object>, '#F': <spec2nexus.plugins.spec_common.SPEC_File object>, '#G\\d+': <spec2nexus.plugins.spec_common.SPEC_Geometry object>, '#H\\d+': <unicat.UNICAT_MetadataMnemonics object>, '#I': <spec2nexus.plugins.spec_common.SPEC_NormalizingFactor object>, '#J\\d+': <spec2nexus.plugins.spec_common.SPEC_CounterNames object>, '#L': <spec2nexus.plugins.spec_common.SPEC_Labels object>, '#M': <spec2nexus.plugins.spec_common.SPEC_Monitor object>, '#MD\\w*': <spec2nexus.plugins.apstools_specwriter.MD_apstools object>, '#N': <spec2nexus.plugins.spec_common.SPEC_NumColumns object>, '#O\\d+': <spec2nexus.plugins.spec_common.SPEC_PositionerNames object>, '#P\\d+': <spec2nexus.plugins.spec_common.SPEC_Positioners object>, '#Q': <spec2nexus.plugins.spec_common.SPEC_HKL object>, '#R': <spec2nexus.plugins.spec_common.SPEC_UserResults object>, '#S': <spec2nexus.plugins.spec_common.SPEC_Scan object>, '#T': <spec2nexus.plugins.spec_common.SPEC_CountTime object>, '#U': <spec2nexus.plugins.spec_common.SPEC_UserReserved object>, '#UIM\\w*': <spec2nexus.plugins.uim.UIM_generic object>, '#UXML': <uxml.UXML_metadata object>, '#VA\\d+': <spec2nexus.plugins.XPCS.XPCS_VA object>, '#VD\\d+': <spec2nexus.plugins.XPCS.XPCS_VD object>, '#VE\\d+': <spec2nexus.plugins.XPCS.XPCS_VE object>, '#V\\d+': <unicat.UNICAT_MetadataValues object>, '#X': <spec2nexus.plugins.spec_common.SPEC_TemperatureSetPoint object>, '#XPCS': <spec2nexus.plugins.XPCS.XPCS_XPCS object>, '#j\\d+': <spec2nexus.plugins.spec_common.SPEC_CounterMnemonics object>, '#o\\d+': <spec2nexus.plugins.spec_common.SPEC_PositionerMnemonics object>, '@A\\d*': <spec2nexus.plugins.spec_common.SPEC_MCA_Array object>, 'scan_data': <spec2nexus.plugins.spec_common.SPEC_DataLine object>, 'unrecognized_control_line': <spec2nexus.plugins.fallback.UnrecognizedControlLine object>}#
- lazy_attributes = ['H', 'V', 'metadata', 'UXML', 'UXML_root', 'MD', '_unrecognized', 'UIM', 'comments', 'G', 'diffractometer', 'I', 'J', 'j', 'L', 'column_first', 'column_last', 'M', 'monitor_name', 'N', 'O', 'o', 'P', 'positioner', 'Q', 'R', 'T', 'time_name', 'U', 'TEMP_SP', 'DEGC_SP', 'data', 'data_lines', 'MCA', 'VA', 'VD', 'VE', 'XPCS', 'CCD']#
- 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 withtext
.
- plugins = [<spec2nexus.plugins.unicat.UNICAT_MetadataMnemonics object>, <spec2nexus.plugins.unicat.UNICAT_MetadataValues object>, <spec2nexus.plugins.uxml.UXML_metadata object>, <apstools_specwriter.MD_apstools object>, <fallback.UnrecognizedControlLine object>, <unicat.UNICAT_MetadataMnemonics object>, <unicat.UNICAT_MetadataValues object>, <uxml.UXML_metadata object>, <uim.UIM_generic object>, <spec_common.SPEC_File object>, <spec_common.SPEC_Epoch object>, <spec_common.SPEC_Date object>, <spec_common.SPEC_Comment object>, <spec_common.SPEC_Scan object>, <spec_common.SPEC_Geometry object>, <spec_common.SPEC_NormalizingFactor object>, <spec_common.SPEC_CounterNames object>, <spec_common.SPEC_CounterMnemonics object>, <spec_common.SPEC_Labels object>, <spec_common.SPEC_Monitor object>, <spec_common.SPEC_NumColumns object>, <spec_common.SPEC_PositionerNames object>, <spec_common.SPEC_PositionerMnemonics object>, <spec_common.SPEC_Positioners object>, <spec_common.SPEC_HKL object>, <spec_common.SPEC_UserResults object>, <spec_common.SPEC_CountTime object>, <spec_common.SPEC_UserReserved object>, <spec_common.SPEC_TemperatureSetPoint object>, <spec_common.SPEC_DataLine object>, <spec_common.SPEC_MCA object>, <spec_common.SPEC_MCA_Array object>, <spec_common.SPEC_MCA_Calibration object>, <spec_common.SPEC_MCA_ChannelInformation object>, <spec_common.SPEC_MCA_CountTime object>, <spec_common.SPEC_MCA_RegionOfInterest object>, <XPCS.XPCS_VA object>, <XPCS.XPCS_VD object>, <XPCS.XPCS_VE object>, <XPCS.XPCS_XPCS object>, <XPCS.XPCS_CCD object>, <spec2nexus.plugins.uim.UIM_generic object>, <spec2nexus.plugins.apstools_specwriter.MD_apstools object>, <spec2nexus.plugins.XPCS.XPCS_VA object>, <spec2nexus.plugins.XPCS.XPCS_VD object>, <spec2nexus.plugins.XPCS.XPCS_VE object>, <spec2nexus.plugins.XPCS.XPCS_XPCS object>, <spec2nexus.plugins.XPCS.XPCS_CCD object>, <spec2nexus.plugins.fallback.UnrecognizedControlLine object>, <spec2nexus.plugins.spec_common.SPEC_File object>, <spec2nexus.plugins.spec_common.SPEC_Epoch object>, <spec2nexus.plugins.spec_common.SPEC_Date object>, <spec2nexus.plugins.spec_common.SPEC_Comment object>, <spec2nexus.plugins.spec_common.SPEC_Scan object>, <spec2nexus.plugins.spec_common.SPEC_Geometry object>, <spec2nexus.plugins.spec_common.SPEC_NormalizingFactor object>, <spec2nexus.plugins.spec_common.SPEC_CounterNames object>, <spec2nexus.plugins.spec_common.SPEC_CounterMnemonics object>, <spec2nexus.plugins.spec_common.SPEC_Labels object>, <spec2nexus.plugins.spec_common.SPEC_Monitor object>, <spec2nexus.plugins.spec_common.SPEC_NumColumns object>, <spec2nexus.plugins.spec_common.SPEC_PositionerNames object>, <spec2nexus.plugins.spec_common.SPEC_PositionerMnemonics object>, <spec2nexus.plugins.spec_common.SPEC_Positioners object>, <spec2nexus.plugins.spec_common.SPEC_HKL object>, <spec2nexus.plugins.spec_common.SPEC_UserResults object>, <spec2nexus.plugins.spec_common.SPEC_CountTime object>, <spec2nexus.plugins.spec_common.SPEC_UserReserved object>, <spec2nexus.plugins.spec_common.SPEC_TemperatureSetPoint object>, <spec2nexus.plugins.spec_common.SPEC_DataLine object>, <spec2nexus.plugins.spec_common.SPEC_MCA object>, <spec2nexus.plugins.spec_common.SPEC_MCA_Array object>, <spec2nexus.plugins.spec_common.SPEC_MCA_Calibration object>, <spec2nexus.plugins.spec_common.SPEC_MCA_ChannelInformation object>, <spec2nexus.plugins.spec_common.SPEC_MCA_CountTime object>, <spec2nexus.plugins.spec_common.SPEC_MCA_RegionOfInterest object>]#
- 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
, orSpecDataFileScan
- scan_attributes_defined = []#
- exception spec2nexus.plugin_core.DuplicateKeyError[source]#
Bases:
KeyError
Cannot add more than one plugin for the same control key.
- add_note()#
Exception.add_note(note) – add a note to the exception
- args#
- with_traceback()#
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
- class spec2nexus.plugin_core.PluginMounter(name, bases, attrs)[source]#
Bases:
type
(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/
- _enroll(plugin)[source]#
Add the plugin to the plugin list and perform any registration logic.
Expects to find these attributes:
.key
(str
).scan_attributes_defined
(list of str
)
- mro()#
Return a type’s method resolution order.