Welcome to bapsflib’s documentation!

About bapsflib

The bapsflib package is intend to be a toolkit for reading, manipulating, and analyzing data collected at the Basic Plasma Science Facility (BaPSF). The current development focus is on providing a high-level, structured interface between the user and the HDF5 files generated by the Large Plasma Device (LaPD). The bapsflib.lapd module provides all the high-level methods while maintaining the not-so-lower “lower level” functionality of the h5py package.

As the package develops additional data visualization and plasma analysis tools will be incorporated.

Installation

Installing from pip

The bapsflib package is registered with PyPI and can be installed with pip via

pip install bapsflib

For the most recent development version, bapsflib can be installed from GitHub.

Installing Directly from GitHub

To install directly from GitHub, you need to have git installed on your computer. If you do not have git installed, then see Installing from a GitHub Clone or Download.

To install directly from the master branch invoke the following command

pip install git+https://github.com/BaPSF/bapsflib.git#egg=bapsflib

If an alternate branch BranchName is desired, then invoke

pip install git+https://github.com/BaPSF/bapsflib.git@BranchName#egg=bapsflib

Installing from a GitHub Clone or Download

A copy of the bapsflib package can be obtained by cloning or downloading from the GitHub repository.

Cloning the repository requires an installation of git on your computer. To clone the master branch, first, on your computer, navigate to the directory you want the clone and do

git clone https://github.com/BaPSF/bapsflib.git

To download a copy, go to the repository, select the branch to be downloaded, click the green button labeled Clone or download, select Download ZIP, save the zip file to the desired directory, and unpack.

After getting a copy of the bapsflib package (via clone or downlaod), navigate to the main package directory, where the package setup.py file is located, and execute

pip install .

or

python setup.py install

Getting Started

The bapsflib package has four key sub-packages:

  • bapsflib._hdf

    This package contains the generic HDF5 utilities for mapping and accessing any HDF5 file generated at the Basic Plasma Science Facility (BaPSF) at UCLA. Typically there is no reason to directly access classes in this package, since these classes are typically sub-classed to provided specific access to HDF5 files generate by each plasma device at BaPSF. For example, any data collected on the Large Plasma Device (LaPD) will be handled by the bapsflib.lapd package. For now, one can access data collected on the Small Plasma Device (SmPD) and Enormous Toroidal Plasma Device (ETPD) by utilizing bapsflib._hdf.File.

  • bapsflib.lapd

    This package contains functionality for accessing HDF5 files generated by the LaPD (bapsflib.lapd.File), LaPD parameters (bapsflib.lapd.constants), and LaPD specific tools (bapsflib.lapd.tools). Look to Using bapsflib.lapd for details about the package.

  • bapsflib.plasma

    Warning

    package currently in development

    This package plasma constants and functions.

  • bapsflib.utils

    This package is for developers and contributors. It contains utilities used for constructing the bapsflib package.

In the future, packages for the Small Plasma Device (SmPD) bapsflib.smpd and the Enormous Toroidal Device (ETPD) bapsflib.etpd will be added, as well as, some fundamental analysis and plasma diagnostic packages.

BaPSF Background

What is HDF5?

HDF5 is a technology developed by the HDF Group that is designed to manage large and complex collections of data, allowing for advanced relationships between data and user metadata to be structured through grouping and linking mechanisms. For HDF5 support visit HDF Group’s HDF5 support site.

BaPSF HDF5 Files

Every plasma device at BaPSF is governed by a DAQ Controller. This DAQ Controller is tasked with operating and monitoring the plasma device, controlling the order of operations for an experimental run, recording data for the run, and generating the HDF5 file.

Types of Recorded Data

Data collected by BaPSF is classified into three types:

  1. MSI diagnostic [device] data

    MSI data is machine state recordings for the plasma device the experiment was run on. For example, MSI data for the LaPD would include diagnostics like partial gas pressure, discharge traces, magnetic field, etc.

  2. Digitizer [device] data

    This is “primary data” recorded by the DAQ digitizers. “Primary data” is any signal recorded from a plasma probe.

  3. Control device data

    Data recorded from a control device. A control device is a piece of equipment that controls some state property of the experiments. For example, a probe drive records position state info for a probe location and a waveform generator can record driving frequencies of an antenna.

Internal HDF5 Structure

HDF5 internal data structure

Example of a LaPD HDF5 internal data-tree.

The internal data structure (data-tree) of a HDF5 file looks very similar to a system file structure (see Fig. 1), where groups are akin to directories and datasets are akin to files. Not depicted in Fig. 1, each group and dataset can have an arbitrary number of key-value pair attributes constituting the component’s metadata.

In the above example, MSI diagnostic data is contain in the MSI group and the Raw data + config group houses both Digitizer data and Control device data. In addition to the three typical Types of Recorded Data, the Raw data + config group contains the Data run sequence for the experimental run. The Data run sequence is the order of operations performed by the DAQ Controller to execute the experimental run.


Using bapsflib.lapd

The bapsflib.lapd is a one-stop-shop for everything specifically related to handling data collected on the LaPD. The package provides:

  1. HDF5 file access via bapsflib.lapd.File
  2. LaPD machine specs and parameters in bapsflib.lapd.constants
  3. LaPD specific tools (e.g. port number to LaPD \(z\) conversion bapsflib.lapd.tools.portnum_to_z()) in bapsflib.lapd.tools.

Accessing HDF5 Files

Opening a File

Opening a HDF5 file is done using the bapsflib.lapd.File class. File subclasses h5py.File, so group and dataset manipulation is handled by the inherited methods; whereas, the new methods (see Table 1) are focused on mapping the data structure and providing a high-level access to the experimental data recorded by the LaPD DAQ system.

File is a wrapper on h5py.File and, thus, HDF5 file manipulation is handled by the inherited methods of h5py.File. File adds methods and attributes specifically for manipulating data and metadata written to the file from the Large Plasma Device (LaPD) DAQ system, see Table 1.

To open a LaPD generated HDF5 file do

>>> from bapsflib import lapd
>>> f = lapd.File('test.hdf5')
>>> f
<HDF5 file "test.hdf5" (mode r)>
>>>
>>> # f is still an instance of h5py.File
>>> isinstance(f, h5py.File)
True

which opens the file as ‘read-only’ by default. File restricts opening modes to ‘read-only’ (mode='r') and ‘read/write’ (mode='r+'), but maintains keyword pass-through to h5py.File.

After Opening a File

Upon opening a file, File calls on the LaPDMap class (a subclass of HDFMap) to construct a mapping of the HDF5 file’s internal data structure. This mapping provides the necessary translation for the high-level data reading methods, read_data(), read_controls(), and read_msi(). If an element of the HDF5 file is un-mappable – a mapping module does not exist or the mapping fails – the data can still be reached using the not-so-lower inherited methods of h5py.File. An instance of the mapping object is bound to File as file_map

>>> from bapsflib import lapd
>>> from bapsflib._hdf import HDFMap
>>> f = lapd.File('test.hdf5')
>>> f.file_map
<LaPDMap of HDF5 file 'test.hdf5'>
>>>
>>> # is still an instance of HDFMap
>>> isinstance(f.file_map, HDFMap)
True

For details on how the mapping works and how the mapping objects are structured see HDF5 File Mapping (HDFMap). For details on using the file_map see File Mapping for details.

The opened file object (f) provides a set of high-level methods and attributes for th user to interface with, see Table 1.

Bound methods and attributes for open HDF5 file object File
method/attribute Description
controls dictionary of control device mappings (quick access to f.file_map.controls)
digitizers dictionary of digitizer [device] mappings (quick access to f.file_map.digitizers)
file_map
instance of the LaPD HDF5 file mapping (instance of LaPDMap)
(see File Mapping for details)
info
dictionary of meta-info about the HDF5 file and the experimental run
msi dictionary of MSI diagnostic [device] mappings (quick access to f.file_map.msi)
overview
instance of LaPDOverview which that allows for printing and saving of the file mapping results
read_controls()
high-level method for reading control device data contained in the HDF5 file (instance of HDFReadControls)
(see For Control Devices for details)
read_data()
high-level method for reading digitizer data and mating control device data at the time of read (instance of HDFReadData)
(see For a Digitizer for details)
read_msi()
high-level method for reading MSI diagnostic date (instance of HDFReadMSI)
(see For a MSI Diagnostic for details)
run_description() printout the LaPD experimental run description (print(f.info['run description'].splitlines()))

File Mapping

The main purpose of the file_map object is to (1) identify the control devices, digitizers, and MSI diagnostic in the HDF5 file and (2) provide the necessary translation info to allow for easy reading of data via read_controls(), read_data(), and read_msi(). For the most part, there is not reason to directly access the file_map object since its results can easily be printed or saved using the overview attribute, see File Overview: Getting, Printing, and Saving for details. However, the mapping objects do contain useful details that are desirable in certain circumstances and can be modified for a special type of control device to augment the resulting numpy array when data is read.

The file map object file_map is an instance of LaPDMap, which subclasses HDFMap (details on HDFMap can be found at HDF5 File Mapping (HDFMap)). The LaPDMap provides a useful set of bound methods, see Table 2.

Bound methods and attributes on f.file_map.
method/attribute Description
controls dictionary of control device mapping objects
digitizers dictionary of digitizer mapping objects
exp_info dictionary of experimental info collected from various group attributes in the HDF5 file
get() retrieve the mapping object for a specified device
is_lapd True if it was determined that the HDF5 file was generated by the LaPD
lapd_version version string of the LaPD DAQ Controller software used to generate the HDF5 file
main_digitizer mapping object for the digitizer that is considered the “main digitizer”
msi dictionary of MSI diagnostic mapping objects
run_info dictionary of experimental run info collected from various group attributes in the HDF5 file
unknowns list of all subgroup and dataset paths in the HDF5 root group, control device group, digitizer group, and MSI group that were unable to be mapped

File Info: Metadata You Want

Every time a HDF5 file is opened a dictionary of metadata about the file and the experiment is bound to the file object as info.

>>> f = lapd.File('test.hdf5')
>>> f.info
{'absolute file path': '/foo/bar/test.hdf5',
 'exp description': 'this is an experiment description',
  ...
  'run status': 'Started'}

Table Table 3 lists and describes all the items that can be found in the info dictionary.

