specplot#

Read a SPEC data file and plot a thumbnail image.

This code can be called as a standalone program or it can be imported into another program and called as a subroutine, as shown in the specplot_gallery program.

The standard representation of a SPEC scan is a line plot of the last data column versus the first data column. Any SPEC macro which name ends with scan ([1]) will be plotted as a line plot.

A special case SPEC scan macro is the hklscan where one of the three reciprocal space axes is scanned while the other two remain constant. A special handler (SPEC’s hklscan macro) is provided to pick properly the scanned axis (not always the first column) for representation as a line plot.

Some SPEC macros scan two positioners over a grid to collect a 2-D image one pixel at a time. These scans are represented as color-mapped images where the first two columns are the vertical and horizontal axes and the image is color-mapped to intensity. Any SPEC macro which name ends with mesh will be plotted as an image plot.

Different handling can be customized for scan macros, as described in How to write a custom scan handling class for specplot.

How to use specplot#

Plot a scan from one of the sample data files supplied with spec2nexus:

user@host ~$ specplot spec2nexus/data/APS_spec_data.dat 2 specplot.png
_images/specplot.png

Plot of scan #2 from example data file APS_spec_data.dat.#

Usage#

user@host ~$ specplot
usage: specplot.py [-h] specFile scan_number plotFile

Help#

user@host ~$ specplot -h
usage: specplot.py [-h] specFile scan_number plotFile

read a SPEC data file and plot scan n

positional arguments:
  specFile     SPEC data file name
  scan_number  scan number in SPEC file
  plotFile     output plot file name

optional arguments:
  -h, --help   show this help message and exit

source code documentation#

Plot the data from scan N in a SPEC data file

Selector(*args, **kwargs)

associate SPEC scan macro names with image makers

ImageMaker()

superclass to handle plotting of data from a SPEC scan

LinePlotter()

create a line plot

MeshPlotter()

create a mesh plot (2-D image)

openSpecFile(specFile)

convenience routine so that others do not have to import spec2nexus.spec

Exceptions:

NoDataToPlot

No data found.

NotPlottable

No plottable data for this scan.

ScanAborted

Scan aborted before all points acquired.

UnexpectedObjectTypeError

Incorrect Python object type: programmer error.

class spec2nexus.specplot.HKLScanPlotter[source]#

Bases: LinePlotter

create a line plot from hklscan macros

_initialize_settings_()#

initial values are set to None

subclasses that set a value should first check if the value has already been set unless explicitly replacing any customizations by the user

data_file_name()#

the name of the file with the actual data

Usually, this is the SPEC data file but it could be something else

data_is_newer_than_plot(plotFile)#

only proceed if mtime of SPEC data file is newer than plotFile

make_image(plotFile)#

make MatPlotLib chart image from the SPEC scan

Parameters:

plotFile (str) – name of image file to write

plot_options()#

define the settings for this, accepting any non-default values first

plot_scan(scan, plotFile, maker=None)#

make an image plot of the data in the scan

Parameters:
  • scan (obj) – instance of SpecDataFileScan

  • plotFile (str) – file name for plot output

plot_subtitle()#

Return the plot_subtitle.

plot_title()#

Return the plot title.

plottable()#

can this data be plotted as expected?

retrieve_plot_data()[source]#

retrieve default data from spec data file

set_plot_subtitle(text)#

Set the plot_subtitle.

set_plot_title(text)#

Set the plot title.

set_timestamp(text)#

Set the plot time stamp.

set_x_log(choice)#

Set the x axis logarithmic if True.

set_x_title(text)#

Set the x axis title.

set_y_log(choice)#

Set the y axis logarithmic if True.

set_y_title(text)#

Set the y axis title.

set_z_log(choice)#

Set the z axis (image) logarithmic if True.

timestamp()#

Return the time of this scan as a string.

x_log()#

Boolean: should the X axis be plotted on a log scale?

x_title()#

Return the title for the X axis.

y_log()#

Boolean: should the Y axis be plotted on a log scale?

y_title()#

Return the title for the Y axis.

z_log()#

Boolean: should the Z axis (image) be plotted on a log scale?

class spec2nexus.specplot.ImageMaker[source]#

Bases: object

superclass to handle plotting of data from a SPEC scan

Internal data model

Signal:

name of the signal data (default data to be plotted)

Data:

values of various collected arrays {label: array}

Axes:

names of the axes of signal data

USAGE:

  1. Create a subclass of ImageMaker

  2. Override any of these methods:

    data_file_name()

    the name of the file with the actual data

    make_image(plotFile)

    make MatPlotLib chart image from the SPEC scan

    plottable()

    can this data be plotted as expected?

    plot_options()

    re-define any plot options in a subclass

    retrieve_plot_data()

    retrieve default plottable data from spec data file and store locally

EXAMPLE

