Reference

bruker_utils.parse_jcampdx(path: Path | str, convert_numerical_values: bool = True) dict

Retrieve parameters from files written in JCAMP-DX format.

Parameters:
  • path – The path to the parameter file.

  • convert_numerical_values – If True, all values which can be converted to numerical objects (int or float) will be converted from str.

Returns:

params – Parameters in the file.

Return type:

dict

Raises:

ValueError – If path does not exist in the filesystem.

Notes

There are two different parameters types which are stored in these files. One is for single values, and the other is for arrayed values.

Single-valued parameters are denoted like this:

##$SW_h= 5494.50549450549

These will appear in params as follows:

params = {..., 'SW_h': 5494.50549450549, ...}

Arrayed values are denoted like this:

##$P= (0..63)
10.8 10.8 21.6 0 0 19.8 30 60 20000 0 0 80000 80000 0 0
200000 1000 2500 10000 600 2500 0 0 0 0 250 0 10.8 1000
1200 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Each value in the array is separated by either a space or a newline. The values are stored in a list:

params = {...,
 'P': [10.8, 10.8, 21.6, 0, 0, 19.8, 30, 60, 20000, 0, 0,
       80000, 80000, 0, 0, 200000, 1000, 2500, 10000, 600,
       2500, 0, 0, 0, 0, 250, 0, 10.8, 1000, 1200, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 ...}

Example

>>> import bruker_utils as butils
>>> path = '/path/to/.../file' # Can be relative or absolute
>>> params = butils.parse_jcampdx(path)
>>> for key, value in params.items():
...     print(f'{key}:  {value}')
ACQT0:  -2.26890760309556
AMP:  [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
       100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
       100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
AMPCOIL:  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
AQSEQ:  0
AQ_mod:  3
AUNM:  <au_zg>
AUTOPOS:  <>
BF1:  500.13
BF2:  500.13
BF3:  500.13
BF4:  500.13
BF5:  500.13
BF6:  500.13
BF7:  500.13
BF8:  500.13
--snip--
YMAX_a:  5188289
YMIN_a:  -3815309
ZGOPTNS:  <>
ZL1:  120
ZL2:  120
ZL3:  120
ZL4:  120
scaledByNS:  no
scaledByRG:  no
class bruker_utils.BrukerDataset(directory: str = '.')

Represenation of a Bruker Dataset.

Parameters:

directory

Path to the directory containing the data.

Different files are expected to exist, dependent on the data type you are importing (note that .. denotes the parent directory of the preceeding directory):

  • 1D data

    • Raw FID

      • directory/fid

      • directory/acqus

    • Processed data

      • directory/1r

      • directory/../../acqus

      • directory/procs

  • 2D data

    • Raw FID

      • directory/ser

      • directory/acqus

      • directory/acqu2s

    • Processed data

      • directory/2rr

      • directory/../../acqus

      • directory/../../acqu2s

      • directory/procs

      • directory/proc2s

  • 3D data

    • Raw FID

      • directory/ser

      • directory/acqus

      • directory/acqu2s

      • directory/acqu3s

    • Processed data

      • directory/3rrr

      • directory/../../acqus

      • directory/../../acqu2s

      • directory/../../acqu3s

      • directory/procs

      • directory/proc2s

      • directory/proc3s

Raises:
  • IOError – If directory doesn’t exist.

  • ValueError – If directory does not contain the files expected of a Bruker dataset. See the description of the class for details.

static _all_paths_exist(files: Iterable[Path]) bool

Determine if all the paths in files exist.

Parameters:

files – File paths to check.

Returns:

allexistTrue is all paths exist, False if not.

Return type:

bool

static _compile_experiment_options(directory: Path) List[dict]

Generate information dictionaries for different experiment types.

Compiles dictionaries of information relavent to each experiment type.

Parameters:

directory – Path to the directory of interest.

Returns:

options – Infomation relating to each experiment option. Each item is a dictionary with the following entires:

  • 'files' - The expected paths to data and parameter files.

  • 'dim' - The data dimension.

  • 'dtype' - The type of data (time-domain or pdata).

Return type:

List[dict]

static _complexify(data: ndarray) ndarray

Make time-domain data complex.

Parameters:

data – Data to be converted to complex form.

Returns:

complex_data – Complex data.

Complex data is stored in the form [re[0], im[0], re[1], im[1], ...], This function takes an input with shape (2N,) and returns [re[0] + im[0]j, re[1] + im[1]j, ...] with shape (N,).

Return type:

numpy.ndarray

_determine_experiment_type(directory: Path) dict | None

Determine the type of Bruker data stored in directory.

This function is used to determine:

  1. whether the specified data is time-domain or pdata

  2. the dimension of the data (checks up to 3D).

If the data satisfies the required criteria for a particular experiment type, a dictionary of information will be returned. Otherwise, None will be returned.

Parameters:

directory – The path to the directory of interest.

Returns:

exptype – Dictionary with the entries:

  • 'dim' (int) The dimension of the data.

  • 'dtype' ('fid' or 'pdata') The type of data (raw time-domain or pdata).

  • 'files' (List[pathlib.Path]) Paths to data and parameter files.

Return type:

Union[dict, None]

static _remove_zeros(data: ndarray, shape: Iterable[int]) ndarray

Strip zeros from data.

Bruker ensures that each stored FID takes up a multiple of 1024 bytes of storage, even if TD is not a multiple of 256 (each datapoint takes either 4 or 8 bytes of space). To do this, each FID is padded with zeros. This function determines the number of trailing zeros and removes them.

Parameters:
  • data – Data to be treated. This should be a one-dimensional array with the number of elements matching the product of the elements in shape.

  • shape – The expected shape of the data.

Returns:

zeroless_data – Data with padded zeros removed.

Return type:

numpy.ndarray

static _repartition_data(data: ndarray, si: Iterable[int], xdim: Iterable[int]) ndarray

Correctly reorganise partitioned data.

Some data (typically older data) is stored in sub-matrix format, such that chucnks of the data are partitioned into smaller blocks. The XDIM parameters in the procs files dictate the size of each partition. This function takes in partitioned data and re-arranges it to the correct order.

Parameters:
  • data – Data to be repartitioned. This should be a one-dimensional array with the number of elements matching the product of the elements in shape.

  • si – The expected shapoe of the data.

  • xdim – The size of partitions in each dimension.

Returns:

repartitioned_data – Correctly repartitioned data.

Return type:

numpy.ndarray

property binary_format: str

Return the format of the binary datafiles.

Four possibilities:

  • '<i4' - Little endian, 32-bit integer.

  • '>i4' - Big endian, 32-bit integer.

  • '<f8' - Little endian, 64-bit float.

  • '>f8' - Big endian, 64-bit float.

property contours: Iterable[float] | None

Return a stored list of contour levels.

For multidimensional processed datasets, the file clevels is searched for, and if found, the contour levels stated in it are returned. If clevels could not be found, None is returned.

property data: ndarray

Return the data.

property dim: int

The number of experiment dimensions.

property directory: Path

Return the full path to the data directory.

property dtype: str

Return the type of data.

Will be either 'fid' or 'pdata'.

get_parameters(filenames: Iterable[str] | str | None = None) dict

Return parameters found in filenames.

Parameters:

filenames – Files to extract parameters from. If this is set to None, all valid files will be read.

Returns:

params – A dictionary containing the parameters of each file in sub-dictionaries.

Return type:

dict

Raises:
  • TypeError – If filenames has an invalid type. It should be None, a str, or an iterable object (list, tuple, set, etc.) of str objects.

  • ValueError – If at least one value in filenames is invalid.

Notes

To determine the list of valid names for filenames, you can use valid_parameter_filenames():

>>> import bruker_utils as butils
>>> # This is a 2-dimensional processed dataset
>>> dataset = butils.BrukerDataset(<path>)
>>> print(dataset.valid_parameter_filenames)
['acqus', 'acqu2s', 'procs', 'proc2s']
get_samples(pdata_unit: str = 'ppm', meshgrid: bool = True) Iterable[ndarray]

Return the points at which the data is sampled.

For time-domain data, this will return the timepoints at which the FID was sampeld. For processed data, this will return the chemical shifts.

Parameters:
  • pdata_unit – The unit to expressed the chemical shifts if, if the dataset corresponds to processed data. Valid options are 'ppm' or 'hz'.

  • meshgrid – If True, samples for multidimensional experiments will be arrayed using numpy.meshgrid.

Returns:

samples – The samples in each dimension.

Return type:

Iterable[np.ndarray]

Notes

For data with more than 1 dimension, the returned object is a list of arrays with the same shape as the data, formed by using numpy.meshgrid, making the output very convienient for plotting pourposes.

property valid_parameter_filenames: List[str]

Return a list of parameter filenames.

The elements are a complete set of the valid strings for the filenames argument in get_parameters().