Items in the f.info dictionary. (info)
key Description & Equivalence
'absolute file path'
absolute path to the HDF5 file
os.path.abspath(f.filename)
'exp description'
description of experiment
f['Raw data + config].attrs['Experiment description']
'exp name'
name of the experiment in which the run of the HDF5 file resides
f['Raw data + config].attrs['Experiment Name']
'exp set description'
description of experiment set
f['Raw data + config].attrs['Experiment set description']
'exp set name'
name of experiment set the 'exp name' resides
f['Raw data + config].attrs['Experiment set name']
'filename'
name of HDF5 file
os.path.basename(f.filename)
'investigator'
name of Investigator/PI of the experiment
f['Raw data + config].attrs['Investigator']
'lapd version'
LaPD DAQ software version that wrote the HDF5 file
f.file_map.hdf_version
'run date'
date of experimental run
f['Raw data + config].attrs['Status date']
'run description'
description of experimental run
f['Raw data + config].attrs['Description']
'run name'
name of experimental data run
f['Raw data + config].attrs['Data run']
'run status'
status of experimental run (started, completed, etc.)
f['Raw data + config].attrs['Status']

File Overview: Getting, Printing, and Saving

The hdfOverview class provides a set of tools (see Table 4) to report the results of the HDF5 file mapping by HDFMap. An instance of hdfOverview is bound to File as the overview attribute and will report the current status of the mapping object.

>>> f = lapd.File('test.hdf5')
>>> f.overview
<bapsflib.lapd._hdf.hdfoverview.hdfOverview>

Thus, if any changes are made to the mapping object (file_map), which could happen for certain control devices [*], then those changes will be reflected in the overview report.

The overview report is divided into three blocks:

  1. General File and Experimental Info
    • This block contains information on the file (name, path, etc.), the experiment (exp. name, investigator, etc.), and the experimental run setup (run name, description, etc.).

    • Example:

      ========================================================================
      test.hdf5 Overview
      Generated by bapsflib
      Generated date: 4/19/2018 3:35:43 PM
      ========================================================================
      
      
      Filename:     test.hdf5
      Abs. Path:    /foo/bar/test.hdf5
      LaPD version: 1.2
      Investigator: Everson
      Run Date:     8/14/2017 9:49:53 PM
      
      Exp. and Run Structure:
        (set)  LaB6_Cathode
        (exp)  +-- HighBetaSAWAug17
        (run)  |   +-- test
      
      Run Description:
          some description of the experimental run
      
      Exp. Description:
          some description of the experiment as a whole
      
  2. Discovery Report
    • This block gives a brief report on what devices the HDFMap class discovered in the the file.

    • There are no details about each discovered device, just what was discovered.

    • Example:

      Discovery Report
      ----------------
      
      MSI/                                                   found
      +-- diagnostics (5)
      |   +-- Discharge
      |   +-- Gas pressure
      |   +-- Heater
      |   +-- Interferometer array
      |   +-- Magnetic field
      Raw data + config/                                     found
      +-- Data run sequence                                  not mapped
      +-- digitizers (1)
      |   +-- SIS crate (main)
      +-- control devices (1)
      |   +-- Waveform
      Unknowns (2)                                           aka unmapped
      +-- /Raw data + config/Data run sequence
      +-- /Raw data + config/N5700_PS
      
  3. Detailed Report
    • This block reports details on the mapping results for each discovered device (MSI diagnostics, control devices, and digitizers).

    • Basically reports the constructed configs dictionary of each devices mapping object.

    • Example:

      Detailed Reports
      -----------------
      
      
      Digitizer Report
      ^^^^^^^^^^^^^^^^
      
      SIS crate (main)
      +-- adc's:  ['SIS 3302', 'SIS 3305']
      +-- Configurations Detected (1)                               (1 active, 0 inactive)
      |   +-- sis0-10ch                                             active
      |   |   +-- adc's (active):  ['SIS 3302']
      |   |   +-- path: /Raw data + config/SIS crate/sis0-10ch
      |   |   +-- SIS 3302 adc connections
      |   |   |   |   +-- (brd, [ch, ...])               bit  clock rate   nshotnum  nt        shot ave.  sample ave.
      |   |   |   |   +-- (1, [3, 4, 5, 6, 7, 8])        16   100.0 MHz    6160      12288     None       8
      |   |   |   |   +-- (2, [1, 2, 3, 4])              16   100.0 MHz    6160      12288     None       8
      
      Control Device Report
      ^^^^^^^^^^^^^^^^^^^^^
      
      Waveform
      +-- path:     /Raw data + config/Waveform
      +-- contype:  waveform
      +-- Configurations Detected (1)
      |   +-- waveform_50to150kHz_df10kHz_nf11
      |   |   +-- {...}
      
      MSI Diagnostic Report
      ^^^^^^^^^^^^^^^^^^^^^
      
      Discharge
      +-- path:  /MSI/Discharge
      +-- configs
      |   +--- {...}
      Gas pressure
      +-- path:  /MSI/Gas pressure
      +-- configs
      |   +-- {...}
      Heater
      +-- path:  /MSI/Heater
      +-- configs
      |   +-- {...}
      Interferometer array
      +-- path:  /MSI/Interferometer array
      +-- configs
      |   +-- {...}
      Magnetic field
      +-- path:  /MSI/Magnetic field
      +-- configs
      |   +-- {...}
      

The methods provided by hdfOverview (see Table 4) allow for printing and saving of the complete overview, as well as, printing the individual blocks or sections of the blocks.

“Methods provided by hdfOverview for reporting a HDF5 file overview”
Method Description and Call
print()

Print to screen the entire overview.

>>> f.overview.print()
save()

Save the report to a file given by filename.

>>> f.overview.save(filename)

If filename=True, then a text file is created with the same name as the HDF5 file in the same location.

>>> f.overview.save(True)
report_general()

Print the general info block.

>>> f.overview.report_general()
report_discovery()

Print the discovery report block.

>>> f.overview.report_discovery()
report_details()

Print the detail report block.

>>> f.overview.report_details()
report_controls()

Print the detail report block for all control devices.

>>> f.overview.report_controls()

Print the detail report block for a specific control device (e.g. Waveform).

>>> f.overview.report_controls(name='Waveform')
report_digitizers()

Print the detail report block for all digitizers.

>>> f.overview.report_digitizers()

Print the detail report block for a specific digitizer (e.g. SIS 3301).

>>> f.overview.report_digtitizers(name='SIS 3301')
report_msi()

Print the detail report block for all MSI diagnostics.

>>> f.overview.report_msi()

Print the detail report block for a specific MSI diagnostic (e.g. Discharge).

>>> f.overview.report_msi(name='Discharge')
[*]the mapping configuration for command list focused control devices can be modified when the command list is parsed ( provide a link to command list control device section here once written)

Reading Data from a HDF5 File

Three classes HDFReadData, HDFReadControls, and HDFReadMSI are given to read data for digitizers, control devices, and MSI diagnostics, respectively. Each of these read classes are bound to File, see Table 5, and will return a structured numpy array with the requested data.

Read classes/methods for extracting data from a HDF5 file
Read Class Bound Method on File What it does
HDFReadData read_data() Designed to extract digitizer data from a HDF5 file with the option of mating control device data at the time of extraction. (see reading For a Digitizer)
HDFReadControls read_controls() Designed to extract control device data. (see reading For Control Devices)
HDFReadMSI read_msi() Designed to extract MSI diagnostic data. (see reading For a MSI Diagnostic)
For a Digitizer

Digitizer data is read using the read_data() method on File. The method also has the option of mating control device data at the time of declaration (see section Adding Control Device Data) [1].

At a minimum the read_data() method only needs a board number and channel number to extract data [2], but there are several additional keyword options:

Optional keywords for read_data()
Keyword Default Description
index slice(None) row index of the HDF5 dataset (see Extracting a sub-set)
shotnum slice(None) global HDF5 file shot number (see Extracting a sub-set)
digitizer None
name of the digitizer for which board and channel belong to
adc None
name of the digitizer’s analog-digital-converter (adc) for which board and channel belong to
config_name None
name of the digitizer configuration
keep_bits False Set True to return the digitizer data in bit values. By default the digitizer data is converted to voltage.
add_controls None
list of control devices whose data will be matched and added to the requested digitizer data
intersection_set True
Ensures that the returned data array only contains shot numbers that are inclusive in shotnum, the digitizer dataset, and all control device datasets.
silent False set True to suppress command line printout of soft-warnings

These keywords are explained in more detail in the following subsections.

If the test.hdf5 file has only one digitizer with one active adc and one configuration, then the entire dataset collected from the signal attached to board = 1 and channel = 0 can be extracted as follows:

>>> from bapsflib import lapd
>>> f = lapd.File('test.hdf5')
>>> board, channel = 1, 0
>>> data = f.read_data(board, channel)

where data is an instance of HDFReadData. The HDFReadData class acts as a wrapper on numpy.recarray. Thus, data behaves just like a numpy.recarray object, but will have additional methods and attributes that describe the data’s origin and parameters (e.g. info, dt, dv, etc.).

By default, data is a structured numpy array with the following dtype:

>>> data.dtype
dtype([('shotnum', '<u4'),
       ('signal', '<f4', (12288,)),
       ('xyz', '<f4', (3,))])

where 'shotnum' contains the HDF5 shot number, 'signal' contains the signal recorded by the digitizer, and 'xyz' is a 3-element array containing the probe position. In this example, the digitized signal is automatically converted into voltage before being added to the array and 12288 is the size of the signal’s time-array. To keep the digitizer 'signal in bit values, then set keep_bits=True at execution of read_data(). The field 'xyz' is initialized with numpy.nan values, but will be populated if a control device of contype = 'motion' is added (see Adding Control Device Data).


For details on handling and manipulating data see handle_data.

Note

Since bapsflib.lapd leverages the h5py package, the data in test.hdf5 resides on disk until one of the read methods, read_data(), read_msi(), or read_controls() is called. In calling on of these methods, the requested data is brought into memory as a numpy.ndarray and a numpy.view onto that ndarray is returned to the user.


Extracting a sub-set

There are three keywords for sub-setting a dataset: index, shotnum, and intersection_set. index and shotnum are indexing keywords, whereas, intersection_set controls sub-setting behavior between the indexing keywords and the dataset(s).

index refers to the row index of the requested dataset and shotnum refers to the global HDF5 shot number. Either indexing keyword can be used, but index overrides shotnum. index and shotnum can be of type() int, list(int), or slice(). Sub-setting with index looks like:

>>> # read dataset row 10
>>> data = f.read_data(board, channel, index=9)
>>> data['shotnum']
array([10], dtype=uint32)

>>> # read dataset rows 10, 20, and 30
>>> data = f.read_data(board, channel, index=[9, 19, 29])

>>> # read dataset rows 10 to 19
>>> data = f.read_data(board, channel, index=slice(9, 19))

>>> # read every third row in the dataset from row 10 to 19
>>> data = f.read_data(board, channel, index=slice(9, 19, 3))
>>> data['shotnum']
array([10, 13, 16, 19], dtype=uint32)

Sub-setting with shotnum looks like:

>>> # read dataset shot number 10
>>> data = f.read_data(board, channel, shotnum=10)
>>> data['shotnum']
array([10], dtype=uint32)

>>> # read dataset shot numbers 10, 20, and 30
>>> data = f.read_data(board, channel, shotnum=[10, 20, 30])

>>> # read dataset shot numbers 10 to 19
>>> data = f.read_data(board, channel, shotnum=slice(10, 20))

>>> # read every 5th dataset shot number from 10 to 19
>>> data = f.read_data(board, channel, index=slice(10, 20, 5))
>>> data['shotnum']
array([10, 15], dtype=uint32)

intersection_set modifies what shot numbers are returned by read_data(). By default intersection_set=True and forces the returned data to only correspond to shot numbers that exist in the digitizer dataset, any specified control device datasets, and those shot numbers represented by index or shotnum. Setting to False will return all shot numbers >=1 associated with index or shotnum and array entries that are not associated with a dataset will be filled with a “NaN” value (np.nan for floats, -99999 for integers, and '' for strings).

Specifying digitizer, adc, and config_name

It is possible for a LaPD generated HDF5 file to contain multiple digitizers, each of which can have multiple analog-digital-converters (adc) and multiple configuration settings. For such a case, read_data() has the keywords digitizer, adc, and config_name to direct the data extraction accordingly.

If digitizer is not specified, then it is assumed that the desired digitizer is the one defined in main_digitizer. Suppose the test.hdf5 has two digitizers, 'SIS 3301' and 'SIS crate'. In this case 'SIS 3301' would be assumed as the main_digitizer. To extract data from 'SIS crate' one would use the digitizer keyword as follows:

>>> data = f.read_data(board, channel, digitizer='SIS crate')
>>> data.info['digitizer']
'SIS crate'

Digitizer 'SIS crate' can have multiple active adc’s, 'SIS 3302' and 'SIS 3305'. By default, if only one adc is active then that adc is assumed; however, if multiple adc’s are active, then the adc with the slower clock rate is assumed. 'SIS 3302' has the slower clock rate in this case. To extract data from 'SIS 3305' one would use the adc keyword as follows:

>>> data = f.read_data(board, channel, digitizer='SIS crate',
>>>                    adc='SIS 3305')
>>> data.info['adc']
'SIS 3305'

A digitizer can have multiple configurations, but typically only one configuration is ever active for the HDF5 file. In the case that multiple configurations are active, there is no overlying hierarchy for assuming one configuration over another. Suppose digitizer 'SIS crate' has two configurations, 'config_01' and 'config_02'. In this case, one of the configurations has to be specified at the time of extraction. To extract data from 'SIS crate' under the the configuration 'config_02' one would use the 'config_name' keyword as follows:

>>> f.file_map.digitizers['SIS crate'].active_configs
['config_01', 'config_02']
>>> data = f.read_data(board, channel, digitizer='SIS crate',
>>>                    config_name='config_02')
>>> data.info['configuration name']
'config_02'
Adding Control Device Data

Adding control device data to a digitizer dataset is done with the keyword add_controls. Specifying add_controls will trigger a call to the HDFReadControls class and extract the desired control device data. HDFReadData then compares and mates that control device data with the digitizer data according to the global HDF5 shot number.

add_controls must be a list of strings and/or 2-element tuples specifying the desired control device data to be added to the digitizer data. If a control device only controls one configuration, then it is sufficient to only name that device. For example, if a '6K Compumotor' is only controlling one probe, then the data extraction call would look like:

>>> list(f.file_map.controls['6K Compumotor'].configs)
[3]
>>> data = f.read_data(board, channel,
>>>                    add_controls=['6K Compumotor'])
>>> data.info['added controls']
[('6K Compumotor', 3)]

In the case the '6K Compumotor' has multiple configurations (controlling multiple probes), the add_controls call must also provide the configuration name to direct the extraction. This is done with a 2-element tuple entry for add_controls, where the first element is the control device name and the second element is the configuration name. For the '6K Compumotor' the configuration name is the receptacle number of the probe drive [3]. Suppose the '6K Compumotor' is utilizing three probe drives with the receptacles 2, 3, and 4. To mate control device data from receptacle 3, the call would look something like:

>>> list(f.file_map.controls['6K Compumotor'].configs)
[2, 3, 4]
>>> control  = [('6K Compumotor', 3)]
>>> data = f.read_data(board, channel, add_controls=control)
>>> data.info['added controls']
[('6K Compumotor', 3)]

Multiple control device datasets can be added at once, but only one control device for each control type ('motion', 'power', and 'waveform') can be added. Adding '6K Compumotor' data from receptacle 3 and 'Waveform' data would look like:

>>> list(f.file_map.controls['Waveform'].configs)
['config01']
>>> f.file_map.controls['Waveform'].contype
'waveform'
>>> f.file_map.controls['6K Compumotor'].contype
'motion'
>>> data = f.read_data(board, channel,
>>>                    add_controls=[('6K Compumotor', 3),
>>>                                  'Waveform'])
>>> data.info['added controls']
[('6K Compumotor', 3), ('Waveform', 'config01')]

Since '6K Compumotor' is a 'motion' control type it fills out the 'xyz' field in the returned numpy structured array; whereas, 'Waveform' will add field names to the numpy structured array according to the fields specified in its mapping constructor. See For Control Devices for details on these added fields.

[1]Control device data can also be independently read using read_controls(). (see For Control Devices for usage)
[2]Review section digi_overview for how a digitizer is organized and configured.
[3]Each control device has its own concept of what constitutes a configuration. The configuration has be unique to a block of recorded data. For the '6K Compumotor' the receptacle number is used as the configuration name, whereas, for the 'Waveform' control the confiugration name is the name of the configuration group inside the 'Waveform group. Since the configurations are contain in the f.file_map.contorols[con_name].configs dictionary, the configuration name need not be a string.
For Control Devices

Note

To be written

For a MSI Diagnostic

MSI diagnostic data is read using the read_msi() method on File. Only the MSI diagnostic name needs to be supplied to read the associated data:

>>> from bapsflib import lapd
>>>
>>> # open file
>>> f = lapd.File('test.hdf5')
>>>
>>> # list mapped MSI diagnostics
>>> f.list_msi
['Discharge',
 'Gas pressure',
 'Heater',
 'Interferometer array',
 'Magnetic field']
>>>
>>> # read 'Discharge' data
>>> mdata = f.read_msi('Discharge')

The returned data mdata is a structured numpy array where its field structure and population is determined by the MSI diagnostic mapping object. Every mdata will have the fields 'shotnum' and 'meta'. 'shotnum' represents the HDF5 shot number. 'meta' is a structured array with fields representing quantities (metadata) that are both diagnostic and shot number specific, but are not considered “primary” data arrays. Any other field in mdata is considered to be a “primary” data array. Continuing with the above example:

>>> # display mdata dytpe
>>> mdata.dtype
dtype([('shotnum', '<i4'),
       ('voltage', '<f4', (2048,)),
       ('current', '<f4', (2048,)),
       ('meta', [('timestamp', '<f8'),
                 ('data valid', 'i1'),
                 ('pulse length', '<f4'),
                 ('peak current', '<f4'),
                 ('bank voltage', '<f4')])])
>>>
>>> # display shot numbers
>>> mdata['shotnum']
array([    0, 19251], dtype=int32)

Here, the fields 'voltage' and 'current' correspond to “primary” data arrays. To display display the first three samples of the 'voltage' array for shot number 19251 do:

>>> mdata['voltage'][1][0:3:]
array([-44.631958, -44.708252, -44.631958], dtype=float32)

The metadata field 'meta' has five quantities in it, 'timestamp', 'data valid', 'pulse length', 'peak current', and 'peak voltage'. Now, these metadata fields will vary depending on the requested MSI diagnostic. To view the 'peak voltage' for shot number 0 do:

>>> mdata['meta']['peak voltage'][0]
6127.1323

The data array mdata is also constructed with a info attribute that contains metadata that is diagnostic specific but not shot number specific.

>>> mdata.info
{'current conversion factor': [0.0],
 'diagnostic name': 'Discharge',
 'diagnostic path': '/MSI/Discharge',
 'dt': [4.88e-05],
 'hdf file': 'test.hdf5',
 't0': [-0.0249856],
 'voltage conversion factor': [0.0]}

Every info attribute will have the keys 'hdf file', 'diagnostic name', and 'diagnostic path'. The rest of the keys will be MSI diagnostic dependent. For example, mdata.info for the 'Magnetic field' diagnostic would have the key 'z' that corresponds to the axial locations of the magnetic field array.

>>> # get magnetic field data
>>> mdata = f.read_msi('Magnetic field')
>>> mdata.dtype
dtype([('shotnum', '<i4'),
       ('magnet ps current', '<f4', (10,)),
       ('magnetic field', '<f4', (1024,)),
       ('meta', [('timestamp', '<f8'),
                 ('data valid', 'i1'),
                 ('peak magnetic field', '<f4')])])
>>> mdata.info
{'diagnostic name': 'Magnetic field',
 'diagnostic path': '/MSI/Magnetic field',
 'hdf file': 'test.hdf5',
 'z': array([-300.     , -297.727  , -295.45395, ..., 2020.754  ,
             2023.027  , 2025.3    ], dtype=float32)}

HDF5 File Mapping (HDFMap)

HDFMap constructs the mapping for a given HDF5 file. When a HDF5 file is opened with File, HDFMap is automatically called to construct the map and an instance of the mapping object is bound to the file object as file_map. Thus, the file mappings for test.hdf5 can be accessed like:

>>> f = lapd.File('test.hdf5')
>>> f.file_map
<bapsflib._hdf.maps.hdfmap.HDFMap>

Architecture

HDFMap takes a modular approach to mapping a HDF5 file. It contains a dictionary of known modules with known layouts. If one or more of these layouts are discovered inside the HDF5 file, then the associated mappings are added to the mapping object. There are five module categories:

msi diagnostic
This is any sub-group of the '/MSI/' group that represents a diagnostic device. A diagnostic device is a probe or sensor that records machine state data for every experimental run.
digitizer
This is any group inside the '/Raw data + config/' group that is associated with a digitizer. A digitizer is a device that records “primary” data; that is, data recorded for a plasma probe.
control device
This is any group inside the '/Raw data + config/' group that is associated with a device that controls a plasma probe. The recorded data is state data for the plasma probe; for example, probe position, bias, driving frequency, etc.
data run sequence
This is the /Raw data + config/Data run sequence/' group which records the run sequence (operation sequence) of the LaPD DAQ controller.
unknown
This is any group or dataset in '/', '/MSI/', or '/Raw data + config/' groups that is not known by HDFMap or is unsuccessfully mapped.

Basic Usage

Retrieving Active Digitizers

A list of all detected digitizers can be obtain by doing

>>> list(f.file_map.digitizers)

The file mappings for all the active digitizers are stored in the dictionary f.file_map.digitizers such that

>>> list(f.file_map.digitizers.keys())
Out: list of strings of all active digitizer names
>>> f.file_map.digitizer[digi_name]
Out: digitizer mapping object

Changelog

1.0.1

1.0.0

  • Initial release

bapsflib

This is the bapsflib package, a Python toolkit designed for the Basic Plasma Science Facility (BaPSF) group at the University of California, Los Angeles (UCLA).

BaPSF Home: http://plasma.physics.ucla.edu/

bapsflib Repository: https://github.com/rocco8773/bapsflib

bapsflib._hdf

This package contains the mapping classes (in maps) and file access classes (in utils) used to map and interface with the HDF5 files generated at BaPSF.

bapsflib._hdf.maps

This package contains an assortment of mapping classes used to inspect and map the various HDF5 files generated during experiments at the Basic Plasma Science Facility. Sub-package controls contains routines for mapping Control Device HDF5 groups, digitizers contains routines for mapping Digitizer HDF5 groups, and msi contains routines for mapping MSI Diagnostic HDF5 groups.

bapsflib._hdf.maps.controls

Package of control device mapping classes and their constructor (HDFMapControls).

bapsflib._hdf.maps.controls.clparse

Classes

CLParse Class for parsing RE from a command list.
class bapsflib._hdf.maps.controls.clparse.CLParse(command_list: Union[str, Iterable[str]])

Bases: object

Class for parsing RE from a command list. (A command list is a list of strings where each string is a set of commands sent to a control device to define that control device’s state.)

Parameters:command_list (list of strings) – the command list for a control device
apply_patterns(patterns: Union[str, Iterable[str]])

Applies a the REs defined in patterns to parse the command list.

Parameters:

patterns (str or list of strings) – list or raw stings defining REs for parsing the command list

Returns:

(bool, dict)

Example:
>>> # define a command list
>>> cl = ['VOLT 20.0', 'VOLT 25.0', 'VOLT 30.0']
>>>
>>> # define clparse object
>>> clparse = CLParse(cl)
>>>
>>> # apply patterns
>>> patterns = (r'(?P<FREQ>(FREQ\s)'
>>>             + r'(?P<VAL>(\d+\.\d*|\.\d+|\d+)))')
>>> results = clparse.apply_patterns(patterns)
>>> results[0]
True
>>> results[1]
{'VOLT': {'cl str': ('VOLT 20.0', 'VOLT 25.0', 'VOLT 30.0'),
          'command list': (20.0, 25.0, 30.0),
          're pattern': re.compile(pattern, re.UNICODE),
          'dtype': numpy.float64}}
try_patterns(patterns: Union[str, Iterable[str]])

Prints to the results of applying the REs in patterns to the command list. Pretty print of apply_patterns().

Parameters:patterns (str or list of strings) – list or raw stings defining REs for parsing the command list
bapsflib._hdf.maps.controls.contype

Classes

ConType Enum of Control Device Types
class bapsflib._hdf.maps.controls.contype.ConType

Bases: enum.Enum

Enum of Control Device Types

motion = 'motion'
power = 'power'
timing = 'timing'
waveform = 'waveform'
bapsflib._hdf.maps.controls.map_controls

Classes

HDFMapControls A dictionary that contains mapping objects for all the discovered control devices in the HDF5 data group.
class bapsflib._hdf.maps.controls.map_controls.HDFMapControls(data_group: h5py._hl.group.Group)

Bases: dict

A dictionary that contains mapping objects for all the discovered control devices in the HDF5 data group. The dictionary keys are the names of the discovered control devices.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapControls
>>> f = lapd.File('sample.hdf5')
>>> # 'Raw data + config' is the LaPD HDF5 group name for the
... # group housing digitizer and control devices
... control_map = HDFMapControls(f['Raw data + config'])
>>> control_map['6K Compumotor']
<bapsflib._hdf.maps.controls.sixk.HDFMapControl6K>
Parameters:

data_group – HDF5 group object

_HDFMapControls__build_dict

Discovers the HDF5 control devices and builds the dictionary containing the control device mapping objects. This is the dictionary used to initialize self.

Returns:control device mapping dictionary
Return type:dict
_defined_mapping_classes = {'6K Compumotor': <class 'bapsflib._hdf.maps.controls.sixk.HDFMapControl6K'>, 'N5700_PS': <class 'bapsflib._hdf.maps.controls.n5700ps.HDFMapControlN5700PS'>, 'NI_XYZ': <class 'bapsflib._hdf.maps.controls.nixyz.HDFMapControlNIXYZ'>, 'NI_XZ': <class 'bapsflib._hdf.maps.controls.nixz.HDFMapControlNIXZ'>, 'Waveform': <class 'bapsflib._hdf.maps.controls.waveform.HDFMapControlWaveform'>}

Dictionary containing references to the defined (known) control device mapping classes.

mappable_devices

tuple of the mappable control devices (i.e. their HDF5 group names)

bapsflib._hdf.maps.controls.n5700ps

Classes

HDFMapControlN5700PS Mapping module for control device ‘N5700_PS’.
class bapsflib._hdf.maps.controls.n5700ps.HDFMapControlN5700PS(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.controls.templates.HDFMapControlCLTemplate

Mapping module for control device ‘N5700_PS’.

Simple group structure looks like:

+-- N5700_PS
|   +-- Run time list
|   +-- nsconf_<descr>
|   |   +--
Parameters:group – the HDF5 control device group
clparse(config_name: str) → bapsflib._hdf.maps.controls.clparse.CLParse

Return instance of CLParse for config_name.

Parameters:config_name (str) – configuration name
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array by HDFReadControls.

– Constructing configs

The configs dict is a nested dictionary where the first level of keys represents the control device configuration names. Each configuration corresponds to one dataset in the HDF5 control group and represents a grouping of state values associated with an probe or instrument used during an experiment.

Each configuration is a dictionary consisting of a set of required keys ('dset paths', 'shotnum', and 'state values') and optional keys. Any optional key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array and are explained in the table below.

Dictionary breakdown for config = configs['config name']
Key Description
config['dset paths']

Internal HDF5 path to the dataset associated with the control device configuration. For example,

config['dset paths'] = ('/foo/bar/Control/d1', )
config['shotnum']

Defines how the run shot numbers are stored in the HDF5 file, which are mapped to the 'shotnum' field of the constructed numpy array. Should look like,

config['shotnum'] = {
    'dset paths': config['dset paths'],
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset, 'dset field' is the field name of the dataset containing shot numbers, 'shape' is the numpy shape of the shot number data, and 'dtype' is the numpy dtype of the data. This all defines the numpy dtype of the 'shotnum' field in the HDFReadControls constructed numpy array.

config['state values']

This is another dictionary defining 'state values. For example,

config['state values'] = {
    'xyz': {
        'dset paths': config['dset paths'],
        'dset field': ('x', 'y', 'z'),
        'shape': (3,),
        'dtype': numpy.float32}
}

will tell HDFReadControls to construct a numpy array with a the 'xyz' field. This field would be a 3-element array of numpy.float32, where the 'x' field of the HDF5 dataset is mapped to the 1st index, 'y' is mapped to the 2nd index, and 'z' is mapped to the 3rd index.

Note:

  • A state value field (key) can not be defined as 'signal' since this field is reserved for digitizer data constructed by HDFReadData.
  • If state value data represents probe position data, then it should be given the field name (key) 'xyz' (like in the example above).

If a control device saves data around the concept of a command list, then configs has a few additional required keys, see table below.

Additional required keys for config = configs['config name'] when the control device saves data around the concept of a command list.
Key Description
config['command list']

A tuple representing the original command list. For example,

config['command list'] = ('VOLT: 20.0',
                          'VOLT 25.0',
                          'VOLT 30.0')
config['state values']

Has all the same keys as before, plus the addition of 'command list', 'cl str, and 're pattern'. For example,

config['state values'] = {
    'command': {
        'dset paths': config['dset paths'],
        'dset field': ('Command index',),
        'shape': (),
        'dtype': numpy.float32,
        'command list': (20.0, 25.0, 30.0),
        'cl str': ('VOLT: 20.0', 'VOLT 25.0',
                   'VOLT 30.0'),
        're pattern': re.compile(r'some RE pattern')}
}

where 're pattern' is the compiled RE pattern used to parse the original command list, 'cl str' is the matched string segment of the command list, and 'command list' is the set of values that will populate the constructed numpy array.

Note

For further details, look to Adding a Control Device Mapping Module.

construct_dataset_name(*args) → str

Constructs name of dataset containing control state value data.

contype

control device type

dataset_names

list of names of the HDF5 datasets in the control group

device_name

Name of Control device

group

Instance of the HDF5 Control Device group

has_command_list
Returns:True if dataset utilizes a command list
info

Control device dictionary of meta-info. For example,

info = {
    'group name': 'Control',
    'group path': '/foo/bar/Control',
    'contype': 'motion',
}
one_config_per_dset

'True' if each control configuration has its own dataset

reset_state_values_config(config_name: str, apply_patterns=False)

Reset the configs[config_name]['state values'] dictionary.

Parameters:
  • config_name – configuration name
  • apply_patterns (bool) – Set False (DEFAULT) to reset to _default_state_values_dict(config_name). Set True to rebuild dict using _default_re_patterns.
set_state_values_config(config_name: str, patterns: Union[str, Iterable[str]])

Rebuild and set configs[config_name]['state values'] based on the supplied RE patterns.

Parameters:
  • config_name – configuration name
  • patterns – list of RE strings
subgroup_names

list of names of the HDF5 sub-groups in the control group

bapsflib._hdf.maps.controls.nixyz

Classes

HDFMapControlNIXYZ Mapping module for control device ‘NI_XYZ’.
class bapsflib._hdf.maps.controls.nixyz.HDFMapControlNIXYZ(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate

Mapping module for control device ‘NI_XYZ’.

Simple group structure looks like:

+-- NI_XYZ
|   +-- <motion list name 1>
|   |   +--
.
.
.
|   +-- <motion list name N>
|   |   +--
|   +-- Run time list
Parameters:group – the HDF5 control device group
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array by HDFReadControls.

– Constructing configs

The configs dict is a nested dictionary where the first level of keys represents the control device configuration names. Each configuration corresponds to one dataset in the HDF5 control group and represents a grouping of state values associated with an probe or instrument used during an experiment.

Each configuration is a dictionary consisting of a set of required keys ('dset paths', 'shotnum', and 'state values') and optional keys. Any optional key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array and are explained in the table below.

Dictionary breakdown for config = configs['config name']
Key Description
config['dset paths']

Internal HDF5 path to the dataset associated with the control device configuration. For example,

config['dset paths'] = ('/foo/bar/Control/d1', )
config['shotnum']

Defines how the run shot numbers are stored in the HDF5 file, which are mapped to the 'shotnum' field of the constructed numpy array. Should look like,

config['shotnum'] = {
    'dset paths': config['dset paths'],
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset, 'dset field' is the field name of the dataset containing shot numbers, 'shape' is the numpy shape of the shot number data, and 'dtype' is the numpy dtype of the data. This all defines the numpy dtype of the 'shotnum' field in the HDFReadControls constructed numpy array.

config['state values']

This is another dictionary defining 'state values. For example,

config['state values'] = {
    'xyz': {
        'dset paths': config['dset paths'],
        'dset field': ('x', 'y', 'z'),
        'shape': (3,),
        'dtype': numpy.float32}
}

will tell HDFReadControls to construct a numpy array with a the 'xyz' field. This field would be a 3-element array of numpy.float32, where the 'x' field of the HDF5 dataset is mapped to the 1st index, 'y' is mapped to the 2nd index, and 'z' is mapped to the 3rd index.

Note:

  • A state value field (key) can not be defined as 'signal' since this field is reserved for digitizer data constructed by HDFReadData.
  • If state value data represents probe position data, then it should be given the field name (key) 'xyz' (like in the example above).

If a control device saves data around the concept of a command list, then configs has a few additional required keys, see table below.

Additional required keys for config = configs['config name'] when the control device saves data around the concept of a command list.
Key Description
config['command list']

A tuple representing the original command list. For example,

config['command list'] = ('VOLT: 20.0',
                          'VOLT 25.0',
                          'VOLT 30.0')
config['state values']

Has all the same keys as before, plus the addition of 'command list', 'cl str, and 're pattern'. For example,

config['state values'] = {
    'command': {
        'dset paths': config['dset paths'],
        'dset field': ('Command index',),
        'shape': (),
        'dtype': numpy.float32,
        'command list': (20.0, 25.0, 30.0),
        'cl str': ('VOLT: 20.0', 'VOLT 25.0',
                   'VOLT 30.0'),
        're pattern': re.compile(r'some RE pattern')}
}

where 're pattern' is the compiled RE pattern used to parse the original command list, 'cl str' is the matched string segment of the command list, and 'command list' is the set of values that will populate the constructed numpy array.

Note

For further details, look to Adding a Control Device Mapping Module.

construct_dataset_name(*args) → str

Constructs name of dataset containing control state value data.

contype

control device type

dataset_names

list of names of the HDF5 datasets in the control group

device_name

Name of Control device

group

Instance of the HDF5 Control Device group

has_command_list
Returns:True if dataset utilizes a command list
info

Control device dictionary of meta-info. For example,

info = {
    'group name': 'Control',
    'group path': '/foo/bar/Control',
    'contype': 'motion',
}
one_config_per_dset

'True' if each control configuration has its own dataset

subgroup_names

list of names of the HDF5 sub-groups in the control group

bapsflib._hdf.maps.controls.nixz

Classes

HDFMapControlNIXZ Mapping module for control device ‘NI_XZ’.
class bapsflib._hdf.maps.controls.nixz.HDFMapControlNIXZ(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate

Mapping module for control device ‘NI_XZ’.

Simple group structure looks like:

+-- NI_XZ
|   +-- <motion list name 1>
|   |   +--
.
.
.
|   +-- <motion list name N>
|   |   +--
|   +-- Run time list
Parameters:group – the HDF5 control device group
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array by HDFReadControls.

– Constructing configs

The configs dict is a nested dictionary where the first level of keys represents the control device configuration names. Each configuration corresponds to one dataset in the HDF5 control group and represents a grouping of state values associated with an probe or instrument used during an experiment.

Each configuration is a dictionary consisting of a set of required keys ('dset paths', 'shotnum', and 'state values') and optional keys. Any optional key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array and are explained in the table below.

Dictionary breakdown for config = configs['config name']
Key Description
config['dset paths']

Internal HDF5 path to the dataset associated with the control device configuration. For example,

config['dset paths'] = ('/foo/bar/Control/d1', )
config['shotnum']

Defines how the run shot numbers are stored in the HDF5 file, which are mapped to the 'shotnum' field of the constructed numpy array. Should look like,

config['shotnum'] = {
    'dset paths': config['dset paths'],
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset, 'dset field' is the field name of the dataset containing shot numbers, 'shape' is the numpy shape of the shot number data, and 'dtype' is the numpy dtype of the data. This all defines the numpy dtype of the 'shotnum' field in the HDFReadControls constructed numpy array.

config['state values']

This is another dictionary defining 'state values. For example,

config['state values'] = {
    'xyz': {
        'dset paths': config['dset paths'],
        'dset field': ('x', 'y', 'z'),
        'shape': (3,),
        'dtype': numpy.float32}
}

will tell HDFReadControls to construct a numpy array with a the 'xyz' field. This field would be a 3-element array of numpy.float32, where the 'x' field of the HDF5 dataset is mapped to the 1st index, 'y' is mapped to the 2nd index, and 'z' is mapped to the 3rd index.

Note:

  • A state value field (key) can not be defined as 'signal' since this field is reserved for digitizer data constructed by HDFReadData.
  • If state value data represents probe position data, then it should be given the field name (key) 'xyz' (like in the example above).

If a control device saves data around the concept of a command list, then configs has a few additional required keys, see table below.

Additional required keys for config = configs['config name'] when the control device saves data around the concept of a command list.
Key Description
config['command list']

A tuple representing the original command list. For example,

config['command list'] = ('VOLT: 20.0',
                          'VOLT 25.0',
                          'VOLT 30.0')
config['state values']

Has all the same keys as before, plus the addition of 'command list', 'cl str, and 're pattern'. For example,

config['state values'] = {
    'command': {
        'dset paths': config['dset paths'],
        'dset field': ('Command index',),
        'shape': (),
        'dtype': numpy.float32,
        'command list': (20.0, 25.0, 30.0),
        'cl str': ('VOLT: 20.0', 'VOLT 25.0',
                   'VOLT 30.0'),
        're pattern': re.compile(r'some RE pattern')}
}

where 're pattern' is the compiled RE pattern used to parse the original command list, 'cl str' is the matched string segment of the command list, and 'command list' is the set of values that will populate the constructed numpy array.

Note

For further details, look to Adding a Control Device Mapping Module.

construct_dataset_name(*args) → str

Constructs name of dataset containing control state value data.

contype

control device type

dataset_names

list of names of the HDF5 datasets in the control group

device_name

Name of Control device

group

Instance of the HDF5 Control Device group

has_command_list
Returns:True if dataset utilizes a command list
info

Control device dictionary of meta-info. For example,

info = {
    'group name': 'Control',
    'group path': '/foo/bar/Control',
    'contype': 'motion',
}
one_config_per_dset

'True' if each control configuration has its own dataset

subgroup_names

list of names of the HDF5 sub-groups in the control group

bapsflib._hdf.maps.controls.sixk

Classes

HDFMapControl6K Mapping module for control device ‘6K Compumotor’.
class bapsflib._hdf.maps.controls.sixk.HDFMapControl6K(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate

Mapping module for control device ‘6K Compumotor’.

Simple group structure looks like:

+-- 6K Compumotor
|   +-- Motion list: <name>
|   |   +--
|   +-- Probe: XY[<receptacle #>]: <probe name>
|   |   +-- Axes[0]
|   |   |   +--
|   |   +-- Axes[1]
|   |   |   +--
|   +-- XY[<receptacle #>]: <probe name>
Parameters:group – the HDF5 control device group
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array by HDFReadControls.

– Constructing configs

The configs dict is a nested dictionary where the first level of keys represents the control device configuration names. Each configuration corresponds to one dataset in the HDF5 control group and represents a grouping of state values associated with an probe or instrument used during an experiment.

Each configuration is a dictionary consisting of a set of required keys ('dset paths', 'shotnum', and 'state values') and optional keys. Any optional key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array and are explained in the table below.

Dictionary breakdown for config = configs['config name']
Key Description
config['dset paths']

Internal HDF5 path to the dataset associated with the control device configuration. For example,

config['dset paths'] = ('/foo/bar/Control/d1', )
config['shotnum']

Defines how the run shot numbers are stored in the HDF5 file, which are mapped to the 'shotnum' field of the constructed numpy array. Should look like,

config['shotnum'] = {
    'dset paths': config['dset paths'],
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset, 'dset field' is the field name of the dataset containing shot numbers, 'shape' is the numpy shape of the shot number data, and 'dtype' is the numpy dtype of the data. This all defines the numpy dtype of the 'shotnum' field in the HDFReadControls constructed numpy array.

config['state values']

This is another dictionary defining 'state values. For example,

config['state values'] = {
    'xyz': {
        'dset paths': config['dset paths'],
        'dset field': ('x', 'y', 'z'),
        'shape': (3,),
        'dtype': numpy.float32}
}

will tell HDFReadControls to construct a numpy array with a the 'xyz' field. This field would be a 3-element array of numpy.float32, where the 'x' field of the HDF5 dataset is mapped to the 1st index, 'y' is mapped to the 2nd index, and 'z' is mapped to the 3rd index.

Note:

  • A state value field (key) can not be defined as 'signal' since this field is reserved for digitizer data constructed by HDFReadData.
  • If state value data represents probe position data, then it should be given the field name (key) 'xyz' (like in the example above).

If a control device saves data around the concept of a command list, then configs has a few additional required keys, see table below.

Additional required keys for config = configs['config name'] when the control device saves data around the concept of a command list.
Key Description
config['command list']

A tuple representing the original command list. For example,

config['command list'] = ('VOLT: 20.0',
                          'VOLT 25.0',
                          'VOLT 30.0')
config['state values']

Has all the same keys as before, plus the addition of 'command list', 'cl str, and 're pattern'. For example,

config['state values'] = {
    'command': {
        'dset paths': config['dset paths'],
        'dset field': ('Command index',),
        'shape': (),
        'dtype': numpy.float32,
        'command list': (20.0, 25.0, 30.0),
        'cl str': ('VOLT: 20.0', 'VOLT 25.0',
                   'VOLT 30.0'),
        're pattern': re.compile(r'some RE pattern')}
}

where 're pattern' is the compiled RE pattern used to parse the original command list, 'cl str' is the matched string segment of the command list, and 'command list' is the set of values that will populate the constructed numpy array.

Note

For further details, look to Adding a Control Device Mapping Module.

construct_dataset_name(*args) → str

Constructs the dataset name corresponding to the input arguments.

Returns:name of dataset
Raise:NotImplementedError
contype

control device type

dataset_names

list of names of the HDF5 datasets in the control group

device_name

Name of Control device

group

Instance of the HDF5 Control Device group

has_command_list
Returns:True if dataset utilizes a command list
info

Control device dictionary of meta-info. For example,

info = {
    'group name': 'Control',
    'group path': '/foo/bar/Control',
    'contype': 'motion',
}
one_config_per_dset

'True' if each control configuration has its own dataset

subgroup_names

list of names of the HDF5 sub-groups in the control group

bapsflib._hdf.maps.controls.templates

Classes

HDFMapControlCLTemplate A modified HDFMapControlTemplate template class for mapping control devices that record around the concept of a command list.
HDFMapControlTemplate Template class for all control mapping classes to inherit from.
class bapsflib._hdf.maps.controls.templates.HDFMapControlCLTemplate(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate

A modified HDFMapControlTemplate template class for mapping control devices that record around the concept of a command list.

Any inheriting class should define __init__ as:

def __init__(self, group: h5py.Group):
    """
    :param group: HDF5 group object
    """
    # initialize
    HDFMapControlCLTemplate.__init__(self, control_group)

    # define control type
    self.info['contype'] = ConType.waveform

    # define known command list RE patterns
    self._default_re_patterns = (
        r'(?P<FREQ>(FREQ\s)(?P<VAL>(\d+\.\d*|\.\d+|\d+)))',
    )

    # populate self.configs
    self._build_configs()

Note

  • Any method that raises a NotImplementedError is intended to be overwritten by the inheriting class.
  • from bapsflib._hdf.maps.controls import ConType
Parameters:group – the control device HDF5 group object
_abc_impl = <_abc_data object>
_construct_state_values_dict(config_name: str, patterns: Union[str, Iterable[str]]) → dict

Returns a dictionary for configs[config_name]['state values'] based on the supplied RE patterns. None is returned if the construction failed.

Parameters:
  • config_name – configuration name
  • patterns – list of RE pattern strings
_default_re_patterns = None

tuple of default RE patterns for the control device

_default_state_values_dict(config_name: str) → dict

Returns the default 'state values' dictionary for configuration config_name.

Parameters:

config_name (str) – configuration name

Raise:

NotImplementedError

Example:
# define default dict
default_dict = {
    'command': {
        'dset paths':
            self._configs[config_name]['dese paths'],
        'dset field': ('Command index', ),
        're pattern': None,
        'command list':
            self._configs[config_name]['command list'],
        'cl str':
            self._configs[config_name]['command list'],
        'shape': (),
    }
}
default_dict['command']['dtype'] = \
    default_dict['command']['command list'].dtype

# return
return default_dict
clparse(config_name: str) → bapsflib._hdf.maps.controls.clparse.CLParse

Return instance of CLParse for config_name.

Parameters:config_name (str) – configuration name
reset_state_values_config(config_name: str, apply_patterns=False)

Reset the configs[config_name]['state values'] dictionary.

Parameters:
  • config_name – configuration name
  • apply_patterns (bool) – Set False (DEFAULT) to reset to _default_state_values_dict(config_name). Set True to rebuild dict using _default_re_patterns.
set_state_values_config(config_name: str, patterns: Union[str, Iterable[str]])

Rebuild and set configs[config_name]['state values'] based on the supplied RE patterns.

Parameters:
  • config_name – configuration name
  • patterns – list of RE strings
class bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate(group: h5py._hl.group.Group)

Bases: abc.ABC

Template class for all control mapping classes to inherit from.

Any inheriting class should define __init__ as:

def __init__(self, group: h5py.Group):
    """
    :param group: HDF5 group object
    """
    # initialize
    HDFMapControlTemplate.__init__(self, group)

    # define control type
    self.info['contype'] = ConType.motion

    # populate self.configs
    self._build_configs()

Note

  • Any method that raises a NotImplementedError is intended to be overwritten by the inheriting class.
  • from bapsflib._hdf.maps.controls import ConType
  • If a control device is structured around a command list, then its mapping class should subclass HDFMapControlCLTemplate. Which is a subclass of HDFMapControlTemplate, but adds methods for parsing/handling a command list.
Parameters:group – the control device HDF5 group object
_abc_impl = <_abc_data object>
_build_configs()

Gathers the necessary metadata and fills configs.

Raise:NotImplementedError
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array by HDFReadControls.

– Constructing configs

The configs dict is a nested dictionary where the first level of keys represents the control device configuration names. Each configuration corresponds to one dataset in the HDF5 control group and represents a grouping of state values associated with an probe or instrument used during an experiment.

Each configuration is a dictionary consisting of a set of required keys ('dset paths', 'shotnum', and 'state values') and optional keys. Any optional key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array and are explained in the table below.

Dictionary breakdown for config = configs['config name']
Key Description
config['dset paths']

Internal HDF5 path to the dataset associated with the control device configuration. For example,

config['dset paths'] = ('/foo/bar/Control/d1', )
config['shotnum']

Defines how the run shot numbers are stored in the HDF5 file, which are mapped to the 'shotnum' field of the constructed numpy array. Should look like,

config['shotnum'] = {
    'dset paths': config['dset paths'],
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset, 'dset field' is the field name of the dataset containing shot numbers, 'shape' is the numpy shape of the shot number data, and 'dtype' is the numpy dtype of the data. This all defines the numpy dtype of the 'shotnum' field in the HDFReadControls constructed numpy array.

config['state values']

This is another dictionary defining 'state values. For example,

config['state values'] = {
    'xyz': {
        'dset paths': config['dset paths'],
        'dset field': ('x', 'y', 'z'),
        'shape': (3,),
        'dtype': numpy.float32}
}

will tell HDFReadControls to construct a numpy array with a the 'xyz' field. This field would be a 3-element array of numpy.float32, where the 'x' field of the HDF5 dataset is mapped to the 1st index, 'y' is mapped to the 2nd index, and 'z' is mapped to the 3rd index.

Note:

  • A state value field (key) can not be defined as 'signal' since this field is reserved for digitizer data constructed by HDFReadData.
  • If state value data represents probe position data, then it should be given the field name (key) 'xyz' (like in the example above).

If a control device saves data around the concept of a command list, then configs has a few additional required keys, see table below.

Additional required keys for config = configs['config name'] when the control device saves data around the concept of a command list.
Key Description
config['command list']

A tuple representing the original command list. For example,

config['command list'] = ('VOLT: 20.0',
                          'VOLT 25.0',
                          'VOLT 30.0')
config['state values']

Has all the same keys as before, plus the addition of 'command list', 'cl str, and 're pattern'. For example,

config['state values'] = {
    'command': {
        'dset paths': config['dset paths'],
        'dset field': ('Command index',),
        'shape': (),
        'dtype': numpy.float32,
        'command list': (20.0, 25.0, 30.0),
        'cl str': ('VOLT: 20.0', 'VOLT 25.0',
                   'VOLT 30.0'),
        're pattern': re.compile(r'some RE pattern')}
}

where 're pattern' is the compiled RE pattern used to parse the original command list, 'cl str' is the matched string segment of the command list, and 'command list' is the set of values that will populate the constructed numpy array.

Note

For further details, look to Adding a Control Device Mapping Module.

construct_dataset_name(*args) → str

Constructs the dataset name corresponding to the input arguments.

Returns:name of dataset
Raise:NotImplementedError
contype

control device type

dataset_names

list of names of the HDF5 datasets in the control group

device_name

Name of Control device

group

Instance of the HDF5 Control Device group

has_command_list
Returns:True if dataset utilizes a command list
info

Control device dictionary of meta-info. For example,

info = {
    'group name': 'Control',
    'group path': '/foo/bar/Control',
    'contype': 'motion',
}
one_config_per_dset

'True' if each control configuration has its own dataset

subgroup_names

list of names of the HDF5 sub-groups in the control group

bapsflib._hdf.maps.controls.waveform

Classes

HDFMapControlWaveform Mapping module for the ‘Waveform’ control device.
class bapsflib._hdf.maps.controls.waveform.HDFMapControlWaveform(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.controls.templates.HDFMapControlCLTemplate

Mapping module for the ‘Waveform’ control device.

Simple group structure looks like:

+-- Waveform
|   +-- Run time list
|   +-- waveform_<descr>
|   |   +--
Parameters:group – the HDF5 control device group
clparse(config_name: str) → bapsflib._hdf.maps.controls.clparse.CLParse

Return instance of CLParse for config_name.

Parameters:config_name (str) – configuration name
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array by HDFReadControls.

– Constructing configs

The configs dict is a nested dictionary where the first level of keys represents the control device configuration names. Each configuration corresponds to one dataset in the HDF5 control group and represents a grouping of state values associated with an probe or instrument used during an experiment.

Each configuration is a dictionary consisting of a set of required keys ('dset paths', 'shotnum', and 'state values') and optional keys. Any optional key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array and are explained in the table below.

Dictionary breakdown for config = configs['config name']
Key Description
config['dset paths']

Internal HDF5 path to the dataset associated with the control device configuration. For example,

config['dset paths'] = ('/foo/bar/Control/d1', )
config['shotnum']

Defines how the run shot numbers are stored in the HDF5 file, which are mapped to the 'shotnum' field of the constructed numpy array. Should look like,

config['shotnum'] = {
    'dset paths': config['dset paths'],
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset, 'dset field' is the field name of the dataset containing shot numbers, 'shape' is the numpy shape of the shot number data, and 'dtype' is the numpy dtype of the data. This all defines the numpy dtype of the 'shotnum' field in the HDFReadControls constructed numpy array.

config['state values']

This is another dictionary defining 'state values. For example,

config['state values'] = {
    'xyz': {
        'dset paths': config['dset paths'],
        'dset field': ('x', 'y', 'z'),
        'shape': (3,),
        'dtype': numpy.float32}
}

will tell HDFReadControls to construct a numpy array with a the 'xyz' field. This field would be a 3-element array of numpy.float32, where the 'x' field of the HDF5 dataset is mapped to the 1st index, 'y' is mapped to the 2nd index, and 'z' is mapped to the 3rd index.

Note:

  • A state value field (key) can not be defined as 'signal' since this field is reserved for digitizer data constructed by HDFReadData.
  • If state value data represents probe position data, then it should be given the field name (key) 'xyz' (like in the example above).

If a control device saves data around the concept of a command list, then configs has a few additional required keys, see table below.

Additional required keys for config = configs['config name'] when the control device saves data around the concept of a command list.
Key Description
config['command list']

A tuple representing the original command list. For example,

config['command list'] = ('VOLT: 20.0',
                          'VOLT 25.0',
                          'VOLT 30.0')
config['state values']

Has all the same keys as before, plus the addition of 'command list', 'cl str, and 're pattern'. For example,

config['state values'] = {
    'command': {
        'dset paths': config['dset paths'],
        'dset field': ('Command index',),
        'shape': (),
        'dtype': numpy.float32,
        'command list': (20.0, 25.0, 30.0),
        'cl str': ('VOLT: 20.0', 'VOLT 25.0',
                   'VOLT 30.0'),
        're pattern': re.compile(r'some RE pattern')}
}

where 're pattern' is the compiled RE pattern used to parse the original command list, 'cl str' is the matched string segment of the command list, and 'command list' is the set of values that will populate the constructed numpy array.

Note

For further details, look to Adding a Control Device Mapping Module.

construct_dataset_name(*args) → str

Constructs name of dataset containing control state value data.

contype

control device type

dataset_names

list of names of the HDF5 datasets in the control group

device_name

Name of Control device

group

Instance of the HDF5 Control Device group

has_command_list
Returns:True if dataset utilizes a command list
info

Control device dictionary of meta-info. For example,

info = {
    'group name': 'Control',
    'group path': '/foo/bar/Control',
    'contype': 'motion',
}
one_config_per_dset

'True' if each control configuration has its own dataset

reset_state_values_config(config_name: str, apply_patterns=False)

Reset the configs[config_name]['state values'] dictionary.

Parameters:
  • config_name – configuration name
  • apply_patterns (bool) – Set False (DEFAULT) to reset to _default_state_values_dict(config_name). Set True to rebuild dict using _default_re_patterns.
set_state_values_config(config_name: str, patterns: Union[str, Iterable[str]])

Rebuild and set configs[config_name]['state values'] based on the supplied RE patterns.

Parameters:
  • config_name – configuration name
  • patterns – list of RE strings
subgroup_names

list of names of the HDF5 sub-groups in the control group

Classes

ConType Enum of Control Device Types
HDFMapControls A dictionary that contains mapping objects for all the discovered control devices in the HDF5 data group.
class bapsflib._hdf.maps.controls.ConType

Bases: enum.Enum

Enum of Control Device Types

motion = 'motion'
power = 'power'
timing = 'timing'
waveform = 'waveform'
class bapsflib._hdf.maps.controls.HDFMapControls(data_group: h5py._hl.group.Group)

Bases: dict

A dictionary that contains mapping objects for all the discovered control devices in the HDF5 data group. The dictionary keys are the names of the discovered control devices.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapControls
>>> f = lapd.File('sample.hdf5')
>>> # 'Raw data + config' is the LaPD HDF5 group name for the
... # group housing digitizer and control devices
... control_map = HDFMapControls(f['Raw data + config'])
>>> control_map['6K Compumotor']
<bapsflib._hdf.maps.controls.sixk.HDFMapControl6K>
Parameters:

data_group – HDF5 group object

mappable_devices

tuple of the mappable control devices (i.e. their HDF5 group names)

bapsflib._hdf.maps.digitizers

Package of digitizer mapping classes and their constructor (HDFMapDigitizers).

bapsflib._hdf.maps.digitizers.map_digis

Classes

HDFMapDigitizers A dictionary that contains mapping objects for all the discovered digitizers in the HDF5 data group.
class bapsflib._hdf.maps.digitizers.map_digis.HDFMapDigitizers(data_group: h5py._hl.group.Group)

Bases: dict

A dictionary that contains mapping objects for all the discovered digitizers in the HDF5 data group. The dictionary keys are the names of he discovered digitizers.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapDigitizers
>>> f = lapd.File('sample.hdf5')
>>> # 'Raw data + config' is the LaPD HDF5 group name for the
... # group housing digitizer and control devices
... digi_map = HDFMapDigitizers(f['Raw data + config'])
>>> digi_map['SIS 3301']
<bapsflib._hdf.maps.digitizers.sis3301.HDFMapDigiSIS3301>
Parameters:

data_group – HDF5 group object

_HDFMapDigitizers__build_dict

Discovers the HDF5 digitizers and builds the dictionary containing the digitizer mapping objects. This is the dictionary used to initialize self.

Returns:digitizer mapping dictionary
Return type:dict
_defined_mapping_classes = {'SIS 3301': <class 'bapsflib._hdf.maps.digitizers.sis3301.HDFMapDigiSIS3301'>, 'SIS crate': <class 'bapsflib._hdf.maps.digitizers.siscrate.HDFMapDigiSISCrate'>}

Dictionary containing references to the defined (known) digitizer mapping classes.

mappable_devices

Tuple of the mappable digitizers (i.e. their HDF5 group names)

bapsflib._hdf.maps.digitizers.sis3301

Classes

HDFMapDigiSIS3301 Mapping class for the ‘SIS 3301’ digitizer.
class bapsflib._hdf.maps.digitizers.sis3301.HDFMapDigiSIS3301(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.digitizers.templates.HDFMapDigiTemplate

Mapping class for the ‘SIS 3301’ digitizer.

Simple group structure looks like:

+-- SIS 3301
|   +-- Config01 [0:0]
|   +-- Config01 [0:0] headers
.
.
.
|   +-- Configuration: Config01
|   |   +-- Boards[0]
|   |   |   +-- Channels[0]
|   |   |   |   +--
.
.
.
Parameters:group – the HDF5 digitizer group
construct_dataset_name(board: int, channel: int, config_name=None, adc='SIS 3301', return_info=False) → Union[str, Tuple[str, Dict[str, Any]]]

Construct the name of the HDF5 dataset containing digitizer data. The dataset name follows the format:

'<config_name> [<board>:<channel>]'

where <config_name> is the digitizer configuration name, <board> is the requested board number, and <channel> is the requested channel number.

Parameters:
  • board – board number
  • channel – channel number
  • config_name (str) – digitizer configuration name
  • adc (str) – analog-digital-converter name
  • return_info (bool) – True will return a dictionary of meta-info associated with the digitizer data (DEFAULT False)
Returns:

digitizer dataset name. If return_info=True, then returns a tuple of (dataset name, dictionary of meta-info)

The returned adc information dictionary looks like:

adc_dict = {
    'adc': str,
    'bit': int,
    'clock rate': astropy.units.Quantity,
    'configuration name': str,
    'digitizer': str,
    'nshotnum': int,
    'nt': int,
    'sample average (hardware)': int,
    'shot average (software)': int,
}
construct_header_dataset_name(board: int, channel: int, config_name=None, adc='SIS 3301', **kwargs) → str

Construct the name of the HDF5 header dataset associated with the digitizer dataset. The header dataset stores shot numbers and other shot number specific meta-data. It also has a one- to-one row correspondence with the digitizer dataset. The header dataset name follows the format:

'<dataset name> headers'

where <dataset name> is the digitizer dataset name specified by the input arguments and constructed by construct_dataset_name().

Parameters:
  • board – board number
  • channel – channel number
  • config_name (str) – digitizer configuration name
  • adc (str) – analog-digital-converter name
Returns:

header dataset name associated with the digitizer dataset

bapsflib._hdf.maps.digitizers.siscrate

Classes

HDFMapDigiSISCrate Mapping class for the ‘SIS crate’ digitizer.
class bapsflib._hdf.maps.digitizers.siscrate.HDFMapDigiSISCrate(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.digitizers.templates.HDFMapDigiTemplate

Mapping class for the ‘SIS crate’ digitizer.

Simple group structure looks like:

+-- SIS crate
|   +-- config01
|   |   +-- SIS crate 3302 calibration[0]
|   |   |   +--
.
|   |   +-- SIS crate 3302 configurations[0]
|   |   |   +--
.
|   |   +-- SIS crate 3305 calibration[0]
|   |   |   +--
.
|   |   +-- SIS crate 3305 configurations[0]
|   |   |   +--
.
.
|   |   +-- SIS crate 3820 configurations[0]
|   |   |   +--
|   +-- config01 [Slot 5: SIS 3302 ch 1]
|   +-- config01 [Slot 5: SIS 3302 ch 1] headers
.
.
.
|   +-- config01 [Slot 13: SIS 3305 FPGA 1 ch 1]
|   +-- config01 [Slot 13: SIS 3305 FPGA 1 ch 1] headers
.
|   +-- config01 [Slot 13: SIS 3305 FPGA 2 ch 1]
|   +-- config01 [Slot 13: SIS 3305 FPGA 2 ch 1] headers
.
.
.
Parameters:group – the HDF5 digitizer group
construct_dataset_name(board: int, channel: int, config_name=None, adc=None, return_info=False) → Union[str, Tuple[str, Dict[str, Any]]]

Construct the name of the HDF5 dataset containing digitizer data. The dataset naming follows two formats based on their associated adc:

# for 'SIS 3302'
'<config_name> [Slot <slot>: SIS 3302 ch <ch>]'

# for 'SIS 3305'
'<config_name> [Slot <slot>: SIS 3305 FPGA <num> ch <ch>]'

where <config_name> is the digitizer configuration name, <slot> is the slot number in the digitizer crate that is associated with the board number, <ch> is the requested channel number, and <num> is the FPGA number. Only the ‘SIS 3305’ utilizes the FPGA nomenclature, where channels 1-4 reside on ‘FPGA 1’ and channels 5-8 reside on ‘FPGA 2’.

Parameters:
  • board – board number
  • channel – channel number
  • config_name (str) – digitizer configuration name
  • adc (str) – analog-digital-converter name
  • return_info (bool) – True will return a dictionary of meta-info associated with the digitizer data (DEFAULT False)
Returns:

digitizer dataset name. If return_info=True, then returns a tuple of (dataset name, dictionary of meta-info)

The returned adc information dictionary looks like:

adc_dict = {
    'adc': str,
    'bit': int,
    'clock rate': astropy.units.Quantity,
    'configuration name': str,
    'digitizer': str,
    'nshotnum': int,
    'nt': int,
    'sample average (hardware)': int,
    'shot average (software)': int,
}
construct_header_dataset_name(board: int, channel: int, config_name=None, adc=None, **kwargs) → str

Construct the name of the HDF5 header dataset associated with the digitizer dataset. The header dataset stores shot numbers and other shot number specific meta-data. It also has a one- to-one row correspondence with the digitizer dataset. The header dataset name follows the format:

'<dataset name> headers'

where <dataset name> is the digitizer dataset name specified by the input arguments and constructed by construct_dataset_name().

Parameters:
  • board – board number
  • channel – channel number
  • config_name (str) – digitizer configuration name
  • adc (str) – analog-digital-converter name
Returns:

header dataset name associated with the digitizer dataset

get_slot(brd: int, adc: str) → Union[None, int]

Get slot number for given board number and adc.

Parameters:
  • brd – board number
  • adc – digitizer analog-digital-converter name
Returns:

slot number, or None if there is no associated slot number

slot_info

Slot info dictionary. Contains relationship between slot number and the associated board number and adc name.

bapsflib._hdf.maps.digitizers.templates

Classes

HDFMapDigiTemplate Template class for all digitizer mapping classes to inherit from.
class bapsflib._hdf.maps.digitizers.templates.HDFMapDigiTemplate(group: h5py._hl.group.Group)

Bases: abc.ABC

Template class for all digitizer mapping classes to inherit from.

Any inheriting class should define __init__ as:

def __init__(self, group: h5py.Group)
    """
    :param group: HDF5 group object
    """
    # initialize
    HDFMapDigiTemplate.__init__(self, group)

    # define device adc's
    self._device_adcs = ()  # type: Tuple[str, ...]

    # populate self.configs
    self._build_configs()

Note

  • In the code sample above, self._device_adcs is digitizer specific and should be defined as a tuple of strings of analog-digital-converter (adc) names.
  • Any method that raises a NotImplementedError is intended to be overwritten by the inheriting class.
Parameters:group – the digitizer HDF5 group
_abc_impl = <_abc_data object>
_build_configs()

Examines the HDF5 group to build the configs dictionary.

Raise:NotImplementedError

Note

It is recommended to define additioal helper methods to construct and populate the configs dictionary.

Possible helper methods.
Method Description
_adc_info_first_pass() Build the tuple of tuples containing the adc connected board and channels numbers, as well as, the associated setup configuration for each connected board.
_adc_info_second_pass() Review and update the adc tuple generated by _adc_info_first_pass(). Here, the expected datasets can be checked for existence and the setup dictionary can be append with any additional entries.
_find_active_adcs() Examine the configuration group to determine which digitizer adc’s were used for the configuration.
_find_adc_connections() Used to determine the adc’s connected board and channels. It can also act as the seed for _adc_info_first_pass().
_parse_config_name() Parse the configuration group name to determine the digitizer configuration name.
active_configs

List of active digitizer configurations

configs

Dictionary containing al the relevant mapping information to translate the HDF5 data into a numpy array by HDFReadData.

– Constructing configs

The configs dict is a nested dictionary where the first level of keys represents the digitizer configuration names. Each configuration dictionary then consists of a set of non-polymorphic and polymorphic keys. Any additional keys are currently ignored. The non-polymorphic keys are as follows:

Required Non-Polymorphic keys for config=configs['config name']
Key Description
config['active']
True or False indicating if this configuration was used in recording the digitizer datasets
config['adc']

Tuple of strings naming the adc’s used for this configuration. For example,

('SIS 3301', )
config['config group path']

Internal HDF5 path to the digitizer configuration group. For example,

'/foo/bar/SIS 3301/Configuration: first_run'
config['shotnum']

Dictionary defining how the digitzier shot numbers are recorded. It is assumed, the shot numbers are recorded in the header dataset associated with the main dataset. The dictionary should look like,

config['shotnum'] = {
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.uint32,
}

where 'dset field' is the field name of the header dataset containing shot numbers, 'shape' is the numpy shape of the shot number data, and 'dtype' is the numpy dtype of the data. This all defines the numpy dtype of the 'shotnum' field in the HDFReadData constructed numpy array.

The required polymorphic keys are the names of each adc listed in configs['config name']['adc']. These entries contain the adc board and channel hookup configuration, as well as, the adc setup configuration for each connected board. Continuing with the example above, this key would look something like

>>> type(config['SIS 3301'])
tuple
>>> type(config['SIS 3301'][0])
tuple
>>> len(config['SIS 3301'][0])
3

where each nested tuple represents one board connection to the adc and is 3 elements long. The breakdown of the nested tuple follows:

Breakdown of Polymorphic Key. (config=configs['config name'])
Key Description
config['SIS 3301'][0][0]
int representing the connected board number
config['SIS 3301'][0][1]
Tuple[int, ...] representing the connected channel numbers associated with the board number
config['SIS 3301'][0][2]

Dict[str, Any] representing the setup configuration of the adc. The dictionary should look like:

config['SIS 3301'][0][2] = {
    'bit: 10,
    'clock rate':
        astropy.units.Quantity(100.0, unit='MHz'),
    'nshotnum': 10,
    'nt': 10000,
    'sample average (hardware)': None,
    'shot average (software)': None,
}

where 'bit' represents the bit resolution of the adc, 'clock rate' represents the base clock rate of the adc, 'nshotnum' is the number of shot numbers recorded, 'nt' is the number of time samples recorded, 'sample average (hardware)' is the number of time samples averaged together (this and the 'clock rate' make up the 'sample rate'), and 'shot average (software)' is the number of shots intended to be average together.

construct_dataset_name(board: int, channel: int, config_name=None, adc=None, return_info=False) → Union[str, Tuple[str, Dict[str, Any]]]

Constructs the name of the HDF5 dataset containing digitizer data.

Parameters:
  • board – board number
  • channel – channel number
  • config_name (str) – digitizer configuration name
  • adc (str) – analog-digital-converter name
  • return_info (bool) – True will return a dictionary of meta-info associated with the digitizer data (DEFAULT False)
Returns:

digitizer dataset name. If return_info=True, then returns a tuple of (dataset name, dictionary of meta-info)

The returned adc information dictionary should look like:

adc_dict = {
    'adc': str,
    'bit': int,
    'clock rate': astropy.units.Quantity,
    'configuration name': str,
    'digitizer': str,
    'nshotnum': int,
    'nt': int,
    'sample average (hardware)': int,
    'shot average (software)': int,
}
Raise:NotImplementedError
construct_header_dataset_name(board: int, channel: int, config_name=None, adc='', **kwargs) → str

Construct the name of the HDF5 header dataset associated with the digitizer dataset. The header dataset stores shot numbers and other shot number specific meta-data. It also has a one- to-one row correspondence with the digitizer dataset.

Parameters:
  • board – board number
  • channel – channel number
  • config_name (str) – digitizer configuration name
  • adc (str) – analog-digital-converter name
Returns:

header dataset name associated with the digitizer dataset

deduce_config_active_status(config_name: str) → bool

Determines if data was recorded using the configuration specified by config_name. This is done by comparing the configuration name against the dataset names.

Parameters:config_name – digitizer configuration name
Returns:True if the configuration was used in recording the group datasets; otherwise, False

Note

If the digitizer does not use the configuration name in the name of the created datasets, then the subclassing digitzier mapping class should override this method with a rule that is appropriate for the digitizer the class is being designed for.

device_adcs

Tuple of the analog-digital-convert (adc) names integrated into the digitizer.

device_name

Name of digitizer

get_adc_info(board: int, channel: int, adc=None, config_name=None) → Dict[str, Any]

Get adc setup info dictionary associated with board and channel.

Parameters:
  • board – board number
  • channel – channel number
  • adc (str) – analog-digital-converter name
  • config_name – digitizer configuration name
Returns:

dictionary of adc setup info (bit, clock rate, averaging, etc.) associated with board* and **channel

group

Instance of the HDF5 digitizer group

info

Digitizer dictionary of meta-info. For example,

info = {
    'group name': 'Digitizer',
    'group path': '/foo/bar/Digitizer',
}

Classes

HDFMapDigitizers A dictionary that contains mapping objects for all the discovered digitizers in the HDF5 data group.
class bapsflib._hdf.maps.digitizers.HDFMapDigitizers(data_group: h5py._hl.group.Group)

Bases: dict

A dictionary that contains mapping objects for all the discovered digitizers in the HDF5 data group. The dictionary keys are the names of he discovered digitizers.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapDigitizers
>>> f = lapd.File('sample.hdf5')
>>> # 'Raw data + config' is the LaPD HDF5 group name for the
... # group housing digitizer and control devices
... digi_map = HDFMapDigitizers(f['Raw data + config'])
>>> digi_map['SIS 3301']
<bapsflib._hdf.maps.digitizers.sis3301.HDFMapDigiSIS3301>
Parameters:

data_group – HDF5 group object

mappable_devices

Tuple of the mappable digitizers (i.e. their HDF5 group names)

bapsflib._hdf.maps.hdfmap

Classes

HDFMap Constructs a complete file mapping of the HDF5 file.
class bapsflib._hdf.maps.hdfmap.HDFMap(hdf_obj: h5py._hl.files.File, control_path: str, digitizer_path: str, msi_path: str)

Bases: object

Constructs a complete file mapping of the HDF5 file. This is utilized by the HDF5 utility classes (in module bapsflib._hdf.utils) to manipulate and read data out of the HDF5 file.

The following classes are leveraged to construct the mappings:

Parameters:
  • hdf_obj (h5py.File) – the HDF5 file object
  • control_path – internal HDF5 path to group containing control devices
  • digitizer_path – internal HDF5 path to group containing digitizers
  • msi_path – internal HDF5 path to group containing MSI diagnostics
controls

Dictionary of all the control device mapping objects.

Example:

How to retrieve the mapping object of the control device '6K Compumotor':

fmap = HDFMap(file_obj)
dmap = fmap.controls['6K Compumotor']
digitizers

Dictionary of all the digitizer device mapping objects.

Example:

How to retrieve the mapping object of the digitizer 'SIS 3301':

fmap = HDFMap(file_obj)
dmap = fmap.digitizers['SIS 3301']
get(name: str)

Get an device mapping instance.

Parameters:

name – name of desired device

Returns:

If the specified device is mapped, then an instance of the mapping is returned. Otherwise, None is returned.

Example:

How to retrieve the mapping object for the 'SIS 3301' digitizer:

>>> fmap = HDFMap(file_obj)
>>> dmap = fmap.get('SIS 3301')
>>>
>>> # which is equivalent to
>>> dmap = fmap.digitizers['SIS 3301']
main_digitizer
Returns:the mapping object for the digitizer that is assumed to be the main digitizer in digitizers

The main digitizer is determine by scanning through the local tuple possible_candidates that contains a hierarchical list of digitizers. The first digitizer found is assumed to be the main digitizer.

possible_candidates = ('SIS 3301', 'SIS crate')
msi

Dictionary of all the MSI diagnostic mapping objects.

Example:

How to retrieve the mapping object of the 'Magnetic field' MSI diagnostic:

fmap = HDFMap(file_obj)
dmap = fmap.msi['Magnetic field']
unknowns

List of all subgroup and dataset paths in the HDF5 root group, control device group, digitizer group, and MSI group that were not mapped.

bapsflib._hdf.maps.msi

Package of MSI diagnostic mapping classes and their constructor (HDFMapMSI).

bapsflib._hdf.maps.msi.discharge

Classes

HDFMapMSIDischarge Mapping class for the ‘Discharge’ MSI diagnostic.
class bapsflib._hdf.maps.msi.discharge.HDFMapMSIDischarge(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.msi.templates.HDFMapMSITemplate

Mapping class for the ‘Discharge’ MSI diagnostic.

Simple group structure looks like:

+-- Discharge
|   +-- Cathode-anode voltage
|   +-- Discharge current
|   +-- Discharge summary
Parameters:group (h5py.Group) – the HDF5 MSI diagnostic group
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array. The actually numpy array construction is done by HDFReadMSI.

– Constructing configs

The configs dict is broken into a set of required keys ('shape', 'shotnum', 'signals', and 'meta') and optional keys. Any option key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array.

Key Description
configs['shape']

This is used as the shape for the HDFReadMSI constructed numpy array and typically looks like:

configs['shape'] = (nsn, )

where nsn is the number of shot numbers saved to the diagnostic’s datasets.

configs['shotnum']

Specifies the dataset(s) containing the recorded HDF5 shot numbers. This maps to the 'shotnum' field of the numpy array constructed by HDFReadMSI. Should look like:

configs['shotnum'] = {
    'dset paths': ('/foo/bar/d1',),
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset(s), 'dset field' is the field name of the dataset containing shot numbers, 'shape' of the shot number data, and 'dtype' is the numpy dtype that the 'shotnum' field of the constructed numpy array will be.

configs['signals']

This is another dictionary where each key will map to a field in the HDFReadMSI numpy array. For example,

configs['signals'] = {
    'current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': (),
        'shape': (100,),
        'dtype': numpy.float32},
}

would created a 'current' field in the constructed numpy array. Any field specified in this key is considered to be your plot-able, or “primary”, diagnostic data.

configs['meta']

This is another dictionary specifying meta-data that is both diagnostic and shot number specific. For example,

configs['meta'] = {
    'shape': (),
    'max current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': ('Max current',),
        'shape': (),
        'dtype': numpy.float32},
}

would create a 'max current' field in the 'meta' field of the constructed numpy array.

Note

For further details, look to Adding a MSI Diagnostic Mapping Module.

device_name

Name of MSI diagnostic (device)

group

Instance of MSI diagnostic group

info

MSI diagnostic dictionary of meta-info. For example,

info = {
    'group name': 'Diagnostic',
    'group path': '/foo/bar/Diagnostic',
}
bapsflib._hdf.maps.msi.gaspressure

Classes

HDFMapMSIGasPressure Mapping class for the ‘Gas pressure’ MSI diagnostic.
class bapsflib._hdf.maps.msi.gaspressure.HDFMapMSIGasPressure(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.msi.templates.HDFMapMSITemplate

Mapping class for the ‘Gas pressure’ MSI diagnostic.

Simple group structure looks like:

+-- Gas pressure
|   +-- Gas pressure summary
|   +-- RGA partial pressures
Parameters:group (h5py.Group) – the HDF5 MSI diagnostic group
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array. The actually numpy array construction is done by HDFReadMSI.

– Constructing configs

The configs dict is broken into a set of required keys ('shape', 'shotnum', 'signals', and 'meta') and optional keys. Any option key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array.

Key Description
configs['shape']

This is used as the shape for the HDFReadMSI constructed numpy array and typically looks like:

configs['shape'] = (nsn, )

where nsn is the number of shot numbers saved to the diagnostic’s datasets.

configs['shotnum']

Specifies the dataset(s) containing the recorded HDF5 shot numbers. This maps to the 'shotnum' field of the numpy array constructed by HDFReadMSI. Should look like:

configs['shotnum'] = {
    'dset paths': ('/foo/bar/d1',),
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset(s), 'dset field' is the field name of the dataset containing shot numbers, 'shape' of the shot number data, and 'dtype' is the numpy dtype that the 'shotnum' field of the constructed numpy array will be.

configs['signals']

This is another dictionary where each key will map to a field in the HDFReadMSI numpy array. For example,

configs['signals'] = {
    'current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': (),
        'shape': (100,),
        'dtype': numpy.float32},
}

would created a 'current' field in the constructed numpy array. Any field specified in this key is considered to be your plot-able, or “primary”, diagnostic data.

configs['meta']

This is another dictionary specifying meta-data that is both diagnostic and shot number specific. For example,

configs['meta'] = {
    'shape': (),
    'max current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': ('Max current',),
        'shape': (),
        'dtype': numpy.float32},
}

would create a 'max current' field in the 'meta' field of the constructed numpy array.

Note

For further details, look to Adding a MSI Diagnostic Mapping Module.

device_name

Name of MSI diagnostic (device)

group

Instance of MSI diagnostic group

info

MSI diagnostic dictionary of meta-info. For example,

info = {
    'group name': 'Diagnostic',
    'group path': '/foo/bar/Diagnostic',
}
bapsflib._hdf.maps.msi.heater

Classes

HDFMapMSIHeater Mapping class for the ‘Heater’ MSI diagnostic.
class bapsflib._hdf.maps.msi.heater.HDFMapMSIHeater(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.msi.templates.HDFMapMSITemplate

Mapping class for the ‘Heater’ MSI diagnostic.

Simple group structure looks like:

+-- Heater
|   +-- Heater summary
Parameters:group (h5py.Group) – the HDF5 MSI diagnostic group
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array. The actually numpy array construction is done by HDFReadMSI.

– Constructing configs

The configs dict is broken into a set of required keys ('shape', 'shotnum', 'signals', and 'meta') and optional keys. Any option key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array.

Key Description
configs['shape']

This is used as the shape for the HDFReadMSI constructed numpy array and typically looks like:

configs['shape'] = (nsn, )

where nsn is the number of shot numbers saved to the diagnostic’s datasets.

configs['shotnum']

Specifies the dataset(s) containing the recorded HDF5 shot numbers. This maps to the 'shotnum' field of the numpy array constructed by HDFReadMSI. Should look like:

configs['shotnum'] = {
    'dset paths': ('/foo/bar/d1',),
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset(s), 'dset field' is the field name of the dataset containing shot numbers, 'shape' of the shot number data, and 'dtype' is the numpy dtype that the 'shotnum' field of the constructed numpy array will be.

configs['signals']

This is another dictionary where each key will map to a field in the HDFReadMSI numpy array. For example,

configs['signals'] = {
    'current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': (),
        'shape': (100,),
        'dtype': numpy.float32},
}

would created a 'current' field in the constructed numpy array. Any field specified in this key is considered to be your plot-able, or “primary”, diagnostic data.

configs['meta']

This is another dictionary specifying meta-data that is both diagnostic and shot number specific. For example,

configs['meta'] = {
    'shape': (),
    'max current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': ('Max current',),
        'shape': (),
        'dtype': numpy.float32},
}

would create a 'max current' field in the 'meta' field of the constructed numpy array.

Note

For further details, look to Adding a MSI Diagnostic Mapping Module.

device_name

Name of MSI diagnostic (device)

group

Instance of MSI diagnostic group

info

MSI diagnostic dictionary of meta-info. For example,

info = {
    'group name': 'Diagnostic',
    'group path': '/foo/bar/Diagnostic',
}
bapsflib._hdf.maps.msi.interferometerarray

Classes

HDFMapMSIInterferometerArray Mapping class for the ‘Interferometer array’ MSI diagnostic.
class bapsflib._hdf.maps.msi.interferometerarray.HDFMapMSIInterferometerArray(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.msi.templates.HDFMapMSITemplate

Mapping class for the ‘Interferometer array’ MSI diagnostic.

Simple group structure looks like:

+-- Interferometer array
|   +-- Interferometer [0]
|   |   +-- Interferometer summary list
|   |   +-- Interferometer trace
|   +-- Interferometer [1]
|   |   +-- Interferometer summary list
|   |   +-- Interferometer trace
.
.
.
|   +-- Interferometer [6]
|   |   +-- Interferometer summary list
|   |   +-- Interferometer trace
Parameters:group (h5py.Group) – the HDF5 MSI diagnostic group
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array. The actually numpy array construction is done by HDFReadMSI.

– Constructing configs

The configs dict is broken into a set of required keys ('shape', 'shotnum', 'signals', and 'meta') and optional keys. Any option key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array.

Key Description
configs['shape']

This is used as the shape for the HDFReadMSI constructed numpy array and typically looks like:

configs['shape'] = (nsn, )

where nsn is the number of shot numbers saved to the diagnostic’s datasets.

configs['shotnum']

Specifies the dataset(s) containing the recorded HDF5 shot numbers. This maps to the 'shotnum' field of the numpy array constructed by HDFReadMSI. Should look like:

configs['shotnum'] = {
    'dset paths': ('/foo/bar/d1',),
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset(s), 'dset field' is the field name of the dataset containing shot numbers, 'shape' of the shot number data, and 'dtype' is the numpy dtype that the 'shotnum' field of the constructed numpy array will be.

configs['signals']

This is another dictionary where each key will map to a field in the HDFReadMSI numpy array. For example,

configs['signals'] = {
    'current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': (),
        'shape': (100,),
        'dtype': numpy.float32},
}

would created a 'current' field in the constructed numpy array. Any field specified in this key is considered to be your plot-able, or “primary”, diagnostic data.

configs['meta']

This is another dictionary specifying meta-data that is both diagnostic and shot number specific. For example,

configs['meta'] = {
    'shape': (),
    'max current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': ('Max current',),
        'shape': (),
        'dtype': numpy.float32},
}

would create a 'max current' field in the 'meta' field of the constructed numpy array.

Note

For further details, look to Adding a MSI Diagnostic Mapping Module.

device_name

Name of MSI diagnostic (device)

group

Instance of MSI diagnostic group

info

MSI diagnostic dictionary of meta-info. For example,

info = {
    'group name': 'Diagnostic',
    'group path': '/foo/bar/Diagnostic',
}
bapsflib._hdf.maps.msi.magneticfield

Classes

HDFMapMSIMagneticField Mapping class for the ‘Magnetic field’ MSI diagnostic.
class bapsflib._hdf.maps.msi.magneticfield.HDFMapMSIMagneticField(group: h5py._hl.group.Group)

Bases: bapsflib._hdf.maps.msi.templates.HDFMapMSITemplate

Mapping class for the ‘Magnetic field’ MSI diagnostic.

Simple group structure looks like:

+-- Magnetic field
|   +-- Magnet power supply currents
|   +-- Magnetic field profile
|   +-- Magnetic field summary
Parameters:group (h5py.Group) – the HDF5 MSI diagnostic group
configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array. The actually numpy array construction is done by HDFReadMSI.

– Constructing configs

The configs dict is broken into a set of required keys ('shape', 'shotnum', 'signals', and 'meta') and optional keys. Any option key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array.

Key Description
configs['shape']

This is used as the shape for the HDFReadMSI constructed numpy array and typically looks like:

configs['shape'] = (nsn, )

where nsn is the number of shot numbers saved to the diagnostic’s datasets.

configs['shotnum']

Specifies the dataset(s) containing the recorded HDF5 shot numbers. This maps to the 'shotnum' field of the numpy array constructed by HDFReadMSI. Should look like:

configs['shotnum'] = {
    'dset paths': ('/foo/bar/d1',),
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset(s), 'dset field' is the field name of the dataset containing shot numbers, 'shape' of the shot number data, and 'dtype' is the numpy dtype that the 'shotnum' field of the constructed numpy array will be.

configs['signals']

This is another dictionary where each key will map to a field in the HDFReadMSI numpy array. For example,

configs['signals'] = {
    'current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': (),
        'shape': (100,),
        'dtype': numpy.float32},
}

would created a 'current' field in the constructed numpy array. Any field specified in this key is considered to be your plot-able, or “primary”, diagnostic data.

configs['meta']

This is another dictionary specifying meta-data that is both diagnostic and shot number specific. For example,

configs['meta'] = {
    'shape': (),
    'max current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': ('Max current',),
        'shape': (),
        'dtype': numpy.float32},
}

would create a 'max current' field in the 'meta' field of the constructed numpy array.

Note

For further details, look to Adding a MSI Diagnostic Mapping Module.

device_name

Name of MSI diagnostic (device)

group

Instance of MSI diagnostic group

info

MSI diagnostic dictionary of meta-info. For example,

info = {
    'group name': 'Diagnostic',
    'group path': '/foo/bar/Diagnostic',
}
bapsflib._hdf.maps.msi.map_msi

Classes

HDFMapMSI A dictionary containing mapping objects for all the discovered MSI diagnostic HDF5 groups.
class bapsflib._hdf.maps.msi.map_msi.HDFMapMSI(msi_group: h5py._hl.group.Group)

Bases: dict

A dictionary containing mapping objects for all the discovered MSI diagnostic HDF5 groups. The dictionary keys are the MSI diagnostic names.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapMSI
>>> f = lapd.File('sample.hdf5')
>>> # 'MSI' is the LaPD HDF5 group name for the group housing
... # MSI diagnostic groups
... msi_map = HDFMapMSI(f['MSI'])
Parameters:

msi_group – HDF5 group object

_HDFMapMSI__build_dict

Discovers the HDF5 MSI diagnostics and builds the dictionary containing the diagnostic mapping objects. This is the dictionary used to initialize self.

Returns:MSI diagnostic mapping dictionary
Return type:dict
_defined_mapping_classes = {'Discharge': <class 'bapsflib._hdf.maps.msi.discharge.HDFMapMSIDischarge'>, 'Gas pressure': <class 'bapsflib._hdf.maps.msi.gaspressure.HDFMapMSIGasPressure'>, 'Heater': <class 'bapsflib._hdf.maps.msi.heater.HDFMapMSIHeater'>, 'Interferometer array': <class 'bapsflib._hdf.maps.msi.interferometerarray.HDFMapMSIInterferometerArray'>, 'Magnetic field': <class 'bapsflib._hdf.maps.msi.magneticfield.HDFMapMSIMagneticField'>}

Dictionary containing references to the defined (known) MSI diagnostic mapping classes.

mappable_devices

tuple of the mappable MSI diagnostics (i.e. their HDF5 group names)

bapsflib._hdf.maps.msi.templates

Classes

HDFMapMSITemplate Template class for all MSI diagnostic mapping classes to inherit from.
class bapsflib._hdf.maps.msi.templates.HDFMapMSITemplate(group: h5py._hl.group.Group)

Bases: abc.ABC

Template class for all MSI diagnostic mapping classes to inherit from.

Any inheriting class should define __init__ as:

def __init__(self, group: h5py.Group):
    """
    :param group: HDF5 group object
    """
    # initialize
    HDFMapMSITemplate.__init__(self, group)

    # populate self.configs
    self._build_configs()

Note

Any method that raises a NotImplementedError is intended to be overwritten by the inheriting class.

Parameters:group – the MSI diagnostic HDF5 group
_abc_impl = <_abc_data object>
_build_configs()

Gathers the necessary mapping data and constructs the configs dictionary.

Raises:NotImplementedError

Note

Examine _build_configs() in existing modules for ideas on how to override this method. Also read Adding a MSI Diagnostic Mapping Module.

configs

Dictionary containing all the relevant mapping information to translate the HDF5 data into a numpy array. The actually numpy array construction is done by HDFReadMSI.

– Constructing configs

The configs dict is broken into a set of required keys ('shape', 'shotnum', 'signals', and 'meta') and optional keys. Any option key is considered as meta-info for the device and is added to the info dictionary when the numpy array is constructed. The required keys constitute the mapping for constructing the numpy array.

Key Description
configs['shape']

This is used as the shape for the HDFReadMSI constructed numpy array and typically looks like:

configs['shape'] = (nsn, )

where nsn is the number of shot numbers saved to the diagnostic’s datasets.

configs['shotnum']

Specifies the dataset(s) containing the recorded HDF5 shot numbers. This maps to the 'shotnum' field of the numpy array constructed by HDFReadMSI. Should look like:

configs['shotnum'] = {
    'dset paths': ('/foo/bar/d1',),
    'dset field': ('Shot number',),
    'shape': (),
    'dtype': numpy.int32,
}

where 'dset paths' is the internal HDF5 path to the dataset(s), 'dset field' is the field name of the dataset containing shot numbers, 'shape' of the shot number data, and 'dtype' is the numpy dtype that the 'shotnum' field of the constructed numpy array will be.

configs['signals']

This is another dictionary where each key will map to a field in the HDFReadMSI numpy array. For example,

configs['signals'] = {
    'current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': (),
        'shape': (100,),
        'dtype': numpy.float32},
}

would created a 'current' field in the constructed numpy array. Any field specified in this key is considered to be your plot-able, or “primary”, diagnostic data.

configs['meta']

This is another dictionary specifying meta-data that is both diagnostic and shot number specific. For example,

configs['meta'] = {
    'shape': (),
    'max current': {
        'dset paths': ('/foo/bar/dset',),
        'dset field': ('Max current',),
        'shape': (),
        'dtype': numpy.float32},
}

would create a 'max current' field in the 'meta' field of the constructed numpy array.

Note

For further details, look to Adding a MSI Diagnostic Mapping Module.

device_name

Name of MSI diagnostic (device)

group

Instance of MSI diagnostic group

info

MSI diagnostic dictionary of meta-info. For example,

info = {
    'group name': 'Diagnostic',
    'group path': '/foo/bar/Diagnostic',
}

Classes

HDFMapMSI A dictionary containing mapping objects for all the discovered MSI diagnostic HDF5 groups.
class bapsflib._hdf.maps.msi.HDFMapMSI(msi_group: h5py._hl.group.Group)

Bases: dict

A dictionary containing mapping objects for all the discovered MSI diagnostic HDF5 groups. The dictionary keys are the MSI diagnostic names.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapMSI
>>> f = lapd.File('sample.hdf5')
>>> # 'MSI' is the LaPD HDF5 group name for the group housing
... # MSI diagnostic groups
... msi_map = HDFMapMSI(f['MSI'])
Parameters:

msi_group – HDF5 group object

mappable_devices

tuple of the mappable MSI diagnostics (i.e. their HDF5 group names)

Classes

ConType Enum of Control Device Types
FauxHDFBuilder Builds a Faux HDF5 file that simulates a HDF5 constructed at BaPSF.
HDFMap Constructs a complete file mapping of the HDF5 file.
HDFMapControls A dictionary that contains mapping objects for all the discovered control devices in the HDF5 data group.
HDFMapDigitizers A dictionary that contains mapping objects for all the discovered digitizers in the HDF5 data group.
HDFMapMSI A dictionary containing mapping objects for all the discovered MSI diagnostic HDF5 groups.
class bapsflib._hdf.maps.ConType

Bases: enum.Enum

Enum of Control Device Types

motion = 'motion'
power = 'power'
timing = 'timing'
waveform = 'waveform'
class bapsflib._hdf.maps.FauxHDFBuilder(name=None, add_modules=None, **kwargs)

Bases: h5py._hl.files.File

Builds a Faux HDF5 file that simulates a HDF5 constructed at BaPSF.

Parameters:
  • name (str) – name of HDF5 file
  • add_modules
  • kwargs
add_module(mod_name, mod_args=None)

Adds all the groups and datasets to the HDF5 file for the requested module.

Parameters:
  • mod_name (str) – name of module (e.g. 'Waveform')
  • mod_args (dict) – dictionary of input arguments for the module adder
cleanup()

Close the HDF5 file and cleanup any temporary directories and files.

clear_control_modules()

Remove all control device modules

clear_digi_modules()

Remove all digitizer modules

clear_msi_modules()

Remove all MSI modules

close()

Close the HDF5 file and remove temporary files/directories if the exist.

modules

Dictionary containing the module objects associated with the added modules.

path

Path to HDF5 file

remove_all_modules()

Remove all modules

remove_module(mod_name)

Remove requested module

reset()

Restore file such that only empty version of the ‘MSI’ and ‘Raw data + config’ group exist.

tempdir

Temporary directory containing tempfile. None if a real directory is specified upon creation.

tempfile

Temporary HDF5 file. None if a real file is specified upon creation.

valid_modules()

List of valid modules and their input arguments. For example,:

valid_modules = [
    {'name': 'Waveform',
     'args': {'n_configs': 1, 'sn_size': 100}},
]
class bapsflib._hdf.maps.HDFMap(hdf_obj: h5py._hl.files.File, control_path: str, digitizer_path: str, msi_path: str)

Bases: object

Constructs a complete file mapping of the HDF5 file. This is utilized by the HDF5 utility classes (in module bapsflib._hdf.utils) to manipulate and read data out of the HDF5 file.

The following classes are leveraged to construct the mappings:

Parameters:
  • hdf_obj (h5py.File) – the HDF5 file object
  • control_path – internal HDF5 path to group containing control devices
  • digitizer_path – internal HDF5 path to group containing digitizers
  • msi_path – internal HDF5 path to group containing MSI diagnostics
controls

Dictionary of all the control device mapping objects.

Example:

How to retrieve the mapping object of the control device '6K Compumotor':

fmap = HDFMap(file_obj)
dmap = fmap.controls['6K Compumotor']
digitizers

Dictionary of all the digitizer device mapping objects.

Example:

How to retrieve the mapping object of the digitizer 'SIS 3301':

fmap = HDFMap(file_obj)
dmap = fmap.digitizers['SIS 3301']
get(name: str)

Get an device mapping instance.

Parameters:

name – name of desired device

Returns:

If the specified device is mapped, then an instance of the mapping is returned. Otherwise, None is returned.

Example:

How to retrieve the mapping object for the 'SIS 3301' digitizer:

>>> fmap = HDFMap(file_obj)
>>> dmap = fmap.get('SIS 3301')
>>>
>>> # which is equivalent to
>>> dmap = fmap.digitizers['SIS 3301']
main_digitizer
Returns:the mapping object for the digitizer that is assumed to be the main digitizer in digitizers

The main digitizer is determine by scanning through the local tuple possible_candidates that contains a hierarchical list of digitizers. The first digitizer found is assumed to be the main digitizer.

possible_candidates = ('SIS 3301', 'SIS crate')
msi

Dictionary of all the MSI diagnostic mapping objects.

Example:

How to retrieve the mapping object of the 'Magnetic field' MSI diagnostic:

fmap = HDFMap(file_obj)
dmap = fmap.msi['Magnetic field']
unknowns

List of all subgroup and dataset paths in the HDF5 root group, control device group, digitizer group, and MSI group that were not mapped.

class bapsflib._hdf.maps.HDFMapControls(data_group: h5py._hl.group.Group)

Bases: dict

A dictionary that contains mapping objects for all the discovered control devices in the HDF5 data group. The dictionary keys are the names of the discovered control devices.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapControls
>>> f = lapd.File('sample.hdf5')
>>> # 'Raw data + config' is the LaPD HDF5 group name for the
... # group housing digitizer and control devices
... control_map = HDFMapControls(f['Raw data + config'])
>>> control_map['6K Compumotor']
<bapsflib._hdf.maps.controls.sixk.HDFMapControl6K>
Parameters:

data_group – HDF5 group object

mappable_devices

tuple of the mappable control devices (i.e. their HDF5 group names)

class bapsflib._hdf.maps.HDFMapDigitizers(data_group: h5py._hl.group.Group)

Bases: dict

A dictionary that contains mapping objects for all the discovered digitizers in the HDF5 data group. The dictionary keys are the names of he discovered digitizers.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapDigitizers
>>> f = lapd.File('sample.hdf5')
>>> # 'Raw data + config' is the LaPD HDF5 group name for the
... # group housing digitizer and control devices
... digi_map = HDFMapDigitizers(f['Raw data + config'])
>>> digi_map['SIS 3301']
<bapsflib._hdf.maps.digitizers.sis3301.HDFMapDigiSIS3301>
Parameters:

data_group – HDF5 group object

mappable_devices

Tuple of the mappable digitizers (i.e. their HDF5 group names)

class bapsflib._hdf.maps.HDFMapMSI(msi_group: h5py._hl.group.Group)

Bases: dict

A dictionary containing mapping objects for all the discovered MSI diagnostic HDF5 groups. The dictionary keys are the MSI diagnostic names.

Example:
>>> from bapsflib import lapd
>>> from bapsflib._hdf.maps import HDFMapMSI
>>> f = lapd.File('sample.hdf5')
>>> # 'MSI' is the LaPD HDF5 group name for the group housing
... # MSI diagnostic groups
... msi_map = HDFMapMSI(f['MSI'])
Parameters:

msi_group – HDF5 group object

mappable_devices

tuple of the mappable MSI diagnostics (i.e. their HDF5 group names)

bapsflib._hdf.utils

This package contains an assortment of utility classes used to access and interface with the HDF5 files generated at BaPSF.

bapsflib._hdf.utils.file

Classes

File Open a HDF5 file created at the Basic Plasma Science Facility.
class bapsflib._hdf.utils.file.File(name: str, mode='r', control_path='/', digitizer_path='/', msi_path='/', silent=False, **kwargs)

Bases: h5py._hl.files.File

Open a HDF5 file created at the Basic Plasma Science Facility.

All functionality of h5py.File is preserved (for details see http://docs.h5py.org/en/latest/)

Parameters:
  • name – name (and path) of file on disk
  • mode – readonly 'r' (DEFAULT) and read/write 'r+'
  • control_path – internal HDF5 path to group containing control devices
  • digitizer_path – internal HDF5 path to group containing digitizer devices
  • msi_path – internal HDF5 path to group containing MSI devices
  • silent – set True to suppress warnings (False DEFAULT)
  • kwargs – additional keywords passed on to h5py.File
Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5',
...          control_path='Raw data + config',
...          digitizer_path='Raw data + config',
...          msi_path='MSI')
>>> type(f)
bapsflib._hdf.utils.file.File
CONTROL_PATH = None

Internal HDF5 path for control devices. (DEFAULT '/')

DIGITIZER_PATH = None

Internal HDF5 path for digitizer devices. (DEFAULT '/')

MSI_PATH = None

Internal HDF5 path for MSI devices. (DEFAULT '/')

controls

Dictionary of control device mappings.

digitizers

Dictionary of digitizer device mappings

file_map

HDF5 file map (HDFMap)

info

Dictionary of general info on the HDF5 file and the experimental run.

msi

Dictionary of MSI device mappings.

overview

HDF5 file overview. (HDFOverview)

read_controls(controls: List[Union[str, Tuple[str, Any]]], shotnum=slice(None, None, None), intersection_set=True, silent=False, **kwargs)

Reads data from control device datasets. See HDFReadControls for more detail.

Parameters:
  • controls (List[Union[str, Tuple[str, Any]]]) – A list of strings and/or 2-element tuples indicating the control device(s). If a control device has only one configuration then only the device name 'control' needs to be passed in the list. If a control device has multiple configurations, then the device name and its configuration “name” needs to be passed as a tuple element ('control', 'config') in the list. (see condition_controls() for details)
  • shotnum (Union[int, list(int), slice(), numpy.array]) – HDF5 file shot number(s) indicating data entries to be extracted
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum and the shot numbers contained in each control device dataset. False will return the union instead of the intersection, minus \(shotnum \le 0\). (see HDFReadControls for details)
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadControls

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list control devices
>>> list(f.controls)
['6K Compumotor', 'Waveform']
>>>
>>> # list '6K Compumotor' configurations
>>> list(f.controls['6K Compumotor'].configs)
[2, 3]
>>>
>>> # extract all '6k Compumotor' data for configuration 3
>>> cdata = f.read_controls([('6K Compumotor', 3)])
>>> type(cdata)
bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls
>>>
>>> # list 'Waveform' configurations
>>> list(f.file_map.controls['Waveform'].configs)
['config01']
>>>
>>> # extract 'Waveform' data
>>> cdata = f.read_controls(['Waveform'])
>>> list(cdata.info['controls'])
['Waveform']
>>>
>>> # extract both 'Waveform' and '6K Compumotor'
>>> controls = ['Waveform', ('6K Compumotor', 2)]
>>> cdata = f.read_controls(controls)
>>> list(cdata.info['controls'])
['6K Compumotor', 'Waveform']
read_data(board: int, channel: int, index=slice(None, None, None), shotnum=slice(None, None, None), digitizer=None, adc=None, config_name=None, keep_bits=False, add_controls=None, intersection_set=True, silent=False, **kwargs)

Reads data from digitizer datasets and attaches control device data when requested. (see hdfreaddata.HDFReadData for details)

Parameters:
  • board – digitizer board number
  • channel – digitizer channel number
  • index (Union[int, list(int), slice(), numpy.array]) – dataset row index
  • shotnum (Union[int, list(int), slice(), numpy.array]) – HDF5 global shot number
  • digitizer (str) – name of digitizer
  • adc (str) – name of the digitizer’s analog-digital converter
  • config_name (str) – name of digitizer configuration
  • keep_bits (bool) – True to keep digitizer signal in bits, False (default) to convert digitizer signal to voltage
  • add_controls (List[Union[str, Tuple[str, Any]]]) – A list of strings and/or 2-element tuples indicating the control device(s). If a control device has only one configuration then only the device name 'control' needs to be passed in the list. If a control device has multiple configurations, then the device name and its configuration “name” needs to be passed as a tuple element ('control', 'config') in the list. (see condition_controls() for details)
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum, the digitizer dataset shot numbers, and, if requested, the shot numbers contained in each control device dataset. False will return the union instead of the intersection, minus \(shotnum \le 0\). (see HDFReadData for details)
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadData

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list control devices
>>> list(f.digitizers)
['SIS crate']
>>>
>>> # get active configurations
>>> f.digitizers['SIS crate'].configs
['config01', 'config02']
>>>
>>> # get active adc's for config
>>> f.digitizers['SIS crate'].configs['config01']['adc']
('SIS 3302,)
>>>
>>> # get first connected brd and channels to adc
>>> brd, chs = f.digitizers['SIS crate'].configs['config01'][
...     'SIS 3302'][0][0:2]
>>> brd
1
>>> chs
(1, 2, 3)
>>>
>>> # get data for brd = 1, ch = 1
>>> data = f.read_data(brd, chs[0],
...                    digitizer='SIS crate',
...                    adc='SIS 3302',
...                    config_name='config01')
>>> type(data)
bapsflib._hdf.utils.hdfreaddata.HDFReadData
>>>
>>> # Note: a quicker way to see how the digitizers are
>>> #       configured is to use
>>> #
>>> #       f.overview.report_digitizers()
>>> #
>>> #       which prints to screen a report of the
>>> #       digitizer hookup
read_msi(msi_diag: str, silent=False, **kwargs)

Reads data from MSI Diagnostic datasets. See HDFReadMSI for more detail.

Parameters:
  • msi_diag – name of MSI diagnostic
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadMSI

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list msi diagnostics
>>> list(f.msi)
['Interferometer array', 'Magnetic field']
>>>
>>> # read 'Interferometer array'
>>> mdata = f.read_msi('Interferometer array')
>>> type(mdata)
bapsflib._hdf.utils.hdfreadmsi.HDFReadMSI
bapsflib._hdf.utils.hdfoverview

Classes

HDFOverview Reports an overview of the HDF5 file mapping.

Functions

status_print Stylistic status printing for HDFOverview.
class bapsflib._hdf.utils.hdfoverview.HDFOverview(hdf_obj: bapsflib._hdf.utils.file.File)

Bases: object

Reports an overview of the HDF5 file mapping.

Parameters:hdf_obj (File) – HDF5 file object
control_discovery()

Prints a discovery report of the Control devices.

digitizer_discovery()

Prints a discovery report of the Digitizer devices.

msi_discovery()

Prints a discovery report of the MSI devices.

print()

Print full Overview Report.

static report_control_configs(control: bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate)

Prints to screen information about the passed control device configuration(s).

Parameters:control – a control device mapping object
report_controls(name=None)

Prints to screen a detailed report of detected control devices and their configuration(s).

Parameters:name (str) – name of control device. If None or name is not among controls, then all control devices are printed.
report_details()

Prints a detailed report of all detected MSI diagnostics, digitizers, and control devices.

static report_digitizer_configs(digi: bapsflib._hdf.maps.digitizers.templates.HDFMapDigiTemplate)

Prints to screen information about the passed digitizer configuration(s).

Parameters:digi – a digitizer mapping object
report_digitizers(name=None)

Prints to screen a report of detected digitizers and their configurations.

Parameters:name (str) – name of digitizer. If None or name is not among digitizers, then all digitizers are printed.
report_discovery()

Prints a discovery (brief) report of all detected MSI diagnostics, digitizers, and control devices.

report_general()

Prints general HDF5 file info.

report_msi(name=None)

Prints to screen a report of detected MSI diagnostics and their configurations.

Parameters:name (str) – name of MSI diagnostic. If None or name is not among MSI diagnostics, then all MSI diagnostics are printed.
static report_msi_configs(msi: bapsflib._hdf.maps.msi.templates.HDFMapMSITemplate)

Print to screan information about the passed MSI configuration.

Parameters:msi – a MSI mapping object
save(filename='')

Saves the HDF5 overview to a text file.

Parameters:filename (str) – name of text file to save the overview report generated by print().
unknowns_discovery()

Prints a discovery report of the Unknown devices.

bapsflib._hdf.utils.hdfoverview.status_print(first: str, second: str, third: str, indent=0, onetwo_pad=' ', second_tab=55)

Stylistic status printing for HDFOverview.

Parameters:
  • first – string for 1st column
  • second – string for 2nd column
  • third – string for 3rd column
  • indent (int) – num. of indentations for 1st column display
  • onetwo_pad (str) – one character string for pad style between 1st and 2nd column
  • second_tab (int) – number of characters between start of string and start of 2nd column
Example:
>>> status_print('one', 'two', 'three', second_tab=15)
one            two    three
>>> status_print('one', 'two', 'three', second_tab=15,
...              indent=2, onetwo_pad='~')
|   +-- one    two    three
bapsflib._hdf.utils.hdfreadcontrols

Classes

HDFReadControls Reads control device data from the HDF5 file.
class bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls

Bases: numpy.ndarray

Reads control device data from the HDF5 file.

This class constructs and returns a structured numpy array. The data in the array is grouped into two categories:

  1. shot numbers which are contained in the 'shotnum' field
  2. control device data which is represented by the remaining fields in the numpy array. These field names are polymorphic and are defined by the control device mapping class.

Data that is not shot number specific is stored in the info attribute.

Note

  • It is assumed that control data is always extracted with the intent of being matched to digitizer data.
  • Only one control for each ConType can be specified at a time.
  • It is assumed that there is only ONE dataset associated with each control device configuration.
  • If multiple device configurations are saved in the same HDF5 dataset (common in the ‘Waveform’ control device), then it is assumed that the configuration writing order is consistent for all recorded shot numbers. That is, if ‘config1’, ‘config2’, and ‘config3’ are recorded in that order for shot number 1, then that order is preserved for all recorded shot numbers.
Parameters:
  • hdf_file – HDF5 file object
  • controls (Union[str, Iterable[str, Tuple[str, Any]]]) – a list indicating the desired control device names and their configuration name (if more than one configuration exists)
  • shotnum (Union[int, List[int], slice, numpy.ndarray]) – HDF5 file shot number(s) indicating data entries to be extracted
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum and the shot numbers contained in each control device dataset. False will return the union instead of the intersection
Behavior of shotnum and intersection_set:
  • shotnum indexing starts at 1
  • Any shotnum values <= 0 will be thrown out
  • If intersection_set=True, then only data corresponding to shot numbers that are specified in shotnum and are in all control datasets will be returned
  • If intersection_set=False, then the returned array will have entries for all shot numbers specified in shotnum but entries that correspond to control datasets that do not have the specified shot number will be given a NULL value of -99999, 0, numpy.nan, or '', depending on the numpy.dtype.
Example:

Here the control device 'Waveform' is used as a basic example:

>>> # open HDF5 file
>>> f = bapsflib.lapd.File('test.hdf5')
>>>
>>> # read control data
>>> # - this is equivalent to 
>>> #   f.read_control(['Waveform', 'config01'])
>>> data = HDFReadControls(f, ['Waveform', 'config01'])
>>> data.dtype
dtype([('shotnum', '<u4'), ('command', '<U18')])
>>>
>>> # display shot numbers
>>> data['shotnum']
array([   1,    2,    3, ..., 6158, 6159, 6160], dtype=uint32)
>>>
>>> # show 'command' values for shot numbers 1 to 2
>>> data['command'][0:2:]
array(['FREQ 50000.000000', 'FREQ 50000.000000'],
      dtype='<U18')
info

A dictionary of meta-info for the control device.

bapsflib._hdf.utils.hdfreaddata

Classes

HDFReadData Reads digitizer and control device data from the HDF5 file.
class bapsflib._hdf.utils.hdfreaddata.HDFReadData

Bases: numpy.ndarray

Reads digitizer and control device data from the HDF5 file. Control device data is extracted using HDFReadControls and combined with the digitizer data.

This class constructs and returns a structured numpy array. The data in the array is grouped into three categories:

  1. shot numbers which are contained in the 'shotnum' field
  2. digitizer data which is contained in the 'signal' field
  3. control device data which is represented by the remaining fields in the numpy array. These field names are polymorphic and are defined by the control device mapping class. (see HDFReadControls for more detail)

Data that is not shot number specific is stored in the info attribute.

Note

  • Evey returned numpy array will have the 'xyz' field, which is reserved for probe position data. If a control device specifies this field, then field will be filled with the control device data;otherwise, the field will be filled with numpy.nan values.
Parameters:
  • hdf_file – HDF5 file object
  • board – analog-digital-converter board number
  • channel – analog-digital-converter channel number
  • index (Union[int, List[int], slice, numpy.ndarray]) – dataset row indices to be sliced (overridden by shotnum)
  • shotnum (Union[int, List[int], slice, numpy.ndarray]) – HDF5 file shot number(s) indicating data entries to be extracted (overrides index)
  • digitizer (str) – digitizer name
  • adc (str) – name of analog-digital-converter
  • config_name (str) – name of the digitizer configuration
  • keep_bits (bool) – set True to keep data in bits, False (DEFAULT) to convert data to voltage
  • add_controls – a list indicating the desired control device names and their configuration name (if more than one configuration exists)
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum and the shot numbers contained in each control device and digitizer dataset. False will return the union of shot numbers.

Behavior of index, shotnum and intersection_set:

Note

  • The shotnum keyword will always override the index keyword, but, due to extra overhead required for identifying shot number locations in the digitizer dataset, the index keyword will always execute quicker than the shotnum keyword.
Example:

Here data is extracted from the digitizer 'SIS crate' and position data is mated from the control device '6K Compumotor'.

>>> # open HDF5 file
>>> f = bapsflib.lapd.File('test.hdf5')
>>>
>>> # read digitizer data from board 1, channel 1,
>>> # - this is equivalent to 
>>> #   f.read_data(1, 1)
>>> data = HDFReadData(f, 1, 1)
>>> data.dtype
dtype([('shotnum', '<u4'), ('signal', '<f4', (100,)), 
      ('xyz', '<f4', (3,))])
>>>
>>> # display shot numbers
>>> data['shotnum']
array([  1,  2, ..., 98, 99], dtype=uint32)
>>>
>>> # show 'signal' values for shot number 1
>>> data['signal'][0]
array([-0.41381955, -0.4134333 , -0.4118886 , ..., -0.41127062,
       -0.4105754 , -0.41119337], dtype=float32)
>>>
>>> # show 'xyz' values for shot number 1
>>> data['xyz'][0]
array([nan, nan, nan], dtype=float32)
>>>
>>> # read digitizer data while adding '6K Compumotor' data
>>> # from receptacle (configuration) 3
>>> data = HDFReadData(f, 1, 1, 
                       add_controls=[('6K Compumotor', 3)])
>>> data.dtype
dtype([('shotnum', '<u4'), ('signal', '<f4', (100,)), 
       ('xyz', '<f4', (3,)), ('ptip_rot_theta', '<f8'), 
       ('ptip_rot_phi', '<f8')])
>>>
>>> # show 'xyz' values for shot number 1
>>> data['xyz'][0]
array([ -32. ,   15. , 1022.4], dtype=float32)
convert_signal(to_volt=False, to_bits=False, force=False)

converts signal from volts (bits) to bits (volts)

dt

Temporal step size (in sec) calculated from the 'clock rate' and 'sample average' items in info. Returns None if step size can not be calculated.

dv

Voltage step size (in volts) calculated from the 'bit' and 'voltage offset' items in info. Returns None if step size can not be calculated.

info

A dictionary of metadata for the extracted data. The dict() keys are:

hdf file str HDF5 file name the data was retrieved from
dataset name str name of the dataset
dataset path str path to said dataset in the HDF5 file
digitizer str digitizer group name
configuration name str name of data configuration
adc str analog-digital converter in which the data was recorded on
bit int bit resolution for the adc
clock rate (int, float) tuple containing clock rate, e.g. (100.0, ‘MHz’)
clock rate int (hardware sampling) number of data sample average together
shot average int (software averaging) number of shot sequences averaged together
board int board that the probe was connected to
channel int channel of the board that the probe was connected to
voltage offset float voltage offset of the digitized signal
probe name str name of deployed probe…empty for user to use at his/her discretion
port (int, str) 2-element tuple indicating which port the probe was deployed on, eg. (19, ‘W’)
plasma

Dictionary of plasma parameters. (All quantities are in cgs units except temperature is in eV)

Base Values
Bo magnetic field
kT temperature (generic)
kTe electron temperature
kTi ion temperature
gamma adiabatic index
m_e electron mass
m_i ion mass
n plasma number density
n_e electron number density
n_i ion number density
Z ion charge number
Calculated Values
fce electron cyclotron frequency
fci ion cyclotron frequency
fpe electron plasma frequency
fpi ion plasma frequency
fUH Upper-Hybrid Resonance frequency
lD Debye Length
lpe electron-inertial length
lpi ion-inertial length
rce electron gyroradius
rci ion gyroradius
cs ion sound speed
VA Alfven speed
vTe electron thermal velocity
vTi ion thermal velocity
set_plasma(Bo, kTe, kTi, m_i, n_e, Z, gamma=None, **kwargs)

Set plasma and add key frequency, length, and velocity parameters. (all quantities in cgs except temperature is in eV)

Parameters:
  • Bo (float) – magnetic field (in Gauss)
  • kTe (float) – electron temperature (in eV)
  • kTi (float) – ion temperature (in eV)
  • m_i (float) – ion mass (in g)
  • n_e (float) – electron number density (in cm^-3)
  • Z (int) – ion charge number
  • gamma (float) – adiabatic index (arb.)
set_plasma_value(key, value)

Re-define one of the base plasma values (Bo, gamma, kT, kTe, kTi, m_i, n, n_e, or Z) in the plasma dictionary.

Parameters:
  • key (str) – one of the base plasma values
  • value – value for key
bapsflib._hdf.utils.hdfreadmsi

Classes

HDFReadMSI Reads MSI diagnostic data from the HDF5 file.
class bapsflib._hdf.utils.hdfreadmsi.HDFReadMSI

Bases: numpy.ndarray

Reads MSI diagnostic data from the HDF5 file.

This class constructs and returns a structured numpy array. The data in the array is grouped in three categories:

  1. shot numbers which are contained in the 'shotnum' field
  2. metadata data that is both shot number and diagnostic specific which is stored in the sub-fields of the 'meta' field
  3. recorded data arrays which get unique fields based on their mapping configs attribute

Data that is not shot number specific is stored in the info attribute.

Parameters:
  • hdf_file (File) – HDF5 file object
  • dname (str) – name of desired MSI diagnostic
Example:

Here the 'Discharge' MSI diagnostic is used as an example:

>>> # open HDF5 file
>>> f = bapsflib.lapd.File('test.hdf5')
>>>
>>> # read MSI data
>>> # - this is equivalent to f.read_msi('Discharge')
>>> mdata = HDFReadMSI(f, 'Discharge')
>>> mdata.dtype
dtype([('shotnum', '<i4'),
       ('voltage', '<f4', (2048,)),
       ('current', '<f4', (2048,)),
       ('meta', [('timestamp', '<f8'),
                 ('data valid', 'i1'),
                 ('pulse length', '<f4'),
                 ('peak current', '<f4'),
                 ('bank voltage', '<f4')])])
>>> # display shot numbers
>>> mdata['shotnum']
array([    0, 19251], dtype=int32)
>>>
>>> # fields 'voltage' and 'current' belong to data arrays
>>> # - show first 3 elements of 'voltage' for shot number 0
>>> mdata['voltage'][0,0:3:]
array([-46.99707 , -46.844482, -46.99707], dtype=float32)
>>>
>>> # display peak current for shot number 0
>>> mdata['meta']['peak current'][0]
6127.1323
>>>
>>> # the `info` attribute has diagnostic specific data
>>> mdata.info
{'current conversion factor': [0.0],
 'device name': 'Discharge',
 'device group path': '/MSI/Discharge',
 'dt': [4.88e-05],
 'source file': '/foo/bar/test.hdf5',
 't0': [-0.0249856],
 'voltage conversion factor': [0.0]}
>>>
>>> # get time step for the data arrays
>>> mdata.info['dt'][0]
4.88e-05
info

A dictionary of meta-info for the MSI diagnostic.

bapsflib._hdf.utils.helpers

Helper functions that are utilized by the the HDF5 utility classes defined in module bapsflib._hdf.utils.

Functions

build_shotnum_dset_relation Compares the shotnum numpy array to the specified dataset, dset, to determine which indices contain the desired shot number(s) [for HDFReadControls].
build_sndr_for_complex_dset Compares the shotnum numpy array to the specified “complex” dataset, dset, to determine which indices contain the desired shot number(s).
build_sndr_for_simple_dset Compares the shotnum numpy array to the specified “simple” dataset, dset, to determine which indices contain the desired shot number(s).
condition_controls Conditions the controls argument for HDFReadControls and HDFReadData.
condition_shotnum Conditions the shotnum argument for HDFReadControls and HDFReadData.
do_shotnum_intersection Calculates intersection of shotnum and all existing dataset shot numbers, shotnum[sni].
bapsflib._hdf.utils.helpers.build_shotnum_dset_relation(shotnum: numpy.ndarray, dset: h5py._hl.dataset.Dataset, shotnumkey: str, cmap: Union[bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate, bapsflib._hdf.maps.controls.templates.HDFMapControlCLTemplate], cconfn: Any) → Tuple[numpy.ndarray, numpy.ndarray]

Compares the shotnum numpy array to the specified dataset, dset, to determine which indices contain the desired shot number(s) [for HDFReadControls]. As a results, two numpy arrays are returned which satisfy the rule:

shotnum[sni] = dset[index, shotnumkey]

where shotnum is the original shot number array, sni is a boolean numpy array masking which shot numbers were determined to be in the dataset, and index is an array of indices corresponding to the desired shot number(s).

Parameters:
  • shotnum – desired HDF5 shot number(s)
  • dset (h5py.Dataset) – control device dataset
  • shotnumkey (str) – field name in the control device dataset that contains shot numbers
  • cmap – mapping object for control device
  • cconfn – configuration name for the control device
Returns:

index and sni numpy arrays

Note

This function leverages the functions build_sndr_for_simple_dset() and build_sndr_for_complex_dset()

bapsflib._hdf.utils.helpers.build_sndr_for_complex_dset(shotnum: numpy.ndarray, dset: h5py._hl.dataset.Dataset, shotnumkey: str, cmap: Union[bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate, bapsflib._hdf.maps.controls.templates.HDFMapControlCLTemplate], cconfn: Any) → Tuple[numpy.ndarray, numpy.ndarray]

Compares the shotnum numpy array to the specified “complex” dataset, dset, to determine which indices contain the desired shot number(s). As a results, two numpy arrays are returned which satisfy the rule:

shotnum[sni] = dset[index, shotnumkey]

where shotnum is the original shot number array, sni is a boolean numpy array masking which shot numbers were determined to be in the dataset, and index is an array of indices corresponding to the desired shot number(s).

A “complex” dataset is a dataset in which the data for MULTIPLE configurations is recorded.

Dataset Assumption

There is an assumption that each shot number spans n_configs number of rows in the dataset, where n_configs is the number of control device configurations. It is also assumed that the order in which the configs are recorded is the same for each shot number. That is, if there are 3 configs (config01, config02, and config03) and the first three rows of the dataset are recorded in that order, then each following grouping of three rows will maintain that order.

Parameters:
  • shotnum – desired HDF5 shot number
  • dset (h5py.Dataset) – dataset containing shot numbers
  • shotnumkey (str) – field name in the dataset that contains the shot numbers
  • cmap – mapping object for control device
  • cconfn – configuration name for the control device
Returns:

index and sni numpy arrays

bapsflib._hdf.utils.helpers.build_sndr_for_simple_dset(shotnum: numpy.ndarray, dset: h5py._hl.dataset.Dataset, shotnumkey: str) → Tuple[numpy.ndarray, numpy.ndarray]

Compares the shotnum numpy array to the specified “simple” dataset, dset, to determine which indices contain the desired shot number(s). As a results, two numpy arrays are returned which satisfy the rule:

shotnum[sni] = dset[index, shotnumkey]

where shotnum is the original shot number array, sni is a boolean numpy array masking which shot numbers were determined to be in the dataset, and index is an array of indices corresponding to the desired shot number(s).

A “simple” dataset is a dataset in which the data for only ONE configuration is recorded.

Parameters:
  • shotnum – desired HDF5 shot number
  • dset (h5py.Dataset) – dataset containing shot numbers
  • shotnumkey (str) – field name in the dataset that contains the shot numbers
Returns:

index and sni numpy arrays

bapsflib._hdf.utils.helpers.condition_controls(hdf_file: bapsflib._hdf.utils.file.File, controls: Any) → List[Tuple[str, Any]]

Conditions the controls argument for HDFReadControls and HDFReadData.

Parameters:
  • hdf_file – HDF5 object instance
  • controlscontrols argument to be conditioned
Returns:

list containing tuple pairs of control device name and desired configuration name

Example:
>>> from bapsflib import lapd
>>> f = lapd.File('sample.hdf5')
>>> controls = ['Wavefrom', ('6K Compumotor', 3)]
>>> conditioned_controls = condition_controls(f, controls)
>>> conditioned_controls
[('Waveform', 'config01'), ('6K Compumotor', 3)]

Condition Criteria

  1. Input controls should be Union[str, Iterable[Union[str, Tuple[str, Any]]]]
  2. There can only be one control for each ConType.
  3. If a control has multiple configurations, then one must be specified.
  4. If a control has ONLY ONE configuration, then that will be assumed (and checked against the specified configuration).
bapsflib._hdf.utils.helpers.condition_shotnum(shotnum: Any, dset_dict: Dict[str, h5py._hl.dataset.Dataset], shotnumkey_dict: Dict[str, str]) → numpy.ndarray

Conditions the shotnum argument for HDFReadControls and HDFReadData.

Parameters:
  • shotnum – desired HDF5 shot numbers
  • dset_dict – dictionary of all control dataset instances
  • shotnumkey_dict – dictionary of the shot number field name for each control dataset in dset_dict
Returns:

conditioned shotnum numpy array

Condition Criteria

  1. Input shotnum should be Union[int, List[int,...], slice, np.ndarray]
  2. Any \(\mathbf{shotnum} \le 0\) will be removed.
  3. A ValueError will be thrown if the conditioned array is NULL.
bapsflib._hdf.utils.helpers.do_shotnum_intersection(shotnum: numpy.ndarray, sni_dict: Dict[str, numpy.ndarray], index_dict: Dict[str, numpy.ndarray]) → Tuple[numpy.ndarray, Dict[str, numpy.ndarray], Dict[str, numpy.ndarray]]

Calculates intersection of shotnum and all existing dataset shot numbers, shotnum[sni].

Parameters:
  • shotnum – desired HDF5 shot numbers
  • sni_dict – dictionary of all dataset sni arrays
  • index_dict – dictionary of all dataset index arrays
Returns:

intersected and re-calculated versions of index and sni numpy arrays

Recall Array Relationship

shotnum[sni] = dset[index, shotnumkey]

Classes

ConType Enum of Control Device Types
File Open a HDF5 file created at the Basic Plasma Science Facility.
HDFMap Constructs a complete file mapping of the HDF5 file.
class bapsflib._hdf.ConType

Bases: enum.Enum

Enum of Control Device Types

motion = 'motion'
power = 'power'
timing = 'timing'
waveform = 'waveform'
class bapsflib._hdf.File(name: str, mode='r', control_path='/', digitizer_path='/', msi_path='/', silent=False, **kwargs)

Bases: h5py._hl.files.File

Open a HDF5 file created at the Basic Plasma Science Facility.

All functionality of h5py.File is preserved (for details see http://docs.h5py.org/en/latest/)

Parameters:
  • name – name (and path) of file on disk
  • mode – readonly 'r' (DEFAULT) and read/write 'r+'
  • control_path – internal HDF5 path to group containing control devices
  • digitizer_path – internal HDF5 path to group containing digitizer devices
  • msi_path – internal HDF5 path to group containing MSI devices
  • silent – set True to suppress warnings (False DEFAULT)
  • kwargs – additional keywords passed on to h5py.File
Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5',
...          control_path='Raw data + config',
...          digitizer_path='Raw data + config',
...          msi_path='MSI')
>>> type(f)
bapsflib._hdf.utils.file.File
CONTROL_PATH = None

Internal HDF5 path for control devices. (DEFAULT '/')

DIGITIZER_PATH = None

Internal HDF5 path for digitizer devices. (DEFAULT '/')

MSI_PATH = None

Internal HDF5 path for MSI devices. (DEFAULT '/')

controls

Dictionary of control device mappings.

digitizers

Dictionary of digitizer device mappings

file_map

HDF5 file map (HDFMap)

info

Dictionary of general info on the HDF5 file and the experimental run.

msi

Dictionary of MSI device mappings.

overview

HDF5 file overview. (HDFOverview)

read_controls(controls: List[Union[str, Tuple[str, Any]]], shotnum=slice(None, None, None), intersection_set=True, silent=False, **kwargs)

Reads data from control device datasets. See HDFReadControls for more detail.

Parameters:
  • controls (List[Union[str, Tuple[str, Any]]]) – A list of strings and/or 2-element tuples indicating the control device(s). If a control device has only one configuration then only the device name 'control' needs to be passed in the list. If a control device has multiple configurations, then the device name and its configuration “name” needs to be passed as a tuple element ('control', 'config') in the list. (see condition_controls() for details)
  • shotnum (Union[int, list(int), slice(), numpy.array]) – HDF5 file shot number(s) indicating data entries to be extracted
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum and the shot numbers contained in each control device dataset. False will return the union instead of the intersection, minus \(shotnum \le 0\). (see HDFReadControls for details)
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadControls

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list control devices
>>> list(f.controls)
['6K Compumotor', 'Waveform']
>>>
>>> # list '6K Compumotor' configurations
>>> list(f.controls['6K Compumotor'].configs)
[2, 3]
>>>
>>> # extract all '6k Compumotor' data for configuration 3
>>> cdata = f.read_controls([('6K Compumotor', 3)])
>>> type(cdata)
bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls
>>>
>>> # list 'Waveform' configurations
>>> list(f.file_map.controls['Waveform'].configs)
['config01']
>>>
>>> # extract 'Waveform' data
>>> cdata = f.read_controls(['Waveform'])
>>> list(cdata.info['controls'])
['Waveform']
>>>
>>> # extract both 'Waveform' and '6K Compumotor'
>>> controls = ['Waveform', ('6K Compumotor', 2)]
>>> cdata = f.read_controls(controls)
>>> list(cdata.info['controls'])
['6K Compumotor', 'Waveform']
read_data(board: int, channel: int, index=slice(None, None, None), shotnum=slice(None, None, None), digitizer=None, adc=None, config_name=None, keep_bits=False, add_controls=None, intersection_set=True, silent=False, **kwargs)

Reads data from digitizer datasets and attaches control device data when requested. (see hdfreaddata.HDFReadData for details)

Parameters:
  • board – digitizer board number
  • channel – digitizer channel number
  • index (Union[int, list(int), slice(), numpy.array]) – dataset row index
  • shotnum (Union[int, list(int), slice(), numpy.array]) – HDF5 global shot number
  • digitizer (str) – name of digitizer
  • adc (str) – name of the digitizer’s analog-digital converter
  • config_name (str) – name of digitizer configuration
  • keep_bits (bool) – True to keep digitizer signal in bits, False (default) to convert digitizer signal to voltage
  • add_controls (List[Union[str, Tuple[str, Any]]]) – A list of strings and/or 2-element tuples indicating the control device(s). If a control device has only one configuration then only the device name 'control' needs to be passed in the list. If a control device has multiple configurations, then the device name and its configuration “name” needs to be passed as a tuple element ('control', 'config') in the list. (see condition_controls() for details)
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum, the digitizer dataset shot numbers, and, if requested, the shot numbers contained in each control device dataset. False will return the union instead of the intersection, minus \(shotnum \le 0\). (see HDFReadData for details)
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadData

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list control devices
>>> list(f.digitizers)
['SIS crate']
>>>
>>> # get active configurations
>>> f.digitizers['SIS crate'].configs
['config01', 'config02']
>>>
>>> # get active adc's for config
>>> f.digitizers['SIS crate'].configs['config01']['adc']
('SIS 3302,)
>>>
>>> # get first connected brd and channels to adc
>>> brd, chs = f.digitizers['SIS crate'].configs['config01'][
...     'SIS 3302'][0][0:2]
>>> brd
1
>>> chs
(1, 2, 3)
>>>
>>> # get data for brd = 1, ch = 1
>>> data = f.read_data(brd, chs[0],
...                    digitizer='SIS crate',
...                    adc='SIS 3302',
...                    config_name='config01')
>>> type(data)
bapsflib._hdf.utils.hdfreaddata.HDFReadData
>>>
>>> # Note: a quicker way to see how the digitizers are
>>> #       configured is to use
>>> #
>>> #       f.overview.report_digitizers()
>>> #
>>> #       which prints to screen a report of the
>>> #       digitizer hookup
read_msi(msi_diag: str, silent=False, **kwargs)

Reads data from MSI Diagnostic datasets. See HDFReadMSI for more detail.

Parameters:
  • msi_diag – name of MSI diagnostic
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadMSI

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list msi diagnostics
>>> list(f.msi)
['Interferometer array', 'Magnetic field']
>>>
>>> # read 'Interferometer array'
>>> mdata = f.read_msi('Interferometer array')
>>> type(mdata)
bapsflib._hdf.utils.hdfreadmsi.HDFReadMSI
class bapsflib._hdf.HDFMap(hdf_obj: h5py._hl.files.File, control_path: str, digitizer_path: str, msi_path: str)

Bases: object

Constructs a complete file mapping of the HDF5 file. This is utilized by the HDF5 utility classes (in module bapsflib._hdf.utils) to manipulate and read data out of the HDF5 file.

The following classes are leveraged to construct the mappings:

Parameters:
  • hdf_obj (h5py.File) – the HDF5 file object
  • control_path – internal HDF5 path to group containing control devices
  • digitizer_path – internal HDF5 path to group containing digitizers
  • msi_path – internal HDF5 path to group containing MSI diagnostics
controls

Dictionary of all the control device mapping objects.

Example:

How to retrieve the mapping object of the control device '6K Compumotor':

fmap = HDFMap(file_obj)
dmap = fmap.controls['6K Compumotor']
digitizers

Dictionary of all the digitizer device mapping objects.

Example:

How to retrieve the mapping object of the digitizer 'SIS 3301':

fmap = HDFMap(file_obj)
dmap = fmap.digitizers['SIS 3301']
get(name: str)

Get an device mapping instance.

Parameters:

name – name of desired device

Returns:

If the specified device is mapped, then an instance of the mapping is returned. Otherwise, None is returned.

Example:

How to retrieve the mapping object for the 'SIS 3301' digitizer:

>>> fmap = HDFMap(file_obj)
>>> dmap = fmap.get('SIS 3301')
>>>
>>> # which is equivalent to
>>> dmap = fmap.digitizers['SIS 3301']
main_digitizer
Returns:the mapping object for the digitizer that is assumed to be the main digitizer in digitizers

The main digitizer is determine by scanning through the local tuple possible_candidates that contains a hierarchical list of digitizers. The first digitizer found is assumed to be the main digitizer.

possible_candidates = ('SIS 3301', 'SIS crate')
msi

Dictionary of all the MSI diagnostic mapping objects.

Example:

How to retrieve the mapping object of the 'Magnetic field' MSI diagnostic:

fmap = HDFMap(file_obj)
dmap = fmap.msi['Magnetic field']
unknowns

List of all subgroup and dataset paths in the HDF5 root group, control device group, digitizer group, and MSI group that were not mapped.

bapsflib.lapd

The bapsflib.lapd package contains the necessary tools to access data relevant to and collected on the LaPD. The _hdf package focuses on accessing and reading data written to HDF5 files. The constants package contains constants relevant to the LaPD configuration (e.g. cathode diameters, port spacing, etc.). The tools package contains functions and classes relevant for calculating LaPD parameters (e.g. converting port number to axial z location, etc.).

bapsflib.lapd._hdf

The bapsflib.lapd._hdf package contains an assortment of tools to access and read out data written to HDF5 files by the LaPD.

bapsflib.lapd._hdf.file

Classes

File Open a HDF5 file created by the LaPD at BaPSF.
class bapsflib.lapd._hdf.file.File(name: str, mode='r', silent=False, **kwargs)

Bases: bapsflib._hdf.utils.file.File

Open a HDF5 file created by the LaPD at BaPSF.

Parameters:
  • name – name (and path) of file on disk
  • mode – readonly 'r' (DEFAULT) and read/write 'r+'
  • silent – set True to suppress warnings (False DEFAULT)
  • kwargs – additional keywords passed on to h5py.File
Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>> type(f)
bapsflib.lapd._hdf.file.File
>>> isinstance(f, bapsflib._hdf.utils.file.File)
True
>>> isinstance(f, h5py.File)
True
controls

Dictionary of control device mappings.

create_dataset_like(name, other, **kwupdate)

Create a dataset similar to other.

name
Name of the dataset (absolute or relative). Provide None to make an anonymous dataset.
other
The dataset which the new dataset should mimic. All properties, such as shape, dtype, chunking, … will be taken from it, but no data or attributes are being copied.

Any dataset keywords (see create_dataset) may be provided, including shape and dtype, in which case the provided values take precedence over those from other.

create_virtual_dataset(name, layout, fillvalue=None)

Create a new virtual dataset in this group.

Creates the virtual dataset from a list of virtual maps, any gaps are filled with a specified fill value.

name
(str) Name of the new dataset
virtual_target
Defines the sources for the virtual dataset
digitizers

Dictionary of digitizer device mappings

file_map

LaPD HDF5 file map (LaPDMap)

filename

File name on disk

info

Dictionary of general info on the HDF5 file and the experimental run.

msi

Dictionary of MSI device mappings.

overview

LaPD HDF5 file overview. (LaPDOverview)

read_controls(controls: List[Union[str, Tuple[str, Any]]], shotnum=slice(None, None, None), intersection_set=True, silent=False, **kwargs)

Reads data from control device datasets. See HDFReadControls for more detail.

Parameters:
  • controls (List[Union[str, Tuple[str, Any]]]) – A list of strings and/or 2-element tuples indicating the control device(s). If a control device has only one configuration then only the device name 'control' needs to be passed in the list. If a control device has multiple configurations, then the device name and its configuration “name” needs to be passed as a tuple element ('control', 'config') in the list. (see condition_controls() for details)
  • shotnum (Union[int, list(int), slice(), numpy.array]) – HDF5 file shot number(s) indicating data entries to be extracted
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum and the shot numbers contained in each control device dataset. False will return the union instead of the intersection, minus \(shotnum \le 0\). (see HDFReadControls for details)
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadControls

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list control devices
>>> list(f.controls)
['6K Compumotor', 'Waveform']
>>>
>>> # list '6K Compumotor' configurations
>>> list(f.controls['6K Compumotor'].configs)
[2, 3]
>>>
>>> # extract all '6k Compumotor' data for configuration 3
>>> cdata = f.read_controls([('6K Compumotor', 3)])
>>> type(cdata)
bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls
>>>
>>> # list 'Waveform' configurations
>>> list(f.file_map.controls['Waveform'].configs)
['config01']
>>>
>>> # extract 'Waveform' data
>>> cdata = f.read_controls(['Waveform'])
>>> list(cdata.info['controls'])
['Waveform']
>>>
>>> # extract both 'Waveform' and '6K Compumotor'
>>> controls = ['Waveform', ('6K Compumotor', 2)]
>>> cdata = f.read_controls(controls)
>>> list(cdata.info['controls'])
['6K Compumotor', 'Waveform']
read_data(board: int, channel: int, index=slice(None, None, None), shotnum=slice(None, None, None), digitizer=None, adc=None, config_name=None, keep_bits=False, add_controls=None, intersection_set=True, silent=False, **kwargs)

Reads data from digitizer datasets and attaches control device data when requested. (see hdfreaddata.HDFReadData for details)

Parameters:
  • board – digitizer board number
  • channel – digitizer channel number
  • index (Union[int, list(int), slice(), numpy.array]) – dataset row index
  • shotnum (Union[int, list(int), slice(), numpy.array]) – HDF5 global shot number
  • digitizer (str) – name of digitizer
  • adc (str) – name of the digitizer’s analog-digital converter
  • config_name (str) – name of digitizer configuration
  • keep_bits (bool) – True to keep digitizer signal in bits, False (default) to convert digitizer signal to voltage
  • add_controls (List[Union[str, Tuple[str, Any]]]) – A list of strings and/or 2-element tuples indicating the control device(s). If a control device has only one configuration then only the device name 'control' needs to be passed in the list. If a control device has multiple configurations, then the device name and its configuration “name” needs to be passed as a tuple element ('control', 'config') in the list. (see condition_controls() for details)
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum, the digitizer dataset shot numbers, and, if requested, the shot numbers contained in each control device dataset. False will return the union instead of the intersection, minus \(shotnum \le 0\). (see HDFReadData for details)
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadData

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list control devices
>>> list(f.digitizers)
['SIS crate']
>>>
>>> # get active configurations
>>> f.digitizers['SIS crate'].configs
['config01', 'config02']
>>>
>>> # get active adc's for config
>>> f.digitizers['SIS crate'].configs['config01']['adc']
('SIS 3302,)
>>>
>>> # get first connected brd and channels to adc
>>> brd, chs = f.digitizers['SIS crate'].configs['config01'][
...     'SIS 3302'][0][0:2]
>>> brd
1
>>> chs
(1, 2, 3)
>>>
>>> # get data for brd = 1, ch = 1
>>> data = f.read_data(brd, chs[0],
...                    digitizer='SIS crate',
...                    adc='SIS 3302',
...                    config_name='config01')
>>> type(data)
bapsflib._hdf.utils.hdfreaddata.HDFReadData
>>>
>>> # Note: a quicker way to see how the digitizers are
>>> #       configured is to use
>>> #
>>> #       f.overview.report_digitizers()
>>> #
>>> #       which prints to screen a report of the
>>> #       digitizer hookup
read_msi(msi_diag: str, silent=False, **kwargs)

Reads data from MSI Diagnostic datasets. See HDFReadMSI for more detail.

Parameters:
  • msi_diag – name of MSI diagnostic
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadMSI

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list msi diagnostics
>>> list(f.msi)
['Interferometer array', 'Magnetic field']
>>>
>>> # read 'Interferometer array'
>>> mdata = f.read_msi('Interferometer array')
>>> type(mdata)
bapsflib._hdf.utils.hdfreadmsi.HDFReadMSI
run_description()

Print description of the LaPD experimental run.

bapsflib.lapd._hdf.lapdmap

Classes

LaPDMap A specialized version of HDFMap which adds attributes that are specific to mapping a HDF5 file generated by the LaPD.
class bapsflib.lapd._hdf.lapdmap.LaPDMap(hdf_obj: h5py._hl.files.File, control_path='Raw data + config', digitizer_path='Raw data + config', msi_path='MSI')

Bases: bapsflib._hdf.maps.hdfmap.HDFMap

A specialized version of HDFMap which adds attributes that are specific to mapping a HDF5 file generated by the LaPD.

Parameters:
  • hdf_obj (h5py.File) – HDF5 file object
  • control_path (str) – internal HDF5 path to group containing control devices (DEFAULT 'Raw data + config')
  • digitizer_path (str) – internal HDF5 path to group containing digitizers (DEFAULT 'Raw data + config')
  • msi_path (str) – internal HDF5 path to group containing MSI diagnostics (DEFAULT 'MSI')
controls

Dictionary of all the control device mapping objects.

Example:

How to retrieve the mapping object of the control device '6K Compumotor':

fmap = HDFMap(file_obj)
dmap = fmap.controls['6K Compumotor']
digitizers

Dictionary of all the digitizer device mapping objects.

Example:

How to retrieve the mapping object of the digitizer 'SIS 3301':

fmap = HDFMap(file_obj)
dmap = fmap.digitizers['SIS 3301']
exp_info

Dictionary of experiment info

get(name: str)

Get an device mapping instance.

Parameters:

name – name of desired device

Returns:

If the specified device is mapped, then an instance of the mapping is returned. Otherwise, None is returned.

Example:

How to retrieve the mapping object for the 'SIS 3301' digitizer:

>>> fmap = HDFMap(file_obj)
>>> dmap = fmap.get('SIS 3301')
>>>
>>> # which is equivalent to
>>> dmap = fmap.digitizers['SIS 3301']
is_lapd

True if HDF5 file was generated by the LaPD

lapd_version

LaPD HDF5 version string.

main_digitizer
Returns:the mapping object for the digitizer that is assumed to be the main digitizer in digitizers

The main digitizer is determine by scanning through the local tuple possible_candidates that contains a hierarchical list of digitizers. The first digitizer found is assumed to be the main digitizer.

possible_candidates = ('SIS 3301', 'SIS crate')
msi

Dictionary of all the MSI diagnostic mapping objects.

Example:

How to retrieve the mapping object of the 'Magnetic field' MSI diagnostic:

fmap = HDFMap(file_obj)
dmap = fmap.msi['Magnetic field']
run_info

Dictionary of experimental run info.

unknowns

List of all subgroup and dataset paths in the HDF5 root group, control device group, digitizer group, and MSI group that were not mapped.

bapsflib.lapd._hdf.lapdoverview

Classes

LaPDOverview Reports an overview of the LaPD HDF5 file mapping.
class bapsflib.lapd._hdf.lapdoverview.LaPDOverview(hdf_obj: bapsflib.lapd._hdf.file.File)

Bases: bapsflib._hdf.utils.hdfoverview.HDFOverview

Reports an overview of the LaPD HDF5 file mapping.

Parameters:hdf_obj (File) – HDF5 file object
control_discovery()

Prints a discovery report of the Control devices.

digitizer_discovery()

Prints a discovery report of the Digitizer devices.

msi_discovery()

Prints a discovery report of the MSI devices.

print()

Print full Overview Report.

static report_control_configs(control: bapsflib._hdf.maps.controls.templates.HDFMapControlTemplate)

Prints to screen information about the passed control device configuration(s).

Parameters:control – a control device mapping object
report_controls(name=None)

Prints to screen a detailed report of detected control devices and their configuration(s).

Parameters:name (str) – name of control device. If None or name is not among controls, then all control devices are printed.
report_details()

Prints a detailed report of all detected MSI diagnostics, digitizers, and control devices.

static report_digitizer_configs(digi: bapsflib._hdf.maps.digitizers.templates.HDFMapDigiTemplate)

Prints to screen information about the passed digitizer configuration(s).

Parameters:digi – a digitizer mapping object
report_digitizers(name=None)

Prints to screen a report of detected digitizers and their configurations.

Parameters:name (str) – name of digitizer. If None or name is not among digitizers, then all digitizers are printed.
report_discovery()

Prints a discovery (brief) report of all detected MSI diagnostics, digitizers, and control devices.

report_general()

Prints general HDF5 file info.

report_msi(name=None)

Prints to screen a report of detected MSI diagnostics and their configurations.

Parameters:name (str) – name of MSI diagnostic. If None or name is not among MSI diagnostics, then all MSI diagnostics are printed.
static report_msi_configs(msi: bapsflib._hdf.maps.msi.templates.HDFMapMSITemplate)

Print to screan information about the passed MSI configuration.

Parameters:msi – a MSI mapping object
save(filename='')

Saves the HDF5 overview to a text file.

Parameters:filename (str) – name of text file to save the overview report generated by print().
unknowns_discovery()

Prints a discovery report of the Unknown devices.

bapsflib.lapd.constants

A package of relevant LaPD parameters and constants.

bapsflib.lapd.constants.constants

Classes

BaPSFConstant BaPSF Constant
SouthCathode Constants related to the South ‘main’ LaPD cathode.

Constants

port_spacing BaPSF Constant: nominal distance between LaPD ports
ref_port BaPSF Constant: LaPD \(z = 0\) reference port (most Northern port and \(+z\) points South towards south cathode)
class bapsflib.lapd.constants.constants.BaPSFConstant

Bases: astropy.constants.constant.Constant

BaPSF Constant

default_reference = 'Basic Plasma Science Facility'
class bapsflib.lapd.constants.constants.SouthCathode(operation_date=datetime.datetime(2019, 6, 1, 20, 6, 28, 776659))

Bases: object

Constants related to the South ‘main’ LaPD cathode.

Parameters:

operation_date (datetime.datetime) – Date the south ‘main’ cathode was operated (i.e. date of the experiment)

Example:
>>> import datetime
>>> MC = SouthCathode(datetime.date(2018, 1, 1))
anode_z

LaPD z location of the anode

cathode_descr

Brief description of the cathode

diameter

Diameter of LaPD’s south ‘main’ cathode

lifespan

Operational lifetime of cathode

operation_date

Date the south ‘main’ cathode was operated (i.e. date of the experiment)

z

LaPD z location of the cathode

bapsflib.lapd.constants.constants.port_spacing = <<class 'bapsflib.lapd.constants.constants.BaPSFConstant'> name='LaPD port spacing' value=31.95 uncertainty=1.0 unit='cm' reference='Basic Plasma Science Facility'>

BaPSF Constant: nominal distance between LaPD ports

bapsflib.lapd.constants.constants.ref_port = <<class 'bapsflib.lapd.constants.constants.BaPSFConstant'> name='LaPD reference port number' value=53 uncertainty=0 unit='' reference='Basic Plasma Science Facility'>

BaPSF Constant: LaPD \(z = 0\) reference port (most Northern port and \(+z\) points South towards south cathode)

Constants

port_spacing BaPSF Constant: nominal distance between LaPD ports
ref_port BaPSF Constant: LaPD \(z = 0\) reference port (most Northern port and \(+z\) points South towards south cathode)
bapsflib.lapd.constants.port_spacing = <<class 'bapsflib.lapd.constants.constants.BaPSFConstant'> name='LaPD port spacing' value=31.95 uncertainty=1.0 unit='cm' reference='Basic Plasma Science Facility'>

BaPSF Constant: nominal distance between LaPD ports

bapsflib.lapd.constants.ref_port = <<class 'bapsflib.lapd.constants.constants.BaPSFConstant'> name='LaPD reference port number' value=53 uncertainty=0 unit='' reference='Basic Plasma Science Facility'>

BaPSF Constant: LaPD \(z = 0\) reference port (most Northern port and \(+z\) points South towards south cathode)

bapsflib.lapd.tools

This package contains a variety of tools (functions, classes, etc.) relevant to the LaPD and its configuration.

bapsflib.lapd.tools.tools

Functions

portnum_to_z Converts LaPD port number to axial z location.
z_to_portnum Converts LaPD axial z location to port number.
bapsflib.lapd.tools.tools.portnum_to_z(portnum: Union[int, float]) → astropy.units.quantity.Quantity

Converts LaPD port number to axial z location.

Note

Port 53 defines z = 0 cm and is the most Northern port. The +z axis points South towards the main cathode.

bapsflib.lapd.tools.tools.z_to_portnum(z: Union[int, float, astropy.units.quantity.Quantity], unit='cm', round_to_nearest=False) → astropy.units.quantity.Quantity

Converts LaPD axial z location to port number.

Parameters:
  • z – axial z location
  • unit – string or astropy.units specifying unit type
  • round_to_nearest (bool) – False (DEFAULT), True will round the port number to the nearest full integer

Note

Port 53 defines z = 0 cm and is the most Northern port. The +z axis points South towards the main cathode.

Functions

portnum_to_z Converts LaPD port number to axial z location.
z_to_portnum Converts LaPD axial z location to port number.
bapsflib.lapd.tools.portnum_to_z(portnum: Union[int, float]) → astropy.units.quantity.Quantity

Converts LaPD port number to axial z location.

Note

Port 53 defines z = 0 cm and is the most Northern port. The +z axis points South towards the main cathode.

bapsflib.lapd.tools.z_to_portnum(z: Union[int, float, astropy.units.quantity.Quantity], unit='cm', round_to_nearest=False) → astropy.units.quantity.Quantity

Converts LaPD axial z location to port number.

Parameters:
  • z – axial z location
  • unit – string or astropy.units specifying unit type
  • round_to_nearest (bool) – False (DEFAULT), True will round the port number to the nearest full integer

Note

Port 53 defines z = 0 cm and is the most Northern port. The +z axis points South towards the main cathode.

Classes

bapsflib.lapd.File Open a HDF5 file created by the LaPD at BaPSF.
class bapsflib.lapd.File(name: str, mode='r', silent=False, **kwargs)

Bases: bapsflib._hdf.utils.file.File

Open a HDF5 file created by the LaPD at BaPSF.

Parameters:
  • name – name (and path) of file on disk
  • mode – readonly 'r' (DEFAULT) and read/write 'r+'
  • silent – set True to suppress warnings (False DEFAULT)
  • kwargs – additional keywords passed on to h5py.File
Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>> type(f)
bapsflib.lapd._hdf.file.File
>>> isinstance(f, bapsflib._hdf.utils.file.File)
True
>>> isinstance(f, h5py.File)
True
controls

Dictionary of control device mappings.

create_dataset_like(name, other, **kwupdate)

Create a dataset similar to other.

name
Name of the dataset (absolute or relative). Provide None to make an anonymous dataset.
other
The dataset which the new dataset should mimic. All properties, such as shape, dtype, chunking, … will be taken from it, but no data or attributes are being copied.

Any dataset keywords (see create_dataset) may be provided, including shape and dtype, in which case the provided values take precedence over those from other.

create_virtual_dataset(name, layout, fillvalue=None)

Create a new virtual dataset in this group.

Creates the virtual dataset from a list of virtual maps, any gaps are filled with a specified fill value.

name
(str) Name of the new dataset
virtual_target
Defines the sources for the virtual dataset
digitizers

Dictionary of digitizer device mappings

file_map

LaPD HDF5 file map (LaPDMap)

info

Dictionary of general info on the HDF5 file and the experimental run.

msi

Dictionary of MSI device mappings.

overview

LaPD HDF5 file overview. (LaPDOverview)

read_controls(controls: List[Union[str, Tuple[str, Any]]], shotnum=slice(None, None, None), intersection_set=True, silent=False, **kwargs)

Reads data from control device datasets. See HDFReadControls for more detail.

Parameters:
  • controls (List[Union[str, Tuple[str, Any]]]) – A list of strings and/or 2-element tuples indicating the control device(s). If a control device has only one configuration then only the device name 'control' needs to be passed in the list. If a control device has multiple configurations, then the device name and its configuration “name” needs to be passed as a tuple element ('control', 'config') in the list. (see condition_controls() for details)
  • shotnum (Union[int, list(int), slice(), numpy.array]) – HDF5 file shot number(s) indicating data entries to be extracted
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum and the shot numbers contained in each control device dataset. False will return the union instead of the intersection, minus \(shotnum \le 0\). (see HDFReadControls for details)
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadControls

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list control devices
>>> list(f.controls)
['6K Compumotor', 'Waveform']
>>>
>>> # list '6K Compumotor' configurations
>>> list(f.controls['6K Compumotor'].configs)
[2, 3]
>>>
>>> # extract all '6k Compumotor' data for configuration 3
>>> cdata = f.read_controls([('6K Compumotor', 3)])
>>> type(cdata)
bapsflib._hdf.utils.hdfreadcontrols.HDFReadControls
>>>
>>> # list 'Waveform' configurations
>>> list(f.file_map.controls['Waveform'].configs)
['config01']
>>>
>>> # extract 'Waveform' data
>>> cdata = f.read_controls(['Waveform'])
>>> list(cdata.info['controls'])
['Waveform']
>>>
>>> # extract both 'Waveform' and '6K Compumotor'
>>> controls = ['Waveform', ('6K Compumotor', 2)]
>>> cdata = f.read_controls(controls)
>>> list(cdata.info['controls'])
['6K Compumotor', 'Waveform']
read_data(board: int, channel: int, index=slice(None, None, None), shotnum=slice(None, None, None), digitizer=None, adc=None, config_name=None, keep_bits=False, add_controls=None, intersection_set=True, silent=False, **kwargs)

Reads data from digitizer datasets and attaches control device data when requested. (see hdfreaddata.HDFReadData for details)

Parameters:
  • board – digitizer board number
  • channel – digitizer channel number
  • index (Union[int, list(int), slice(), numpy.array]) – dataset row index
  • shotnum (Union[int, list(int), slice(), numpy.array]) – HDF5 global shot number
  • digitizer (str) – name of digitizer
  • adc (str) – name of the digitizer’s analog-digital converter
  • config_name (str) – name of digitizer configuration
  • keep_bits (bool) – True to keep digitizer signal in bits, False (default) to convert digitizer signal to voltage
  • add_controls (List[Union[str, Tuple[str, Any]]]) – A list of strings and/or 2-element tuples indicating the control device(s). If a control device has only one configuration then only the device name 'control' needs to be passed in the list. If a control device has multiple configurations, then the device name and its configuration “name” needs to be passed as a tuple element ('control', 'config') in the list. (see condition_controls() for details)
  • intersection_set (bool) – True (DEFAULT) will force the returned shot numbers to be the intersection of shotnum, the digitizer dataset shot numbers, and, if requested, the shot numbers contained in each control device dataset. False will return the union instead of the intersection, minus \(shotnum \le 0\). (see HDFReadData for details)
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadData

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list control devices
>>> list(f.digitizers)
['SIS crate']
>>>
>>> # get active configurations
>>> f.digitizers['SIS crate'].configs
['config01', 'config02']
>>>
>>> # get active adc's for config
>>> f.digitizers['SIS crate'].configs['config01']['adc']
('SIS 3302,)
>>>
>>> # get first connected brd and channels to adc
>>> brd, chs = f.digitizers['SIS crate'].configs['config01'][
...     'SIS 3302'][0][0:2]
>>> brd
1
>>> chs
(1, 2, 3)
>>>
>>> # get data for brd = 1, ch = 1
>>> data = f.read_data(brd, chs[0],
...                    digitizer='SIS crate',
...                    adc='SIS 3302',
...                    config_name='config01')
>>> type(data)
bapsflib._hdf.utils.hdfreaddata.HDFReadData
>>>
>>> # Note: a quicker way to see how the digitizers are
>>> #       configured is to use
>>> #
>>> #       f.overview.report_digitizers()
>>> #
>>> #       which prints to screen a report of the
>>> #       digitizer hookup
read_msi(msi_diag: str, silent=False, **kwargs)

Reads data from MSI Diagnostic datasets. See HDFReadMSI for more detail.

Parameters:
  • msi_diag – name of MSI diagnostic
  • silent (bool) – False (DEFAULT). Set True to ignore any UserWarnings (soft-warnings)
Return type:

HDFReadMSI

Example:
>>> # open HDF5 file
>>> f = File('sample.hdf5')
>>>
>>> # list msi diagnostics
>>> list(f.msi)
['Interferometer array', 'Magnetic field']
>>>
>>> # read 'Interferometer array'
>>> mdata = f.read_msi('Interferometer array')
>>> type(mdata)
bapsflib._hdf.utils.hdfreadmsi.HDFReadMSI
run_description()

Print description of the LaPD experimental run.

bapsflib.utils

Package of developer utilities.

bapsflib.utils.decorators

Decorators for the bapsflib package.

Functions

with_bf Context decorator for managing the opening and closing BaPSF HDF5 Files (bapsflib._hdf.utils.file.File).
with_lapdf Context decorator for managing the opening and closing LaPD HDF5 Files (bapsflib.lapd._hdf.file.File).
bapsflib.utils.decorators.with_bf(wfunc=None, *, filename: Optional[str] = None, control_path: Optional[str] = None, digitizer_path: Optional[str] = None, msi_path: Optional[str] = None)

Context decorator for managing the opening and closing BaPSF HDF5 Files (bapsflib._hdf.utils.file.File). An instance of the BaPSF HDF5 file is injected into the decorated function at the end of the positional arguments. The decorator is primarily designed for use on test methods, but can also be used as a function decorator.

Parameters:
  • wfunc – function or method to be wrapped
  • filename – name of the BaPSF HDF5 file
  • control_path – internal HDF5 path for control devices
  • digitizer_path – internal HDF5 path for digitizers
  • msi_path – internal HDF5 path for MSI devices
Example:

The HDF5 file parameters (filename, control_path, digitizer_path, and msi_path) can be passed to the decorator in three ways (listed by predominance):

  1. The wrapped function arguments.
  2. If the wrapped function is a method, then through appropriately named self attributes.
  3. The decorator keywords.

Defined with wrapped function arguments:

>>> # as function keywords
>>> @with_bf
... def foo(bf, **kwargs):
...     # * bf will be the HDF5 file object
...     # * do whatever is needed with bf and @with_bf will close
...     #   the file at the end
...     return bf.filename
>>> foo(filename='test.hdf5', control_path='Raw data + config',
...     digitizer_path='Raw data + config', msi_path='MSI')
'test.hdf5'
>>>
>>> # as a function argument
>>> @with_bf
... def foo(filename, bf, **kwargs):
...     # use bf
...     return bf.filename
... foo('test.hdf5')
'test.hdf5'

Defined with wrapped method attributes:

>>> # use `self` to pass file settings
>>> class BehaveOnFile:
...     def __init__(self):
...         super().__init__()
...         self.filename = 'test.hdf5'
...         self.control_path = 'Raw data + config'
...         self.digitizer_path = 'Raw data + config'
...         self.msi_path = 'MSI'
...
...     @with_bf
...     def foo(self, bf, **kwargs):
...         return bf.filename
>>> a = BehaveOnFile()
>>> a.foo()
'test.hdf5'
>>>
>>> # but keywords will still take precedence
>>> a.foo(filename='test_2.hdf5')
'test_2.hdf5'

Defined with decorator keywords:

>>> # as function keywords
>>> @with_bf(filename='test.hdf5',
...          control_path='Raw data + config',
...          digitizer_path='Raw data +config',
...          msi_path='MSI')
... def foo(bf, **kwargs):
...     return bf.filename
>>> foo()
'test.hdf5'
>>>
>>> # function keywords will still take precedence
>>> foo(filename='test_2.hdf5')
'test_2.hdf5'
bapsflib.utils.decorators.with_lapdf(wfunc=None, *, filename: Optional[str] = None)

Context decorator for managing the opening and closing LaPD HDF5 Files (bapsflib.lapd._hdf.file.File). An instance of the LaPD HDF5 file is injected into the decorated function at the end of the positional arguments. The decorator is primarily designed for use on test methods, but can also be used as a function decorator.

Parameters:
  • wfunc – function or method to be wrapped
  • filename – name of the BaPSF HDF5 file
Example:

The HDF5 filename can be passed to the decorator in three ways (listed by predominance):

  1. The wrapped function arguments.
  2. If the wrapped function is a method, then through the appropriately named self attributes.
  3. The decorator keywords.

Defined with wrapped function arguments:

>>> # as function keywords
>>> @with_lapdf
... def foo(lapdf, **kwargs):
...     # * bf will be the HDF5 file object
...     # * do whatever is needed with bf and @with_bf will close
...     #   the file at the end
...     return lapdf.filename
>>> foo(filename='test.hdf5')
'test.hdf5'
>>>
>>> # as a function argument
>>> @with_lapdf
... def foo(filename, lapdf, **kwargs):
...     # use bf
...     return lapdf.filename
... foo('test.hdf5')
'test.hdf5'

Defined with wrapped method attributes:

>>> # use `self` to pass file settings
>>> class BehaveOnFile:
...     def __init__(self):
...         super().__init__()
...         self.filename = 'test.hdf5'
...
...     @with_bf
...     def foo(self, lapdf, **kwargs):
...         return lapdf.filename
>>> a = BehaveOnFile()
>>> a.foo()
'test.hdf5'
>>>
>>> # but keywords will still take precedence
>>> a.foo(filename='test_2.hdf5')
'test_2.hdf5'

Defined with decorator keywords:

>>> # as function keywords
>>> @with_bf(filename='test.hdf5')
... def foo(lapdf, **kwargs):
...     return lapdf.filename
>>> foo()
'test.hdf5'
>>>
>>> # function keywords will still take precedence
>>> foo(filename='test_2.hdf5')
'test_2.hdf5'

Index

Module Index

Glossary

adc
analog-digital converter
BaPSF
Basic Plasma Science Facility
LaPD
Large Plasma Device