class LinePlotter(ImageMaker):
    '''create a line plot'''

    def make_image(self, plotFile):
        '''
        make MatPlotLib chart image from the SPEC scan

        :param obj plotData: object returned from :meth:`retrieve_plot_data`
        :param str plotFile: name of image file to write
        '''
        assert(self.signal in self.data)
        assert(len(self.axes) == 1)
        assert(self.axes[0] in self.data)

        y = self.data[self.signal]
        x = self.data[self.axes[0]]
        xy_plot(x, y,  plotFile,
               title = self.plot_title(),
               plot_subtitle = self.plot_subtitle(),
               xtitle = self.x_title(),
               ytitle = self.y_title(),
               xlog = self.x_log(),
               ylog = self.y_log(),
               timestamp_str = self.timestamp())

sfile = specplot.openSpecFile(specFile)
scan = sfile.getScan(scan_number)
plotter = LinePlotter()
plotter.plot_scan(scan, plotFile, y_log=True)
_initialize_settings_()[source]#

initial values are set to None

subclasses that set a value should first check if the value has already been set unless explicitly replacing any customizations by the user

data_file_name()[source]#

the name of the file with the actual data

Usually, this is the SPEC data file but it could be something else

data_is_newer_than_plot(plotFile)[source]#

only proceed if mtime of SPEC data file is newer than plotFile

make_image(plotFile)[source]#

make MatPlotLib chart image from the SPEC scan

The data to be plotted are provided in:

  • self.signal

  • self.axes

  • self.data

Parameters:

plotFile (str) – name of image file to write

plot_options()[source]#

re-define any plot options in a subclass

plot_scan(scan, plotFile, maker=None)[source]#

make an image plot of the data in the scan

Parameters:
  • scan (obj) – instance of SpecDataFileScan

  • plotFile (str) – file name for plot output

plot_subtitle()[source]#

Return the plot_subtitle.

plot_title()[source]#

Return the plot title.

plottable()[source]#

can this data be plotted as expected?

retrieve_plot_data()[source]#

retrieve default plottable data from spec data file and store locally

This method must retrieve the data to be plotted, either from the SPEC data file scan or from a file which name is provided in the scan detalis.

These attributes must be set by this method:

Data:

dictionary containing values of the various collected arrays {label: array}

Signal:

name of the ‘signal’ data (default data to be plotted)

Axes:

names of the axes of signal data

Example data

self.data = {
    'angle': [1, 2, 3, 4, 5],
    'counts': [0. 2. 55. 3. 0]}
self.signal = 'counts'
self.axes = ['angle']

Raise any of these exceptions as appropriate:

NoDataToPlot

No data found.

NotPlottable

No plottable data for this scan.

ScanAborted

Scan aborted before all points acquired.

set_plot_subtitle(text)[source]#

Set the plot_subtitle.

set_plot_title(text)[source]#

Set the plot title.

set_timestamp(text)[source]#

Set the plot time stamp.

set_x_log(choice)[source]#

Set the x axis logarithmic if True.

set_x_title(text)[source]#

Set the x axis title.

set_y_log(choice)[source]#

Set the y axis logarithmic if True.

set_y_title(text)[source]#

Set the y axis title.

set_z_log(choice)[source]#

Set the z axis (image) logarithmic if True.

timestamp()[source]#

Return the time of this scan as a string.

x_log()[source]#

Boolean: should the X axis be plotted on a log scale?

x_title()[source]#

Return the title for the X axis.

y_log()[source]#

Boolean: should the Y axis be plotted on a log scale?

y_title()[source]#

Return the title for the Y axis.

z_log()[source]#

Boolean: should the Z axis (image) be plotted on a log scale?

class spec2nexus.specplot.LinePlotter[source]#

Bases: ImageMaker

create a line plot

_initialize_settings_()#

initial values are set to None

subclasses that set a value should first check if the value has already been set unless explicitly replacing any customizations by the user

data_file_name()#

the name of the file with the actual data

Usually, this is the SPEC data file but it could be something else

data_is_newer_than_plot(plotFile)#

only proceed if mtime of SPEC data file is newer than plotFile

make_image(plotFile)[source]#

make MatPlotLib chart image from the SPEC scan

Parameters:

plotFile (str) – name of image file to write

plot_options()[source]#

define the settings for this, accepting any non-default values first

plot_scan(scan, plotFile, maker=None)#

make an image plot of the data in the scan

Parameters:
  • scan (obj) – instance of SpecDataFileScan

  • plotFile (str) – file name for plot output

plot_subtitle()#

Return the plot_subtitle.

plot_title()#

Return the plot title.

plottable()[source]#

can this data be plotted as expected?

retrieve_plot_data()[source]#

retrieve default data from spec data file

set_plot_subtitle(text)#

Set the plot_subtitle.

set_plot_title(text)#

Set the plot title.

set_timestamp(text)#

Set the plot time stamp.

set_x_log(choice)#

Set the x axis logarithmic if True.

set_x_title(text)#

Set the x axis title.

set_y_log(choice)#

Set the y axis logarithmic if True.

set_y_title(text)#

Set the y axis title.

set_z_log(choice)#

