Source code for spec2nexus.utils

# -*- coding: utf-8 -*-

"""
(internal library) common methods used in **spec2nexus** modules

.. autosummary::

    ~clean_name
    ~iso8601
    ~strip_first_word
    ~sanitize_name
    ~reshape_data

"""

import logging
import numpy
import re
import time


logger = logging.getLogger(__name__)


[docs]def clean_name(key): """ create a name that is allowed by both HDF5 and NeXus rules :param str key: identifying string from SPEC data file :see: http://download.nexusformat.org/doc/html/datarules.html The "sanitized" name fits this regexp:: [A-Za-z_][\w_]* An easier expression might be: ``[\w_]*`` but this will not pass the rule that valid NeXus group or field names cannot start with a digit. """ replacement = "_" noncompliance = r"[^\w_]" txt = replacement.join( re.split(noncompliance, key) ) # replace ALL non-compliances with '_' if txt[0].isdigit(): txt = replacement + txt # can't start with a digit return txt
[docs]def iso8601(date): """ convert SPEC time (example: Wed Nov 03 13:39:34 2010) into ISO8601 string :param str date: time string from SPEC data file **Example** :SPEC: Wed Nov 03 13:39:34 2010 :ISO8601: 2010-11-03T13:39:34 :SPOCK: 09/15/17 04:39:10 :ISO8601: 2017-09-15T04:39:10 """ spec_fmt = "%a %b %d %H:%M:%S %Y" try: t_obj = time.strptime(date, spec_fmt) except ValueError: spock_fmt = "%m/%d/%y %H:%M:%S" try: t_obj = time.strptime(date, spock_fmt) except ValueError as ex: raise ex iso_fmt = "%Y-%m-%dT%H:%M:%S" iso = time.strftime(iso_fmt, t_obj) return iso
[docs]def strip_first_word(line): """return everything after the first space on the line from the spec data file""" pos = line.find(" ") val = line[pos:] return val.strip()
[docs]def split_column_labels(text): """SPEC labels may contain one space""" return re.split(" +", text.replace("\t", " "))
[docs]def sanitize_name(group, key): # for legacy support only """make name that is allowed by HDF5 and NeXus rules :note: **deprecated** use :func:`clean_name` instead (``group`` is never used) :param str group: unused :param str key: identifying string from SPEC data file :see: http://download.nexusformat.org/doc/html/datarules.html sanitized name fits this regexp:: [A-Za-z_][\w_]* An easier expression might be: ``[\w_]*`` but this will not pass the rule that valid names cannot start with a digit. """ return clean_name(key)
[docs]def reshape_data(scan_data, scan_shape): """ Shape scan data from raw to different dimensionality Some SPEC macros collect data in a mesh or grid yet report the data as a 1-D sequence of observations. For further processing (such as plotting), the scan data needs to be reshaped according to its intended dimensionality. modified from nexpy.readers.readspec.reshape_data """ scan_size = numpy.prod(scan_shape) if scan_data.size == scan_size: data = scan_data elif scan_data.size < scan_size: data = numpy.empty(scan_size) data.fill(numpy.NaN) # pad data with NaN data[0: scan_data.size] = scan_data.ravel() # flatten & insert else: data = scan_data.ravel() # flatten data = data[0:scan_size] # truncate extra data return data.reshape(scan_shape)
# ----------------------------------------------------------------------------- # :author: Pete R. Jemian # :email: prjemian@gmail.com # :copyright: (c) 2014-2022, Pete R. Jemian # # Distributed under the terms of the Creative Commons Attribution 4.0 International Public License. # # The full license is in the file LICENSE.txt, distributed with this software. # -----------------------------------------------------------------------------