Set the z axis (image) logarithmic if True.

timestamp()#

Return the time of this scan as a string.

x_log()#

Boolean: should the X axis be plotted on a log scale?

x_title()#

Return the title for the X axis.

y_log()#

Boolean: should the Y axis be plotted on a log scale?

y_title()#

Return the title for the Y axis.

z_log()#

Boolean: should the Z axis (image) be plotted on a log scale?

class spec2nexus.specplot.MeshPlotter[source]#

Bases: ImageMaker

create a mesh plot (2-D image)

..rubric:: References:

Mesh 2-D parser:

https://www.certif.com/spec_help/mesh.html

mesh motor1 start1 end1 intervals1 motor2 start2 end2 intervals2 time
Hklmesh 2-D parser:

https://www.certif.com/spec_help/hklmesh.html

hklmesh Q1 start1 end1 intervals1 Q2 start2 end2 intervals2 time
_initialize_settings_()#

initial values are set to None

subclasses that set a value should first check if the value has already been set unless explicitly replacing any customizations by the user

data_file_name()#

the name of the file with the actual data

Usually, this is the SPEC data file but it could be something else

data_is_newer_than_plot(plotFile)#

only proceed if mtime of SPEC data file is newer than plotFile

make_image(plotFile)[source]#

make MatPlotLib chart image from the SPEC scan

Parameters:

plotFile (str) – name of image file to write

plot_options()[source]#

define the settings for this, accepting any non-default values first

plot_scan(scan, plotFile, maker=None)#

make an image plot of the data in the scan

Parameters:
  • scan (obj) – instance of SpecDataFileScan

  • plotFile (str) – file name for plot output

plot_subtitle()#

Return the plot_subtitle.

plot_title()#

Return the plot title.

plottable()[source]#

can this data be plotted as expected?

retrieve_plot_data()[source]#

retrieve default data from spec data file

data parser for 2-D mesh and hklmesh

set_plot_subtitle(text)#

Set the plot_subtitle.

set_plot_title(text)#

Set the plot title.

set_timestamp(text)#

Set the plot time stamp.

set_x_log(choice)#

Set the x axis logarithmic if True.

set_x_title(text)#

Set the x axis title.

set_y_log(choice)#

Set the y axis logarithmic if True.

set_y_title(text)#

Set the y axis title.

set_z_log(choice)#

Set the z axis (image) logarithmic if True.

timestamp()#

Return the time of this scan as a string.

x_log()#

Boolean: should the X axis be plotted on a log scale?

x_title()#

Return the title for the X axis.

y_log()#

Boolean: should the Y axis be plotted on a log scale?

y_title()#

Return the title for the Y axis.

z_log()#

Boolean: should the Z axis (image) be plotted on a log scale?

exception spec2nexus.specplot.NoDataToPlot[source]#

Bases: ValueError

No data found.

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.

exception spec2nexus.specplot.NotPlottable[source]#

Bases: ValueError

No plottable data for this scan.

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.

exception spec2nexus.specplot.ScanAborted[source]#

Bases: RuntimeWarning

Scan aborted before all points acquired.

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.specplot.Selector(*args, **kwargs)[source]#

Bases: Singleton

associate SPEC scan macro names with image makers

Image maker:

subclass of ImageMaker

To include a custom image maker from outside this module, create the subclass and then add it to an instance of this class. Such as this plotter that defaults to a logarithmic scale for the X axis for all logxscan macros:

from spec2nexus import specplot

class LogX_Plotter(specplot.ImageMaker):

def x_log(self):

return True

# …

selector = specplot.Selector() selector.add(‘logxscan’, LogX_Plotter)

# …

image_maker = specplot.Selector().auto(scan) plotter = image_maker() plotter.plot_scan(scan, fullPlotFile)

This class is a singleton which means you will always get the same instance when you call this class many times in your program.

auto(scan)

automatically choose a scan image maker based on the SPEC scan macro

add(key, value[, default])

register a new value by key

update(key, value[, default])

replace an existing key with a new value

get(key)

return a value by key

exists(key)

is the key known?

default()

retrieve the value of the default key

add(key, value, default=False)[source]#

register a new value by key

Parameters:

key (str) – name of key, typically the macro name

Raises:
auto(scan)[source]#

automatically choose a scan image maker based on the SPEC scan macro

Selection Rules:

default()[source]#

retrieve the value of the default key

default_key = '__default__'#
exists(key)[source]#

is the key known?

get(key)[source]#

return a value by key

Returns:

subclass of ImageMaker or None if key not found

update(key, value, default=False)[source]#

replace an existing key with a new value

Parameters:

key (str) – name of key, typically the macro name

Raises:
exception spec2nexus.specplot.UnexpectedObjectTypeError[source]#

Bases: RuntimeError

Incorrect Python object type: programmer error.

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.

spec2nexus.specplot.main()[source]#
spec2nexus.specplot.openSpecFile(specFile)[source]#

convenience routine so that others do not have to import spec2nexus.spec