summaryrefslogtreecommitdiff
path: root/silx/io
diff options
context:
space:
mode:
authorPicca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>2017-08-18 14:48:52 +0200
committerPicca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>2017-08-18 14:48:52 +0200
commitf7bdc2acff3c13a6d632c28c4569690ab106eed7 (patch)
tree9d67cdb7152ee4e711379e03fe0546c7c3b97303 /silx/io
Import Upstream version 0.5.0+dfsg
Diffstat (limited to 'silx/io')
-rw-r--r--silx/io/__init__.py45
-rw-r--r--silx/io/configdict.py540
-rw-r--r--silx/io/dictdump.py366
-rw-r--r--silx/io/fabioh5.py1151
-rw-r--r--silx/io/nxdata.py535
-rw-r--r--silx/io/octaveh5.py176
-rw-r--r--silx/io/setup.py88
-rw-r--r--silx/io/specfile/include/Lists.h51
-rw-r--r--silx/io/specfile/include/SpecFile.h291
-rw-r--r--silx/io/specfile/include/SpecFileCython.h28
-rw-r--r--silx/io/specfile/include/SpecFileP.h74
-rw-r--r--silx/io/specfile/include/locale_management.h23
-rw-r--r--silx/io/specfile/specfile.c21782
-rw-r--r--silx/io/specfile/specfile.pyx1273
-rw-r--r--silx/io/specfile/specfile_wrapper.pxd77
-rw-r--r--silx/io/specfile/src/locale_management.c64
-rw-r--r--silx/io/specfile/src/sfdata.c775
-rw-r--r--silx/io/specfile/src/sfheader.c787
-rw-r--r--silx/io/specfile/src/sfindex.c551
-rw-r--r--silx/io/specfile/src/sfinit.c827
-rw-r--r--silx/io/specfile/src/sflabel.c649
-rw-r--r--silx/io/specfile/src/sflists.c184
-rw-r--r--silx/io/specfile/src/sfmca.c336
-rw-r--r--silx/io/specfile/src/sftools.c550
-rw-r--r--silx/io/specfile/src/sfwrite.c587
-rw-r--r--silx/io/specfilewrapper.py371
-rw-r--r--silx/io/spech5.py1634
-rw-r--r--silx/io/spectoh5.py304
-rw-r--r--silx/io/test/__init__.py53
-rw-r--r--silx/io/test/test_dictdump.py249
-rw-r--r--silx/io/test/test_fabioh5.py236
-rw-r--r--silx/io/test/test_nxdata.py305
-rw-r--r--silx/io/test/test_octaveh5.py165
-rw-r--r--silx/io/test/test_specfile.py431
-rw-r--r--silx/io/test/test_specfilewrapper.py220
-rw-r--r--silx/io/test/test_spech5.py820
-rw-r--r--silx/io/test/test_spectoh5.py197
-rw-r--r--silx/io/test/test_utils.py510
-rw-r--r--silx/io/utils.py500
39 files changed, 37805 insertions, 0 deletions
diff --git a/silx/io/__init__.py b/silx/io/__init__.py
new file mode 100644
index 0000000..4e3cace
--- /dev/null
+++ b/silx/io/__init__.py
@@ -0,0 +1,45 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""I/O modules"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "20/01/2017"
+
+
+import logging
+
+
+# Init logging once for the whole module
+logging.basicConfig()
+
+from .utils import open # pylint:disable=redefined-builtin
+from .utils import save1D
+
+from .utils import is_dataset
+from .utils import is_file
+from .utils import is_group
+
+__all__ = ["save1D", "is_dataset", "is_file", "is_group"] # avoid to import open with "import *"
diff --git a/silx/io/configdict.py b/silx/io/configdict.py
new file mode 100644
index 0000000..21e24b7
--- /dev/null
+++ b/silx/io/configdict.py
@@ -0,0 +1,540 @@
+# /*##########################################################################
+# Copyright (C) 2004-2016 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""
+This module handles read and write operations to INI files, with data type
+preservation and support for nesting subsections to any depth.
+
+Data to be written to INI must be stored in a dictionary with string keys.
+Data cannot be stored at the root level of the dictionary, it must be inside
+a sub-dictionary. This means that in the INI file, all parameters must be
+in a section, and if you need a `default` section you must define it
+explicitly.
+
+Usage example:
+==============
+
+Write a dictionary to an INI file::
+
+ from silx.io.configdict import ConfigDict
+
+ ddict = {
+ 'simple_types': {
+ 'float': 1.0,
+ 'int': 1,
+ 'string': 'Hello World',
+ },
+ 'containers': {
+ 'list': [-1, 'string', 3.0, False],
+ 'array': numpy.array([1.0, 2.0, 3.0]),
+ 'dict': {
+ 'key1': 'Hello World',
+ 'key2': 2.0,
+ }
+ }
+ }
+
+ ConfigDict(initdict=ddict).write("foo.ini")
+
+
+Read an INI file into a dictionary like structure::
+
+ from silx.io.configdict import ConfigDict
+
+ confdict = ConfigDict()
+ confdict.read("foo.ini")
+
+ print("Available sections in INI file:")
+ print(confdict.keys())
+
+ for key in confdict:
+ for subkey in confdict[key]:
+ print("Section %s, parameter %s:" % (key, subkey))
+ print(confdict[key][subkey])
+
+
+Classes:
+========
+
+- :class:`ConfigDict`
+- :class:`OptionStr`
+
+"""
+
+
+__author__ = ["E. Papillon", "V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+
+from collections import OrderedDict
+import numpy
+import re
+import sys
+if sys.version < '3.0':
+ import ConfigParser as configparser
+else:
+ import configparser
+
+
+string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+
+
+def _boolean(sstr):
+ """Coerce a string to a boolean following the same convention as
+ :meth:`configparser.ConfigParser.getboolean`:
+ - '1', 'yes', 'true' and 'on' cause this function to return ``True``
+ - '0', 'no', 'false' and 'off' cause this function to return ``False``
+
+ :param sstr: String representation of a boolean
+ :return: ``True`` or ``False``
+ :raise: ``ValueError`` if ``sstr`` is not a valid string representation
+ of a boolean
+ """
+ if sstr.lower() in ['1', 'yes', 'true', 'on']:
+ return True
+ if sstr.lower() in ['0', 'no', 'false', 'off']:
+ return False
+ msg = "Cannot coerce string '%s' to a boolean value. " % sstr
+ msg += "Valid boolean strings: '1', 'yes', 'true', 'on', "
+ msg += "'0', 'no', 'false', 'off'"
+ raise ValueError(msg)
+
+
+def _parse_simple_types(sstr):
+ """Coerce a string representation of a value to the most appropriate data
+ type, by trial and error.
+
+ Typecasting is attempted to following data types (in this order):
+ `int`, `float`, `boolean`. If all of these conversions fail, ``sstr``
+ is assumed to be a string.
+
+ :param sstr: String representation of an unknown data type
+ :return: Value coerced into the most appropriate data type
+ """
+ try:
+ return int(sstr)
+ except ValueError:
+ try:
+ return float(sstr)
+ except ValueError:
+ try:
+ return _boolean(sstr)
+ except ValueError:
+ if sstr.strip() == "None":
+ return None
+ # un-escape string
+ sstr = sstr.lstrip("\\")
+ # un-escape commas
+ sstr = sstr.replace("\,", ",").replace("^@", ",")
+ return sstr
+
+
+def _parse_container(sstr):
+ """Parse a string representation of a list or a numpy array.
+
+ A string such as ``"-1, Hello World, 3.0"`` is interpreted as the list
+ ``[-1, "Hello World", 3.0]``. ``"-1, "no", 3.0\n\t1, 2"`` is interpreted
+ a list of 2 lists ``[[-1, False, 3.0], [1, 2]]``
+
+ Strings such as ``"[ [ 1. 2. 3.] [ 4. 5. 6.] ]"`` or
+ ``[ 1.0 2.0 3.0 ]`` are interpreted as numpy arrays. Only 1D and 2D
+ arrays are permitted.
+
+ :param sstr: String representation of an container type
+ :return: List or array
+ :raise: ``ValueError`` if string is not a list or an array
+ """
+ sstr = sstr.strip()
+
+ if not sstr:
+ raise ValueError
+
+ if sstr.find(',') == -1:
+ # it is not a list
+ if (sstr[0] == '[') and (sstr[-1] == ']'):
+ # this looks like an array
+ try:
+ # try parsing as a 1D array
+ return numpy.array([float(x) for x in sstr[1:-1].split()])
+ except ValueError:
+ # try parsing as a 2D array
+ if (sstr[2] == '[') and (sstr[-3] == ']'):
+ nrows = len(sstr[3:-3].split('] ['))
+ data = sstr[3:-3].replace('] [', ' ')
+ data = numpy.array([float(x) for x in
+ data.split()])
+ data.shape = nrows, -1
+ return data
+ # not a list and not an array
+ raise ValueError
+ else:
+ # if all commas are escaped, it is a strinq, not a list
+ if sstr.count(",") == sstr.count("\,"):
+ raise ValueError
+
+ dataline = [line for line in sstr.splitlines()]
+ if len(dataline) == 1:
+ return _parse_list_line(dataline[0])
+ else:
+ return [_parse_list_line(line) for line in dataline]
+
+
+def _parse_list_line(sstr):
+ """Parse the string representation of a simple 1D list:
+
+ ``"12, 13.1, True, Hello"`` ``->`` ``[12, 13.1, True, "Hello"]``
+
+ :param sstr: String
+ :return: List
+ """
+ sstr = sstr.strip()
+
+ # preserve escaped commas in strings before splitting list
+ # (_parse_simple_types recognizes ^@ as a comma)
+ sstr.replace("\,", "^@")
+ # it is a list
+ if sstr.endswith(','):
+ if ',' in sstr[:-1]:
+ return [_parse_simple_types(sstr2.strip())
+ for sstr2 in sstr[:-1].split(',')]
+ else:
+ return [_parse_simple_types(sstr[:-1].strip())]
+ else:
+ return [_parse_simple_types(sstr2.strip())
+ for sstr2 in sstr.split(',')]
+
+
+class OptionStr(str):
+ """String class providing typecasting methods to parse values in a
+ :class:`ConfigDict` generated configuration file.
+ """
+ def toint(self):
+ """
+ :return: integer
+ :raise: ``ValueError`` if conversion to ``int`` failed
+ """
+ return int(self)
+
+ def tofloat(self):
+ """
+ :return: Floating point value
+ :raise: ``ValueError`` if conversion to ``float`` failed
+ """
+ return float(self)
+
+ def toboolean(self):
+ """
+ '1', 'yes', 'true' and 'on' are interpreted as ``True``
+
+ '0', 'no', 'false' and 'off' are interpreted as ``False``
+
+ :return: Boolean
+ :raise: ``ValueError`` if conversion to ``bool`` failed
+ """
+ return _boolean(self)
+
+ def tostr(self):
+ """Return string after replacing escaped commas ``\,`` with regular
+ commas ``,`` and removing leading backslash.
+
+ :return: str(self)
+ """
+ return str(self.replace("\,", ",").lstrip("\\"))
+
+ def tocontainer(self):
+ """Return a list or a numpy array.
+
+ Any string containing a comma (``,``) character will be interpreted
+ as a list: for instance ``-1, Hello World, 3.0``, or ``2.0,``
+
+ The format for numpy arrays is a blank space delimited list of values
+ between square brackets: ``[ 1.3 2.2 3.1 ]``, or
+ ``[ [ 1 2 3 ] [ 1 4 9 ] ]``"""
+ return _parse_container(self)
+
+ def tobestguess(self):
+ """Parse string without prior knowledge of type.
+
+ Conversion to following types is attempted, in this order:
+ `list`, `numpy array`, `int`, `float`, `boolean`.
+ If all of these conversions fail, the string is returned after
+ removing escape characters.
+ """
+ try:
+ return _parse_container(self)
+ except ValueError:
+ return _parse_simple_types(self)
+
+
+class ConfigDict(OrderedDict):
+ """Store configuration parameters as an ordered dictionary.
+
+ Parameters can be grouped into sections, by storing them as
+ sub-dictionaries.
+
+ Keys must be strings. Values can be: integers, booleans, lists,
+ numpy arrays, floats, strings.
+
+ Methods are provided to write a configuration file in a variant of INI
+ format. A :class:`ConfigDict` can load (or be initialized from) a list of files.
+
+ The main differences between files written/read by this class and standard
+ ``ConfigParser`` files are:
+
+ - sections can be nested to any depth
+ - value types are guessed when the file is read back
+ - to prevent strings from being interpreted as lists, commas are
+ escaped with a backslash (``\,``)
+ - strings may be prefixed with a leading backslash (``\``) to prevent
+ conversion to numeric or boolean values
+
+ :param defaultdict: Default dictionary used to initialize the
+ :class:`ConfigDict` instance and reinitialize it in case
+ :meth:`reset` is called
+ :param initdict: Additional initialisation dictionary, added into dict
+ after initialisation with ``defaultdict``
+ :param filelist: List of configuration files to be read and added into
+ dict after ``defaultdict`` and ``initdict``
+ """
+ def __init__(self, defaultdict=None, initdict=None, filelist=None):
+ self.default = defaultdict if defaultdict is not None else OrderedDict()
+ OrderedDict.__init__(self, self.default)
+ self.filelist = []
+
+ if initdict is not None:
+ self.update(initdict)
+ if filelist is not None:
+ self.read(filelist)
+
+ def reset(self):
+ """ Revert to default values
+ """
+ self.clear()
+ self.update(self.default)
+
+ def clear(self):
+ """ Clear dictionnary
+ """
+ OrderedDict.clear(self)
+ self.filelist = []
+
+ def __tolist(self, mylist):
+ """ If ``mylist` is not a list, encapsulate it in a list and return
+ it.
+
+ :param mylist: List to encapsulate
+ :returns: ``mylist`` if it is a list, ``[mylist]`` if it isn't
+ """
+ if mylist is None:
+ return None
+ if not isinstance(mylist, list):
+ return [mylist]
+ else:
+ return mylist
+
+ def getfiles(self):
+ """Return list of configuration file names"""
+ return self.filelist
+
+ def getlastfile(self):
+ """Return last configuration file name"""
+ return self.filelist[len(self.filelist) - 1]
+
+ def __convert(self, option):
+ """Used as ``configparser.ConfigParser().optionxform`` to transform
+ option names on every read, get, or set operation.
+
+ This overrides the default :mod:`ConfigParser` behavior, in order to
+ preserve case rather converting names to lowercase.
+
+ :param option: Option name (any string)
+ :return: ``option`` unchanged
+ """
+ return option
+
+ def read(self, filelist, sections=None):
+ """
+ Read all specified configuration files into the internal dictionary.
+
+ :param filelist: List of names of files to be added into the internal
+ dictionary
+ :param sections: If not ``None``, add only the content of the
+ specified sections
+ :type sections: list
+ """
+ filelist = self.__tolist(filelist)
+ sections = self.__tolist(sections)
+ cfg = configparser.ConfigParser()
+ cfg.optionxform = self.__convert
+ cfg.read(filelist)
+ self.__read(cfg, sections)
+
+ for ffile in filelist:
+ self.filelist.append([ffile, sections])
+
+ def __read(self, cfg, sections=None):
+ """Read a :class:`configparser.ConfigParser` instance into the
+ internal dictionary.
+
+ :param cfg: Instance of :class:`configparser.ConfigParser`
+ :param sections: If not ``None``, add only the content of the
+ specified sections into the internal dictionary
+ """
+ cfgsect = cfg.sections()
+
+ if sections is None:
+ readsect = cfgsect
+ else:
+ readsect = [sect for sect in cfgsect if sect in sections]
+
+ for sect in readsect:
+ ddict = self
+ for subsectw in sect.split('.'):
+ subsect = subsectw.replace("_|_", ".")
+ if not subsect in ddict:
+ ddict[subsect] = OrderedDict()
+ ddict = ddict[subsect]
+ for opt in cfg.options(sect):
+ ddict[opt] = self.__parse_data(cfg.get(sect, opt))
+
+ def __parse_data(self, data):
+ """Parse an option returned by ``ConfigParser``.
+
+ :param data: Option string to be parsed
+
+ The original option is a string, we try to parse it as one of
+ following types: `numpx array`, `list`, `float`, `int`, `boolean`,
+ `string`
+ """
+ return OptionStr(data).tobestguess()
+
+ def tostring(self):
+ """Return INI file content generated by :meth:`write` as a string
+ """
+ import StringIO
+ tmp = StringIO.StringIO()
+ self.__write(tmp, self)
+ return tmp.getvalue()
+
+ def write(self, ffile):
+ """Write the current dictionary to the given filename or
+ file handle.
+
+ :param ffile: Output file name or file handle. If a file name is
+ provided, the method opens it, writes it and closes it again.
+ """
+ if not hasattr(ffile, "write"):
+ fp = open(ffile, "w")
+ else:
+ fp = ffile
+
+ self.__write(fp, self)
+
+ if not hasattr(ffile, "write"):
+ fp.close()
+
+ def _escape_str(self, sstr):
+ """Escape strings and special characters in strings with a ``\``
+ character to ensure they are read back as strings and not parsed.
+
+ :param sstr: String to be escaped
+ :returns sstr: String with escape characters (if needed)
+
+ This way, we ensure these strings cannot be interpreted as a numeric
+ or boolean types and commas in strings are not interpreted as list
+ items separators. We also escape ``%`` when it is not followed by a
+ ``(``, as required by :mod:`configparser` because ``%`` is used in
+ the interpolation syntax
+ (https://docs.python.org/3/library/configparser.html#interpolation-of-values).
+ """
+ non_str = r'^([0-9]+|[0-9]*\.[0-9]*|none|false|true|on|off|yes|no)$'
+ if re.match(non_str, sstr.lower()):
+ sstr = "\\" + sstr
+ # Escape commas
+ sstr = sstr.replace(",", "\,")
+
+ if sys.version > '3.0':
+ # Escape % characters except in "%%" and "%("
+ sstr = re.sub(r'%([^%\(])', r'%%\1', sstr)
+
+ return sstr
+
+ def __write(self, fp, ddict, secthead=None):
+ """Do the actual file writing when called by the ``write`` method.
+
+ :param fp: File handle
+ :param ddict: Dictionary to be written to file
+ :param secthead: Prefix for section name, used for handling nested
+ dictionaries recursively.
+ """
+ dictkey = []
+
+ for key in ddict.keys():
+ if hasattr(ddict[key], 'keys'):
+ # subsections are added at the end of a section
+ dictkey.append(key)
+ elif isinstance(ddict[key], list):
+ fp.write('%s = ' % key)
+ llist = []
+ sep = ', '
+ for item in ddict[key]:
+ if isinstance(item, list):
+ if len(item) == 1:
+ if isinstance(item[0], string_types):
+ self._escape_str(item[0])
+ llist.append('%s,' % self._escape_str(item[0]))
+ else:
+ llist.append('%s,' % item[0])
+ else:
+ item2 = []
+ for val in item:
+ if isinstance(val, string_types):
+ val = self._escape_str(val)
+ item2.append(val)
+ llist.append(', '.join([str(val) for val in item2]))
+ sep = '\n\t'
+ elif isinstance(item, string_types):
+ llist.append(self._escape_str(item))
+ else:
+ llist.append(str(item))
+ fp.write('%s\n' % (sep.join(llist)))
+ elif isinstance(ddict[key], string_types):
+ fp.write('%s = %s\n' % (key, self._escape_str(ddict[key])))
+ else:
+ if isinstance(ddict[key], numpy.ndarray):
+ fp.write('%s =' % key + ' [ ' +
+ ' '.join([str(val) for val in ddict[key]]) +
+ ' ]\n')
+ else:
+ fp.write('%s = %s\n' % (key, ddict[key]))
+
+ for key in dictkey:
+ if secthead is None:
+ newsecthead = key.replace(".", "_|_")
+ else:
+ newsecthead = '%s.%s' % (secthead, key.replace(".", "_|_"))
+
+ fp.write('\n[%s]\n' % newsecthead)
+ self.__write(fp, ddict[key], newsecthead)
diff --git a/silx/io/dictdump.py b/silx/io/dictdump.py
new file mode 100644
index 0000000..ae7a457
--- /dev/null
+++ b/silx/io/dictdump.py
@@ -0,0 +1,366 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""This module offers a set of functions to dump a python dictionary indexed
+by text strings to following file formats: `HDF5, INI, JSON`
+"""
+
+from collections import OrderedDict
+import json
+import logging
+import numpy
+import os.path
+import sys
+
+try:
+ import h5py
+except ImportError as e:
+ h5py_missing = True
+ h5py_import_error = e
+else:
+ h5py_missing = False
+
+from .configdict import ConfigDict
+from .utils import is_group, is_file
+
+from silx.io import open as h5open
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "10/02/2017"
+
+logger = logging.getLogger(__name__)
+
+string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+
+
+def _prepare_hdf5_dataset(array_like):
+ """Cast a python object into a numpy array in a HDF5 friendly format.
+
+ :param array_like: Input dataset in a type that can be digested by
+ ``numpy.array()`` (`str`, `list`, `numpy.ndarray`…)
+ :return: ``numpy.ndarray`` ready to be written as an HDF5 dataset
+ """
+ # simple strings
+ if isinstance(array_like, string_types):
+ array_like = numpy.string_(array_like)
+
+ # Ensure our data is a numpy.ndarray
+ if not isinstance(array_like, (numpy.ndarray, numpy.string_)):
+ array = numpy.array(array_like)
+ else:
+ array = array_like
+
+ # handle list of strings or numpy array of strings
+ if not isinstance(array, numpy.string_):
+ data_kind = array.dtype.kind
+ # unicode: convert to byte strings
+ # (http://docs.h5py.org/en/latest/strings.html)
+ if data_kind.lower() in ["s", "u"]:
+ array = numpy.asarray(array, dtype=numpy.string_)
+
+ return array
+
+
+def dicttoh5(treedict, h5file, h5path='/',
+ mode="w", overwrite_data=False,
+ create_dataset_args=None):
+ """Write a nested dictionary to a HDF5 file, using keys as member names.
+
+ If a dictionary value is a sub-dictionary, a group is created. If it is
+ any other data type, it is cast into a numpy array and written as a
+ :mod:`h5py` dataset. Dictionary keys must be strings and cannot contain
+ the ``/`` character.
+
+ .. note::
+
+ This function requires `h5py <http://www.h5py.org/>`_ to be installed.
+
+ :param treedict: Nested dictionary/tree structure with strings as keys
+ and array-like objects as leafs. The ``"/"`` character is not allowed
+ in keys.
+ :param h5file: HDF5 file name or handle. If a file name is provided, the
+ function opens the file in the specified mode and closes it again
+ before completing.
+ :param h5path: Target path in HDF5 file in which scan groups are created.
+ Default is root (``"/"``)
+ :param mode: Can be ``"r+"`` (read/write, file must exist),
+ ``"w"`` (write, existing file is lost), ``"w-"`` (write, fail if
+ exists) or ``"a"`` (read/write if exists, create otherwise).
+ This parameter is ignored if ``h5file`` is a file handle.
+ :param overwrite_data: If ``True``, existing groups and datasets can be
+ overwritten, if ``False`` they are skipped. This parameter is only
+ relevant if ``h5file_mode`` is ``"r+"`` or ``"a"``.
+ :param create_dataset_args: Dictionary of args you want to pass to
+ ``h5f.create_dataset``. This allows you to specify filters and
+ compression parameters. Don't specify ``name`` and ``data``.
+
+ Example::
+
+ from silx.io.dictdump import dicttoh5
+
+ city_area = {
+ "Europe": {
+ "France": {
+ "Isère": {
+ "Grenoble": "18.44 km2"
+ },
+ "Nord": {
+ "Tourcoing": "15.19 km2"
+ },
+ },
+ },
+ }
+
+ create_ds_args = {'compression': "gzip",
+ 'shuffle': True,
+ 'fletcher32': True}
+
+ dicttoh5(city_area, "cities.h5", h5path="/area",
+ create_dataset_args=create_ds_args)
+ """
+ if h5py_missing:
+ raise h5py_import_error
+
+ if not isinstance(h5file, h5py.File):
+ h5f = h5py.File(h5file, mode)
+ else:
+ h5f = h5file
+
+ if not h5path.endswith("/"):
+ h5path += "/"
+
+ for key in treedict:
+
+ if isinstance(treedict[key], dict) and len(treedict[key]):
+ # non-empty group: recurse
+ dicttoh5(treedict[key], h5f, h5path + key,
+ overwrite_data=overwrite_data,
+ create_dataset_args=create_dataset_args)
+
+ elif treedict[key] is None or (isinstance(treedict[key], dict) and
+ not len(treedict[key])):
+ # Create empty group
+ h5f.create_group(h5path + key)
+
+ else:
+ ds = _prepare_hdf5_dataset(treedict[key])
+ # can't apply filters on scalars (datasets with shape == () )
+ if ds.shape == () or create_dataset_args is None:
+ h5f.create_dataset(h5path + key,
+ data=ds)
+ else:
+ h5f.create_dataset(h5path + key,
+ data=ds,
+ **create_dataset_args)
+
+ if isinstance(h5file, string_types):
+ h5f.close()
+
+
+def _name_contains_string_in_list(name, strlist):
+ if strlist is None:
+ return False
+ for filter_str in strlist:
+ if filter_str in name:
+ return True
+ return False
+
+
+def h5todict(h5file, path="/", exclude_names=None):
+ """Read a HDF5 file and return a nested dictionary with the complete file
+ structure and all data.
+
+ Example of usage::
+
+ from silx.io.dictdump import h5todict
+
+ # initialize dict with file header and scan header
+ header94 = h5todict("oleg.dat",
+ "/94.1/instrument/specfile")
+ # add positioners subdict
+ header94["positioners"] = h5todict("oleg.dat",
+ "/94.1/instrument/positioners")
+ # add scan data without mca data
+ header94["detector data"] = h5todict("oleg.dat",
+ "/94.1/measurement",
+ exclude_names="mca_")
+
+
+ .. note:: This function requires `h5py <http://www.h5py.org/>`_ to be
+ installed.
+
+ .. note:: If you write a dictionary to a HDF5 file with
+ :func:`dicttoh5` and then read it back with :func:`h5todict`, data
+ types are not preserved. All values are cast to numpy arrays before
+ being written to file, and they are read back as numpy arrays (or
+ scalars). In some cases, you may find that a list of heterogeneous
+ data types is converted to a numpy array of strings.
+
+ :param h5file: File name or :class:`h5py.File` object or spech5 file or
+ fabioh5 file.
+ :param str path: Name of HDF5 group to use as dictionary root level,
+ to read only a sub-group in the file
+ :param list[str] exclude_names: Groups and datasets whose name contains
+ a string in this list will be ignored. Default is None (ignore nothing)
+ :return: Nested dictionary
+ """
+ if h5py_missing:
+ raise h5py_import_error
+
+ if not is_file(h5file):
+ h5f = h5open(h5file)
+ else:
+ h5f = h5file
+
+ ddict = {}
+ for key in h5f[path]:
+ if _name_contains_string_in_list(key, exclude_names):
+ continue
+ if is_group(h5f[path + "/" + key]):
+ ddict[key] = h5todict(h5f,
+ path + "/" + key,
+ exclude_names=exclude_names)
+ else:
+ # Convert HDF5 dataset to numpy array
+ ddict[key] = h5f[path + "/" + key][...]
+
+ if not is_file(h5file):
+ # close file, if we opened it
+ h5f.close()
+
+ return ddict
+
+
+def dicttojson(ddict, jsonfile, indent=None, mode="w"):
+ """Serialize ``ddict`` as a JSON formatted stream to ``jsonfile``.
+
+ :param ddict: Dictionary (or any object compatible with ``json.dump``).
+ :param jsonfile: JSON file name or file-like object.
+ If a file name is provided, the function opens the file in the
+ specified mode and closes it again.
+ :param indent: If indent is a non-negative integer, then JSON array
+ elements and object members will be pretty-printed with that indent
+ level. An indent level of ``0`` will only insert newlines.
+ ``None`` (the default) selects the most compact representation.
+ :param mode: File opening mode (``w``, ``a``, ``w+``…)
+ """
+ if not hasattr(jsonfile, "write"):
+ jsonf = open(jsonfile, mode)
+ else:
+ jsonf = jsonfile
+
+ json.dump(ddict, jsonf, indent=indent)
+
+ if not hasattr(jsonfile, "write"):
+ jsonf.close()
+
+
+def dicttoini(ddict, inifile, mode="w"):
+ """Output dict as configuration file (similar to Microsoft Windows INI).
+
+ :param dict: Dictionary of configuration parameters
+ :param inifile: INI file name or file-like object.
+ If a file name is provided, the function opens the file in the
+ specified mode and closes it again.
+ :param mode: File opening mode (``w``, ``a``, ``w+``…)
+ """
+ if not hasattr(inifile, "write"):
+ inif = open(inifile, mode)
+ else:
+ inif = inifile
+
+ ConfigDict(initdict=ddict).write(inif)
+
+ if not hasattr(inifile, "write"):
+ inif.close()
+
+
+def dump(ddict, ffile, mode="w", fmat=None):
+ """Dump dictionary to a file
+
+ :param ddict: Dictionary with string keys
+ :param ffile: File name or file-like object with a ``write`` method
+ :param str fmat: Output format: ``"json"``, ``"hdf5"`` or ``"ini"``.
+ When None (the default), it uses the filename extension as the format.
+ Dumping to a HDF5 file requires `h5py <http://www.h5py.org/>`_ to be
+ installed.
+ :param str mode: File opening mode (``w``, ``a``, ``w+``…)
+ Default is *"w"*, write mode, overwrite if exists.
+ :raises IOError: if file format is not supported
+ """
+ if fmat is None:
+ # If file-like object get its name, else use ffile as filename
+ filename = getattr(ffile, 'name', ffile)
+ fmat = os.path.splitext(filename)[1][1:] # Strip extension leading '.'
+ fmat = fmat.lower()
+
+ if fmat == "json":
+ dicttojson(ddict, ffile, indent=2, mode=mode)
+ elif fmat in ["hdf5", "h5"]:
+ if h5py_missing:
+ logger.error("Cannot dump to HDF5 format, missing h5py library")
+ raise h5py_import_error
+ dicttoh5(ddict, ffile, mode=mode)
+ elif fmat in ["ini", "cfg"]:
+ dicttoini(ddict, ffile, mode=mode)
+ else:
+ raise IOError("Unknown format " + fmat)
+
+
+def load(ffile, fmat=None):
+ """Load dictionary from a file
+
+ When loading from a JSON or INI file, an OrderedDict is returned to
+ preserve the values' insertion order.
+
+ :param ffile: File name or file-like object with a ``read`` method
+ :param fmat: Input format: ``json``, ``hdf5`` or ``ini``.
+ When None (the default), it uses the filename extension as the format.
+ Loading from a HDF5 file requires `h5py <http://www.h5py.org/>`_ to be
+ installed.
+ :return: Dictionary (ordered dictionary for JSON and INI)
+ :raises IOError: if file format is not supported
+ """
+ if not hasattr(ffile, "read"):
+ f = open(ffile, "r")
+ fname = ffile
+ else:
+ f = ffile
+ fname = ffile.name
+
+ if fmat is None: # Use file extension as format
+ fmat = os.path.splitext(fname)[1][1:] # Strip extension leading '.'
+ fmat = fmat.lower()
+
+ if fmat == "json":
+ return json.load(f, object_pairs_hook=OrderedDict)
+ if fmat in ["hdf5", "h5"]:
+ if h5py_missing:
+ logger.error("Cannot load from HDF5 format, missing h5py library")
+ raise h5py_import_error
+ return h5todict(fname)
+ elif fmat in ["ini", "cfg"]:
+ return ConfigDict(filelist=[fname])
+ else:
+ raise IOError("Unknown format " + fmat)
diff --git a/silx/io/fabioh5.py b/silx/io/fabioh5.py
new file mode 100644
index 0000000..092ac0c
--- /dev/null
+++ b/silx/io/fabioh5.py
@@ -0,0 +1,1151 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""This module provides functions to read fabio images as an HDF5 file.
+
+ >>> import silx.io.fabioh5
+ >>> f = silx.io.fabioh5.File("foobar.edf")
+
+.. note:: This module has a dependency on the `h5py <http://www.h5py.org/>`_
+ and `fabio <https://github.com/silx-kit/fabio>`_ libraries,
+ which are not a mandatory dependencies for `silx`. You might need
+ to install it if you don't already have it.
+"""
+
+import collections
+import numpy
+import numbers
+import logging
+from silx.third_party import six
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import fabio
+except ImportError as e:
+ _logger.error("Module %s requires fabio", __name__)
+ raise e
+
+try:
+ import h5py
+except ImportError as e:
+ _logger.error("Module %s requires h5py", __name__)
+ raise e
+
+
+class Node(object):
+ """Main class for all fabioh5 classes. Help to manage a tree."""
+
+ def __init__(self, name, parent=None):
+ self.__parent = parent
+ self.__basename = name
+
+ @property
+ def h5py_class(self):
+ """Returns the h5py classes which is mimicked by this class. It can be
+ one of `h5py.File, h5py.Group` or `h5py.Dataset`
+
+ :rtype: Class
+ """
+ raise NotImplementedError()
+
+ @property
+ def parent(self):
+ """Returns the parent of the node.
+
+ :rtype: Node
+ """
+ return self.__parent
+
+ @property
+ def file(self):
+ """Returns the file node of this node.
+
+ :rtype: Node
+ """
+ node = self
+ while node.__parent is not None:
+ node = node.__parent
+ if isinstance(node, File):
+ return node
+ else:
+ return None
+
+ def _set_parent(self, parent):
+ """Set the parent of this node.
+
+ It do not update the parent object.
+
+ :param Node parent: New parent for this node
+ """
+ self.__parent = parent
+
+ @property
+ def attrs(self):
+ """Returns HDF5 attributes of this node.
+
+ :rtype: dict
+ """
+ return {}
+
+ @property
+ def name(self):
+ """Returns the HDF5 name of this node.
+ """
+ if self.__parent is None:
+ return "/"
+ if self.__parent.name == "/":
+ return "/" + self.basename
+ return self.__parent.name + "/" + self.basename
+
+ @property
+ def basename(self):
+ """Returns the HDF5 basename of this node.
+ """
+ return self.__basename
+
+
+class Dataset(Node):
+ """Class which handle a numpy data as a mimic of a h5py.Dataset.
+ """
+
+ def __init__(self, name, data, parent=None, attrs=None):
+ self.__data = data
+ Node.__init__(self, name, parent)
+ if attrs is None:
+ self.__attrs = {}
+ else:
+ self.__attrs = attrs
+
+ def _set_data(self, data):
+ """Set the data exposed by the dataset.
+
+ It have to be called only one time before the data is used. It should
+ not be edited after use.
+
+ :param numpy.ndarray data: Data associated to the dataset
+ """
+ self.__data = data
+
+ def _get_data(self):
+ """Returns the exposed data
+
+ :rtype: numpy.ndarray
+ """
+ return self.__data
+
+ @property
+ def attrs(self):
+ """Returns HDF5 attributes of this node.
+
+ :rtype: dict
+ """
+ return self.__attrs
+
+ @property
+ def h5py_class(self):
+ """Returns the h5py classes which is mimicked by this class. It can be
+ one of `h5py.File, h5py.Group` or `h5py.Dataset`
+
+ :rtype: Class
+ """
+ return h5py.Dataset
+
+ @property
+ def dtype(self):
+ """Returns the numpy datatype exposed by this dataset.
+
+ :rtype: numpy.dtype
+ """
+ return self._get_data().dtype
+
+ @property
+ def shape(self):
+ """Returns the shape of the data exposed by this dataset.
+
+ :rtype: tuple
+ """
+ if isinstance(self._get_data(), numpy.ndarray):
+ return self._get_data().shape
+ else:
+ return tuple()
+
+ @property
+ def size(self):
+ """Returns the size of the data exposed by this dataset.
+
+ :rtype: int
+ """
+ if isinstance(self._get_data(), numpy.ndarray):
+ return self._get_data().size
+ else:
+ # It is returned as float64 1.0 by h5py
+ return numpy.float64(1.0)
+
+ def __len__(self):
+ """Returns the size of the data exposed by this dataset.
+
+ :rtype: int
+ """
+ if isinstance(self._get_data(), numpy.ndarray):
+ return len(self._get_data())
+ else:
+ # It is returned as float64 1.0 by h5py
+ raise TypeError("Attempt to take len() of scalar dataset")
+
+ def __getitem__(self, item):
+ """Returns the slice of the data exposed by this dataset.
+
+ :rtype: numpy.ndarray
+ """
+ if not isinstance(self._get_data(), numpy.ndarray):
+ if item == Ellipsis:
+ return numpy.array(self._get_data())
+ elif item == tuple():
+ return self._get_data()
+ else:
+ raise ValueError("Scalar can only be reached with an ellipsis or an empty tuple")
+ return self._get_data().__getitem__(item)
+
+ def __str__(self):
+ basename = self.name.split("/")[-1]
+ return '<FabIO dataset "%s": shape %s, type "%s">' % \
+ (basename, self.shape, self.dtype.str)
+
+ def __getslice__(self, i, j):
+ """Returns the slice of the data exposed by this dataset.
+
+ Deprecated but still in use for python 2.7
+
+ :rtype: numpy.ndarray
+ """
+ return self.__getitem__(slice(i, j, None))
+
+ @property
+ def value(self):
+ """Returns the data exposed by this dataset.
+
+ Deprecated by h5py. It is prefered to use indexing `[()]`.
+
+ :rtype: numpy.ndarray
+ """
+ return self._get_data()
+
+ @property
+ def compression(self):
+ """Returns compression as provided by `h5py.Dataset`.
+
+ There is no compression."""
+ return None
+
+ @property
+ def compression_opts(self):
+ """Returns compression options as provided by `h5py.Dataset`.
+
+ There is no compression."""
+ return None
+
+ @property
+ def chunks(self):
+ """Returns chunks as provided by `h5py.Dataset`.
+
+ There is no chunks."""
+ return None
+
+
+class LazyLoadableDataset(Dataset):
+ """Abstract dataset which provide a lazy loading of the data.
+
+ The class have to be inherited and the :meth:`_create_data` have to be
+ implemented to return the numpy data exposed by the dataset. This factory
+ is only called ones, when the data is needed.
+ """
+
+ def __init__(self, name, parent=None, attrs=None):
+ super(LazyLoadableDataset, self).__init__(name, None, parent, attrs=attrs)
+ self.__is_initialized = False
+
+ def _create_data(self):
+ """
+ Factory to create the data exposed by the dataset when it is needed.
+
+ It have to be implemented to work.
+
+ :rtype: numpy.ndarray
+ """
+ raise NotImplementedError()
+
+ def _get_data(self):
+ """Returns the data exposed by the dataset.
+
+ Overwrite Dataset method :meth:`_get_data` to implement the lazy
+ loading feature.
+
+ :rtype: numpy.ndarray
+ """
+ if not self.__is_initialized:
+ data = self._create_data()
+ self._set_data(data)
+ self.__is_initialized = True
+ return super(LazyLoadableDataset, self)._get_data()
+
+
+class Group(Node):
+ """Class which mimic a `h5py.Group`."""
+
+ def __init__(self, name, parent=None, attrs=None):
+ Node.__init__(self, name, parent)
+ self.__items = collections.OrderedDict()
+ if attrs is None:
+ attrs = {}
+ self.__attrs = attrs
+
+ def _get_items(self):
+ """Returns the child items as a name-node dictionary.
+
+ :rtype: dict
+ """
+ return self.__items
+
+ def add_node(self, node):
+ """Add a child to this group.
+
+ :param Node node: Child to add to this group
+ """
+ self._get_items()[node.basename] = node
+ node._set_parent(self)
+
+ @property
+ def h5py_class(self):
+ """Returns the h5py classes which is mimicked by this class.
+
+ It returns `h5py.Group`
+
+ :rtype: Class
+ """
+ return h5py.Group
+
+ @property
+ def attrs(self):
+ """Returns HDF5 attributes of this node.
+
+ :rtype: dict
+ """
+ return self.__attrs
+
+ def items(self):
+ """Returns items iterator containing name-node mapping.
+
+ :rtype: iterator
+ """
+ return self._get_items().items()
+
+ def get(self, name, default=None, getclass=False, getlink=False):
+ """ Retrieve an item or other information.
+
+ If getlink only is true, the returned value is always HardLink
+ cause this implementation do not use links. Like the original
+ implementation.
+
+ :param str name: name of the item
+ :param object default: default value returned if the name is not found
+ :param bool getclass: if true, the returned object is the class of the object found
+ :param bool getlink: if true, links object are returned instead of the target
+ :return: An object, else None
+ :rtype: object
+ """
+ if name not in self._get_items():
+ return default
+
+ if getlink:
+ node = h5py.HardLink()
+ else:
+ node = self._get_items()[name]
+
+ if getclass:
+ obj = node.h5py_class
+ else:
+ obj = node
+ return obj
+
+ def __len__(self):
+ """Returns the number of child contained in this group.
+
+ :rtype: int
+ """
+ return len(self._get_items())
+
+ def __iter__(self):
+ """Iterate over member names"""
+ for x in self._get_items().__iter__():
+ yield x
+
+ def __getitem__(self, name):
+ """Return a child from is name.
+
+ :param name str: name of a member or a path throug members using '/'
+ separator. A '/' as a prefix access to the root item of the tree.
+ :rtype: Node
+ """
+
+ if name is None or name == "":
+ raise ValueError("No name")
+
+ if "/" not in name:
+ return self._get_items()[name]
+
+ if name.startswith("/"):
+ root = self
+ while root.parent is not None:
+ root = root.parent
+ if name == "/":
+ return root
+ return root[name[1:]]
+
+ path = name.split("/")
+ result = self
+ for item_name in path:
+ if not isinstance(result, Group):
+ raise KeyError("Unable to open object (Component not found)")
+ result = result._get_items()[item_name]
+
+ return result
+
+ def __contains__(self, name):
+ """Returns true is a name is an existing child of this group.
+
+ :rtype: bool
+ """
+ return name in self._get_items()
+
+ def keys(self):
+ return self._get_items().keys()
+
+
+class LazyLoadableGroup(Group):
+ """Abstract group which provide a lazy loading of the child.
+
+ The class have to be inherited and the :meth:`_create_child` have to be
+ implemented to add (:meth:`_add_node`) all child. This factory
+ is only called ones, when child are needed.
+ """
+
+ def __init__(self, name, parent=None, attrs=None):
+ Group.__init__(self, name, parent, attrs)
+ self.__is_initialized = False
+
+ def _get_items(self):
+ """Returns internal structure which contains child.
+
+ It overwrite method :meth:`_get_items` to implement the lazy
+ loading feature.
+
+ :rtype: dict
+ """
+ if not self.__is_initialized:
+ self.__is_initialized = True
+ self._create_child()
+ return Group._get_items(self)
+
+ def _create_child(self):
+ """
+ Factory to create the child contained by the group when it is needed.
+
+ It have to be implemented to work.
+ """
+ raise NotImplementedError()
+
+
+class FrameData(LazyLoadableDataset):
+ """Expose a cube of image from a Fabio file using `FabioReader` as
+ cache."""
+
+ def __init__(self, name, fabio_reader, parent=None):
+ attrs = {"interpretation": "image"}
+ LazyLoadableDataset.__init__(self, name, parent, attrs=attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_data(self):
+ return self.__fabio_reader.get_data()
+
+
+class RawHeaderData(LazyLoadableDataset):
+ """Lazy loadable raw header"""
+
+ def __init__(self, name, fabio_file, parent=None):
+ LazyLoadableDataset.__init__(self, name, parent)
+ self.__fabio_file = fabio_file
+
+ def _create_data(self):
+ """Initialize hold data by merging all headers of each frames.
+ """
+ headers = []
+ for frame in range(self.__fabio_file.nframes):
+ if self.__fabio_file.nframes == 1:
+ header = self.__fabio_file.header
+ else:
+ header = self.__fabio_file.getframe(frame).header
+
+ data = []
+ for key, value in header.items():
+ data.append("%s: %s" % (str(key), str(value)))
+
+ headers.append(u"\n".join(data))
+
+ # create the header list
+ return numpy.array(headers)
+
+
+class MetadataGroup(LazyLoadableGroup):
+ """Abstract class for groups containing a reference to a fabio image.
+ """
+
+ def __init__(self, name, metadata_reader, kind, parent=None, attrs=None):
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__metadata_reader = metadata_reader
+ self.__kind = kind
+
+ def _create_child(self):
+ keys = self.__metadata_reader.get_keys(self.__kind)
+ for name in keys:
+ data = self.__metadata_reader.get_value(self.__kind, name)
+ dataset = Dataset(name, data)
+ self.add_node(dataset)
+
+ @property
+ def _metadata_reader(self):
+ return self.__metadata_reader
+
+
+class DetectorGroup(LazyLoadableGroup):
+ """Define the detector group (sub group of instrument) using Fabio data.
+ """
+
+ def __init__(self, name, fabio_reader, parent=None, attrs=None):
+ if attrs is None:
+ attrs = {"NX_class": "NXdetector"}
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_child(self):
+ data = FrameData("data", self.__fabio_reader)
+ self.add_node(data)
+
+ # TODO we should add here Nexus informations we can extract from the
+ # metadata
+
+ others = MetadataGroup("others", self.__fabio_reader, kind=FabioReader.DEFAULT)
+ self.add_node(others)
+
+
+class ImageGroup(LazyLoadableGroup):
+ """Define the image group (sub group of measurement) using Fabio data.
+ """
+
+ def __init__(self, name, fabio_reader, parent=None, attrs=None):
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_child(self):
+ data = FrameData("data", self.__fabio_reader)
+ self.add_node(data)
+
+ # TODO detector should be a real soft-link
+ detector = DetectorGroup("info", self.__fabio_reader)
+ self.add_node(detector)
+
+
+class SampleGroup(LazyLoadableGroup):
+ """Define the image group (sub group of measurement) using Fabio data.
+ """
+
+ def __init__(self, name, fabio_reader, parent=None):
+ attrs = {"NXclass": "NXsample"}
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_child(self):
+ if self.__fabio_reader.has_ub_matrix():
+ scalar = {"interpretation": "scalar"}
+ data = self.__fabio_reader.get_unit_cell_abc()
+ data = Dataset("unit_cell_abc", data, attrs=scalar)
+ self.add_node(data)
+ unit_cell_data = numpy.zeros((1, 6), numpy.float32)
+ unit_cell_data[0, :3] = data
+ data = self.__fabio_reader.get_unit_cell_alphabetagamma()
+ data = Dataset("unit_cell_alphabetagamma", data, attrs=scalar)
+ self.add_node(data)
+ unit_cell_data[0, 3:] = data
+ data = Dataset("unit_cell", unit_cell_data, attrs=scalar)
+ self.add_node(data)
+ data = self.__fabio_reader.get_ub_matrix()
+ data = Dataset("ub_matrix", data, attrs=scalar)
+ self.add_node(data)
+
+
+class MeasurementGroup(LazyLoadableGroup):
+ """Define the measurement group for fabio file.
+ """
+
+ def __init__(self, name, fabio_reader, parent=None, attrs=None):
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_child(self):
+ keys = self.__fabio_reader.get_keys(FabioReader.COUNTER)
+
+ # create image measurement but take care that no other metadata use
+ # this name
+ for i in range(1000):
+ name = "image_%i" % i
+ if name not in keys:
+ data = ImageGroup(name, self.__fabio_reader)
+ self.add_node(data)
+ break
+ else:
+ raise Exception("image_i for 0..1000 already used")
+
+ # add all counters
+ for name in keys:
+ data = self.__fabio_reader.get_value(FabioReader.COUNTER, name)
+ dataset = Dataset(name, data)
+ self.add_node(dataset)
+
+
+class FabioReader(object):
+ """Class which read and cache data and metadata from a fabio image."""
+
+ DEFAULT = 0
+ COUNTER = 1
+ POSITIONER = 2
+
+ def __init__(self, fabio_file):
+ self.__fabio_file = fabio_file
+ self.__counters = {}
+ self.__positioners = {}
+ self.__measurements = {}
+ self.__data = None
+ self.__frame_count = self.__fabio_file.nframes
+ self._read(self.__fabio_file)
+
+ def fabio_file(self):
+ return self.__fabio_file
+
+ def _create_data(self):
+ """Initialize hold data by merging all frames into a single cube.
+
+ Choose the cube size which fit the best the data. If some images are
+ smaller than expected, the empty space is set to 0.
+
+ The computation is cached into the class, and only done ones.
+ """
+ images = []
+ for frame in range(self.__fabio_file.nframes):
+ if self.__fabio_file.nframes == 1:
+ image = self.__fabio_file.data
+ else:
+ image = self.__fabio_file.getframe(frame).data
+ images.append(image)
+
+ # get the max size
+ max_shape = [0, 0]
+ for image in images:
+ if image.shape[0] > max_shape[0]:
+ max_shape[0] = image.shape[0]
+ if image.shape[1] > max_shape[1]:
+ max_shape[1] = image.shape[1]
+ max_shape = tuple(max_shape)
+
+ # fix smallest images
+ for index, image in enumerate(images):
+ if image.shape == max_shape:
+ continue
+ right_image = numpy.zeros(max_shape)
+ right_image[0:image.shape[0], 0:image.shape[1]] = image
+ images[index] = right_image
+
+ # create a cube
+ return numpy.array(images)
+
+ def __get_dict(self, kind):
+ """Returns a dictionary from according to an expected kind"""
+ if kind == self.DEFAULT:
+ return self.__measurements
+ elif kind == self.COUNTER:
+ return self.__counters
+ elif kind == self.POSITIONER:
+ return self.__positioners
+ else:
+ raise Exception("Unexpected kind %s", kind)
+
+ def get_data(self):
+ """Returns a cube from all available data from frames
+
+ :rtype: numpy.ndarray
+ """
+ if self.__data is None:
+ self.__data = self._create_data()
+ return self.__data
+
+ def get_keys(self, kind):
+ """Get all available keys according to a kind of metadata.
+
+ :rtype: list
+ """
+ return self.__get_dict(kind).keys()
+
+ def get_value(self, kind, name):
+ """Get a metadata value according to the kind and the name.
+
+ :rtype: numpy.ndarray
+ """
+ value = self.__get_dict(kind)[name]
+ if not isinstance(value, numpy.ndarray):
+ value = self._convert_metadata_vector(value)
+ self.__get_dict(kind)[name] = value
+ return value
+
+ def _set_counter_value(self, frame_id, name, value):
+ """Set a counter metadata according to the frame id"""
+ if name not in self.__counters:
+ self.__counters[name] = [None] * self.__frame_count
+ self.__counters[name][frame_id] = value
+
+ def _set_positioner_value(self, frame_id, name, value):
+ """Set a positioner metadata according to the frame id"""
+ if name not in self.__positioners:
+ self.__positioners[name] = [None] * self.__frame_count
+ self.__positioners[name][frame_id] = value
+
+ def _set_measurement_value(self, frame_id, name, value):
+ """Set a measurement metadata according to the frame id"""
+ if name not in self.__measurements:
+ self.__measurements[name] = [None] * self.__frame_count
+ self.__measurements[name][frame_id] = value
+
+ def _read(self, fabio_file):
+ """Read all metadata from the fabio file and store it into this
+ object."""
+ for frame in range(fabio_file.nframes):
+ if fabio_file.nframes == 1:
+ header = fabio_file.header
+ else:
+ header = fabio_file.getframe(frame).header
+ self._read_frame(frame, header)
+
+ def _read_frame(self, frame_id, header):
+ """Read all metadata from a frame and store it into this
+ object."""
+ for key, value in header.items():
+ self._read_key(frame_id, key, value)
+
+ def _read_key(self, frame_id, name, value):
+ """Read a key from the metadata and cache it into this object."""
+ self._set_measurement_value(frame_id, name, value)
+
+ def _convert_metadata_vector(self, values):
+ """Convert a list of numpy data into a numpy array with the better
+ fitting type."""
+ converted = []
+ types = set([])
+ has_none = False
+ for v in values:
+ if v is None:
+ converted.append(None)
+ has_none = True
+ else:
+ c = self._convert_value(v)
+ converted.append(c)
+ types.add(c.dtype)
+
+ if has_none and len(types) == 0:
+ # That's a list of none values
+ return numpy.array([0] * len(values), numpy.int8)
+
+ result_type = numpy.result_type(*types)
+
+ if issubclass(result_type.type, numpy.string_):
+ # use the raw data to create the array
+ result = values
+ elif issubclass(result_type.type, numpy.unicode_):
+ # use the raw data to create the array
+ result = values
+ else:
+ result = converted
+
+ if has_none:
+ # Fix missing data according to the array type
+ if result_type.kind in ["S", "U"]:
+ none_value = ""
+ elif result_type.kind == "f":
+ none_value = numpy.float("NaN")
+ elif result_type.kind == "i":
+ none_value = numpy.int(0)
+ elif result_type.kind == "u":
+ none_value = numpy.int(0)
+ elif result_type.kind == "b":
+ none_value = numpy.bool(False)
+ else:
+ none_value = None
+
+ for index, r in enumerate(result):
+ if r is not None:
+ continue
+ result[index] = none_value
+
+ return numpy.array(result, dtype=result_type)
+
+ def _convert_value(self, value):
+ """Convert a string into a numpy object (scalar or array).
+
+ The value is most of the time a string, but it can be python object
+ in case if TIFF decoder for example.
+ """
+ if isinstance(value, list):
+ # convert to a numpy array
+ return numpy.array(value)
+ if isinstance(value, dict):
+ # convert to a numpy associative array
+ key_dtype = numpy.min_scalar_type(list(value.keys()))
+ value_dtype = numpy.min_scalar_type(list(value.values()))
+ associative_type = [('key', key_dtype), ('value', value_dtype)]
+ assert key_dtype.kind != "O" and value_dtype.kind != "O"
+ return numpy.array(list(value.items()), dtype=associative_type)
+ if isinstance(value, numbers.Number):
+ dtype = numpy.min_scalar_type(value)
+ assert dtype.kind != "O"
+ return dtype.type(value)
+
+ if isinstance(value, six.binary_type):
+ try:
+ value = value.decode('utf-8')
+ except UnicodeDecodeError:
+ return numpy.void(value)
+
+ if " " in value:
+ result = self._convert_list(value)
+ else:
+ result = self._convert_scalar_value(value)
+ return result
+
+ def _convert_scalar_value(self, value):
+ """Convert a string into a numpy int or float.
+
+ If it is not possible it returns a numpy string.
+ """
+ try:
+ value = int(value)
+ dtype = numpy.min_scalar_type(value)
+ assert dtype.kind != "O"
+ return dtype.type(value)
+ except ValueError:
+ try:
+ # numpy.min_scalar_type is not able to do very well the job
+ # when there is a lot of digit after the dot
+ # https://github.com/numpy/numpy/issues/8207
+ # Let's count the digit of the string
+ digits = len(value) - 1 # minus the dot
+ if digits <= 7:
+ # A float32 is accurate with about 7 digits
+ return numpy.float32(value)
+ elif digits <= 16:
+ # A float64 is accurate with about 16 digits
+ return numpy.float64(value)
+ else:
+ if hasattr(numpy, "float128"):
+ return numpy.float128(value)
+ else:
+ return numpy.float64(value)
+ except ValueError:
+ return numpy.string_(value)
+
+ def _convert_list(self, value):
+ """Convert a string into a typed numpy array.
+
+ If it is not possible it returns a numpy string.
+ """
+ try:
+ numpy_values = []
+ values = value.split(" ")
+ types = set([])
+ for string_value in values:
+ v = self._convert_scalar_value(string_value)
+ numpy_values.append(v)
+ types.add(v.dtype.type)
+
+ result_type = numpy.result_type(*types)
+
+ if issubclass(result_type.type, numpy.string_):
+ # use the raw data to create the result
+ return numpy.string_(value)
+ elif issubclass(result_type.type, numpy.unicode_):
+ # use the raw data to create the result
+ return numpy.unicode_(value)
+ else:
+ return numpy.array(numpy_values, dtype=result_type)
+ except ValueError:
+ return numpy.string_(value)
+
+ def has_sample_information(self):
+ """Returns true if there is information about the sample in the
+ file
+
+ :rtype: bool
+ """
+ return self.has_ub_matrix()
+
+ def has_ub_matrix(self):
+ """Returns true if a UB matrix is available.
+
+ :rtype: bool
+ """
+ return False
+
+
+class EdfFabioReader(FabioReader):
+ """Class which read and cache data and metadata from a fabio image.
+
+ It is mostly the same as FabioReader, but counter_mne and
+ motor_mne are parsed using a special way.
+ """
+
+ def __init__(self, fabio_file):
+ FabioReader.__init__(self, fabio_file)
+ self.__unit_cell_abc = None
+ self.__unit_cell_alphabetagamma = None
+ self.__ub_matrix = None
+
+ def _read_frame(self, frame_id, header):
+ """Overwrite the method to check and parse special keys: counter and
+ motors keys."""
+ self.__catch_keys = set([])
+ if "motor_pos" in header and "motor_mne" in header:
+ self.__catch_keys.add("motor_pos")
+ self.__catch_keys.add("motor_mne")
+ self._read_mnemonic_key(frame_id, "motor", header)
+ if "counter_pos" in header and "counter_mne" in header:
+ self.__catch_keys.add("counter_pos")
+ self.__catch_keys.add("counter_mne")
+ self._read_mnemonic_key(frame_id, "counter", header)
+ FabioReader._read_frame(self, frame_id, header)
+
+ def _read_key(self, frame_id, name, value):
+ """Overwrite the method to filter counter or motor keys."""
+ if name in self.__catch_keys:
+ return
+ FabioReader._read_key(self, frame_id, name, value)
+
+ def _get_mnemonic_key(self, base_key, header):
+ mnemonic_values_key = base_key + "_mne"
+ mnemonic_values = header.get(mnemonic_values_key, "")
+ mnemonic_values = mnemonic_values.split()
+ pos_values_key = base_key + "_pos"
+ pos_values = header.get(pos_values_key, "")
+ pos_values = pos_values.split()
+
+ result = collections.OrderedDict()
+ nbitems = max(len(mnemonic_values), len(pos_values))
+ for i in range(nbitems):
+ if i < len(mnemonic_values):
+ mnemonic = mnemonic_values[i]
+ else:
+ # skip the element
+ continue
+
+ if i < len(pos_values):
+ pos = pos_values[i]
+ else:
+ pos = None
+
+ result[mnemonic] = pos
+ return result
+
+ def _read_mnemonic_key(self, frame_id, base_key, header):
+ """Parse a mnemonic key"""
+ is_counter = base_key == "counter"
+ is_positioner = base_key == "motor"
+ data = self._get_mnemonic_key(base_key, header)
+
+ for mnemonic, pos in data.items():
+ if is_counter:
+ self._set_counter_value(frame_id, mnemonic, pos)
+ elif is_positioner:
+ self._set_positioner_value(frame_id, mnemonic, pos)
+ else:
+ raise Exception("State unexpected (base_key: %s)" % base_key)
+
+ def has_ub_matrix(self):
+ """Returns true if a UB matrix is available.
+
+ :rtype: bool
+ """
+ header = self.fabio_file().header
+ expected_keys = set(["UB_mne", "UB_pos", "sample_mne", "sample_pos"])
+ return expected_keys.issubset(header)
+
+ def parse_ub_matrix(self):
+ header = self.fabio_file().header
+ ub_data = self._get_mnemonic_key("UB", header)
+ s_data = self._get_mnemonic_key("sample", header)
+ if len(ub_data) > 9:
+ _logger.warning("UB_mne and UB_pos contains more than expected keys.")
+ if len(s_data) > 6:
+ _logger.warning("sample_mne and sample_pos contains more than expected keys.")
+
+ data = numpy.array([s_data["U0"], s_data["U1"], s_data["U2"]], dtype=float)
+ unit_cell_abc = data
+
+ data = numpy.array([s_data["U3"], s_data["U4"], s_data["U5"]], dtype=float)
+ unit_cell_alphabetagamma = data
+
+ ub_matrix = numpy.array([[
+ [ub_data["UB0"], ub_data["UB1"], ub_data["UB2"]],
+ [ub_data["UB3"], ub_data["UB4"], ub_data["UB5"]],
+ [ub_data["UB6"], ub_data["UB7"], ub_data["UB8"]]]], dtype=float)
+
+ self.__unit_cell_abc = unit_cell_abc
+ self.__unit_cell_alphabetagamma = unit_cell_alphabetagamma
+ self.__ub_matrix = ub_matrix
+
+ def get_unit_cell_abc(self):
+ """Get a numpy array data as defined for the dataset unit_cell_abc
+ from the NXsample dataset.
+
+ :rtype: numpy.ndarray
+ """
+ if self.__unit_cell_abc is None:
+ self.parse_ub_matrix()
+ return self.__unit_cell_abc
+
+ def get_unit_cell_alphabetagamma(self):
+ """Get a numpy array data as defined for the dataset
+ unit_cell_alphabetagamma from the NXsample dataset.
+
+ :rtype: numpy.ndarray
+ """
+ if self.__unit_cell_alphabetagamma is None:
+ self.parse_ub_matrix()
+ return self.__unit_cell_alphabetagamma
+
+ def get_ub_matrix(self):
+ """Get a numpy array data as defined for the dataset ub_matrix
+ from the NXsample dataset.
+
+ :rtype: numpy.ndarray
+ """
+ if self.__ub_matrix is None:
+ self.parse_ub_matrix()
+ return self.__ub_matrix
+
+
+class File(Group):
+ """Class which handle a fabio image as a mimick of a h5py.File.
+ """
+
+ def __init__(self, file_name=None, fabio_image=None):
+ self.__must_be_closed = False
+ if file_name is not None and fabio_image is not None:
+ raise TypeError("Parameters file_name and fabio_image are mutually exclusive.")
+ if file_name is not None:
+ self.__fabio_image = fabio.open(file_name)
+ self.__must_be_closed = True
+ elif fabio_image is not None:
+ self.__fabio_image = fabio_image
+ Group.__init__(self, name="", parent=None, attrs={"NX_class": "NXroot"})
+ self.__fabio_reader = self.create_fabio_reader(self.__fabio_image)
+ scan = self.create_scan_group(self.__fabio_image, self.__fabio_reader)
+ self.add_node(scan)
+
+ def create_scan_group(self, fabio_image, fabio_reader):
+ """Factory to create the scan group.
+
+ :param FabioImage fabio_image: A Fabio image
+ :param FabioReader fabio_reader: A reader for the Fabio image
+ :rtype: Group
+ """
+
+ scan = Group("scan_0", attrs={"NX_class": "NXentry"})
+ instrument = Group("instrument", attrs={"NX_class": "NXinstrument"})
+ measurement = MeasurementGroup("measurement", fabio_reader, attrs={"NX_class": "NXcollection"})
+ file_ = Group("file", attrs={"NX_class": "NXcollection"})
+ positioners = MetadataGroup("positioners", fabio_reader, FabioReader.POSITIONER, attrs={"NX_class": "NXpositioner"})
+ raw_header = RawHeaderData("scan_header", fabio_image, self)
+ detector = DetectorGroup("detector_0", fabio_reader)
+
+ scan.add_node(instrument)
+ instrument.add_node(positioners)
+ instrument.add_node(file_)
+ instrument.add_node(detector)
+ file_.add_node(raw_header)
+ scan.add_node(measurement)
+
+ if fabio_reader.has_sample_information():
+ sample = SampleGroup("sample", fabio_reader)
+ scan.add_node(sample)
+
+ return scan
+
+ def create_fabio_reader(self, fabio_file):
+ """Factory to create fabio reader.
+
+ :rtype: FabioReader"""
+ if isinstance(fabio_file, fabio.edfimage.EdfImage):
+ metadata = EdfFabioReader(fabio_file)
+ else:
+ metadata = FabioReader(fabio_file)
+ return metadata
+
+ @property
+ def h5py_class(self):
+ return h5py.File
+
+ @property
+ def filename(self):
+ return self.__fabio_image.filename
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb): # pylint: disable=W0622
+ """Called at the end of a `with` statement.
+
+ It will close the internal FabioImage only if the FabioImage was
+ created by the class itself. The reference to the FabioImage is anyway
+ broken.
+ """
+ if self.__must_be_closed:
+ self.close()
+ else:
+ self.__fabio_image = None
+
+ def close(self):
+ """Close the object, and free up associated resources.
+
+ The associated FabioImage is closed anyway the object was created from
+ a filename or from a FabioImage.
+
+ After calling this method, attempts to use the object may fail.
+ """
+ # It looks like there is no close on FabioImage
+ # self.__fabio_image.close()
+ self.__fabio_image = None
diff --git a/silx/io/nxdata.py b/silx/io/nxdata.py
new file mode 100644
index 0000000..c0e53fc
--- /dev/null
+++ b/silx/io/nxdata.py
@@ -0,0 +1,535 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""This module provides a collection of functions to work with h5py-like
+groups following the NeXus *NXdata* specification.
+
+See http://download.nexusformat.org/sphinx/classes/base_classes/NXdata.html
+
+"""
+import logging
+import numpy
+from .utils import is_dataset, is_group
+from silx.third_party import six
+
+_logger = logging.getLogger(__name__)
+
+
+_INTERPDIM = {"scalar": 0,
+ "spectrum": 1,
+ "image": 2,
+ # "rgba-image": 3, "hsla-image": 3, "cmyk-image": 3, # TODO
+ "vertex": 1} # 3D scatter: 1D signal + 3 axes (x, y, z) of same legth
+"""Number of signal dimensions associated to each possible @interpretation
+attribute.
+"""
+
+
+def _nxdata_warning(msg):
+ """Log a warning message prefixed with
+ *"NXdata warning: "*
+
+ :param str msg: Warning message
+ """
+ _logger.warning("NXdata warning: " + msg)
+
+
+def _get_attr(item, attr_name, default=None):
+ """Return item.attrs[attr_name]. If it is a byte-string or an array of
+ byte-strings, return it as a default python string.
+
+ For Python 3, this involves a coercion from bytes into unicode.
+ For Python 2, there is nothing special to do, as strings are bytes.
+
+ :param item: Group or dataset
+ :param attr_name: Attribute name
+ :return: item.attrs[attr_name]
+ """
+ attr = item.attrs.get(attr_name, default)
+ if six.PY2:
+ return attr
+ if six.PY3:
+ if hasattr(attr, "decode"):
+ # byte-string
+ return attr.decode("ascii")
+ elif isinstance(attr, numpy.ndarray) and hasattr(attr[0], "decode"):
+ # array of byte-strinqs
+ return [element.decode("ascii") for element in attr]
+ else:
+ # attr is not a byte-strinq
+ return attr
+
+
+def is_valid_nxdata(group): # noqa
+ """Check if a h5py group is a **valid** NX_data group.
+
+ If the group does not have attribute *@NX_class=NXdata*, this function
+ simply returns *False*.
+
+ Else, warning messages are logged to troubleshoot malformed NXdata groups
+ prior to returning *False*.
+
+ :param group: h5py-like group
+ :return: True if this NXdata group is valid.
+ :raise: TypeError if group is not a h5py group, a spech5 group,
+ or a fabioh5 group
+ """
+ if not is_group(group):
+ raise TypeError("group must be a h5py-like group")
+ if _get_attr(group, "NX_class") != "NXdata":
+ return False
+ if "signal" not in group.attrs:
+ _logger.warning("NXdata group does not define a signal attr.")
+ return False
+
+ signal_name = _get_attr(group, "signal")
+ if signal_name not in group or not is_dataset(group[signal_name]):
+ _logger.warning(
+ "Cannot find signal dataset '%s' in NXdata group" % signal_name)
+ return False
+
+ ndim = len(group[signal_name].shape)
+
+ if "axes" in group.attrs:
+ axes_names = _get_attr(group, "axes")
+ if isinstance(axes_names, str):
+ axes_names = [axes_names]
+
+ if 1 < ndim < len(axes_names):
+ # ndim = 1 and several axes could be a scatter
+ _nxdata_warning(
+ "More @axes defined than there are " +
+ "signal dimensions: " +
+ "%d axes, %d dimensions." % (len(axes_names), ndim))
+ return False
+
+ # case of less axes than dimensions: number of axes must match
+ # dimensionality defined by @interpretation
+ if ndim > len(axes_names):
+ interpretation = _get_attr(group[signal_name], "interpretation", None)
+ if interpretation is None:
+ interpretation = _get_attr(group, "interpretation", None)
+ if interpretation is None:
+ _nxdata_warning("No @interpretation and not enough" +
+ " @axes defined.")
+ return False
+
+ if interpretation not in _INTERPDIM:
+ _nxdata_warning("Unrecognized @interpretation=" + interpretation +
+ " for data with wrong number of defined @axes.")
+ return False
+
+ if len(axes_names) != _INTERPDIM[interpretation]:
+ _nxdata_warning(
+ "%d-D signal with @interpretation=%s " % (ndim, interpretation) +
+ "must define %d or %d axes." % (ndim, _INTERPDIM[interpretation]))
+ return False
+
+ # Test consistency of @uncertainties
+ uncertainties_names = _get_attr(group, "uncertainties")
+ if uncertainties_names is None:
+ uncertainties_names = _get_attr(group[signal_name], "uncertainties")
+ if isinstance(uncertainties_names, str):
+ uncertainties_names = [uncertainties_names]
+ if uncertainties_names is not None:
+ if len(uncertainties_names) != len(axes_names):
+ _nxdata_warning("@uncertainties does not define the same " +
+ "number of fields than @axes")
+ return False
+
+ # Test individual axes
+ is_scatter = True # true if all axes have the same size as the signal
+ signal_size = 1
+ for dim in group[signal_name].shape:
+ signal_size *= dim
+ polynomial_axes_names = []
+ for i, axis_name in enumerate(axes_names):
+ if axis_name == ".":
+ continue
+ if axis_name not in group or not is_dataset(group[axis_name]):
+ _nxdata_warning("Could not find axis dataset '%s'" % axis_name)
+ return False
+
+ axis_size = 1
+ for dim in group[axis_name].shape:
+ axis_size *= dim
+
+ if len(group[axis_name].shape) != 1:
+ # too me, it makes only sense to have a n-D axis if it's total
+ # size is exactly the signal's size (weird n-d scatter)
+ if axis_size != signal_size:
+ _nxdata_warning("Axis %s is not a 1D dataset" % axis_name +
+ " and its shape does not match the signal's shape")
+ return False
+ axis_len = axis_size
+ else:
+ # for a 1-d axis,
+ fg_idx = _get_attr(group[axis_name], "first_good", 0)
+ lg_idx = _get_attr(group[axis_name], "last_good", len(group[axis_name]) - 1)
+ axis_len = lg_idx + 1 - fg_idx
+
+ if axis_len != signal_size:
+ if axis_len not in group[signal_name].shape + (1, 2):
+ _nxdata_warning(
+ "Axis %s number of elements does not " % axis_name +
+ "correspond to the length of any signal dimension,"
+ " it does not appear to be a constant or a linear calibration," +
+ " and this does not seem to be a scatter plot.")
+ return False
+ elif axis_len in (1, 2):
+ polynomial_axes_names.append(axis_name)
+ is_scatter = False
+ else:
+ if not is_scatter:
+ _nxdata_warning(
+ "Axis %s number of elements is equal " % axis_name +
+ "to the length of the signal, but this does not seem" +
+ " to be a scatter (other axes have different sizes)")
+ return False
+
+ # Test individual uncertainties
+ errors_name = axis_name + "_errors"
+ if errors_name not in group and uncertainties_names is not None:
+ errors_name = uncertainties_names[i]
+ if errors_name in group and axis_name not in polynomial_axes_names:
+ if group[errors_name].shape != group[axis_name].shape:
+ _nxdata_warning(
+ "Errors '%s' does not have the same " % errors_name +
+ "dimensions as axis '%s'." % axis_name)
+ return False
+
+ # test dimensions of errors associated with signal
+ if "errors" in group and is_dataset(group["errors"]):
+ if group["errors"].shape != group[signal_name].shape:
+ _nxdata_warning("Dataset containing standard deviations must " +
+ "have the same dimensions as the signal.")
+ return False
+ return True
+
+
+class NXdata(object):
+ """
+
+ :param group: h5py-like group following the NeXus *NXdata* specification.
+ """
+ def __init__(self, group):
+ if not is_valid_nxdata(group):
+ raise TypeError("group is not a valid NXdata class")
+ super(NXdata, self).__init__()
+
+ self._is_scatter = None
+ self._axes = None
+
+ self.group = group
+ """h5py-like group object compliant with NeXus NXdata specification.
+ """
+
+ self.signal = self.group[self.group.attrs["signal"]]
+ """Signal dataset in this NXdata group.
+ """
+
+ # ndim will be available in very recent h5py versions only
+ self.signal_ndim = getattr(self.signal, "ndim",
+ len(self.signal.shape))
+
+ self.signal_is_0d = self.signal_ndim == 0
+ self.signal_is_1d = self.signal_ndim == 1
+ self.signal_is_2d = self.signal_ndim == 2
+ self.signal_is_3d = self.signal_ndim == 3
+
+ self.axes_names = []
+ """List of axes names in a NXdata group.
+
+ This attribute is similar to :attr:`axes_dataset_names` except that
+ if an axis dataset has a "@long_name" attribute, it will be used
+ instead of the dataset name.
+ """
+ # check if axis dataset defines @long_name
+ for i, dsname in enumerate(self.axes_dataset_names):
+ if dsname is not None and "long_name" in self.group[dsname].attrs:
+ self.axes_names.append(self.group[dsname].attrs["long_name"])
+ else:
+ self.axes_names.append(dsname)
+
+ # excludes scatters
+ self.signal_is_1d = self.signal_is_1d and len(self.axes) <= 1 # excludes n-D scatters
+
+ @property
+ def interpretation(self):
+ """*@interpretation* attribute associated with the *signal*
+ dataset of the NXdata group. ``None`` if no interpretation
+ attribute is present.
+
+ The *interpretation* attribute provides information about the last
+ dimensions of the signal. The allowed values are:
+
+ - *"scalar"*: 0-D data to be plotted
+ - *"spectrum"*: 1-D data to be plotted
+ - *"image"*: 2-D data to be plotted
+ - *"vertex"*: 3-D data to be plotted
+
+ For example, a 3-D signal with interpretation *"spectrum"* should be
+ considered to be a 2-D array of 1-D data. A 3-D signal with
+ interpretation *"image"* should be interpreted as a 1-D array (a list)
+ of 2-D images. An n-D array with interpretation *"image"* should be
+ interpreted as an (n-2)-D array of images.
+
+ A warning message is logged if the returned interpretation is not one
+ of the allowed values, but no error is raised and the unknown
+ interpretation is returned anyway.
+ """
+ allowed_interpretations = [None, "scalar", "spectrum", "image",
+ # "rgba-image", "hsla-image", "cmyk-image" # TODO
+ "vertex"]
+
+ interpretation = _get_attr(self.signal, "interpretation", None)
+ if interpretation is None:
+ interpretation = _get_attr(self.group, "interpretation", None)
+
+ if interpretation not in allowed_interpretations:
+ _logger.warning("Interpretation %s is not valid." % interpretation +
+ " Valid values: " + ", ".join(allowed_interpretations))
+ return interpretation
+
+ @property
+ def axes(self):
+ """List of the axes datasets.
+
+ The list typically has as many elements as there are dimensions in the
+ signal dataset, the exception being scatter plots which typically
+ use a 1D signal and several 1D axes of the same size.
+
+ If an axis dataset applies to several dimensions of the signal, it
+ will be repeated in the list.
+
+ If a dimension of the signal has no dimension scale (i.e. there is a
+ "." in that position in the *@axes* array), `None` is inserted in the
+ output list in its position.
+
+ .. note::
+
+ In theory, the *@axes* attribute defines as many entries as there
+ are dimensions in the signal. In such a case, there is no ambiguity.
+ If this is not the case, this implementation relies on the existence
+ of an *@interpretation* (*spectrum* or *image*) attribute in the
+ *signal* dataset.
+
+ .. note::
+
+ If an axis dataset defines attributes @first_good or @last_good,
+ the output will be a numpy array resulting from slicing that
+ axis to keep only the good index range: axis[first_good:last_good + 1]
+
+ :rtype: list[Dataset or 1D array or None]
+ """
+ if self._axes is not None:
+ # use cache
+ return self._axes
+ ndims = len(self.signal.shape)
+ axes_names = _get_attr(self.group, "axes")
+ interpretation = self.interpretation
+
+ if axes_names is None:
+ self._axes = [None for _i in range(ndims)]
+ return self._axes
+
+ if isinstance(axes_names, str):
+ axes_names = [axes_names]
+
+ if len(axes_names) == ndims:
+ # axes is a list of strings, one axis per dim is explicitly defined
+ axes = [None] * ndims
+ for i, axis_n in enumerate(axes_names):
+ if axis_n != ".":
+ axes[i] = self.group[axis_n]
+ elif interpretation is not None:
+ # case of @interpretation attribute defined: we expect 1, 2 or 3 axes
+ # corresponding to the 1, 2, or 3 last dimensions of the signal
+ assert len(axes_names) == _INTERPDIM[interpretation]
+ axes = [None] * (ndims - _INTERPDIM[interpretation])
+ for axis_n in axes_names:
+ if axis_n != ".":
+ axes.append(self.group[axis_n])
+ else:
+ axes.append(None)
+ else: # scatter
+ axes = []
+ for axis_n in axes_names:
+ if axis_n != ".":
+ axes.append(self.group[axis_n])
+ else:
+ axes.append(None)
+ # keep only good range of axis data
+ for i, axis in enumerate(axes):
+ if axis is None:
+ continue
+ if "first_good" not in axis.attrs and "last_good" not in axis.attrs:
+ continue
+ fg_idx = _get_attr(axis, "first_good") or 0
+ lg_idx = _get_attr(axis, "last_good") or (len(axis) - 1)
+ axes[i] = axis[fg_idx:lg_idx + 1]
+
+ self._axes = axes
+ return self._axes
+
+ @property
+ def axes_dataset_names(self):
+ """
+ If an axis dataset applies to several dimensions of the signal, its
+ name will be repeated in the list.
+
+ If a dimension of the signal has no dimension scale (i.e. there is a
+ "." in that position in the *@axes* array), `None` is inserted in the
+ output list in its position.
+ """
+ axes_dataset_names = _get_attr(self.group, "axes")
+ if axes_dataset_names is None:
+ axes_dataset_names = _get_attr(self.group, "axes")
+
+ ndims = len(self.signal.shape)
+ if axes_dataset_names is None:
+ return [None] * ndims
+
+ if isinstance(axes_dataset_names, str):
+ axes_dataset_names = [axes_dataset_names]
+
+ for i, axis_name in enumerate(axes_dataset_names):
+ if axis_name == ".":
+ axes_dataset_names[i] = None
+
+ if len(axes_dataset_names) != ndims:
+ if self.is_scatter and ndims == 1:
+ return list(axes_dataset_names)
+ # @axes may only define 1 or 2 axes if @interpretation=spectrum/image.
+ # Use the existing names for the last few dims, and prepend with Nones.
+ assert len(axes_dataset_names) == _INTERPDIM[self.interpretation]
+ all_dimensions_names = [None] * (ndims - _INTERPDIM[self.interpretation])
+ for axis_name in axes_dataset_names:
+ all_dimensions_names.append(axis_name)
+ return all_dimensions_names
+
+ return list(axes_dataset_names)
+
+ def get_axis_errors(self, axis_name):
+ """Return errors (uncertainties) associated with an axis.
+
+ If the axis has attributes @first_good or @last_good, the output
+ is trimmed accordingly (a numpy array will be returned rather than a
+ dataset).
+
+ :param str axis_name: Name of axis dataset. This dataset **must exist**.
+ :return: Dataset with axis errors, or None
+ :raise: KeyError if this group does not contain a dataset named axis_name
+ """
+ if axis_name not in self.group:
+ # tolerate axis_name given as @long_name
+ for item in self.group:
+ long_name = _get_attr(self.group[item], "long_name")
+ if long_name is not None and long_name == axis_name:
+ axis_name = item
+ break
+
+ if axis_name not in self.group:
+ raise KeyError("group does not contain a dataset named '%s'" % axis_name)
+
+ len_axis = len(self.group[axis_name])
+
+ fg_idx = _get_attr(self.group[axis_name], "first_good", 0)
+ lg_idx = _get_attr(self.group[axis_name], "last_good", len_axis - 1)
+
+ # case of axisname_errors dataset present
+ errors_name = axis_name + "_errors"
+ if errors_name in self.group and is_dataset(self.group[errors_name]):
+ if fg_idx != 0 or lg_idx != (len_axis-1):
+ return self.group[errors_name][fg_idx:lg_idx + 1]
+ else:
+ return self.group[errors_name]
+ # case of uncertainties dataset name provided in @uncertainties
+ uncertainties_names = _get_attr(self.group, "uncertainties")
+ if uncertainties_names is None:
+ uncertainties_names = _get_attr(self.signal, "uncertainties")
+ if isinstance(uncertainties_names, str):
+ uncertainties_names = [uncertainties_names]
+ if uncertainties_names is not None:
+ # take the uncertainty with the same index as the axis in @axes
+ axes_ds_names = _get_attr(self.group, "axes")
+ if axes_ds_names is None:
+ axes_ds_names = _get_attr(self.signal, "axes")
+ if isinstance(axes_ds_names, str):
+ axes_ds_names = [axes_ds_names]
+ elif not isinstance(axes_ds_names, list):
+ # transform numpy.ndarray(dtype('S21')) into list(str)
+ axes_ds_names = map(str, axes_ds_names)
+ if axis_name not in axes_ds_names:
+ raise KeyError("group attr @axes does not mention a dataset " +
+ "named '%s'" % axis_name)
+ errors = self.group[uncertainties_names[list(axes_ds_names).index(axis_name)]]
+ if fg_idx == 0 and lg_idx == (len_axis-1):
+ return errors # dataset
+ else:
+ return errors[fg_idx:lg_idx + 1] # numpy array
+ return None
+
+ @property
+ def errors(self):
+ """Return errors (uncertainties) associated with the signal values.
+
+ :return: Dataset with errors, or None
+ """
+ if "errors" not in self.group:
+ return None
+ return self.group["errors"]
+
+ @property
+ def is_scatter(self):
+ """True if the signal is 1D and all the axes have the
+ same size as the signal."""
+ if self._is_scatter is not None:
+ return self._is_scatter
+ if not self.signal_is_1d:
+ self._is_scatter = False
+ else:
+ self._is_scatter = True
+ sigsize = 1
+ for dim in self.signal.shape:
+ sigsize *= dim
+ for axis in self.axes:
+ if axis is None:
+ continue
+ axis_size = 1
+ for dim in axis.shape:
+ axis_size *= dim
+ self._is_scatter = self._is_scatter and (axis_size == sigsize)
+ return self._is_scatter
+
+ @property
+ def is_x_y_value_scatter(self):
+ """True if this is a scatter with a signal and two axes."""
+ return self.is_scatter and len(self.axes) == 2
+
+ # we currently have no widget capable of plotting 4D data
+ @property
+ def is_unsupported_scatter(self):
+ """True if this is a scatter with a signal and more than 2 axes."""
+ return self.is_scatter and len(self.axes) > 2
diff --git a/silx/io/octaveh5.py b/silx/io/octaveh5.py
new file mode 100644
index 0000000..e63c026
--- /dev/null
+++ b/silx/io/octaveh5.py
@@ -0,0 +1,176 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""
+Python h5 module and octave h5 module have different ways to deal with
+h5 files.
+This module is used to make the link between octave and python using such files.
+(python is using a dictionary and octave a struct )
+
+This module provides tool to set HDF5 file for fasttomo input.
+
+Here is an example of a simple read and write :
+
+.. code-block:: python
+ :emphasize-lines: 3,5
+
+ # writing a structure
+ myStruct = {'MKEEP_MASK': 0.0, 'UNSHARP_SIGMA': 0.80000000000000004 }
+ writer = Octaveh5().open("my_h5file", 'a')
+ writer.write('mt_struct_name', myStruct)
+
+ # reading a h5 file
+ reader = Octaveh5().open("my_h5file")
+ strucDict = reader.get('mt_struct_name')
+
+.. note:: These functions depend on the `h5py <http://www.h5py.org/>`_
+ library, which is not a mandatory dependency for `silx`.
+
+"""
+
+import logging
+logger = logging.getLogger(__name__)
+import numpy as np
+
+try:
+ import h5py
+except ImportError as e:
+ logger.error("Module " + __name__ + " requires h5py")
+ raise e
+
+__authors__ = ["C. Nemoz", "H. Payno"]
+__license__ = "MIT"
+__date__ = "05/10/2016"
+
+
+class Octaveh5(object):
+ """This class allows communication between octave and python using hdf5 format.
+ """
+
+ def __init__(self, octave_targetted_version=3.8):
+ """Constructor
+
+ :param octave_targetted_version: the version of Octave for which we want to write this hdf5 file.
+
+ This is needed because for old Octave version we need to had a hack(adding one extra character)
+ """
+ self.file = None
+ self.octave_targetted_version = octave_targetted_version
+
+ def open(self, h5file, mode='r'):
+ """Open the h5 file which has been write by octave
+
+ :param h5file: The path of the file to read
+ :param mode: the opening mode of the file :'r', 'w'...
+ """
+ try:
+ self.file = h5py.File(h5file, mode)
+ return self
+ except IOError as e:
+ if mode == 'a':
+ reason = "\n %s: Can t find or create " % h5file
+ else:
+ reason = "\n %s: File not found" % h5file
+ self.file = None
+
+ logger.info(reason)
+ raise e
+
+ def get(self, struct_name):
+ """Read octave equivalent structures in hdf5 file
+
+ :param struct_name: the identification of the top level identity we want to get from an hdf5 structure
+ :return: the dictionnary of the requested struct. None if can t find it
+ """
+ if self.file is None:
+ info = "No file currently open"
+ logger.info(info)
+ return None
+
+ data_dict = {}
+ grr = (list(self.file[struct_name].items())[1])[1]
+ try:
+ gr_level2 = grr.items()
+ except AttributeError:
+ reason = "no gr_level2"
+ logger.info(reason)
+ return None
+
+ for key, val in iter(dict(gr_level2).items()):
+ data_dict[str(key)] = list(val.items())[1][1].value
+
+ if list(val.items())[0][1].value != np.string_('sq_string'):
+ data_dict[str(key)] = float(data_dict[str(key)])
+ else:
+ if list(val.items())[0][1].value == np.string_('sq_string'):
+ # in the case the string has been stored as an nd-array of char
+ if type(data_dict[str(key)]) is np.ndarray:
+ data_dict[str(key)] = "".join(chr(item) for item in data_dict[str(key)])
+ else:
+ data_dict[str(key)] = data_dict[str(key)].decode('UTF-8')
+
+ # In the case Octave have added an extra character at the end
+ if self.octave_targetted_version < 3.8:
+ data_dict[str(key)] = data_dict[str(key)][:-1]
+
+ return data_dict
+
+ def write(self, struct_name, data_dict):
+ """write data_dict under the group struct_name in the open hdf5 file
+
+ :param struct_name: the identificatioon of the structure to write in the hdf5
+ :param data_dict: The python dictionnary containing the informations to write
+ """
+ if self.file is None:
+ info = "No file currently open"
+ logger.info(info)
+ return
+
+ group_l1 = self.file.create_group(struct_name)
+ group_l1.attrs['OCTAVE_GLOBAL'] = np.uint8(1)
+ group_l1.attrs['OCTAVE_NEW_FORMAT'] = np.uint8(1)
+ group_l1.create_dataset("type", data=np.string_('scalar struct'), dtype="|S14")
+ group_l2 = group_l1.create_group('value')
+ for ftparams in data_dict:
+ group_l3 = group_l2.create_group(ftparams)
+ group_l3.attrs['OCTAVE_NEW_FORMAT'] = np.uint8(1)
+ if type(data_dict[ftparams]) == str:
+ group_l3.create_dataset("type", (), data=np.string_('sq_string'), dtype="|S10")
+ if self.octave_targetted_version < 3.8:
+ group_l3.create_dataset("value", data=np.string_(data_dict[ftparams] + '0'))
+ else:
+ group_l3.create_dataset("value", data=np.string_(data_dict[ftparams]))
+ else:
+ group_l3.create_dataset("type", (), data=np.string_('scalar'), dtype="|S7")
+ group_l3.create_dataset("value", data=data_dict[ftparams])
+
+ def close(self):
+ """Close the file after calling read function
+ """
+ if self.file:
+ self.file.close()
+
+ def __del__(self):
+ """Destructor
+ """
+ self.close()
diff --git a/silx/io/setup.py b/silx/io/setup.py
new file mode 100644
index 0000000..3483bcb
--- /dev/null
+++ b/silx/io/setup.py
@@ -0,0 +1,88 @@
+# coding: ascii
+#
+# JK: Numpy.distutils which imports this does not handle utf-8 in version<1.12
+#
+# /*##########################################################################
+#
+# Copyright (c) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+
+__authors__ = ["P. Knobel", "V.A. Sole"]
+__license__ = "MIT"
+__date__ = "03/10/2016"
+
+import os
+import sys
+
+import numpy
+from numpy.distutils.misc_util import Configuration
+
+
+# Locale and platform management
+SPECFILE_USE_GNU_SOURCE = os.getenv("SPECFILE_USE_GNU_SOURCE")
+if SPECFILE_USE_GNU_SOURCE is None:
+ SPECFILE_USE_GNU_SOURCE = 0
+ if sys.platform.lower().startswith("linux"):
+ warn = ("silx.io.specfile WARNING:",
+ "A cleaner locale independent implementation",
+ "may be achieved setting SPECFILE_USE_GNU_SOURCE to 1",
+ "For instance running this script as:",
+ "SPECFILE_USE_GNU_SOURCE=1 python setup.py build")
+ print(os.linesep.join(warn))
+else:
+ SPECFILE_USE_GNU_SOURCE = int(SPECFILE_USE_GNU_SOURCE)
+
+if sys.platform == "win32":
+ define_macros = [('WIN32', None)]
+elif os.name.lower().startswith('posix'):
+ define_macros = [('SPECFILE_POSIX', None)]
+ # the best choice is to have _GNU_SOURCE defined
+ # as a compilation flag because that allows the
+ # use of strtod_l
+ if SPECFILE_USE_GNU_SOURCE:
+ define_macros = [('_GNU_SOURCE', 1)]
+else:
+ define_macros = []
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('io', parent_package, top_path)
+ config.add_subpackage('test')
+
+ srcfiles = ['sfheader', 'sfinit', 'sflists', 'sfdata', 'sfindex',
+ 'sflabel', 'sfmca', 'sftools', 'locale_management']
+ sources = [os.path.join('specfile', 'src', ffile + '.c') for ffile in srcfiles]
+ sources.append(os.path.join('specfile', 'specfile.pyx'))
+
+ config.add_extension('specfile',
+ sources=sources,
+ define_macros=define_macros,
+ include_dirs=[os.path.join('specfile', 'include'),
+ numpy.get_include()],
+ language='c')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/io/specfile/include/Lists.h b/silx/io/specfile/include/Lists.h
new file mode 100644
index 0000000..bcda100
--- /dev/null
+++ b/silx/io/specfile/include/Lists.h
@@ -0,0 +1,51 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/***************************************************************************
+ *
+ * File: Lists.h
+ *
+ * Description: Include file for dealing with lists.
+ *
+ * Author: Vicente Rey
+ *
+ * Created: 22 May 1995
+ *
+ * (copyright by E.S.R.F. March 1995)
+ *
+ ***************************************************************************/
+#ifndef LISTS_H
+#define LISTS_H
+
+/* #include <malloc.h> */
+
+typedef struct _ObjectList {
+ struct _ObjectList *next;
+ struct _ObjectList *prev;
+ void *contents;
+} ObjectList;
+
+typedef struct _ListHeader {
+ struct _ObjectList *first;
+ struct _ObjectList *last;
+} ListHeader;
+
+extern ObjectList * findInList ( ListHeader *list, int (*proc)(void *,void *), void *value );
+extern long addToList ( ListHeader *list, void *object,long size);
+extern void unlinkFromList ( ListHeader *list, ObjectList *element);
+
+#endif /* LISTS_H */
diff --git a/silx/io/specfile/include/SpecFile.h b/silx/io/specfile/include/SpecFile.h
new file mode 100644
index 0000000..fce729c
--- /dev/null
+++ b/silx/io/specfile/include/SpecFile.h
@@ -0,0 +1,291 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/***************************************************************************
+ *
+ * File: SpecFile.h
+ *
+ * Description: Include file for treating spec data files.
+ *
+ * Author: Vicente Rey
+ *
+ * Created: 2 March 1995
+ *
+ * (copyright by E.S.R.F. March 1995)
+ *
+ ***************************************************************************/
+#ifndef SPECFILE_H
+#define SPECFILE_H
+
+#include <math.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <time.h>
+#include <stdlib.h>
+/* #include <malloc.h> */
+#include <string.h>
+#include <Lists.h>
+
+#ifdef _WINDOWS /* compiling on windows */
+#include <windows.h>
+#include <io.h>
+#define SF_OPENFLAG O_RDONLY | O_BINARY
+#define SF_WRITEFLAG O_CREAT | O_WRONLY
+#define SF_UMASK 0666
+#else /* if not windows */
+#define SF_OPENFLAG O_RDONLY
+#define SF_WRITEFLAG O_CREAT | O_WRONLY
+#define SF_UMASK 0666
+#endif
+
+#ifdef _GENLIB /* for windows dll generation */
+#define DllExport __declspec (dllexport)
+#else
+#define DllExport
+#endif
+
+
+#ifdef SUN4
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+/*
+ * Defines.
+ */
+#define ROW 0 /* data_info index for no. of data rows */
+#define COL 1 /* data_info index for no. of data columns*/
+#define REG 2 /* data_info index for regular */
+#define H 0
+#define K 1
+#define L 2
+#define ABORTED -1
+#define NOT_ABORTED 0
+
+#define SF_ERR_NO_ERRORS 0
+#define SF_ERR_MEMORY_ALLOC 1
+#define SF_ERR_FILE_OPEN 2
+#define SF_ERR_FILE_CLOSE 3
+#define SF_ERR_FILE_READ 4
+#define SF_ERR_FILE_WRITE 5
+#define SF_ERR_LINE_NOT_FOUND 6
+#define SF_ERR_SCAN_NOT_FOUND 7
+#define SF_ERR_HEADER_NOT_FOUND 8
+#define SF_ERR_LABEL_NOT_FOUND 9
+#define SF_ERR_MOTOR_NOT_FOUND 10
+#define SF_ERR_POSITION_NOT_FOUND 11
+#define SF_ERR_LINE_EMPTY 12
+#define SF_ERR_USER_NOT_FOUND 13
+#define SF_ERR_COL_NOT_FOUND 14
+#define SF_ERR_MCA_NOT_FOUND 15
+
+typedef struct _SfCursor {
+ long int scanno; /* nb of scans */
+ long int cursor; /* beginning of current scan */
+ long int hdafoffset; /* global offset of header after beginning of data */
+ long int datalines; /* contains nb of data lines */
+ long int dataoffset; /* contains data offset from begin of scan */
+ long int mcaspectra; /* contains nb of mca spectra in scan */
+ long int bytecnt; /* total file byte count */
+ long int what; /* scan of file block */
+ long int data; /* data flag */
+ long int file_header; /* address of file header for this scan */
+ long int fileh_size; /* size of it */
+} SfCursor;
+
+
+typedef struct _SpecFile{
+ int fd;
+ long m_time;
+ char *sfname;
+ struct _ListHeader list;
+ long int no_scans;
+ ObjectList *current;
+ char *scanbuffer;
+ long scanheadersize;
+ char *filebuffer;
+ long filebuffersize;
+ long scansize;
+ char **labels;
+ long int no_labels;
+ char **motor_names;
+ long int no_motor_names;
+ double *motor_pos;
+ long int no_motor_pos;
+ double **data;
+ long *data_info;
+ SfCursor cursor;
+ short updating;
+} SpecFile;
+
+typedef struct _SpecFileOut{
+ SpecFile *sf;
+ long *list;
+ long list_size;
+ long file_header;
+} SpecFileOut;
+
+typedef struct _SpecScan {
+ long int index;
+ long int scan_no;
+ long int order;
+ long int offset;
+ long int size;
+ long int last;
+ long int file_header;
+ long int data_offset;
+ long int hdafter_offset;
+ long int mcaspectra;
+} SpecScan;
+
+/*
+ * Function declarations.
+ */
+
+ /*
+ * Init
+ */
+/*
+ * init
+ */
+DllExport extern SpecFile *SfOpen ( char *name, int *error );
+DllExport extern short SfUpdate ( SpecFile *sf,int *error );
+DllExport extern int SfClose ( SpecFile *sf );
+
+/*
+ * indexes
+ */
+DllExport extern long SfScanNo ( SpecFile *sf );
+DllExport extern long *SfList ( SpecFile *sf, int *error );
+DllExport extern long SfCondList ( SpecFile *sf, long cond,
+ long **scan_list, int *error );
+DllExport extern long SfIndex ( SpecFile *sf, long number,
+ long order );
+DllExport extern long SfIndexes ( SpecFile *sf, long number,
+ long **indexlist );
+DllExport extern long SfNumber ( SpecFile *sf, long index );
+DllExport extern long SfOrder ( SpecFile *sf, long index );
+DllExport extern int SfNumberOrder ( SpecFile *sf, long index,
+ long *number, long *order );
+
+ /*
+ * Header
+ */
+DllExport extern char *SfCommand ( SpecFile *sf, long index, int *error );
+DllExport extern long SfNoColumns ( SpecFile *sf, long index, int *error );
+DllExport extern char *SfDate ( SpecFile *sf, long index, int *error );
+DllExport extern long SfEpoch ( SpecFile *sf, long index, int *error );
+DllExport extern long SfNoHeaderBefore ( SpecFile *sf, long index, int *error );
+DllExport extern double *SfHKL ( SpecFile *sf, long index, int *error );
+DllExport extern long SfHeader ( SpecFile *sf, long index, char *string,
+ char ***lines, int *error );
+DllExport extern long SfGeometry ( SpecFile *sf, long index,
+ char ***lines, int *error );
+DllExport extern long SfFileHeader ( SpecFile *sf, long index, char *string,
+ char ***lines, int *error );
+DllExport extern char *SfFileDate ( SpecFile *sf, long index, int *error );
+DllExport extern char *SfUser ( SpecFile *sf, long index, int *error );
+DllExport extern char *SfTitle ( SpecFile *sf, long index, int *error );
+
+ /*
+ * Labels
+ */
+DllExport extern long SfAllLabels ( SpecFile *sf, long index,
+ char ***labels, int *error );
+DllExport extern char *SfLabel ( SpecFile *sf, long index, long column,
+ int *error );
+
+ /*
+ * Motors
+ */
+DllExport extern long SfAllMotors ( SpecFile *sf, long index,
+ char ***names, int *error );
+DllExport extern char * SfMotor ( SpecFile *sf, long index,
+ long number, int *error );
+DllExport extern long SfAllMotorPos ( SpecFile *sf, long index,
+ double **pos, int *error );
+DllExport extern double SfMotorPos ( SpecFile *sf, long index,
+ long number, int *error );
+DllExport extern double SfMotorPosByName ( SpecFile *sf, long index,
+ char *name, int *error );
+
+ /*
+ * Data
+ */
+DllExport extern long SfNoDataLines ( SpecFile *sf, long index, int *error );
+DllExport extern int SfData ( SpecFile *sf, long index,
+ double ***data, long **data_info, int *error );
+DllExport extern long SfDataAsString ( SpecFile *sf, long index,
+ char ***data, int *error );
+DllExport extern long SfDataLine ( SpecFile *sf, long index, long line,
+ double **data_line, int *error );
+DllExport extern long SfDataCol ( SpecFile *sf, long index, long col,
+ double **data_col, int *error );
+DllExport extern long SfDataColByName ( SpecFile *sf, long index,
+ char *label, double **data_col, int *error );
+
+ /*
+ * MCA functions
+ */
+DllExport extern long SfNoMca ( SpecFile *sf, long index, int *error );
+DllExport extern int SfGetMca ( SpecFile *sf, long index, long mcano,
+ double **retdata, int *error );
+DllExport extern long SfMcaCalib ( SpecFile *sf, long index, double **calib,
+ int *error );
+
+ /*
+ * Write and write related functions
+ */
+DllExport extern SpecFileOut *SfoInit ( SpecFile *sf, int *error );
+DllExport extern void SfoClose ( SpecFileOut *sfo );
+DllExport extern long SfoSelectAll ( SpecFileOut *sfo, int *error );
+DllExport extern long SfoSelectOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport extern long SfoSelect ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport extern long SfoSelectRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport extern long SfoRemoveOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport extern long SfoRemove ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport extern long SfoRemoveRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport extern long SfoRemoveAll ( SpecFileOut *sfo, int *error );
+DllExport extern long SfoWrite ( SpecFileOut *sfo, char *name,
+ int *error );
+DllExport extern long SfoGetList ( SpecFileOut *sfo, long **list,
+ int *error );
+ /*
+ * Memory free functions
+ */
+DllExport extern void freeArrNZ ( void ***ptr, long no_lines );
+DllExport extern void freePtr ( void *ptr );
+
+ /*
+ * Sf Tools
+ */
+DllExport extern void SfShow ( SpecFile *sf );
+DllExport extern void SfShowScan ( SpecFile *sf ,long index);
+ /*
+ * Error
+ */
+DllExport extern char *SfError ( int code );
+
+#endif /* SPECFILE_H */
diff --git a/silx/io/specfile/include/SpecFileCython.h b/silx/io/specfile/include/SpecFileCython.h
new file mode 100644
index 0000000..3225e13
--- /dev/null
+++ b/silx/io/specfile/include/SpecFileCython.h
@@ -0,0 +1,28 @@
+#/*##########################################################################
+# coding: utf-8
+# Copyright (C) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+#############################################################################*/
+
+/* The original SpecFile.h has a `#define L 2` directive
+ that breaks cython lists and memory views. */
+#include "SpecFile.h"
+#undef L
diff --git a/silx/io/specfile/include/SpecFileP.h b/silx/io/specfile/include/SpecFileP.h
new file mode 100644
index 0000000..de9904d
--- /dev/null
+++ b/silx/io/specfile/include/SpecFileP.h
@@ -0,0 +1,74 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/***************************************************************************
+ *
+ * File: SpecFileP.h
+ *
+ * Description: Include file for treating spec data files.
+ *
+ * Author: Vicente Rey
+ *
+ * Created: 2 March 1995
+ *
+ * (copyright by E.S.R.F. March 1995)
+ *
+ ***************************************************************************/
+#ifndef SPECFILE_P_H
+#define SPECFILE_P_H
+
+/*
+ * Defines.
+ */
+#define FILE_HEADER 0
+#define SCAN 1
+
+#define FROM_SCAN 0
+#define FROM_FILE 1
+
+#define SF_COMMENT 'C'
+#define SF_DATE 'D'
+#define SF_EPOCH 'E'
+#define SF_FILE_NAME 'F'
+#define SF_GEOMETRY 'G'
+#define SF_INTENSITY 'I'
+#define SF_LABEL 'L'
+#define SF_MON_NORM 'M'
+#define SF_COLUMNS 'N'
+#define SF_MOTOR_NAMES 'O'
+#define SF_MOTOR_POSITIONS 'P'
+#define SF_RECIP_SPACE 'Q'
+#define SF_RESULTS 'R'
+#define SF_SCAN_NUM 'S'
+#define SF_TIME_NORM 'T'
+#define SF_USER_DEFINED 'U'
+#define SF_TEMPERATURE 'X'
+#define SF_MCA_DATA '@'
+
+/*
+ * Library internal functions
+ */
+extern int sfSetCurrent ( SpecFile *sf, long index, int *error);
+extern ObjectList *findScanByIndex ( ListHeader *list, long index );
+extern ObjectList *findScanByNo ( ListHeader *list, long scan_no, long order );
+extern void freeArr ( void ***ptr, long lines );
+extern void freeAllData ( SpecFile *sf );
+extern long mulstrtod ( char *str, double **arr, int *error );
+extern int sfGetHeaderLine ( SpecFile *sf, int from, char character,
+ char **buf,int *error);
+
+#endif /* SPECFILE_P_H */
diff --git a/silx/io/specfile/include/locale_management.h b/silx/io/specfile/include/locale_management.h
new file mode 100644
index 0000000..d3b9f51
--- /dev/null
+++ b/silx/io/specfile/include/locale_management.h
@@ -0,0 +1,23 @@
+#/*##########################################################################
+# Copyright (C) 2012-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+#ifndef PyMca_LOCALE_MANAGEMENT_H
+#define PyMca_LOCALE_MANAGEMENT_H
+
+double PyMcaAtof(const char*);
+
+#endif
diff --git a/silx/io/specfile/specfile.c b/silx/io/specfile/specfile.c
new file mode 100644
index 0000000..17e3eb2
--- /dev/null
+++ b/silx/io/specfile/specfile.c
@@ -0,0 +1,21782 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__specfile
+#define __PYX_HAVE_API__specfile
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include "SpecFileCython.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+ #if defined(__cplusplus)
+ #define CYTHON_CCOMPLEX 1
+ #elif defined(_Complex_I)
+ #define CYTHON_CCOMPLEX 1
+ #else
+ #define CYTHON_CCOMPLEX 0
+ #endif
+#endif
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #include <complex>
+ #else
+ #include <complex.h>
+ #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+ #undef _Complex_I
+ #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+ "specfile.pyx",
+ "__init__.pxd",
+ "type.pxd",
+};
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":723
+ * # in Cython to enable them only on the right systems.
+ *
+ * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":724
+ *
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":725
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int64 int64_t
+ * #ctypedef npy_int96 int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96 int96_t
+ * #ctypedef npy_int128 int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":730
+ * #ctypedef npy_int128 int128_t
+ *
+ * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":731
+ *
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":732
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64 uint64_t
+ * #ctypedef npy_uint96 uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96 uint96_t
+ * #ctypedef npy_uint128 uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":737
+ * #ctypedef npy_uint128 uint128_t
+ *
+ * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_float64 float64_t
+ * #ctypedef npy_float80 float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":738
+ *
+ * ctypedef npy_float32 float32_t
+ * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80 float80_t
+ * #ctypedef npy_float128 float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong longlong_t
+ *
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":749
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_ulong uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * ctypedef npy_longlong longlong_t
+ *
+ * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ *
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":753
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_intp intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ * ctypedef npy_intp intp_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp uintp_t
+ *
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ *
+ * ctypedef npy_intp intp_t
+ * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_double float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_uintp uintp_t
+ *
+ * ctypedef npy_double float_t # <<<<<<<<<<<<<<
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ *
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ *
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":760
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cfloat cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< float > __pyx_t_float_complex;
+ #else
+ typedef float _Complex __pyx_t_float_complex;
+ #endif
+#else
+ typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< double > __pyx_t_double_complex;
+ #else
+ typedef double _Complex __pyx_t_double_complex;
+ #endif
+#else
+ typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_8specfile_SpecFile;
+struct __pyx_obj_8specfile___pyx_scope_struct____iter__;
+struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ *
+ * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ *
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":764
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cdouble complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "specfile_wrapper.pxd":35
+ * pass
+ * # Renaming struct because we have too many SpecFile items (files, classes)
+ * ctypedef _SpecFile SpecFileHandle # <<<<<<<<<<<<<<
+ *
+ * cdef extern from "SpecFileCython.h":
+ */
+typedef struct _SpecFile __pyx_t_16specfile_wrapper_SpecFileHandle;
+
+/* "specfile.pyx":647
+ *
+ *
+ * cdef class SpecFile(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+struct __pyx_obj_8specfile_SpecFile {
+ PyObject_HEAD
+ __pyx_t_16specfile_wrapper_SpecFileHandle *handle;
+ PyObject *filename;
+ int __pyx___open_failed;
+};
+
+
+/* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+struct __pyx_obj_8specfile___pyx_scope_struct____iter__ {
+ PyObject_HEAD
+ Py_ssize_t __pyx_v_mca_index;
+ PyObject *__pyx_v_self;
+ Py_ssize_t __pyx_t_0;
+ Py_ssize_t __pyx_t_1;
+};
+
+
+/* "specfile.pyx":698
+ * return specfile_wrapper.SfScanNo(self.handle)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next :class:`Scan` in a SpecFile each time this method
+ * is called.
+ */
+struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ {
+ PyObject_HEAD
+ Py_ssize_t __pyx_v_scan_index;
+ struct __pyx_obj_8specfile_SpecFile *__pyx_v_self;
+ Py_ssize_t __pyx_t_0;
+ Py_ssize_t __pyx_t_1;
+};
+
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o,n,NULL)
+static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_setattro))
+ return tp->tp_setattro(obj, attr_name, value);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_setattr))
+ return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value);
+#endif
+ return PyObject_SetAttr(obj, attr_name, value);
+}
+#else
+#define __Pyx_PyObject_DelAttrStr(o,n) PyObject_DelAttr(o,n)
+#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq, int eq) {
+ int result = PySequence_Contains(seq, item);
+ return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg);
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+#if PY_MAJOR_VERSION < 3
+#define __Pyx_PyString_Join __Pyx_PyBytes_Join
+#define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v))
+#else
+#define __Pyx_PyString_Join PyUnicode_Join
+#define __Pyx_PyBaseString_Join PyUnicode_Join
+#endif
+#if CYTHON_COMPILING_IN_CPYTHON
+ #if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyBytes_Join _PyString_Join
+ #else
+ #define __Pyx_PyBytes_Join _PyBytes_Join
+ #endif
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values);
+#endif
+
+static CYTHON_INLINE int __Pyx_PyDict_Contains(PyObject* item, PyObject* dict, int eq) {
+ int result = PyDict_Contains(dict, item);
+ return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+ PyObject *value;
+ value = PyDict_GetItemWithError(d, key);
+ if (unlikely(!value)) {
+ if (!PyErr_Occurred()) {
+ PyObject* args = PyTuple_Pack(1, key);
+ if (likely(args))
+ PyErr_SetObject(PyExc_KeyError, args);
+ Py_XDECREF(args);
+ }
+ return NULL;
+ }
+ Py_INCREF(value);
+ return value;
+}
+#else
+ #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
+ const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE PyObject* __Pyx_decode_bytes(
+ PyObject* string, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ return __Pyx_decode_c_bytes(
+ PyBytes_AS_STRING(string), PyBytes_GET_SIZE(string),
+ start, stop, encoding, errors, decode_func);
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
+ __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck);
+
+#include <string.h>
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases);
+
+static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname,
+ PyObject *mkw, PyObject *modname, PyObject *doc);
+static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict,
+ PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass);
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
+
+#define __Pyx_CyFunction_USED 1
+#include <structmember.h>
+#define __Pyx_CYFUNCTION_STATICMETHOD 0x01
+#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02
+#define __Pyx_CYFUNCTION_CCLASS 0x04
+#define __Pyx_CyFunction_GetClosure(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_closure)
+#define __Pyx_CyFunction_GetClassObj(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_classobj)
+#define __Pyx_CyFunction_Defaults(type, f) \
+ ((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
+#define __Pyx_CyFunction_SetDefaultsGetter(f, g) \
+ ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g)
+typedef struct {
+ PyCFunctionObject func;
+#if PY_VERSION_HEX < 0x030500A0
+ PyObject *func_weakreflist;
+#endif
+ PyObject *func_dict;
+ PyObject *func_name;
+ PyObject *func_qualname;
+ PyObject *func_doc;
+ PyObject *func_globals;
+ PyObject *func_code;
+ PyObject *func_closure;
+ PyObject *func_classobj;
+ void *defaults;
+ int defaults_pyobjects;
+ int flags;
+ PyObject *defaults_tuple;
+ PyObject *defaults_kwdict;
+ PyObject *(*defaults_getter)(PyObject *);
+ PyObject *func_annotations;
+} __pyx_CyFunctionObject;
+static PyTypeObject *__pyx_CyFunctionType = 0;
+#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
+ __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
+ int flags, PyObject* qualname,
+ PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject* code);
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
+ size_t size,
+ int pyobjects);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
+ PyObject *tuple);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m,
+ PyObject *dict);
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
+ PyObject *dict);
+static int __Pyx_CyFunction_init(void);
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #define __Pyx_CREAL(z) ((z).real())
+ #define __Pyx_CIMAG(z) ((z).imag())
+ #else
+ #define __Pyx_CREAL(z) (__real__(z))
+ #define __Pyx_CIMAG(z) (__imag__(z))
+ #endif
+#else
+ #define __Pyx_CREAL(z) ((z).real)
+ #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+ #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+ #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+ #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+ #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eqf(a, b) ((a)==(b))
+ #define __Pyx_c_sumf(a, b) ((a)+(b))
+ #define __Pyx_c_difff(a, b) ((a)-(b))
+ #define __Pyx_c_prodf(a, b) ((a)*(b))
+ #define __Pyx_c_quotf(a, b) ((a)/(b))
+ #define __Pyx_c_negf(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+ #define __Pyx_c_conjf(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_absf(z) (::std::abs(z))
+ #define __Pyx_c_powf(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zerof(z) ((z)==0)
+ #define __Pyx_c_conjf(z) (conjf(z))
+ #if 1
+ #define __Pyx_c_absf(z) (cabsf(z))
+ #define __Pyx_c_powf(a, b) (cpowf(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eq(a, b) ((a)==(b))
+ #define __Pyx_c_sum(a, b) ((a)+(b))
+ #define __Pyx_c_diff(a, b) ((a)-(b))
+ #define __Pyx_c_prod(a, b) ((a)*(b))
+ #define __Pyx_c_quot(a, b) ((a)/(b))
+ #define __Pyx_c_neg(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zero(z) ((z)==(double)0)
+ #define __Pyx_c_conj(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (::std::abs(z))
+ #define __Pyx_c_pow(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zero(z) ((z)==0)
+ #define __Pyx_c_conj(z) (conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (cabs(z))
+ #define __Pyx_c_pow(a, b) (cpow(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+#define __Pyx_Generator_USED
+#include <structmember.h>
+#include <frameobject.h>
+typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
+typedef struct {
+ PyObject_HEAD
+ __pyx_generator_body_t body;
+ PyObject *closure;
+ PyObject *exc_type;
+ PyObject *exc_value;
+ PyObject *exc_traceback;
+ PyObject *gi_weakreflist;
+ PyObject *classobj;
+ PyObject *yieldfrom;
+ PyObject *gi_name;
+ PyObject *gi_qualname;
+ int resume_label;
+ char is_running;
+} __pyx_GeneratorObject;
+static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
+ PyObject *closure, PyObject *name, PyObject *qualname);
+static int __pyx_Generator_init(void);
+static int __Pyx_Generator_clear(PyObject* self);
+#if 1 || PY_VERSION_HEX < 0x030300B0
+static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
+#else
+#define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue)
+#endif
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+ #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'specfile_wrapper' */
+
+/* Module declarations from 'specfile' */
+static PyTypeObject *__pyx_ptype_8specfile_SpecFile = 0;
+static PyTypeObject *__pyx_ptype_8specfile___pyx_scope_struct____iter__ = 0;
+static PyTypeObject *__pyx_ptype_8specfile___pyx_scope_struct_1___iter__ = 0;
+#define __Pyx_MODULE_NAME "specfile"
+int __pyx_module_is_main_specfile = 0;
+
+/* Implementation of 'specfile' */
+static PyObject *__pyx_builtin_Exception;
+static PyObject *__pyx_builtin_object;
+static PyObject *__pyx_builtin_property;
+static PyObject *__pyx_builtin_map;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_open;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_KeyError;
+static PyObject *__pyx_builtin_AttributeError;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_pf_8specfile_3MCA___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_scan); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_2_parse_channels(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_4_parse_calibration(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_6__len__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_8__getitem__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_10__iter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile__add_or_concatenate(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_dictionary, PyObject *__pyx_v_key, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_specfile, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_2index(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_4number(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_6order(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_8header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_10scan_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_12file_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_14scan_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_16mca_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_18file_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_20labels(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_22data(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_24mca(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_26motor_names(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_28motor_positions(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_30record_exists_in_hdr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_record); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_32data_line(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_line_index); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_34data_column_by_name(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_label); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_36motor_position_by_name(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_pf_8specfile_2_string_to_char_star(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_string_); /* proto */
+static PyObject *__pyx_pf_8specfile_4is_specfile(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename); /* proto */
+static int __pyx_pf_8specfile_8SpecFile___cinit__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
+static int __pyx_pf_8specfile_8SpecFile_2__init__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
+static void __pyx_pf_8specfile_8SpecFile_4__dealloc__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_pf_8specfile_8SpecFile_6__len__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_8__iter__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_11__getitem__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_13keys(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static int __pyx_pf_8specfile_8SpecFile_15__contains__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_17_get_error_string(CYTHON_UNUSED struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_error_code); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_19_handle_error(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_error_code); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_21index(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_number, PyObject *__pyx_v_scan_order); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_23number(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_25order(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_27_list(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_29list(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_31data(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_33data_column_by_name(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_label); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_35scan_header(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_37file_header(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_39columns(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_41command(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_43date(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_45labels(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_47motor_names(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_49motor_positions(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_51motor_position_by_name(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_53number_of_mca(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_55mca_calibration(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_57get_mca(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_mca_index); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static PyObject *__pyx_tp_new_8specfile_SpecFile(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_8specfile___pyx_scope_struct____iter__(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_8specfile___pyx_scope_struct_1___iter__(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_[] = "\n";
+static char __pyx_k_2[] = " {2,}";
+static char __pyx_k_3[] = "3";
+static char __pyx_k_B[] = "B";
+static char __pyx_k_F[] = "#F ";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_S[] = "#S ";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_w[] = "#(\\w+) *(.*)";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k__7[] = "#";
+static char __pyx_k_os[] = "os";
+static char __pyx_k_re[] = "re";
+static char __pyx_k_MCA[] = "MCA";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k__14[] = " ";
+static char __pyx_k__25[] = ".";
+static char __pyx_k__27[] = "', '";
+static char __pyx_k__28[] = "'";
+static char __pyx_k__29[] = "";
+static char __pyx_k_d_d[] = "%d.%d";
+static char __pyx_k_doc[] = "__doc__";
+static char __pyx_k_key[] = "key";
+static char __pyx_k_len[] = "__len__";
+static char __pyx_k_map[] = "map";
+static char __pyx_k_mca[] = "_mca";
+static char __pyx_k_msg[] = "msg";
+static char __pyx_k_ret[] = "ret";
+static char __pyx_k_sub[] = "sub";
+static char __pyx_k_sys[] = "sys";
+static char __pyx_k_w_2[] = "#@(\\w+) *(.*)";
+static char __pyx_k_Scan[] = "Scan";
+static char __pyx_k_args[] = "args";
+static char __pyx_k_data[] = "_data";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_hkey[] = "hkey";
+static char __pyx_k_init[] = "__init__";
+static char __pyx_k_iter[] = "__iter__";
+static char __pyx_k_join[] = "join";
+static char __pyx_k_keys[] = "keys";
+static char __pyx_k_line[] = "line";
+static char __pyx_k_list[] = "_list";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_open[] = "open";
+static char __pyx_k_path[] = "path";
+static char __pyx_k_scan[] = "scan";
+static char __pyx_k_self[] = "self";
+static char __pyx_k_send[] = "send";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_CALIB[] = "CALIB";
+static char __pyx_k_CHANN[] = "CHANN";
+static char __pyx_k_ascii[] = "ascii";
+static char __pyx_k_close[] = "close";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_group[] = "group";
+static char __pyx_k_index[] = "index";
+static char __pyx_k_label[] = "label";
+static char __pyx_k_match[] = "match";
+static char __pyx_k_mca_2[] = "mca";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_order[] = "order";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_split[] = "split";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_strip[] = "strip";
+static char __pyx_k_throw[] = "throw";
+static char __pyx_k_value[] = "value";
+static char __pyx_k_ERRORS[] = "ERRORS";
+static char __pyx_k_append[] = "append";
+static char __pyx_k_data_2[] = "data";
+static char __pyx_k_decode[] = "decode";
+static char __pyx_k_double[] = "double";
+static char __pyx_k_encode[] = "encode";
+static char __pyx_k_header[] = "_header";
+static char __pyx_k_hvalue[] = "hvalue";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_isfile[] = "isfile";
+static char __pyx_k_labels[] = "_labels";
+static char __pyx_k_length[] = "length";
+static char __pyx_k_logger[] = "_logger";
+static char __pyx_k_lstrip[] = "lstrip";
+static char __pyx_k_module[] = "__module__";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_number[] = "number";
+static char __pyx_k_object[] = "object";
+static char __pyx_k_record[] = "record";
+static char __pyx_k_scan_2[] = "_scan";
+static char __pyx_k_search[] = "search";
+static char __pyx_k_string[] = "string_";
+static char __pyx_k_SfError[] = "SfError";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_get_mca[] = "get_mca";
+static char __pyx_k_getitem[] = "__getitem__";
+static char __pyx_k_index_2[] = "_index";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_logging[] = "logging";
+static char __pyx_k_order_2[] = "_order";
+static char __pyx_k_os_path[] = "os.path";
+static char __pyx_k_prepare[] = "__prepare__";
+static char __pyx_k_version[] = "version";
+static char __pyx_k_warning[] = "warning";
+static char __pyx_k_KeyError[] = "KeyError";
+static char __pyx_k_L_header[] = "L_header";
+static char __pyx_k_P_Knobel[] = "P. Knobel";
+static char __pyx_k_Scan_mca[] = "Scan.mca";
+static char __pyx_k_channels[] = "channels";
+static char __pyx_k_filename[] = "filename";
+static char __pyx_k_header_2[] = "header";
+static char __pyx_k_labels_2[] = "labels";
+static char __pyx_k_number_2[] = "_number";
+static char __pyx_k_property[] = "property";
+static char __pyx_k_qualname[] = "__qualname__";
+static char __pyx_k_specfile[] = "_specfile";
+static char __pyx_k_Exception[] = "Exception";
+static char __pyx_k_MCA___len[] = "MCA.__len__";
+static char __pyx_k_Scan_data[] = "Scan.data";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_data_line[] = "data_line";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_getLogger[] = "getLogger";
+static char __pyx_k_increment[] = "increment";
+static char __pyx_k_match_mca[] = "match_mca";
+static char __pyx_k_mca_index[] = "mca_index";
+static char __pyx_k_metaclass[] = "__metaclass__";
+static char __pyx_k_transpose[] = "transpose";
+static char __pyx_k_27_09_2016[] = "27/09/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_MCA___init[] = "MCA.__init__";
+static char __pyx_k_MCA___iter[] = "MCA.__iter__";
+static char __pyx_k_Scan_index[] = "Scan.index";
+static char __pyx_k_Scan_order[] = "Scan.order";
+static char __pyx_k_Valid_keys[] = "\nValid keys: '";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_calib_line[] = "calib_line";
+static char __pyx_k_chann_line[] = "chann_line";
+static char __pyx_k_dictionary[] = "dictionary";
+static char __pyx_k_line_index[] = "line_index";
+static char __pyx_k_scan_index[] = "scan_index";
+static char __pyx_k_scan_order[] = "scan_order";
+static char __pyx_k_specfile_2[] = "specfile";
+static char __pyx_k_startswith[] = "startswith";
+static char __pyx_k_Scan___init[] = "Scan.__init__";
+static char __pyx_k_Scan_header[] = "Scan.header";
+static char __pyx_k_Scan_labels[] = "Scan.labels";
+static char __pyx_k_Scan_number[] = "Scan.number";
+static char __pyx_k_basicConfig[] = "basicConfig";
+static char __pyx_k_calib_lines[] = "calib_lines";
+static char __pyx_k_calibration[] = "calibration";
+static char __pyx_k_chann_lines[] = "chann_lines";
+static char __pyx_k_file_header[] = "file_header";
+static char __pyx_k_is_specfile[] = "is_specfile";
+static char __pyx_k_motor_names[] = "motor_names";
+static char __pyx_k_scan_header[] = "scan_header";
+static char __pyx_k_scan_number[] = "scan_number";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_SfNoMcaError[] = "SfNoMcaError";
+static char __pyx_k_handle_error[] = "_handle_error";
+static char __pyx_k_version_info[] = "version_info";
+static char __pyx_k_MCA___getitem[] = "MCA.__getitem__";
+static char __pyx_k_SfErrFileOpen[] = "SfErrFileOpen";
+static char __pyx_k_SfErrFileRead[] = "SfErrFileRead";
+static char __pyx_k_motor_names_2[] = "_motor_names";
+static char __pyx_k_number_of_mca[] = "number_of_mca";
+static char __pyx_k_AttributeError[] = "AttributeError";
+static char __pyx_k_Scan_data_line[] = "Scan.data_line";
+static char __pyx_k_SfErrFileClose[] = "SfErrFileClose";
+static char __pyx_k_SfErrFileWrite[] = "SfErrFileWrite";
+static char __pyx_k_SfErrLineEmpty[] = "SfErrLineEmpty";
+static char __pyx_k_parse_channels[] = "_parse_channels";
+static char __pyx_k_SpecFile___iter[] = "SpecFile.__iter__";
+static char __pyx_k_mca_header_dict[] = "mca_header_dict";
+static char __pyx_k_motor_positions[] = "motor_positions";
+static char __pyx_k_SF_ERR_FILE_OPEN[] = "SF_ERR_FILE_OPEN";
+static char __pyx_k_SF_ERR_NO_ERRORS[] = "SF_ERR_NO_ERRORS";
+static char __pyx_k_Scan_file_header[] = "Scan.file_header";
+static char __pyx_k_Scan_motor_names[] = "Scan.motor_names";
+static char __pyx_k_Scan_scan_header[] = "Scan.scan_header";
+static char __pyx_k_SfErrColNotFound[] = "SfErrColNotFound";
+static char __pyx_k_SfErrMcaNotFound[] = "SfErrMcaNotFound";
+static char __pyx_k_SfErrMemoryAlloc[] = "SfErrMemoryAlloc";
+static char __pyx_k_all_calib_values[] = "all_calib_values";
+static char __pyx_k_all_chann_values[] = "all_chann_values";
+static char __pyx_k_file_header_dict[] = "_file_header_dict";
+static char __pyx_k_get_error_string[] = "_get_error_string";
+static char __pyx_k_scan_header_dict[] = "_scan_header_dict";
+static char __pyx_k_SfErrLineNotFound[] = "SfErrLineNotFound";
+static char __pyx_k_SfErrScanNotFound[] = "SfErrScanNotFound";
+static char __pyx_k_SfErrUserNotFound[] = "SfErrUserNotFound";
+static char __pyx_k_file_header_lines[] = "_file_header_lines";
+static char __pyx_k_mca_header_dict_2[] = "_mca_header_dict";
+static char __pyx_k_motor_positions_2[] = "_motor_positions";
+static char __pyx_k_parse_calibration[] = "_parse_calibration";
+static char __pyx_k_scan_header_lines[] = "_scan_header_lines";
+static char __pyx_k_SfErrLabelNotFound[] = "SfErrLabelNotFound";
+static char __pyx_k_SfErrMotorNotFound[] = "SfErrMotorNotFound";
+static char __pyx_k_SfNoMca_returned_1[] = "(SfNoMca returned -1)";
+static char __pyx_k_add_or_concatenate[] = "_add_or_concatenate";
+static char __pyx_k_file_header_dict_2[] = "file_header_dict";
+static char __pyx_k_scan_header_dict_2[] = "scan_header_dict";
+static char __pyx_k_MCA__parse_channels[] = "MCA._parse_channels";
+static char __pyx_k_SfErrHeaderNotFound[] = "SfErrHeaderNotFound";
+static char __pyx_k_data_column_by_name[] = "data_column_by_name";
+static char __pyx_k_string_to_char_star[] = "_string_to_char_star";
+static char __pyx_k_Scan_mca_header_dict[] = "Scan.mca_header_dict";
+static char __pyx_k_Scan_motor_positions[] = "Scan.motor_positions";
+static char __pyx_k_record_exists_in_hdr[] = "record_exists_in_hdr";
+static char __pyx_k_SF_ERR_SCAN_NOT_FOUND[] = "SF_ERR_SCAN_NOT_FOUND";
+static char __pyx_k_Scan_file_header_dict[] = "Scan.file_header_dict";
+static char __pyx_k_Scan_scan_header_dict[] = "Scan.scan_header_dict";
+static char __pyx_k_SfErrPositionNotFound[] = "SfErrPositionNotFound";
+static char __pyx_k_one_line_calib_values[] = "one_line_calib_values";
+static char __pyx_k_one_line_chann_values[] = "one_line_chann_values";
+static char __pyx_k_MCA__parse_calibration[] = "MCA._parse_calibration";
+static char __pyx_k_motor_position_by_name[] = "motor_position_by_name";
+static char __pyx_k_Scan_data_column_by_name[] = "Scan.data_column_by_name";
+static char __pyx_k_Scan_record_exists_in_hdr[] = "Scan.record_exists_in_hdr";
+static char __pyx_k_Scan_motor_position_by_name[] = "Scan.motor_position_by_name";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_Error_while_closing_SpecFile[] = "Error while closing SpecFile";
+static char __pyx_k_number_and_M_the_order_eg_2_3[] = " number and M the order (eg '2.3').";
+static char __pyx_k_MCA_index_must_be_in_range_0_d[] = "MCA index must be in range 0-%d";
+static char __pyx_k_param_specfile_Parent_SpecFile[] = "\n\n :param specfile: Parent SpecFile from which this scan is extracted.\n :type specfile: :class:`SpecFile`\n :param scan_index: Unique index defining the scan in the SpecFile\n :type scan_index: int\n\n Interface to access a SpecFile scan\n\n A scan is a block of descriptive header lines followed by a 2D data array.\n\n Following three ways of accessing a scan are equivalent::\n\n sf = SpecFile(\"/path/to/specfile.dat\")\n\n # Explicit class instantiation\n scan2 = Scan(sf, scan_index=2)\n\n # 0-based index on a SpecFile object\n scan2 = sf[2]\n\n # Using a \"n.m\" key (scan number starting with 1, scan order)\n scan2 = sf[\"3.1\"]\n ";
+static char __pyx_k_users_payno_Documents_dev_esrf[] = "/users/payno/Documents/dev/esrf/silx/paynoSilx/silx/silx/io/specfile/specfile.pyx";
+static char __pyx_k_Base_exception_inherited_by_all[] = "Base exception inherited by all exceptions raised when a\n C function from the legacy SpecFile library returns an error\n code.\n ";
+static char __pyx_k_Scan_index_must_be_in_range_0_d[] = "Scan index must be in range 0-%d";
+static char __pyx_k_The_scan_identification_key_can[] = "The scan identification key can be an integer representing ";
+static char __pyx_k_This_module_is_a_cython_binding[] = "\nThis module is a cython binding to wrap the C SpecFile library, to access\nSpecFile data within a python program.\n\nDocumentation for the original C library SpecFile can be found on the ESRF\nwebsite:\n`The manual for the SpecFile Library <http://www.esrf.eu/files/live/sites/www/files/Instrumentation/software/beamline-control/BLISS/documentation/SpecFileManual.pdf>`_\n\nExamples\n========\n\nStart by importing :class:`SpecFile` and instantiate it:\n\n.. code-block:: python\n\n from silx.io.specfile import SpecFile\n\n sf = SpecFile(\"test.dat\")\n\nA :class:`SpecFile` instance can be accessed like a dictionary to obtain a\n:class:`Scan` instance.\n\nIf the key is a string representing two values\nseparated by a dot (e.g. ``\"1.2\"``), they will be treated as the scan number\n(``#S`` header line) and the scan order::\n\n # get second occurrence of scan \"#S 1\"\n myscan = sf[\"1.2\"]\n\n # access scan data as a numpy array\n nlines, ncolumns = myscan.data.shape\n\nIf the key is an integer, it will be treated as a 0-based index::\n\n first_scan = sf[0]\n second_scan = sf[1]\n\nIt is also possible to browse through all scans using :class:`SpecFile` as\nan iterator::\n\n for scan in sf:\n print(scan.scan_header_dict['S'])\n\nMCA spectra can be selectively loaded using an instance of :class:`MCA`\nprovided by :class:`Scan`::\n\n # Only one MCA spectrum is loaded in memory\n second_mca = first_scan.mca[1]\n\n # Iterating trough all MCA spectra in a scan:\n for mca_data in first_scan.mca:\n print(sum(mca_data))\n\nClasses\n=======\n\n- :class:`SpecFile`\n- :class:`Scan`\n- :class:`MCA`\n\nExceptions\n==========\n\n- :class:`SfError`\n- :class:`SfErrMemoryAlloc`\n- :class:`SfErrFileOpen`\n- :class:`SfErrFileClose`\n- :class:`SfErrFileRead`\n- :class:`SfErrFileWrite`\n- :class:`SfErrLineNotFound`\n- :class:`SfErrScanNotFound`\n- :class:`SfErrHeaderNotFound`\n- :class:`SfErrLabelNotFound`\n- :class:`SfErrMotorNotFound`""\n- :class:`SfErrPositionNotFound`\n- :class:`SfErrLineEmpty`\n- :class:`SfErrUserNotFound`\n- :class:`SfErrColNotFound`\n- :class:`SfErrMcaNotFound`\n\n";
+static char __pyx_k_param_scan_Parent_Scan_instance[] = "\n\n :param scan: Parent Scan instance\n :type scan: :class:`Scan`\n\n :var calibration: MCA calibration :math:`(a, b, c)` (as in\n :math:`a + b x + c x\302\262`) from ``#@CALIB`` scan header.\n :type calibration: list of 3 floats, default ``[0., 1., 0.]``\n :var channels: MCA channels list from ``#@CHANN`` scan header.\n In the absence of a ``#@CHANN`` header, this attribute is a list\n ``[0, \342\200\246, N-1]`` where ``N`` is the length of the first spectrum.\n In the absence of MCA spectra, this attribute defaults to ``None``.\n :type channels: list of int\n\n This class provides access to Multi-Channel Analysis data. A :class:`MCA`\n instance can be indexed to access 1D numpy arrays representing single \n MCA\302\240spectra.\n\n To create a :class:`MCA` instance, you must provide a parent :class:`Scan`\n instance, which in turn will provide a reference to the original\n :class:`SpecFile` instance::\n\n sf = SpecFile(\"/path/to/specfile.dat\")\n scan2 = Scan(sf, scan_index=2)\n mcas_in_scan2 = MCA(scan2)\n for i in len(mcas_in_scan2):\n mca_data = mcas_in_scan2[i]\n ... # do some something with mca_data (1D numpy array)\n\n A more pythonic way to do the same work, without having to explicitly\n instantiate ``scan`` and ``mcas_in_scan``, would be::\n\n sf = SpecFile(\"specfilename.dat\")\n # scan2 from previous example can be referred to as sf[2]\n # mcas_in_scan2 from previous example can be referred to as scan2.mca\n for mca_data in sf[2].mca:\n ... # do some something with mca_data (1D numpy array)\n\n ";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_Cannot_get_data_column_s_in_scan[] = "Cannot get data column %s in scan %d.%d";
+static char __pyx_k_Custom_exception_raised_when_SfN[] = "Custom exception raised when ``SfNoMca()`` returns ``-1``\n ";
+static char __pyx_k_Failed_to_retrieve_number_of_MCA[] = "Failed to retrieve number of MCA ";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_MCA_calibration_line_CALIB_not_f[] = "MCA calibration line (@CALIB) not found";
+static char __pyx_k_MCA_index_should_be_an_integer_s[] = "MCA index should be an integer (%s provided)";
+static char __pyx_k_No_MCA_spectrum_found_in_this_sc[] = "No MCA spectrum found in this scan";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_Parameter_value_must_be_a_string[] = "Parameter value must be a string.";
+static char __pyx_k_Unable_to_parse_file_header_line[] = "Unable to parse file header line ";
+static char __pyx_k_Unable_to_parse_scan_header_line[] = "Unable to parse scan header line ";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_the_unique_scan_index_or_a_strin[] = "the unique scan index or a string 'N.M' with N being the scan";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static PyObject *__pyx_kp_s_;
+static PyObject *__pyx_kp_s_2;
+static PyObject *__pyx_kp_s_27_09_2016;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_n_s_AttributeError;
+static PyObject *__pyx_kp_s_Base_exception_inherited_by_all;
+static PyObject *__pyx_n_s_CALIB;
+static PyObject *__pyx_n_s_CHANN;
+static PyObject *__pyx_kp_s_Cannot_get_data_column_s_in_scan;
+static PyObject *__pyx_kp_s_Custom_exception_raised_when_SfN;
+static PyObject *__pyx_n_s_ERRORS;
+static PyObject *__pyx_kp_s_Error_while_closing_SpecFile;
+static PyObject *__pyx_n_s_Exception;
+static PyObject *__pyx_kp_s_F;
+static PyObject *__pyx_kp_s_Failed_to_retrieve_number_of_MCA;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_n_s_KeyError;
+static PyObject *__pyx_n_s_L;
+static PyObject *__pyx_n_s_L_header;
+static PyObject *__pyx_n_s_MCA;
+static PyObject *__pyx_n_s_MCA___getitem;
+static PyObject *__pyx_n_s_MCA___init;
+static PyObject *__pyx_n_s_MCA___iter;
+static PyObject *__pyx_n_s_MCA___len;
+static PyObject *__pyx_n_s_MCA__parse_calibration;
+static PyObject *__pyx_n_s_MCA__parse_channels;
+static PyObject *__pyx_kp_s_MCA_calibration_line_CALIB_not_f;
+static PyObject *__pyx_kp_s_MCA_index_must_be_in_range_0_d;
+static PyObject *__pyx_kp_s_MCA_index_should_be_an_integer_s;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_kp_s_No_MCA_spectrum_found_in_this_sc;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_kp_s_P_Knobel;
+static PyObject *__pyx_kp_s_Parameter_value_must_be_a_string;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_S;
+static PyObject *__pyx_n_s_SF_ERR_FILE_OPEN;
+static PyObject *__pyx_n_s_SF_ERR_NO_ERRORS;
+static PyObject *__pyx_n_s_SF_ERR_SCAN_NOT_FOUND;
+static PyObject *__pyx_n_s_Scan;
+static PyObject *__pyx_n_s_Scan___init;
+static PyObject *__pyx_n_s_Scan_data;
+static PyObject *__pyx_n_s_Scan_data_column_by_name;
+static PyObject *__pyx_n_s_Scan_data_line;
+static PyObject *__pyx_n_s_Scan_file_header;
+static PyObject *__pyx_n_s_Scan_file_header_dict;
+static PyObject *__pyx_n_s_Scan_header;
+static PyObject *__pyx_n_s_Scan_index;
+static PyObject *__pyx_kp_s_Scan_index_must_be_in_range_0_d;
+static PyObject *__pyx_n_s_Scan_labels;
+static PyObject *__pyx_n_s_Scan_mca;
+static PyObject *__pyx_n_s_Scan_mca_header_dict;
+static PyObject *__pyx_n_s_Scan_motor_names;
+static PyObject *__pyx_n_s_Scan_motor_position_by_name;
+static PyObject *__pyx_n_s_Scan_motor_positions;
+static PyObject *__pyx_n_s_Scan_number;
+static PyObject *__pyx_n_s_Scan_order;
+static PyObject *__pyx_n_s_Scan_record_exists_in_hdr;
+static PyObject *__pyx_n_s_Scan_scan_header;
+static PyObject *__pyx_n_s_Scan_scan_header_dict;
+static PyObject *__pyx_n_s_SfErrColNotFound;
+static PyObject *__pyx_n_s_SfErrFileClose;
+static PyObject *__pyx_n_s_SfErrFileOpen;
+static PyObject *__pyx_n_s_SfErrFileRead;
+static PyObject *__pyx_n_s_SfErrFileWrite;
+static PyObject *__pyx_n_s_SfErrHeaderNotFound;
+static PyObject *__pyx_n_s_SfErrLabelNotFound;
+static PyObject *__pyx_n_s_SfErrLineEmpty;
+static PyObject *__pyx_n_s_SfErrLineNotFound;
+static PyObject *__pyx_n_s_SfErrMcaNotFound;
+static PyObject *__pyx_n_s_SfErrMemoryAlloc;
+static PyObject *__pyx_n_s_SfErrMotorNotFound;
+static PyObject *__pyx_n_s_SfErrPositionNotFound;
+static PyObject *__pyx_n_s_SfErrScanNotFound;
+static PyObject *__pyx_n_s_SfErrUserNotFound;
+static PyObject *__pyx_n_s_SfError;
+static PyObject *__pyx_n_s_SfNoMcaError;
+static PyObject *__pyx_kp_s_SfNoMca_returned_1;
+static PyObject *__pyx_n_s_SpecFile___iter;
+static PyObject *__pyx_kp_s_The_scan_identification_key_can;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_parse_file_header_line;
+static PyObject *__pyx_kp_s_Unable_to_parse_scan_header_line;
+static PyObject *__pyx_kp_s_Valid_keys;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s__14;
+static PyObject *__pyx_kp_s__25;
+static PyObject *__pyx_kp_s__27;
+static PyObject *__pyx_kp_s__28;
+static PyObject *__pyx_kp_s__7;
+static PyObject *__pyx_n_s_add_or_concatenate;
+static PyObject *__pyx_n_s_all_calib_values;
+static PyObject *__pyx_n_s_all_chann_values;
+static PyObject *__pyx_n_s_append;
+static PyObject *__pyx_n_s_args;
+static PyObject *__pyx_n_s_ascii;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_basicConfig;
+static PyObject *__pyx_n_s_calib_line;
+static PyObject *__pyx_n_s_calib_lines;
+static PyObject *__pyx_n_s_calibration;
+static PyObject *__pyx_n_s_chann_line;
+static PyObject *__pyx_n_s_chann_lines;
+static PyObject *__pyx_n_s_channels;
+static PyObject *__pyx_n_s_close;
+static PyObject *__pyx_kp_u_d_d;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_n_s_data_2;
+static PyObject *__pyx_n_s_data_column_by_name;
+static PyObject *__pyx_n_s_data_line;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_decode;
+static PyObject *__pyx_n_s_dictionary;
+static PyObject *__pyx_n_s_doc;
+static PyObject *__pyx_n_s_double;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_encode;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_f;
+static PyObject *__pyx_n_s_file_header;
+static PyObject *__pyx_n_s_file_header_dict;
+static PyObject *__pyx_n_s_file_header_dict_2;
+static PyObject *__pyx_n_s_file_header_lines;
+static PyObject *__pyx_n_s_filename;
+static PyObject *__pyx_n_s_getLogger;
+static PyObject *__pyx_n_s_get_error_string;
+static PyObject *__pyx_n_s_get_mca;
+static PyObject *__pyx_n_s_getitem;
+static PyObject *__pyx_n_s_group;
+static PyObject *__pyx_n_s_handle_error;
+static PyObject *__pyx_n_s_header;
+static PyObject *__pyx_n_s_header_2;
+static PyObject *__pyx_n_s_hkey;
+static PyObject *__pyx_n_s_hvalue;
+static PyObject *__pyx_n_s_i;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_increment;
+static PyObject *__pyx_n_s_index;
+static PyObject *__pyx_n_s_index_2;
+static PyObject *__pyx_n_s_init;
+static PyObject *__pyx_n_s_is_specfile;
+static PyObject *__pyx_n_s_isfile;
+static PyObject *__pyx_n_s_iter;
+static PyObject *__pyx_n_s_join;
+static PyObject *__pyx_n_s_key;
+static PyObject *__pyx_n_s_keys;
+static PyObject *__pyx_n_s_label;
+static PyObject *__pyx_n_s_labels;
+static PyObject *__pyx_n_s_labels_2;
+static PyObject *__pyx_n_s_len;
+static PyObject *__pyx_n_s_length;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_line;
+static PyObject *__pyx_n_s_line_index;
+static PyObject *__pyx_n_s_list;
+static PyObject *__pyx_n_s_logger;
+static PyObject *__pyx_n_s_logging;
+static PyObject *__pyx_n_s_lstrip;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_map;
+static PyObject *__pyx_n_s_match;
+static PyObject *__pyx_n_s_match_mca;
+static PyObject *__pyx_n_s_mca;
+static PyObject *__pyx_n_s_mca_2;
+static PyObject *__pyx_n_s_mca_header_dict;
+static PyObject *__pyx_n_s_mca_header_dict_2;
+static PyObject *__pyx_n_s_mca_index;
+static PyObject *__pyx_n_s_metaclass;
+static PyObject *__pyx_n_s_module;
+static PyObject *__pyx_n_s_motor_names;
+static PyObject *__pyx_n_s_motor_names_2;
+static PyObject *__pyx_n_s_motor_position_by_name;
+static PyObject *__pyx_n_s_motor_positions;
+static PyObject *__pyx_n_s_motor_positions_2;
+static PyObject *__pyx_n_s_msg;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_number;
+static PyObject *__pyx_n_s_number_2;
+static PyObject *__pyx_kp_s_number_and_M_the_order_eg_2_3;
+static PyObject *__pyx_n_s_number_of_mca;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_object;
+static PyObject *__pyx_n_s_one_line_calib_values;
+static PyObject *__pyx_n_s_one_line_chann_values;
+static PyObject *__pyx_n_s_open;
+static PyObject *__pyx_n_s_order;
+static PyObject *__pyx_n_s_order_2;
+static PyObject *__pyx_n_s_os;
+static PyObject *__pyx_n_s_os_path;
+static PyObject *__pyx_kp_s_param_scan_Parent_Scan_instance;
+static PyObject *__pyx_kp_s_param_specfile_Parent_SpecFile;
+static PyObject *__pyx_n_s_parse_calibration;
+static PyObject *__pyx_n_s_parse_channels;
+static PyObject *__pyx_n_s_path;
+static PyObject *__pyx_n_s_prepare;
+static PyObject *__pyx_n_s_property;
+static PyObject *__pyx_n_s_qualname;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_re;
+static PyObject *__pyx_n_s_record;
+static PyObject *__pyx_n_s_record_exists_in_hdr;
+static PyObject *__pyx_n_s_ret;
+static PyObject *__pyx_n_s_scan;
+static PyObject *__pyx_n_s_scan_2;
+static PyObject *__pyx_n_s_scan_header;
+static PyObject *__pyx_n_s_scan_header_dict;
+static PyObject *__pyx_n_s_scan_header_dict_2;
+static PyObject *__pyx_n_s_scan_header_lines;
+static PyObject *__pyx_n_s_scan_index;
+static PyObject *__pyx_n_s_scan_number;
+static PyObject *__pyx_n_s_scan_order;
+static PyObject *__pyx_n_s_search;
+static PyObject *__pyx_n_s_self;
+static PyObject *__pyx_n_s_send;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_specfile;
+static PyObject *__pyx_n_s_specfile_2;
+static PyObject *__pyx_n_s_split;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_startswith;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_n_s_string;
+static PyObject *__pyx_n_s_string_to_char_star;
+static PyObject *__pyx_n_s_strip;
+static PyObject *__pyx_n_s_sub;
+static PyObject *__pyx_n_s_sys;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_s_the_unique_scan_index_or_a_strin;
+static PyObject *__pyx_n_s_throw;
+static PyObject *__pyx_n_s_transpose;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_kp_s_users_payno_Documents_dev_esrf;
+static PyObject *__pyx_n_s_value;
+static PyObject *__pyx_n_s_version;
+static PyObject *__pyx_n_s_version_info;
+static PyObject *__pyx_kp_s_w;
+static PyObject *__pyx_kp_s_w_2;
+static PyObject *__pyx_n_s_warning;
+static PyObject *__pyx_float_0_;
+static PyObject *__pyx_float_1_;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_3;
+static PyObject *__pyx_int_4;
+static PyObject *__pyx_int_5;
+static PyObject *__pyx_int_6;
+static PyObject *__pyx_int_7;
+static PyObject *__pyx_int_8;
+static PyObject *__pyx_int_9;
+static PyObject *__pyx_int_10;
+static PyObject *__pyx_int_11;
+static PyObject *__pyx_int_12;
+static PyObject *__pyx_int_13;
+static PyObject *__pyx_int_14;
+static PyObject *__pyx_int_15;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__19;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__26;
+static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__32;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__34;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__36;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__43;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_tuple__47;
+static PyObject *__pyx_tuple__49;
+static PyObject *__pyx_tuple__51;
+static PyObject *__pyx_tuple__53;
+static PyObject *__pyx_tuple__55;
+static PyObject *__pyx_tuple__57;
+static PyObject *__pyx_tuple__59;
+static PyObject *__pyx_tuple__61;
+static PyObject *__pyx_tuple__63;
+static PyObject *__pyx_tuple__65;
+static PyObject *__pyx_tuple__67;
+static PyObject *__pyx_tuple__69;
+static PyObject *__pyx_tuple__71;
+static PyObject *__pyx_tuple__73;
+static PyObject *__pyx_tuple__75;
+static PyObject *__pyx_tuple__77;
+static PyObject *__pyx_tuple__79;
+static PyObject *__pyx_tuple__81;
+static PyObject *__pyx_tuple__83;
+static PyObject *__pyx_tuple__85;
+static PyObject *__pyx_tuple__87;
+static PyObject *__pyx_tuple__89;
+static PyObject *__pyx_tuple__91;
+static PyObject *__pyx_codeobj__38;
+static PyObject *__pyx_codeobj__40;
+static PyObject *__pyx_codeobj__42;
+static PyObject *__pyx_codeobj__44;
+static PyObject *__pyx_codeobj__46;
+static PyObject *__pyx_codeobj__48;
+static PyObject *__pyx_codeobj__50;
+static PyObject *__pyx_codeobj__52;
+static PyObject *__pyx_codeobj__54;
+static PyObject *__pyx_codeobj__56;
+static PyObject *__pyx_codeobj__58;
+static PyObject *__pyx_codeobj__60;
+static PyObject *__pyx_codeobj__62;
+static PyObject *__pyx_codeobj__64;
+static PyObject *__pyx_codeobj__66;
+static PyObject *__pyx_codeobj__68;
+static PyObject *__pyx_codeobj__70;
+static PyObject *__pyx_codeobj__72;
+static PyObject *__pyx_codeobj__74;
+static PyObject *__pyx_codeobj__76;
+static PyObject *__pyx_codeobj__78;
+static PyObject *__pyx_codeobj__80;
+static PyObject *__pyx_codeobj__82;
+static PyObject *__pyx_codeobj__84;
+static PyObject *__pyx_codeobj__86;
+static PyObject *__pyx_codeobj__88;
+static PyObject *__pyx_codeobj__90;
+static PyObject *__pyx_codeobj__92;
+
+/* "specfile.pyx":234
+ *
+ * """
+ * def __init__(self, scan): # <<<<<<<<<<<<<<
+ * self._scan = scan
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_3MCA___init__[] = "MCA.__init__(self, scan)";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_1__init__ = {"__init__", (PyCFunction)__pyx_pw_8specfile_3MCA_1__init__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_3MCA___init__};
+static PyObject *__pyx_pw_8specfile_3MCA_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_scan = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_scan,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_scan = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.MCA.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_3MCA___init__(__pyx_self, __pyx_v_self, __pyx_v_scan);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_scan) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "specfile.pyx":235
+ * """
+ * def __init__(self, scan):
+ * self._scan = scan # <<<<<<<<<<<<<<
+ *
+ * # Header dict
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_scan_2, __pyx_v_scan) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":238
+ *
+ * # Header dict
+ * self._header = scan.mca_header_dict # <<<<<<<<<<<<<<
+ *
+ * self.calibration = []
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_scan, __pyx_n_s_mca_header_dict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_header, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":240
+ * self._header = scan.mca_header_dict
+ *
+ * self.calibration = [] # <<<<<<<<<<<<<<
+ * """List of lists of calibration values,
+ * one list of 3 floats per MCA device or a single list applying to
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_calibration, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":244
+ * one list of 3 floats per MCA device or a single list applying to
+ * all devices """
+ * self._parse_calibration() # <<<<<<<<<<<<<<
+ *
+ * self.channels = []
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_parse_calibration); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":246
+ * self._parse_calibration()
+ *
+ * self.channels = [] # <<<<<<<<<<<<<<
+ * """List of lists of channels,
+ * one list of integers per MCA device or a single list applying to
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_channels, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":250
+ * one list of integers per MCA device or a single list applying to
+ * all devices"""
+ * self._parse_channels() # <<<<<<<<<<<<<<
+ *
+ * def _parse_channels(self):
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_parse_channels); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":234
+ *
+ * """
+ * def __init__(self, scan): # <<<<<<<<<<<<<<
+ * self._scan = scan
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.MCA.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":252
+ * self._parse_channels()
+ *
+ * def _parse_channels(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_3_parse_channels(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_3MCA_2_parse_channels[] = "MCA._parse_channels(self)\nFill :attr:`channels`";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_3_parse_channels = {"_parse_channels", (PyCFunction)__pyx_pw_8specfile_3MCA_3_parse_channels, METH_O, __pyx_doc_8specfile_3MCA_2_parse_channels};
+static PyObject *__pyx_pw_8specfile_3MCA_3_parse_channels(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_parse_channels (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_3MCA_2_parse_channels(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_2_parse_channels(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_v_chann_lines = NULL;
+ PyObject *__pyx_v_all_chann_values = NULL;
+ PyObject *__pyx_v_one_line_chann_values = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_v_start = NULL;
+ PyObject *__pyx_v_stop = NULL;
+ PyObject *__pyx_v_increment = NULL;
+ PyObject *__pyx_v_chann_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *(*__pyx_t_12)(PyObject *);
+ int __pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_parse_channels", 0);
+
+ /* "specfile.pyx":255
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ * if "CHANN" in self._header: # <<<<<<<<<<<<<<
+ * chann_lines = self._header["CHANN"].split("\n")
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_n_s_CHANN, __pyx_t_1, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":256
+ * # Channels list
+ * if "CHANN" in self._header:
+ * chann_lines = self._header["CHANN"].split("\n") # <<<<<<<<<<<<<<
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = PyObject_GetItem(__pyx_t_1, __pyx_n_s_CHANN); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_split); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_chann_lines = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":257
+ * if "CHANN" in self._header:
+ * chann_lines = self._header["CHANN"].split("\n")
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines] # <<<<<<<<<<<<<<
+ * for one_line_chann_values in all_chann_values:
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ */
+ __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (likely(PyList_CheckExact(__pyx_v_chann_lines)) || PyTuple_CheckExact(__pyx_v_chann_lines)) {
+ __pyx_t_1 = __pyx_v_chann_lines; __Pyx_INCREF(__pyx_t_1); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_chann_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_1);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_chann_line, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_chann_line, __pyx_n_s_split); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (__pyx_t_9) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_9); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_7 = __Pyx_PyObject_CallNoArg(__pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_4, (PyObject*)__pyx_t_7))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_all_chann_values = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":258
+ * chann_lines = self._header["CHANN"].split("\n")
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values: # <<<<<<<<<<<<<<
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ */
+ __pyx_t_4 = __pyx_v_all_chann_values; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ for (;;) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_1); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_one_line_chann_values, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":259
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values:
+ * length, start, stop, increment = map(int, one_line_chann_values) # <<<<<<<<<<<<<<
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ * elif len(self):
+ */
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+ PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
+ __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+ __Pyx_INCREF(__pyx_v_one_line_chann_values);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_one_line_chann_values);
+ __Pyx_GIVEREF(__pyx_v_one_line_chann_values);
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_map, __pyx_t_1, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if ((likely(PyTuple_CheckExact(__pyx_t_7))) || (PyList_CheckExact(__pyx_t_7))) {
+ PyObject* sequence = __pyx_t_7;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 4)) {
+ if (size > 4) __Pyx_RaiseTooManyValuesError(4);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1);
+ __pyx_t_9 = PyTuple_GET_ITEM(sequence, 2);
+ __pyx_t_10 = PyTuple_GET_ITEM(sequence, 3);
+ } else {
+ __pyx_t_1 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_8 = PyList_GET_ITEM(sequence, 1);
+ __pyx_t_9 = PyList_GET_ITEM(sequence, 2);
+ __pyx_t_10 = PyList_GET_ITEM(sequence, 3);
+ }
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_10);
+ #else
+ {
+ Py_ssize_t i;
+ PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_8,&__pyx_t_9,&__pyx_t_10};
+ for (i=0; i < 4; i++) {
+ PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(item);
+ *(temps[i]) = item;
+ }
+ }
+ #endif
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ } else {
+ Py_ssize_t index = -1;
+ PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_8,&__pyx_t_9,&__pyx_t_10};
+ __pyx_t_11 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_12 = Py_TYPE(__pyx_t_11)->tp_iternext;
+ for (index=0; index < 4; index++) {
+ PyObject* item = __pyx_t_12(__pyx_t_11); if (unlikely(!item)) goto __pyx_L8_unpacking_failed;
+ __Pyx_GOTREF(item);
+ *(temps[index]) = item;
+ }
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_11), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_12 = NULL;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ goto __pyx_L9_unpacking_done;
+ __pyx_L8_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_12 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L9_unpacking_done:;
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_1);
+ __pyx_t_1 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_start, __pyx_t_8);
+ __pyx_t_8 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_stop, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_increment, __pyx_t_10);
+ __pyx_t_10 = 0;
+
+ /* "specfile.pyx":260
+ * for one_line_chann_values in all_chann_values:
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ * self.channels.append(list(range(start, stop + 1, increment))) # <<<<<<<<<<<<<<
+ * elif len(self):
+ * # in the absence of #@CHANN, use shape of first MCA
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_channels); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_10 = PyNumber_Add(__pyx_v_stop, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_INCREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_start);
+ __Pyx_GIVEREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_increment);
+ PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_increment);
+ __Pyx_GIVEREF(__pyx_v_increment);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_9, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_9, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_13 = __Pyx_PyObject_Append(__pyx_t_7, __pyx_t_10); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+
+ /* "specfile.pyx":258
+ * chann_lines = self._header["CHANN"].split("\n")
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values: # <<<<<<<<<<<<<<
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+
+ /* "specfile.pyx":261
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ * elif len(self): # <<<<<<<<<<<<<<
+ * # in the absence of #@CHANN, use shape of first MCA
+ * length = self[0].shape[0]
+ */
+ __pyx_t_5 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = (__pyx_t_5 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":263
+ * elif len(self):
+ * # in the absence of #@CHANN, use shape of first MCA
+ * length = self[0].shape[0] # <<<<<<<<<<<<<<
+ * start, stop, increment = (0, length - 1, 1)
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ */
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_self, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_shape); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_10, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_v_length = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":264
+ * # in the absence of #@CHANN, use shape of first MCA
+ * length = self[0].shape[0]
+ * start, stop, increment = (0, length - 1, 1) # <<<<<<<<<<<<<<
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ */
+ __pyx_t_4 = __pyx_int_0;
+ __Pyx_INCREF(__pyx_t_4);
+ __pyx_t_10 = PyNumber_Subtract(__pyx_v_length, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_7 = __pyx_int_1;
+ __Pyx_INCREF(__pyx_t_7);
+ __pyx_v_start = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_stop = __pyx_t_10;
+ __pyx_t_10 = 0;
+ __pyx_v_increment = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "specfile.pyx":265
+ * length = self[0].shape[0]
+ * start, stop, increment = (0, length - 1, 1)
+ * self.channels.append(list(range(start, stop + 1, increment))) # <<<<<<<<<<<<<<
+ *
+ * def _parse_calibration(self):
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_channels); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_10 = PyNumber_Add(__pyx_v_stop, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_start);
+ __Pyx_GIVEREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_increment);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_increment);
+ __Pyx_GIVEREF(__pyx_v_increment);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_4, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_4, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_13 = __Pyx_PyObject_Append(__pyx_t_7, __pyx_t_10); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":252
+ * self._parse_channels()
+ *
+ * def _parse_channels(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("specfile.MCA._parse_channels", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_chann_lines);
+ __Pyx_XDECREF(__pyx_v_all_chann_values);
+ __Pyx_XDECREF(__pyx_v_one_line_chann_values);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XDECREF(__pyx_v_start);
+ __Pyx_XDECREF(__pyx_v_stop);
+ __Pyx_XDECREF(__pyx_v_increment);
+ __Pyx_XDECREF(__pyx_v_chann_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":267
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ * def _parse_calibration(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_5_parse_calibration(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_3MCA_4_parse_calibration[] = "MCA._parse_calibration(self)\nFill :attr:`calibration`";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_5_parse_calibration = {"_parse_calibration", (PyCFunction)__pyx_pw_8specfile_3MCA_5_parse_calibration, METH_O, __pyx_doc_8specfile_3MCA_4_parse_calibration};
+static PyObject *__pyx_pw_8specfile_3MCA_5_parse_calibration(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_parse_calibration (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_3MCA_4_parse_calibration(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_4_parse_calibration(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_v_calib_lines = NULL;
+ PyObject *__pyx_v_all_calib_values = NULL;
+ PyObject *__pyx_v_one_line_calib_values = NULL;
+ PyObject *__pyx_v_calib_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_parse_calibration", 0);
+
+ /* "specfile.pyx":270
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ * if "CALIB" in self._header: # <<<<<<<<<<<<<<
+ * calib_lines = self._header["CALIB"].split("\n")
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_n_s_CALIB, __pyx_t_1, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":271
+ * # Channels list
+ * if "CALIB" in self._header:
+ * calib_lines = self._header["CALIB"].split("\n") # <<<<<<<<<<<<<<
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = PyObject_GetItem(__pyx_t_1, __pyx_n_s_CALIB); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_split); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_calib_lines = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":272
+ * if "CALIB" in self._header:
+ * calib_lines = self._header["CALIB"].split("\n")
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines] # <<<<<<<<<<<<<<
+ * for one_line_calib_values in all_calib_values:
+ * self.calibration.append(list(map(float, one_line_calib_values)))
+ */
+ __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (likely(PyList_CheckExact(__pyx_v_calib_lines)) || PyTuple_CheckExact(__pyx_v_calib_lines)) {
+ __pyx_t_1 = __pyx_v_calib_lines; __Pyx_INCREF(__pyx_t_1); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_calib_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_1);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_calib_line, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_calib_line, __pyx_n_s_split); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (__pyx_t_9) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_9); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_7 = __Pyx_PyObject_CallNoArg(__pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_4, (PyObject*)__pyx_t_7))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_all_calib_values = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":273
+ * calib_lines = self._header["CALIB"].split("\n")
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values: # <<<<<<<<<<<<<<
+ * self.calibration.append(list(map(float, one_line_calib_values)))
+ * else:
+ */
+ __pyx_t_4 = __pyx_v_all_calib_values; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ for (;;) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_1); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_one_line_calib_values, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":274
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values:
+ * self.calibration.append(list(map(float, one_line_calib_values))) # <<<<<<<<<<<<<<
+ * else:
+ * # in the absence of #@calib, use default
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_calibration); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(((PyObject *)((PyObject*)(&PyFloat_Type))));
+ PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)((PyObject*)(&PyFloat_Type))));
+ __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyFloat_Type))));
+ __Pyx_INCREF(__pyx_v_one_line_calib_values);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_one_line_calib_values);
+ __Pyx_GIVEREF(__pyx_v_one_line_calib_values);
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_map, __pyx_t_7, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_7, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Append(__pyx_t_1, __pyx_t_8); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "specfile.pyx":273
+ * calib_lines = self._header["CALIB"].split("\n")
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values: # <<<<<<<<<<<<<<
+ * self.calibration.append(list(map(float, one_line_calib_values)))
+ * else:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":277
+ * else:
+ * # in the absence of #@calib, use default
+ * self.calibration.append([0., 1., 0.]) # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_calibration); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_8 = PyList_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_float_0_);
+ PyList_SET_ITEM(__pyx_t_8, 0, __pyx_float_0_);
+ __Pyx_GIVEREF(__pyx_float_0_);
+ __Pyx_INCREF(__pyx_float_1_);
+ PyList_SET_ITEM(__pyx_t_8, 1, __pyx_float_1_);
+ __Pyx_GIVEREF(__pyx_float_1_);
+ __Pyx_INCREF(__pyx_float_0_);
+ PyList_SET_ITEM(__pyx_t_8, 2, __pyx_float_0_);
+ __Pyx_GIVEREF(__pyx_float_0_);
+ __pyx_t_10 = __Pyx_PyObject_Append(__pyx_t_4, __pyx_t_8); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":267
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ * def _parse_calibration(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("specfile.MCA._parse_calibration", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_calib_lines);
+ __Pyx_XDECREF(__pyx_v_all_calib_values);
+ __Pyx_XDECREF(__pyx_v_one_line_calib_values);
+ __Pyx_XDECREF(__pyx_v_calib_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":279
+ * self.calibration.append([0., 1., 0.])
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_7__len__(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_3MCA_6__len__[] = "MCA.__len__(self)\n\n\n :return: Number of mca in Scan\n :rtype: int\n ";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_7__len__ = {"__len__", (PyCFunction)__pyx_pw_8specfile_3MCA_7__len__, METH_O, __pyx_doc_8specfile_3MCA_6__len__};
+static PyObject *__pyx_pw_8specfile_3MCA_7__len__(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_3MCA_6__len__(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_6__len__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "specfile.pyx":285
+ * :rtype: int
+ * """
+ * return self._scan._specfile.number_of_mca(self._scan.index) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, key):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_specfile); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_number_of_mca); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_index); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":279
+ * self.calibration.append([0., 1., 0.])
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("specfile.MCA.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":287
+ * return self._scan._specfile.number_of_mca(self._scan.index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a single MCA data line
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_9__getitem__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_3MCA_8__getitem__[] = "MCA.__getitem__(self, key)\nReturn a single MCA data line\n\n :param key: 0-based index of MCA within Scan\n :type key: int\n\n :return: Single MCA\n :rtype: 1D numpy array\n ";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_9__getitem__ = {"__getitem__", (PyCFunction)__pyx_pw_8specfile_3MCA_9__getitem__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_3MCA_8__getitem__};
+static PyObject *__pyx_pw_8specfile_3MCA_9__getitem__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_key = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_key,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__getitem__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__getitem__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_key = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__getitem__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.MCA.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_3MCA_8__getitem__(__pyx_self, __pyx_v_self, __pyx_v_key);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_8__getitem__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_v_mca_index = NULL;
+ PyObject *__pyx_v_msg = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "specfile.pyx":296
+ * :rtype: 1D numpy array
+ * """
+ * if not len(self): # <<<<<<<<<<<<<<
+ * raise IndexError("No MCA spectrum found in this scan")
+ *
+ */
+ __pyx_t_1 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":297
+ * """
+ * if not len(self):
+ * raise IndexError("No MCA spectrum found in this scan") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(key, int):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":299
+ * raise IndexError("No MCA spectrum found in this scan")
+ *
+ * if isinstance(key, int): # <<<<<<<<<<<<<<
+ * mca_index = key
+ * # allow negative index, like lists
+ */
+ __pyx_t_2 = PyInt_Check(__pyx_v_key);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":300
+ *
+ * if isinstance(key, int):
+ * mca_index = key # <<<<<<<<<<<<<<
+ * # allow negative index, like lists
+ * if mca_index < 0:
+ */
+ __Pyx_INCREF(__pyx_v_key);
+ __pyx_v_mca_index = __pyx_v_key;
+
+ /* "specfile.pyx":302
+ * mca_index = key
+ * # allow negative index, like lists
+ * if mca_index < 0: # <<<<<<<<<<<<<<
+ * mca_index = len(self) + mca_index
+ * else:
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_mca_index, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":303
+ * # allow negative index, like lists
+ * if mca_index < 0:
+ * mca_index = len(self) + mca_index # <<<<<<<<<<<<<<
+ * else:
+ * raise TypeError("MCA index should be an integer (%s provided)" %
+ */
+ __pyx_t_1 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = PyNumber_Add(__pyx_t_3, __pyx_v_mca_index); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_mca_index, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":305
+ * mca_index = len(self) + mca_index
+ * else:
+ * raise TypeError("MCA index should be an integer (%s provided)" % # <<<<<<<<<<<<<<
+ * (type(key)))
+ *
+ */
+ __pyx_t_5 = __Pyx_PyString_Format(__pyx_kp_s_MCA_index_should_be_an_integer_s, ((PyObject *)Py_TYPE(__pyx_v_key))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L4:;
+
+ /* "specfile.pyx":308
+ * (type(key)))
+ *
+ * if not 0 <= mca_index < len(self): # <<<<<<<<<<<<<<
+ * msg = "MCA index must be in range 0-%d" % (len(self) - 1)
+ * raise IndexError(msg)
+ */
+ __pyx_t_5 = PyObject_RichCompare(__pyx_int_0, __pyx_v_mca_index, Py_LE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__Pyx_PyObject_IsTrue(__pyx_t_5)) {
+ __Pyx_DECREF(__pyx_t_5);
+ __pyx_t_1 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = PyObject_RichCompare(__pyx_v_mca_index, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_2 = ((!__pyx_t_4) != 0);
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":309
+ *
+ * if not 0 <= mca_index < len(self):
+ * msg = "MCA index must be in range 0-%d" % (len(self) - 1) # <<<<<<<<<<<<<<
+ * raise IndexError(msg)
+ *
+ */
+ __pyx_t_1 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_t_1 - 1)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MCA_index_must_be_in_range_0_d, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_msg = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "specfile.pyx":310
+ * if not 0 <= mca_index < len(self):
+ * msg = "MCA index must be in range 0-%d" % (len(self) - 1)
+ * raise IndexError(msg) # <<<<<<<<<<<<<<
+ *
+ * return self._scan._specfile.get_mca(self._scan.index,
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_msg);
+ __Pyx_GIVEREF(__pyx_v_msg);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":312
+ * raise IndexError(msg)
+ *
+ * return self._scan._specfile.get_mca(self._scan.index, # <<<<<<<<<<<<<<
+ * mca_index)
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_specfile); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_get_mca); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_index); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "specfile.pyx":313
+ *
+ * return self._scan._specfile.get_mca(self._scan.index,
+ * mca_index) # <<<<<<<<<<<<<<
+ *
+ * def __iter__(self):
+ */
+ __pyx_t_6 = NULL;
+ __pyx_t_1 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ __pyx_t_1 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_6) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_mca_index);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_1, __pyx_v_mca_index);
+ __Pyx_GIVEREF(__pyx_v_mca_index);
+ __pyx_t_7 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":287
+ * return self._scan._specfile.number_of_mca(self._scan.index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a single MCA data line
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.MCA.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_mca_index);
+ __Pyx_XDECREF(__pyx_v_msg);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+static PyObject *__pyx_gb_8specfile_3MCA_12generator(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_11__iter__(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_3MCA_10__iter__[] = "MCA.__iter__(self)\nReturn the next MCA data line each time this method is called.\n\n :return: Single MCA\n :rtype: 1D numpy array\n ";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_11__iter__ = {"__iter__", (PyCFunction)__pyx_pw_8specfile_3MCA_11__iter__, METH_O, __pyx_doc_8specfile_3MCA_10__iter__};
+static PyObject *__pyx_pw_8specfile_3MCA_11__iter__(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_3MCA_10__iter__(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_10__iter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *__pyx_cur_scope;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__iter__", 0);
+ __pyx_cur_scope = (struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)__pyx_tp_new_8specfile___pyx_scope_struct____iter__(__pyx_ptype_8specfile___pyx_scope_struct____iter__, __pyx_empty_tuple, NULL);
+ if (unlikely(!__pyx_cur_scope)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_cur_scope);
+ __pyx_cur_scope->__pyx_v_self = __pyx_v_self;
+ __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self);
+ __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_self);
+ {
+ __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_8specfile_3MCA_12generator, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_MCA___iter); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_cur_scope);
+ __Pyx_RefNannyFinishContext();
+ return (PyObject *) gen;
+ }
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_AddTraceback("specfile.MCA.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_gb_8specfile_3MCA_12generator(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *__pyx_cur_scope = ((struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)__pyx_generator->closure);
+ PyObject *__pyx_r = NULL;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("None", 0);
+ switch (__pyx_generator->resume_label) {
+ case 0: goto __pyx_L3_first_run;
+ case 1: goto __pyx_L6_resume_from_yield;
+ default: /* CPython raises the right error here */
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __pyx_L3_first_run:;
+ if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":321
+ * :rtype: 1D numpy array
+ * """
+ * for mca_index in range(len(self)): # <<<<<<<<<<<<<<
+ * yield self._scan._specfile.get_mca(self._scan.index, mca_index)
+ *
+ */
+ __pyx_t_1 = PyObject_Length(__pyx_cur_scope->__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_cur_scope->__pyx_v_mca_index = __pyx_t_2;
+
+ /* "specfile.pyx":322
+ * """
+ * for mca_index in range(len(self)):
+ * yield self._scan._specfile.get_mca(self._scan.index, mca_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_specfile); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_get_mca); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_index); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyInt_FromSsize_t(__pyx_cur_scope->__pyx_v_mca_index); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_6 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
+ __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ /* return from generator, yielding value */
+ __pyx_generator->resume_label = 1;
+ return __pyx_r;
+ __pyx_L6_resume_from_yield:;
+ __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
+ __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
+ if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+
+ /* function exit code */
+ PyErr_SetNone(PyExc_StopIteration);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_generator->resume_label = -1;
+ __Pyx_Generator_clear((PyObject*)__pyx_generator);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+}
+
+/* "specfile.pyx":325
+ *
+ *
+ * def _add_or_concatenate(dictionary, key, value): # <<<<<<<<<<<<<<
+ * """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ * Else append/concatenate the new value to the existing one
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_1_add_or_concatenate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile__add_or_concatenate[] = "_add_or_concatenate(dictionary, key, value)\nIf key doesn't exist in dictionary, create a new ``key: value`` pair.\n Else append/concatenate the new value to the existing one\n ";
+static PyMethodDef __pyx_mdef_8specfile_1_add_or_concatenate = {"_add_or_concatenate", (PyCFunction)__pyx_pw_8specfile_1_add_or_concatenate, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile__add_or_concatenate};
+static PyObject *__pyx_pw_8specfile_1_add_or_concatenate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_dictionary = 0;
+ PyObject *__pyx_v_key = 0;
+ PyObject *__pyx_v_value = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_add_or_concatenate (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_dictionary,&__pyx_n_s_key,&__pyx_n_s_value,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dictionary)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_add_or_concatenate", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_value)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_add_or_concatenate", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_add_or_concatenate") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ }
+ __pyx_v_dictionary = values[0];
+ __pyx_v_key = values[1];
+ __pyx_v_value = values[2];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_add_or_concatenate", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile._add_or_concatenate", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile__add_or_concatenate(__pyx_self, __pyx_v_dictionary, __pyx_v_key, __pyx_v_value);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile__add_or_concatenate(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_dictionary, PyObject *__pyx_v_key, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_add_or_concatenate", 0);
+
+ /* "specfile.pyx":329
+ * Else append/concatenate the new value to the existing one
+ * """
+ * try: # <<<<<<<<<<<<<<
+ * if not key in dictionary:
+ * dictionary[key] = value
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ /*try:*/ {
+
+ /* "specfile.pyx":330
+ * """
+ * try:
+ * if not key in dictionary: # <<<<<<<<<<<<<<
+ * dictionary[key] = value
+ * else:
+ */
+ __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_key, __pyx_v_dictionary, Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_t_5 = (__pyx_t_4 != 0);
+ if (__pyx_t_5) {
+
+ /* "specfile.pyx":331
+ * try:
+ * if not key in dictionary:
+ * dictionary[key] = value # <<<<<<<<<<<<<<
+ * else:
+ * dictionary[key] += "\n" + value
+ */
+ if (unlikely(PyObject_SetItem(__pyx_v_dictionary, __pyx_v_key, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":333
+ * dictionary[key] = value
+ * else:
+ * dictionary[key] += "\n" + value # <<<<<<<<<<<<<<
+ * except TypeError:
+ * raise TypeError("Parameter value must be a string.")
+ */
+ __Pyx_INCREF(__pyx_v_key);
+ __pyx_t_6 = __pyx_v_key;
+ __pyx_t_7 = PyObject_GetItem(__pyx_v_dictionary, __pyx_t_6); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L3_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = PyNumber_Add(__pyx_kp_s_, __pyx_v_value); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (unlikely(PyObject_SetItem(__pyx_v_dictionary, __pyx_t_6, __pyx_t_9) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __pyx_L11:;
+ }
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L10_try_end;
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "specfile.pyx":334
+ * else:
+ * dictionary[key] += "\n" + value
+ * except TypeError: # <<<<<<<<<<<<<<
+ * raise TypeError("Parameter value must be a string.")
+ *
+ */
+ __pyx_t_10 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_10) {
+ __Pyx_AddTraceback("specfile._add_or_concatenate", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_9, &__pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_GOTREF(__pyx_t_8);
+
+ /* "specfile.pyx":335
+ * dictionary[key] += "\n" + value
+ * except TypeError:
+ * raise TypeError("Parameter value must be a string.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_1);
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+ goto __pyx_L1_error;
+ __pyx_L10_try_end:;
+ }
+
+ /* "specfile.pyx":325
+ *
+ *
+ * def _add_or_concatenate(dictionary, key, value): # <<<<<<<<<<<<<<
+ * """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ * Else append/concatenate the new value to the existing one
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("specfile._add_or_concatenate", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":363
+ * scan2 = sf["3.1"]
+ * """
+ * def __init__(self, specfile, scan_index): # <<<<<<<<<<<<<<
+ * self._specfile = specfile
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan___init__[] = "Scan.__init__(self, specfile, scan_index)";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_1__init__ = {"__init__", (PyCFunction)__pyx_pw_8specfile_4Scan_1__init__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan___init__};
+static PyObject *__pyx_pw_8specfile_4Scan_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_specfile = 0;
+ PyObject *__pyx_v_scan_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_specfile_2,&__pyx_n_s_scan_index,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_specfile_2)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_specfile = values[1];
+ __pyx_v_scan_index = values[2];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan___init__(__pyx_self, __pyx_v_self, __pyx_v_specfile, __pyx_v_scan_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_specfile, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_v_match = NULL;
+ PyObject *__pyx_v_match_mca = NULL;
+ PyObject *__pyx_v_hkey = NULL;
+ PyObject *__pyx_v_hvalue = NULL;
+ PyObject *__pyx_v_L_header = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ Py_ssize_t __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ int __pyx_t_14;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "specfile.pyx":364
+ * """
+ * def __init__(self, specfile, scan_index):
+ * self._specfile = specfile # <<<<<<<<<<<<<<
+ *
+ * self._index = scan_index
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_specfile, __pyx_v_specfile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":366
+ * self._specfile = specfile
+ *
+ * self._index = scan_index # <<<<<<<<<<<<<<
+ * self._number = specfile.number(scan_index)
+ * self._order = specfile.order(scan_index)
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_index_2, __pyx_v_scan_index) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":367
+ *
+ * self._index = scan_index
+ * self._number = specfile.number(scan_index) # <<<<<<<<<<<<<<
+ * self._order = specfile.order(scan_index)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_specfile, __pyx_n_s_number); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_scan_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(__pyx_v_scan_index);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_scan_index);
+ __Pyx_GIVEREF(__pyx_v_scan_index);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_number_2, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":368
+ * self._index = scan_index
+ * self._number = specfile.number(scan_index)
+ * self._order = specfile.order(scan_index) # <<<<<<<<<<<<<<
+ *
+ * self._scan_header_lines = self._specfile.scan_header(self._index)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_specfile, __pyx_n_s_order); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_scan_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_scan_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_scan_index);
+ __Pyx_GIVEREF(__pyx_v_scan_index);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_order_2, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":370
+ * self._order = specfile.order(scan_index)
+ *
+ * self._scan_header_lines = self._specfile.scan_header(self._index) # <<<<<<<<<<<<<<
+ * self._file_header_lines = self._specfile.file_header(self._index)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_scan_header); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":371
+ *
+ * self._scan_header_lines = self._specfile.scan_header(self._index)
+ * self._file_header_lines = self._specfile.file_header(self._index) # <<<<<<<<<<<<<<
+ *
+ * if self._file_header_lines == self._scan_header_lines:
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_file_header); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":373
+ * self._file_header_lines = self._specfile.file_header(self._index)
+ *
+ * if self._file_header_lines == self._scan_header_lines: # <<<<<<<<<<<<<<
+ * self._file_header_lines = []
+ * self._header = self._file_header_lines + self._scan_header_lines
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":374
+ *
+ * if self._file_header_lines == self._scan_header_lines:
+ * self._file_header_lines = [] # <<<<<<<<<<<<<<
+ * self._header = self._file_header_lines + self._scan_header_lines
+ *
+ */
+ __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":375
+ * if self._file_header_lines == self._scan_header_lines:
+ * self._file_header_lines = []
+ * self._header = self._file_header_lines + self._scan_header_lines # <<<<<<<<<<<<<<
+ *
+ * self._scan_header_dict = {}
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_header, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":377
+ * self._header = self._file_header_lines + self._scan_header_lines
+ *
+ * self._scan_header_dict = {} # <<<<<<<<<<<<<<
+ * self._mca_header_dict = {}
+ * for line in self._scan_header_lines:
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_dict, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":378
+ *
+ * self._scan_header_dict = {}
+ * self._mca_header_dict = {} # <<<<<<<<<<<<<<
+ * for line in self._scan_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line)
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_mca_header_dict_2, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":379
+ * self._scan_header_dict = {}
+ * self._mca_header_dict = {}
+ * for line in self._scan_header_lines: # <<<<<<<<<<<<<<
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+ __pyx_t_5 = __pyx_t_1; __Pyx_INCREF(__pyx_t_5); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = Py_TYPE(__pyx_t_5)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_5))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_5)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_1 = __pyx_t_8(__pyx_t_5);
+ if (unlikely(!__pyx_t_1)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_line, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":380
+ * self._mca_header_dict = {}
+ * for line in self._scan_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line) # <<<<<<<<<<<<<<
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ * if match:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_search); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_2 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_w);
+ PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_9, __pyx_kp_s_w);
+ __Pyx_GIVEREF(__pyx_kp_s_w);
+ __Pyx_INCREF(__pyx_v_line);
+ PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_9, __pyx_v_line);
+ __Pyx_GIVEREF(__pyx_v_line);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_match, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":381
+ * for line in self._scan_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * match_mca = re.search(r"#@(\w+) *(.*)", line) # <<<<<<<<<<<<<<
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip()
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_search); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_4 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_w_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+__pyx_t_9, __pyx_kp_s_w_2);
+ __Pyx_GIVEREF(__pyx_kp_s_w_2);
+ __Pyx_INCREF(__pyx_v_line);
+ PyTuple_SET_ITEM(__pyx_t_4, 1+__pyx_t_9, __pyx_v_line);
+ __Pyx_GIVEREF(__pyx_v_line);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_match_mca, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":382
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ * if match: # <<<<<<<<<<<<<<
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip()
+ */
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_match); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":383
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_lstrip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hkey, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":384
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca:
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hvalue, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":385
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue) # <<<<<<<<<<<<<<
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_add_or_concatenate); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_dict); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_10 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_hkey);
+ PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_v_hkey);
+ __Pyx_GIVEREF(__pyx_v_hkey);
+ __Pyx_INCREF(__pyx_v_hvalue);
+ PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_v_hvalue);
+ __Pyx_GIVEREF(__pyx_v_hvalue);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L6;
+ }
+
+ /* "specfile.pyx":386
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca: # <<<<<<<<<<<<<<
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ * hvalue = match_mca.group(2).strip()
+ */
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_match_mca); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":387
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match_mca.group(2).strip()
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match_mca, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_lstrip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_10) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hkey, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":388
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ * hvalue = match_mca.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match_mca, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_10) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hvalue, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":389
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ * hvalue = match_mca.group(2).strip()
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue) # <<<<<<<<<<<<<<
+ * else:
+ * # this shouldn't happen
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_add_or_concatenate); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_mca_header_dict_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_4 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_3 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_9, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_hkey);
+ PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_9, __pyx_v_hkey);
+ __Pyx_GIVEREF(__pyx_v_hkey);
+ __Pyx_INCREF(__pyx_v_hvalue);
+ PyTuple_SET_ITEM(__pyx_t_3, 2+__pyx_t_9, __pyx_v_hvalue);
+ __Pyx_GIVEREF(__pyx_v_hvalue);
+ __pyx_t_10 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":392
+ * else:
+ * # this shouldn't happen
+ * _logger.warning("Unable to parse scan header line " + line) # <<<<<<<<<<<<<<
+ *
+ * self._labels = []
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warning); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyNumber_Add(__pyx_kp_s_Unable_to_parse_scan_header_line, __pyx_v_line); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_10) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L6:;
+
+ /* "specfile.pyx":379
+ * self._scan_header_dict = {}
+ * self._mca_header_dict = {}
+ * for line in self._scan_header_lines: # <<<<<<<<<<<<<<
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ */
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "specfile.pyx":394
+ * _logger.warning("Unable to parse scan header line " + line)
+ *
+ * self._labels = [] # <<<<<<<<<<<<<<
+ * if self.record_exists_in_hdr('L'):
+ * try:
+ */
+ __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_labels, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "specfile.pyx":395
+ *
+ * self._labels = []
+ * if self.record_exists_in_hdr('L'): # <<<<<<<<<<<<<<
+ * try:
+ * self._labels = self._specfile.labels(self._index)
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_record_exists_in_hdr); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":396
+ * self._labels = []
+ * if self.record_exists_in_hdr('L'):
+ * try: # <<<<<<<<<<<<<<
+ * self._labels = self._specfile.labels(self._index)
+ * except SfErrLineNotFound:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_11, &__pyx_t_12, &__pyx_t_13);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __Pyx_XGOTREF(__pyx_t_12);
+ __Pyx_XGOTREF(__pyx_t_13);
+ /*try:*/ {
+
+ /* "specfile.pyx":397
+ * if self.record_exists_in_hdr('L'):
+ * try:
+ * self._labels = self._specfile.labels(self._index) # <<<<<<<<<<<<<<
+ * except SfErrLineNotFound:
+ * # SpecFile.labels raises an IndexError when encountering
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_labels_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_labels, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+ __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+ goto __pyx_L15_try_end;
+ __pyx_L8_error:;
+ __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":398
+ * try:
+ * self._labels = self._specfile.labels(self._index)
+ * except SfErrLineNotFound: # <<<<<<<<<<<<<<
+ * # SpecFile.labels raises an IndexError when encountering
+ * # a Scan with no data, even if the header exists.
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLineNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_14 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_14) {
+ __Pyx_AddTraceback("specfile.Scan.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_3, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_t_2);
+
+ /* "specfile.pyx":401
+ * # SpecFile.labels raises an IndexError when encountering
+ * # a Scan with no data, even if the header exists.
+ * L_header = re.sub(r" {2,}", " ", # max. 2 spaces # <<<<<<<<<<<<<<
+ * self._scan_header_dict["L"])
+ * self._labels = L_header.split(" ")
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sub); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":402
+ * # a Scan with no data, even if the header exists.
+ * L_header = re.sub(r" {2,}", " ", # max. 2 spaces
+ * self._scan_header_dict["L"]) # <<<<<<<<<<<<<<
+ * self._labels = L_header.split(" ")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_dict); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_15 = PyObject_GetItem(__pyx_t_4, __pyx_n_s_L); if (unlikely(__pyx_t_15 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;};
+ __Pyx_GOTREF(__pyx_t_15);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_16 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_2);
+ PyTuple_SET_ITEM(__pyx_t_16, 0+__pyx_t_7, __pyx_kp_s_2);
+ __Pyx_GIVEREF(__pyx_kp_s_2);
+ __Pyx_INCREF(__pyx_kp_s__14);
+ PyTuple_SET_ITEM(__pyx_t_16, 1+__pyx_t_7, __pyx_kp_s__14);
+ __Pyx_GIVEREF(__pyx_kp_s__14);
+ PyTuple_SET_ITEM(__pyx_t_16, 2+__pyx_t_7, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ __pyx_t_15 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_16, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_v_L_header = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "specfile.pyx":403
+ * L_header = re.sub(r" {2,}", " ", # max. 2 spaces
+ * self._scan_header_dict["L"])
+ * self._labels = L_header.split(" ") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_L_header, __pyx_n_s_split); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_labels, __pyx_t_10) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9_exception_handled;
+ }
+ goto __pyx_L10_except_error;
+ __pyx_L10_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_XGIVEREF(__pyx_t_12);
+ __Pyx_XGIVEREF(__pyx_t_13);
+ __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
+ goto __pyx_L1_error;
+ __pyx_L9_exception_handled:;
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_XGIVEREF(__pyx_t_12);
+ __Pyx_XGIVEREF(__pyx_t_13);
+ __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
+ __pyx_L15_try_end:;
+ }
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+
+ /* "specfile.pyx":406
+ *
+ *
+ * self._file_header_dict = {} # <<<<<<<<<<<<<<
+ * for line in self._file_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line)
+ */
+ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_file_header_dict, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":407
+ *
+ * self._file_header_dict = {}
+ * for line in self._file_header_lines: # <<<<<<<<<<<<<<
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * if match:
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) {
+ __pyx_t_3 = __pyx_t_2; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_2 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_2)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_line, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":408
+ * self._file_header_dict = {}
+ * for line in self._file_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line) # <<<<<<<<<<<<<<
+ * if match:
+ * # header type
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_search); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_5 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__pyx_t_1) {
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_w);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_9, __pyx_kp_s_w);
+ __Pyx_GIVEREF(__pyx_kp_s_w);
+ __Pyx_INCREF(__pyx_v_line);
+ PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_9, __pyx_v_line);
+ __Pyx_GIVEREF(__pyx_v_line);
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_match, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":409
+ * for line in self._file_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * if match: # <<<<<<<<<<<<<<
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip()
+ */
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_match); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":411
+ * if match:
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ */
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_lstrip); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_strip); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hkey, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":412
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ * else:
+ */
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_strip); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hvalue, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":413
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue) # <<<<<<<<<<<<<<
+ * else:
+ * _logger.warning("Unable to parse file header line " + line)
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_add_or_concatenate); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_dict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_16 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ if (__pyx_t_1) {
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_16, 0+__pyx_t_9, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_hkey);
+ PyTuple_SET_ITEM(__pyx_t_16, 1+__pyx_t_9, __pyx_v_hkey);
+ __Pyx_GIVEREF(__pyx_v_hkey);
+ __Pyx_INCREF(__pyx_v_hvalue);
+ PyTuple_SET_ITEM(__pyx_t_16, 2+__pyx_t_9, __pyx_v_hvalue);
+ __Pyx_GIVEREF(__pyx_v_hvalue);
+ __pyx_t_5 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":415
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ * else:
+ * _logger.warning("Unable to parse file header line " + line) # <<<<<<<<<<<<<<
+ *
+ * self._motor_names = self._specfile.motor_names(self._index)
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_warning); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyNumber_Add(__pyx_kp_s_Unable_to_parse_file_header_line, __pyx_v_line); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_16))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_16);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_16);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_16, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_16, __pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_1 = PyTuple_New(1+1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_1, 0+1, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_16, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L20:;
+
+ /* "specfile.pyx":407
+ *
+ * self._file_header_dict = {}
+ * for line in self._file_header_lines: # <<<<<<<<<<<<<<
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * if match:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":417
+ * _logger.warning("Unable to parse file header line " + line)
+ *
+ * self._motor_names = self._specfile.motor_names(self._index) # <<<<<<<<<<<<<<
+ * self._motor_positions = self._specfile.motor_positions(self._index)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_motor_names); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_16))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_16);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_16);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_16, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_16, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_16, __pyx_t_10, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_motor_names_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":418
+ *
+ * self._motor_names = self._specfile.motor_names(self._index)
+ * self._motor_positions = self._specfile.motor_positions(self._index) # <<<<<<<<<<<<<<
+ *
+ * self._data = None
+ */
+ __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_16, __pyx_n_s_motor_positions); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_1 = PyTuple_New(1+1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_1, 0+1, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_16 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_motor_positions_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":420
+ * self._motor_positions = self._specfile.motor_positions(self._index)
+ *
+ * self._data = None # <<<<<<<<<<<<<<
+ * self._mca = None
+ *
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_data, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":421
+ *
+ * self._data = None
+ * self._mca = None # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_mca, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":363
+ * scan2 = sf["3.1"]
+ * """
+ * def __init__(self, specfile, scan_index): # <<<<<<<<<<<<<<
+ * self._specfile = specfile
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("specfile.Scan.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XDECREF(__pyx_v_match);
+ __Pyx_XDECREF(__pyx_v_match_mca);
+ __Pyx_XDECREF(__pyx_v_hkey);
+ __Pyx_XDECREF(__pyx_v_hvalue);
+ __Pyx_XDECREF(__pyx_v_L_header);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":425
+ * @cython.embedsignature(False)
+ * @property
+ * def index(self): # <<<<<<<<<<<<<<
+ * """Unique scan index 0 - len(specfile)-1
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_3index(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_2index[] = "Unique scan index 0 - len(specfile)-1\n\n This attribute is implemented as a read-only property as changing\n its value may cause nasty side-effects (such as loading data from a\n different scan without updating the header accordingly.";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_3index = {"index", (PyCFunction)__pyx_pw_8specfile_4Scan_3index, METH_O, __pyx_doc_8specfile_4Scan_2index};
+static PyObject *__pyx_pw_8specfile_4Scan_3index(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("index (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_2index(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_2index(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("index", 0);
+
+ /* "specfile.pyx":431
+ * its value may cause nasty side-effects (such as loading data from a
+ * different scan without updating the header accordingly."""
+ * return self._index # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 431; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":425
+ * @cython.embedsignature(False)
+ * @property
+ * def index(self): # <<<<<<<<<<<<<<
+ * """Unique scan index 0 - len(specfile)-1
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":435
+ * @cython.embedsignature(False)
+ * @property
+ * def number(self): # <<<<<<<<<<<<<<
+ * """First value on #S line (as int)"""
+ * return self._number
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_5number(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_4number[] = "First value on #S line (as int)";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_5number = {"number", (PyCFunction)__pyx_pw_8specfile_4Scan_5number, METH_O, __pyx_doc_8specfile_4Scan_4number};
+static PyObject *__pyx_pw_8specfile_4Scan_5number(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("number (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_4number(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_4number(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("number", 0);
+
+ /* "specfile.pyx":437
+ * def number(self):
+ * """First value on #S line (as int)"""
+ * return self._number # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_number_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":435
+ * @cython.embedsignature(False)
+ * @property
+ * def number(self): # <<<<<<<<<<<<<<
+ * """First value on #S line (as int)"""
+ * return self._number
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.number", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":441
+ * @cython.embedsignature(False)
+ * @property
+ * def order(self): # <<<<<<<<<<<<<<
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_7order(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_6order[] = "Order can be > 1 if the same number is repeated in a specfile";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_7order = {"order", (PyCFunction)__pyx_pw_8specfile_4Scan_7order, METH_O, __pyx_doc_8specfile_4Scan_6order};
+static PyObject *__pyx_pw_8specfile_4Scan_7order(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("order (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_6order(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_6order(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("order", 0);
+
+ /* "specfile.pyx":443
+ * def order(self):
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_order_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":441
+ * @cython.embedsignature(False)
+ * @property
+ * def order(self): # <<<<<<<<<<<<<<
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.order", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":447
+ * @cython.embedsignature(False)
+ * @property
+ * def header(self): # <<<<<<<<<<<<<<
+ * """List of raw header lines (as a list of strings).
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_9header(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_8header[] = "List of raw header lines (as a list of strings).\n\n This includes the file header, the scan header and possibly a MCA\n header.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_9header = {"header", (PyCFunction)__pyx_pw_8specfile_4Scan_9header, METH_O, __pyx_doc_8specfile_4Scan_8header};
+static PyObject *__pyx_pw_8specfile_4Scan_9header(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("header (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_8header(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_8header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("header", 0);
+
+ /* "specfile.pyx":453
+ * header.
+ * """
+ * return self._header # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":447
+ * @cython.embedsignature(False)
+ * @property
+ * def header(self): # <<<<<<<<<<<<<<
+ * """List of raw header lines (as a list of strings).
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":457
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header(self): # <<<<<<<<<<<<<<
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_11scan_header(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_10scan_header[] = "List of raw scan header lines (as a list of strings).\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_11scan_header = {"scan_header", (PyCFunction)__pyx_pw_8specfile_4Scan_11scan_header, METH_O, __pyx_doc_8specfile_4Scan_10scan_header};
+static PyObject *__pyx_pw_8specfile_4Scan_11scan_header(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("scan_header (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_10scan_header(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_10scan_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("scan_header", 0);
+
+ /* "specfile.pyx":460
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ * return self._scan_header_lines # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":457
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header(self): # <<<<<<<<<<<<<<
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.scan_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":464
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header(self): # <<<<<<<<<<<<<<
+ * """List of raw file header lines (as a list of strings).
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_13file_header(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_12file_header[] = "List of raw file header lines (as a list of strings).\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_13file_header = {"file_header", (PyCFunction)__pyx_pw_8specfile_4Scan_13file_header, METH_O, __pyx_doc_8specfile_4Scan_12file_header};
+static PyObject *__pyx_pw_8specfile_4Scan_13file_header(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("file_header (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_12file_header(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_12file_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("file_header", 0);
+
+ /* "specfile.pyx":467
+ * """List of raw file header lines (as a list of strings).
+ * """
+ * return self._file_header_lines # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":464
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header(self): # <<<<<<<<<<<<<<
+ * """List of raw file header lines (as a list of strings).
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.file_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":471
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of scan header strings, keys without the leading``#``
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_15scan_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_14scan_header_dict[] = "\n Dictionary of scan header strings, keys without the leading``#``\n (e.g. ``scan_header_dict[\"S\"]``).\n Note: this does not include MCA header lines starting with ``#@``.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_15scan_header_dict = {"scan_header_dict", (PyCFunction)__pyx_pw_8specfile_4Scan_15scan_header_dict, METH_O, __pyx_doc_8specfile_4Scan_14scan_header_dict};
+static PyObject *__pyx_pw_8specfile_4Scan_15scan_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("scan_header_dict (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_14scan_header_dict(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_14scan_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("scan_header_dict", 0);
+
+ /* "specfile.pyx":477
+ * Note: this does not include MCA header lines starting with ``#@``.
+ * """
+ * return self._scan_header_dict # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_dict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":471
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of scan header strings, keys without the leading``#``
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.scan_header_dict", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":481
+ * @cython.embedsignature(False)
+ * @property
+ * def mca_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of MCA header strings, keys without the leading ``#@``
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_17mca_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_16mca_header_dict[] = "\n Dictionary of MCA header strings, keys without the leading ``#@``\n (e.g. ``mca_header_dict[\"CALIB\"]``).\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_17mca_header_dict = {"mca_header_dict", (PyCFunction)__pyx_pw_8specfile_4Scan_17mca_header_dict, METH_O, __pyx_doc_8specfile_4Scan_16mca_header_dict};
+static PyObject *__pyx_pw_8specfile_4Scan_17mca_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("mca_header_dict (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_16mca_header_dict(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_16mca_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("mca_header_dict", 0);
+
+ /* "specfile.pyx":486
+ * (e.g. ``mca_header_dict["CALIB"]``).
+ * """
+ * return self._mca_header_dict # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_mca_header_dict_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":481
+ * @cython.embedsignature(False)
+ * @property
+ * def mca_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of MCA header strings, keys without the leading ``#@``
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.mca_header_dict", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":490
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of file header strings, keys without the leading ``#``
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_19file_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_18file_header_dict[] = "\n Dictionary of file header strings, keys without the leading ``#``\n (e.g. ``file_header_dict[\"F\"]``).\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_19file_header_dict = {"file_header_dict", (PyCFunction)__pyx_pw_8specfile_4Scan_19file_header_dict, METH_O, __pyx_doc_8specfile_4Scan_18file_header_dict};
+static PyObject *__pyx_pw_8specfile_4Scan_19file_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("file_header_dict (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_18file_header_dict(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_18file_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("file_header_dict", 0);
+
+ /* "specfile.pyx":495
+ * (e.g. ``file_header_dict["F"]``).
+ * """
+ * return self._file_header_dict # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_dict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":490
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of file header strings, keys without the leading ``#``
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.file_header_dict", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":499
+ * @cython.embedsignature(False)
+ * @property
+ * def labels(self): # <<<<<<<<<<<<<<
+ * """
+ * List of data column headers from ``#L`` scan header
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_21labels(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_20labels[] = "\n List of data column headers from ``#L`` scan header\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_21labels = {"labels", (PyCFunction)__pyx_pw_8specfile_4Scan_21labels, METH_O, __pyx_doc_8specfile_4Scan_20labels};
+static PyObject *__pyx_pw_8specfile_4Scan_21labels(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("labels (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_20labels(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_20labels(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("labels", 0);
+
+ /* "specfile.pyx":503
+ * List of data column headers from ``#L`` scan header
+ * """
+ * return self._labels # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_labels); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":499
+ * @cython.embedsignature(False)
+ * @property
+ * def labels(self): # <<<<<<<<<<<<<<
+ * """
+ * List of data column headers from ``#L`` scan header
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.labels", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":507
+ * @cython.embedsignature(False)
+ * @property
+ * def data(self): # <<<<<<<<<<<<<<
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ * (e.g. data.shape).
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_23data(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_22data[] = "Scan data as a 2D numpy.ndarray with the usual attributes\n (e.g. data.shape).\n\n The first index is the detector, the second index is the sample index.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_23data = {"data", (PyCFunction)__pyx_pw_8specfile_4Scan_23data, METH_O, __pyx_doc_8specfile_4Scan_22data};
+static PyObject *__pyx_pw_8specfile_4Scan_23data(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_22data(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_22data(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data", 0);
+
+ /* "specfile.pyx":513
+ * The first index is the detector, the second index is the sample index.
+ * """
+ * if self._data is None: # <<<<<<<<<<<<<<
+ * self._data = numpy.transpose(self._specfile.data(self._index))
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__pyx_t_1 == Py_None);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":514
+ * """
+ * if self._data is None:
+ * self._data = numpy.transpose(self._specfile.data(self._index)) # <<<<<<<<<<<<<<
+ *
+ * return self._data
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_transpose); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_data_2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_data, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":516
+ * self._data = numpy.transpose(self._specfile.data(self._index))
+ *
+ * return self._data # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 516; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":507
+ * @cython.embedsignature(False)
+ * @property
+ * def data(self): # <<<<<<<<<<<<<<
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ * (e.g. data.shape).
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("specfile.Scan.data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":520
+ * @cython.embedsignature(False)
+ * @property
+ * def mca(self): # <<<<<<<<<<<<<<
+ * """MCA data in this scan.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_25mca(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_24mca[] = "MCA data in this scan.\n\n Each multichannel analysis is a 1D numpy array. Metadata about\n MCA data is to be found in :py:attr:`mca_header`.\n\n :rtype: :class:`MCA`\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_25mca = {"mca", (PyCFunction)__pyx_pw_8specfile_4Scan_25mca, METH_O, __pyx_doc_8specfile_4Scan_24mca};
+static PyObject *__pyx_pw_8specfile_4Scan_25mca(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("mca (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_24mca(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_24mca(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("mca", 0);
+
+ /* "specfile.pyx":528
+ * :rtype: :class:`MCA`
+ * """
+ * if self._mca is None: # <<<<<<<<<<<<<<
+ * self._mca = MCA(self)
+ * return self._mca
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_mca); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__pyx_t_1 == Py_None);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":529
+ * """
+ * if self._mca is None:
+ * self._mca = MCA(self) # <<<<<<<<<<<<<<
+ * return self._mca
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_MCA); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_self);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_self);
+ __Pyx_GIVEREF(__pyx_v_self);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_mca, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":530
+ * if self._mca is None:
+ * self._mca = MCA(self)
+ * return self._mca # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_mca); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 530; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":520
+ * @cython.embedsignature(False)
+ * @property
+ * def mca(self): # <<<<<<<<<<<<<<
+ * """MCA data in this scan.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("specfile.Scan.mca", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":534
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_names(self): # <<<<<<<<<<<<<<
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_27motor_names(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_26motor_names[] = "List of motor names from the ``#O`` file header line.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_27motor_names = {"motor_names", (PyCFunction)__pyx_pw_8specfile_4Scan_27motor_names, METH_O, __pyx_doc_8specfile_4Scan_26motor_names};
+static PyObject *__pyx_pw_8specfile_4Scan_27motor_names(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_names (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_26motor_names(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_26motor_names(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_names", 0);
+
+ /* "specfile.pyx":537
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ * return self._motor_names # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_motor_names_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 537; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":534
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_names(self): # <<<<<<<<<<<<<<
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.motor_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":541
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_positions(self): # <<<<<<<<<<<<<<
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_29motor_positions(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_28motor_positions[] = "List of motor positions as floats from the ``#P`` scan header line.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_29motor_positions = {"motor_positions", (PyCFunction)__pyx_pw_8specfile_4Scan_29motor_positions, METH_O, __pyx_doc_8specfile_4Scan_28motor_positions};
+static PyObject *__pyx_pw_8specfile_4Scan_29motor_positions(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_positions (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_28motor_positions(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_28motor_positions(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_positions", 0);
+
+ /* "specfile.pyx":544
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ * return self._motor_positions # <<<<<<<<<<<<<<
+ *
+ * def record_exists_in_hdr(self, record):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_motor_positions_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":541
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_positions(self): # <<<<<<<<<<<<<<
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.motor_positions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":546
+ * return self._motor_positions
+ *
+ * def record_exists_in_hdr(self, record): # <<<<<<<<<<<<<<
+ * """Check whether a scan header line exists.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_31record_exists_in_hdr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan_30record_exists_in_hdr[] = "Scan.record_exists_in_hdr(self, record)\nCheck whether a scan header line exists.\n \n This should be used before attempting to retrieve header information \n using a C function that may crash with a *segmentation fault* if the\n header isn't defined in the SpecFile.\n \n :param record: single upper case letter corresponding to the\n header you want to test (e.g. ``L`` for labels)\n :type record: str\n\n :return: True or False\n :rtype: boolean\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_31record_exists_in_hdr = {"record_exists_in_hdr", (PyCFunction)__pyx_pw_8specfile_4Scan_31record_exists_in_hdr, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan_30record_exists_in_hdr};
+static PyObject *__pyx_pw_8specfile_4Scan_31record_exists_in_hdr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_record = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("record_exists_in_hdr (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_record,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_record)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("record_exists_in_hdr", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "record_exists_in_hdr") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_record = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("record_exists_in_hdr", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.record_exists_in_hdr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan_30record_exists_in_hdr(__pyx_self, __pyx_v_self, __pyx_v_record);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_30record_exists_in_hdr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_record) {
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("record_exists_in_hdr", 0);
+
+ /* "specfile.pyx":560
+ * :rtype: boolean
+ * """
+ * for line in self._header: # <<<<<<<<<<<<<<
+ * if line.startswith("#" + record):
+ * return True
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+ __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_1 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_1)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_line, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":561
+ * """
+ * for line in self._header:
+ * if line.startswith("#" + record): # <<<<<<<<<<<<<<
+ * return True
+ * return False
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_line, __pyx_n_s_startswith); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyNumber_Add(__pyx_kp_s__7, __pyx_v_record); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_9) {
+
+ /* "specfile.pyx":562
+ * for line in self._header:
+ * if line.startswith("#" + record):
+ * return True # <<<<<<<<<<<<<<
+ * return False
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_True);
+ __pyx_r = Py_True;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "specfile.pyx":560
+ * :rtype: boolean
+ * """
+ * for line in self._header: # <<<<<<<<<<<<<<
+ * if line.startswith("#" + record):
+ * return True
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":563
+ * if line.startswith("#" + record):
+ * return True
+ * return False # <<<<<<<<<<<<<<
+ *
+ * def data_line(self, line_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_False);
+ __pyx_r = Py_False;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":546
+ * return self._motor_positions
+ *
+ * def record_exists_in_hdr(self, record): # <<<<<<<<<<<<<<
+ * """Check whether a scan header line exists.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.Scan.record_exists_in_hdr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":565
+ * return False
+ *
+ * def data_line(self, line_index): # <<<<<<<<<<<<<<
+ * """Returns data for a given line of this scan.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_33data_line(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan_32data_line[] = "Scan.data_line(self, line_index)\nReturns data for a given line of this scan.\n\n .. note::\n\n A data line returned by this method, corresponds to a data line\n in the original specfile (a series of data points, one per\n detector). In the :attr:`data` array, this line index corresponds\n to the index in the second dimension (~ column) of the array.\n \n :param line_index: Index of data line to retrieve (starting with 0)\n :type line_index: int\n\n :return: Line data as a 1D array of doubles\n :rtype: numpy.ndarray \n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_33data_line = {"data_line", (PyCFunction)__pyx_pw_8specfile_4Scan_33data_line, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan_32data_line};
+static PyObject *__pyx_pw_8specfile_4Scan_33data_line(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_line_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data_line (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_line_index,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_line_index)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("data_line", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "data_line") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_line_index = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("data_line", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.data_line", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan_32data_line(__pyx_self, __pyx_v_self, __pyx_v_line_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_32data_line(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_line_index) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data_line", 0);
+
+ /* "specfile.pyx":583
+ * # attribute data corresponds to a transposed version of the original
+ * # specfile data (where detectors correspond to columns)
+ * return self.data[:, line_index] # <<<<<<<<<<<<<<
+ *
+ * def data_column_by_name(self, label):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_data_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_slice__19);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_slice__19);
+ __Pyx_GIVEREF(__pyx_slice__19);
+ __Pyx_INCREF(__pyx_v_line_index);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_line_index);
+ __Pyx_GIVEREF(__pyx_v_line_index);
+ __pyx_t_3 = PyObject_GetItem(__pyx_t_1, __pyx_t_2); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":565
+ * return False
+ *
+ * def data_line(self, line_index): # <<<<<<<<<<<<<<
+ * """Returns data for a given line of this scan.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.Scan.data_line", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":585
+ * return self.data[:, line_index]
+ *
+ * def data_column_by_name(self, label): # <<<<<<<<<<<<<<
+ * """Returns a data column
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_35data_column_by_name(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan_34data_column_by_name[] = "Scan.data_column_by_name(self, label)\nReturns a data column\n\n :param label: Label of data column to retrieve, as defined on the\n ``#L`` line of the scan header.\n :type label: str\n\n :return: Line data as a 1D array of doubles\n :rtype: numpy.ndarray\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_35data_column_by_name = {"data_column_by_name", (PyCFunction)__pyx_pw_8specfile_4Scan_35data_column_by_name, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan_34data_column_by_name};
+static PyObject *__pyx_pw_8specfile_4Scan_35data_column_by_name(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_label = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data_column_by_name (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_label,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_label)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("data_column_by_name", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "data_column_by_name") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_label = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("data_column_by_name", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan_34data_column_by_name(__pyx_self, __pyx_v_self, __pyx_v_label);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_34data_column_by_name(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_label) {
+ PyObject *__pyx_v_ret = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data_column_by_name", 0);
+
+ /* "specfile.pyx":595
+ * :rtype: numpy.ndarray
+ * """
+ * try: # <<<<<<<<<<<<<<
+ * ret = self._specfile.data_column_by_name(self._index, label)
+ * except SfErrLineNotFound:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ /*try:*/ {
+
+ /* "specfile.pyx":596
+ * """
+ * try:
+ * ret = self._specfile.data_column_by_name(self._index, label) # <<<<<<<<<<<<<<
+ * except SfErrLineNotFound:
+ * # Could be a "#C Scan aborted after 0 points"
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_data_column_by_name); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_label);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_label);
+ __Pyx_GIVEREF(__pyx_v_label);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_ret = __pyx_t_4;
+ __pyx_t_4 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L10_try_end;
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":597
+ * try:
+ * ret = self._specfile.data_column_by_name(self._index, label)
+ * except SfErrLineNotFound: # <<<<<<<<<<<<<<
+ * # Could be a "#C Scan aborted after 0 points"
+ * _logger.warning("Cannot get data column %s in scan %d.%d",
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLineNotFound); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_10 = PyErr_ExceptionMatches(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_10) {
+ __Pyx_AddTraceback("specfile.Scan.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "specfile.pyx":599
+ * except SfErrLineNotFound:
+ * # Could be a "#C Scan aborted after 0 points"
+ * _logger.warning("Cannot get data column %s in scan %d.%d", # <<<<<<<<<<<<<<
+ * label, self.number, self.order)
+ * ret = numpy.empty((0, ), numpy.double)
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_warning); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "specfile.pyx":600
+ * # Could be a "#C Scan aborted after 0 points"
+ * _logger.warning("Cannot get data column %s in scan %d.%d",
+ * label, self.number, self.order) # <<<<<<<<<<<<<<
+ * ret = numpy.empty((0, ), numpy.double)
+ * return ret
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_number); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_order); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ __pyx_t_13 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_11))) {
+ __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_11);
+ if (likely(__pyx_t_13)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+ __Pyx_INCREF(__pyx_t_13);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_11, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_14 = PyTuple_New(4+__pyx_t_8); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ if (__pyx_t_13) {
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_13); __Pyx_GIVEREF(__pyx_t_13); __pyx_t_13 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_Cannot_get_data_column_s_in_scan);
+ PyTuple_SET_ITEM(__pyx_t_14, 0+__pyx_t_8, __pyx_kp_s_Cannot_get_data_column_s_in_scan);
+ __Pyx_GIVEREF(__pyx_kp_s_Cannot_get_data_column_s_in_scan);
+ __Pyx_INCREF(__pyx_v_label);
+ PyTuple_SET_ITEM(__pyx_t_14, 1+__pyx_t_8, __pyx_v_label);
+ __Pyx_GIVEREF(__pyx_v_label);
+ PyTuple_SET_ITEM(__pyx_t_14, 2+__pyx_t_8, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_14, 3+__pyx_t_8, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ __pyx_t_7 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_14, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "specfile.pyx":601
+ * _logger.warning("Cannot get data column %s in scan %d.%d",
+ * label, self.number, self.order)
+ * ret = numpy.empty((0, ), numpy.double) # <<<<<<<<<<<<<<
+ * return ret
+ *
+ */
+ __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_empty); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_double); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_11 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_14))) {
+ __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_14);
+ if (likely(__pyx_t_11)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_14);
+ __Pyx_INCREF(__pyx_t_11);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_14, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_7 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ if (__pyx_t_11) {
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_11); __Pyx_GIVEREF(__pyx_t_11); __pyx_t_11 = NULL;
+ }
+ __Pyx_INCREF(__pyx_tuple__20);
+ PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_8, __pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+ PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_8, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ __pyx_t_12 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_14, __pyx_t_7, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_ret, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L4_exception_handled;
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_1);
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+ goto __pyx_L1_error;
+ __pyx_L4_exception_handled:;
+ __Pyx_XGIVEREF(__pyx_t_1);
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+ __pyx_L10_try_end:;
+ }
+
+ /* "specfile.pyx":602
+ * label, self.number, self.order)
+ * ret = numpy.empty((0, ), numpy.double)
+ * return ret # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_ret);
+ __pyx_r = __pyx_v_ret;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":585
+ * return self.data[:, line_index]
+ *
+ * def data_column_by_name(self, label): # <<<<<<<<<<<<<<
+ * """Returns a data column
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_AddTraceback("specfile.Scan.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_ret);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":605
+ *
+ *
+ * def motor_position_by_name(self, name): # <<<<<<<<<<<<<<
+ * """Returns the position for a given motor
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_37motor_position_by_name(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan_36motor_position_by_name[] = "Scan.motor_position_by_name(self, name)\nReturns the position for a given motor\n\n :param name: Name of motor, as defined on the ``#O`` line of the\n file header.\n :type name: str\n\n :return: Motor position\n :rtype: float\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_37motor_position_by_name = {"motor_position_by_name", (PyCFunction)__pyx_pw_8specfile_4Scan_37motor_position_by_name, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan_36motor_position_by_name};
+static PyObject *__pyx_pw_8specfile_4Scan_37motor_position_by_name(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_position_by_name (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_name,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("motor_position_by_name", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "motor_position_by_name") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_name = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("motor_position_by_name", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.motor_position_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan_36motor_position_by_name(__pyx_self, __pyx_v_self, __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_36motor_position_by_name(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_name) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_position_by_name", 0);
+
+ /* "specfile.pyx":615
+ * :rtype: float
+ * """
+ * return self._specfile.motor_position_by_name(self._index, name) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_motor_position_by_name); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = NULL;
+ __pyx_t_5 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ __pyx_t_5 = 1;
+ }
+ }
+ __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_name);
+ PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":605
+ *
+ *
+ * def motor_position_by_name(self, name): # <<<<<<<<<<<<<<
+ * """Returns the position for a given motor
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("specfile.Scan.motor_position_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":618
+ *
+ *
+ * def _string_to_char_star(string_): # <<<<<<<<<<<<<<
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3_string_to_char_star(PyObject *__pyx_self, PyObject *__pyx_v_string_); /*proto*/
+static char __pyx_doc_8specfile_2_string_to_char_star[] = "_string_to_char_star(string_)\nConvert a string to ASCII encoded bytes when using python3";
+static PyMethodDef __pyx_mdef_8specfile_3_string_to_char_star = {"_string_to_char_star", (PyCFunction)__pyx_pw_8specfile_3_string_to_char_star, METH_O, __pyx_doc_8specfile_2_string_to_char_star};
+static PyObject *__pyx_pw_8specfile_3_string_to_char_star(PyObject *__pyx_self, PyObject *__pyx_v_string_) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_string_to_char_star (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_2_string_to_char_star(__pyx_self, ((PyObject *)__pyx_v_string_));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_2_string_to_char_star(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_string_) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_string_to_char_star", 0);
+
+ /* "specfile.pyx":620
+ * def _string_to_char_star(string_):
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes): # <<<<<<<<<<<<<<
+ * return bytes(string_, "ascii")
+ * return string_
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_sys); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_version); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_startswith); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_1 = __pyx_t_4;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_4 = PyBytes_Check(__pyx_v_string_);
+ __pyx_t_5 = ((!(__pyx_t_4 != 0)) != 0);
+ __pyx_t_1 = __pyx_t_5;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "specfile.pyx":621
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ * return bytes(string_, "ascii") # <<<<<<<<<<<<<<
+ * return string_
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_string_);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_string_);
+ __Pyx_GIVEREF(__pyx_v_string_);
+ __Pyx_INCREF(__pyx_n_s_ascii);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_n_s_ascii);
+ __Pyx_GIVEREF(__pyx_n_s_ascii);
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyBytes_Type))), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "specfile.pyx":622
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ * return bytes(string_, "ascii")
+ * return string_ # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_string_);
+ __pyx_r = __pyx_v_string_;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":618
+ *
+ *
+ * def _string_to_char_star(string_): # <<<<<<<<<<<<<<
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile._string_to_char_star", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":625
+ *
+ *
+ * def is_specfile(filename): # <<<<<<<<<<<<<<
+ * """Test if a file is a SPEC file, by checking if one of the first two
+ * lines starts with *#F* (SPEC file header) or *#S* (scan header).
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_5is_specfile(PyObject *__pyx_self, PyObject *__pyx_v_filename); /*proto*/
+static char __pyx_doc_8specfile_4is_specfile[] = "is_specfile(filename)\nTest if a file is a SPEC file, by checking if one of the first two\n lines starts with *#F* (SPEC file header) or *#S* (scan header).\n\n :param str filename: File path\n :return: *True* if file is a SPEC file, *False* if it is not a SPEC file\n :rtype: bool\n ";
+static PyMethodDef __pyx_mdef_8specfile_5is_specfile = {"is_specfile", (PyCFunction)__pyx_pw_8specfile_5is_specfile, METH_O, __pyx_doc_8specfile_4is_specfile};
+static PyObject *__pyx_pw_8specfile_5is_specfile(PyObject *__pyx_self, PyObject *__pyx_v_filename) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_specfile (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4is_specfile(__pyx_self, ((PyObject *)__pyx_v_filename));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4is_specfile(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename) {
+ PyObject *__pyx_v_f = NULL;
+ PyObject *__pyx_v_i = NULL;
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_specfile", 0);
+
+ /* "specfile.pyx":633
+ * :rtype: bool
+ * """
+ * if not os.path.isfile(filename): # <<<<<<<<<<<<<<
+ * return False
+ * # test for presence of #S or #F in first two lines
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_os); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_path); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isfile); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_filename); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(__pyx_v_filename);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_filename);
+ __Pyx_GIVEREF(__pyx_v_filename);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = ((!__pyx_t_5) != 0);
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":634
+ * """
+ * if not os.path.isfile(filename):
+ * return False # <<<<<<<<<<<<<<
+ * # test for presence of #S or #F in first two lines
+ * f = open(filename)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_False);
+ __pyx_r = Py_False;
+ goto __pyx_L0;
+ }
+
+ /* "specfile.pyx":636
+ * return False
+ * # test for presence of #S or #F in first two lines
+ * f = open(filename) # <<<<<<<<<<<<<<
+ * for i, line in enumerate(f):
+ * if line.startswith("#S ") or line.startswith("#F "):
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_filename);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_filename);
+ __Pyx_GIVEREF(__pyx_v_filename);
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_f = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":637
+ * # test for presence of #S or #F in first two lines
+ * f = open(filename)
+ * for i, line in enumerate(f): # <<<<<<<<<<<<<<
+ * if line.startswith("#S ") or line.startswith("#F "):
+ * f.close()
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_2 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_f)) || PyTuple_CheckExact(__pyx_v_f)) {
+ __pyx_t_1 = __pyx_v_f; __Pyx_INCREF(__pyx_t_1); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_8 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_4 = __pyx_t_8(__pyx_t_1);
+ if (unlikely(!__pyx_t_4)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_4);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_line, __pyx_t_4);
+ __pyx_t_4 = 0;
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_2);
+ __pyx_t_4 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2);
+ __pyx_t_2 = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":638
+ * f = open(filename)
+ * for i, line in enumerate(f):
+ * if line.startswith("#S ") or line.startswith("#F "): # <<<<<<<<<<<<<<
+ * f.close()
+ * return True
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_line, __pyx_n_s_startswith); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (!__pyx_t_5) {
+ } else {
+ __pyx_t_6 = __pyx_t_5;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_line, __pyx_n_s_startswith); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __pyx_t_5;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":639
+ * for i, line in enumerate(f):
+ * if line.startswith("#S ") or line.startswith("#F "):
+ * f.close() # <<<<<<<<<<<<<<
+ * return True
+ * if i >= 10:
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_f, __pyx_n_s_close); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 639; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_9) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 639; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 639; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":640
+ * if line.startswith("#S ") or line.startswith("#F "):
+ * f.close()
+ * return True # <<<<<<<<<<<<<<
+ * if i >= 10:
+ * break
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_True);
+ __pyx_r = Py_True;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "specfile.pyx":641
+ * f.close()
+ * return True
+ * if i >= 10: # <<<<<<<<<<<<<<
+ * break
+ * f.close()
+ */
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_i, __pyx_int_10, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":642
+ * return True
+ * if i >= 10:
+ * break # <<<<<<<<<<<<<<
+ * f.close()
+ * return False
+ */
+ goto __pyx_L5_break;
+ }
+
+ /* "specfile.pyx":637
+ * # test for presence of #S or #F in first two lines
+ * f = open(filename)
+ * for i, line in enumerate(f): # <<<<<<<<<<<<<<
+ * if line.startswith("#S ") or line.startswith("#F "):
+ * f.close()
+ */
+ }
+ __pyx_L5_break:;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":643
+ * if i >= 10:
+ * break
+ * f.close() # <<<<<<<<<<<<<<
+ * return False
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_f, __pyx_n_s_close); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":644
+ * break
+ * f.close()
+ * return False # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_False);
+ __pyx_r = Py_False;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":625
+ *
+ *
+ * def is_specfile(filename): # <<<<<<<<<<<<<<
+ * """Test if a file is a SPEC file, by checking if one of the first two
+ * lines starts with *#F* (SPEC file header) or *#S* (scan header).
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("specfile.is_specfile", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_f);
+ __Pyx_XDECREF(__pyx_v_i);
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":661
+ * int __open_failed
+ *
+ * def __cinit__(self, filename): # <<<<<<<<<<<<<<
+ * cdef int error = SF_ERR_NO_ERRORS
+ * self.__open_failed = 0
+ */
+
+/* Python wrapper */
+static int __pyx_pw_8specfile_8SpecFile_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_8specfile_8SpecFile_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_filename = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 661; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_filename = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 661; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile___cinit__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_filename);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_8specfile_8SpecFile___cinit__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_filename) {
+ int __pyx_v_error;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_t_6;
+ char *__pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_filename);
+
+ /* "specfile.pyx":662
+ *
+ * def __cinit__(self, filename):
+ * cdef int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ * self.__open_failed = 0
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":663
+ * def __cinit__(self, filename):
+ * cdef int error = SF_ERR_NO_ERRORS
+ * self.__open_failed = 0 # <<<<<<<<<<<<<<
+ *
+ * if is_specfile(filename):
+ */
+ __pyx_v_self->__pyx___open_failed = 0;
+
+ /* "specfile.pyx":665
+ * self.__open_failed = 0
+ *
+ * if is_specfile(filename): # <<<<<<<<<<<<<<
+ * filename = _string_to_char_star(filename)
+ * self.handle = specfile_wrapper.SfOpen(filename, &error)
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_is_specfile); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_filename);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_filename);
+ __Pyx_GIVEREF(__pyx_v_filename);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":666
+ *
+ * if is_specfile(filename):
+ * filename = _string_to_char_star(filename) # <<<<<<<<<<<<<<
+ * self.handle = specfile_wrapper.SfOpen(filename, &error)
+ * else:
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_string_to_char_star); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_filename);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_filename);
+ __Pyx_GIVEREF(__pyx_v_filename);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_filename, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":667
+ * if is_specfile(filename):
+ * filename = _string_to_char_star(filename)
+ * self.handle = specfile_wrapper.SfOpen(filename, &error) # <<<<<<<<<<<<<<
+ * else:
+ * self.__open_failed = 1
+ */
+ __pyx_t_7 = __Pyx_PyObject_AsString(__pyx_v_filename); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->handle = SfOpen(__pyx_t_7, (&__pyx_v_error));
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":669
+ * self.handle = specfile_wrapper.SfOpen(filename, &error)
+ * else:
+ * self.__open_failed = 1 # <<<<<<<<<<<<<<
+ * self._handle_error(SF_ERR_FILE_OPEN)
+ * if error:
+ */
+ __pyx_v_self->__pyx___open_failed = 1;
+
+ /* "specfile.pyx":670
+ * else:
+ * self.__open_failed = 1
+ * self._handle_error(SF_ERR_FILE_OPEN) # <<<<<<<<<<<<<<
+ * if error:
+ * self.__open_failed = 1
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_FILE_OPEN); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":671
+ * self.__open_failed = 1
+ * self._handle_error(SF_ERR_FILE_OPEN)
+ * if error: # <<<<<<<<<<<<<<
+ * self.__open_failed = 1
+ * self._handle_error(error)
+ */
+ __pyx_t_6 = (__pyx_v_error != 0);
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":672
+ * self._handle_error(SF_ERR_FILE_OPEN)
+ * if error:
+ * self.__open_failed = 1 # <<<<<<<<<<<<<<
+ * self._handle_error(error)
+ *
+ */
+ __pyx_v_self->__pyx___open_failed = 1;
+
+ /* "specfile.pyx":673
+ * if error:
+ * self.__open_failed = 1
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * def __init__(self, filename):
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "specfile.pyx":661
+ * int __open_failed
+ *
+ * def __cinit__(self, filename): # <<<<<<<<<<<<<<
+ * cdef int error = SF_ERR_NO_ERRORS
+ * self.__open_failed = 0
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_filename);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":675
+ * self._handle_error(error)
+ *
+ * def __init__(self, filename): # <<<<<<<<<<<<<<
+ * if not isinstance(filename, str):
+ * # encode unicode to str in python 2
+ */
+
+/* Python wrapper */
+static int __pyx_pw_8specfile_8SpecFile_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_8specfile_8SpecFile_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_filename = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_filename = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_2__init__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_filename);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_8specfile_8SpecFile_2__init__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_filename) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "specfile.pyx":676
+ *
+ * def __init__(self, filename):
+ * if not isinstance(filename, str): # <<<<<<<<<<<<<<
+ * # encode unicode to str in python 2
+ * if sys.version_info[0] < 3:
+ */
+ __pyx_t_1 = PyString_Check(__pyx_v_filename);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":678
+ * if not isinstance(filename, str):
+ * # encode unicode to str in python 2
+ * if sys.version_info[0] < 3: # <<<<<<<<<<<<<<
+ * self.filename = filename.encode()
+ * # decode bytes to str in python 3
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_sys); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_version_info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_4, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_int_3, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":679
+ * # encode unicode to str in python 2
+ * if sys.version_info[0] < 3:
+ * self.filename = filename.encode() # <<<<<<<<<<<<<<
+ * # decode bytes to str in python 3
+ * elif sys.version_info[0] >= 3:
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_filename, __pyx_n_s_encode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (!(likely(PyString_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GIVEREF(__pyx_t_4);
+ __Pyx_GOTREF(__pyx_v_self->filename);
+ __Pyx_DECREF(__pyx_v_self->filename);
+ __pyx_v_self->filename = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L4;
+ }
+
+ /* "specfile.pyx":681
+ * self.filename = filename.encode()
+ * # decode bytes to str in python 3
+ * elif sys.version_info[0] >= 3: # <<<<<<<<<<<<<<
+ * self.filename = filename.decode()
+ * else:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_sys); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_version_info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyObject_RichCompare(__pyx_t_4, __pyx_int_3, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":682
+ * # decode bytes to str in python 3
+ * elif sys.version_info[0] >= 3:
+ * self.filename = filename.decode() # <<<<<<<<<<<<<<
+ * else:
+ * self.filename = filename
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_filename, __pyx_n_s_decode); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!(likely(PyString_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->filename);
+ __Pyx_DECREF(__pyx_v_self->filename);
+ __pyx_v_self->filename = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":684
+ * self.filename = filename.decode()
+ * else:
+ * self.filename = filename # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(self):
+ */
+ if (!(likely(PyString_CheckExact(__pyx_v_filename))||((__pyx_v_filename) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_v_filename)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 684; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_filename;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->filename);
+ __Pyx_DECREF(__pyx_v_self->filename);
+ __pyx_v_self->filename = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":675
+ * self._handle_error(error)
+ *
+ * def __init__(self, filename): # <<<<<<<<<<<<<<
+ * if not isinstance(filename, str):
+ * # encode unicode to str in python 2
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("specfile.SpecFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":686
+ * self.filename = filename
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * """Destructor: Calls SfClose(self.handle)"""
+ * #SfClose makes a segmentation fault if file failed to open
+ */
+
+/* Python wrapper */
+static void __pyx_pw_8specfile_8SpecFile_5__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_8specfile_8SpecFile_5__dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_pf_8specfile_8SpecFile_4__dealloc__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_8specfile_8SpecFile_4__dealloc__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "specfile.pyx":689
+ * """Destructor: Calls SfClose(self.handle)"""
+ * #SfClose makes a segmentation fault if file failed to open
+ * if not self.__open_failed: # <<<<<<<<<<<<<<
+ * if specfile_wrapper.SfClose(self.handle):
+ * _logger.warning("Error while closing SpecFile")
+ */
+ __pyx_t_1 = ((!(__pyx_v_self->__pyx___open_failed != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "specfile.pyx":690
+ * #SfClose makes a segmentation fault if file failed to open
+ * if not self.__open_failed:
+ * if specfile_wrapper.SfClose(self.handle): # <<<<<<<<<<<<<<
+ * _logger.warning("Error while closing SpecFile")
+ *
+ */
+ __pyx_t_1 = (SfClose(__pyx_v_self->handle) != 0);
+ if (__pyx_t_1) {
+
+ /* "specfile.pyx":691
+ * if not self.__open_failed:
+ * if specfile_wrapper.SfClose(self.handle):
+ * _logger.warning("Error while closing SpecFile") # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warning); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":686
+ * self.filename = filename
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * """Destructor: Calls SfClose(self.handle)"""
+ * #SfClose makes a segmentation fault if file failed to open
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("specfile.SpecFile.__dealloc__", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "specfile.pyx":693
+ * _logger.warning("Error while closing SpecFile")
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """Return the number of scans in the SpecFile
+ * """
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_pw_8specfile_8SpecFile_7__len__(PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_6__len__[] = "Return the number of scans in the SpecFile\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_8specfile_8SpecFile_6__len__;
+#endif
+static Py_ssize_t __pyx_pw_8specfile_8SpecFile_7__len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_6__len__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_pf_8specfile_8SpecFile_6__len__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "specfile.pyx":696
+ * """Return the number of scans in the SpecFile
+ * """
+ * return specfile_wrapper.SfScanNo(self.handle) # <<<<<<<<<<<<<<
+ *
+ * def __iter__(self):
+ */
+ __pyx_r = SfScanNo(__pyx_v_self->handle);
+ goto __pyx_L0;
+
+ /* "specfile.pyx":693
+ * _logger.warning("Error while closing SpecFile")
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """Return the number of scans in the SpecFile
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+static PyObject *__pyx_gb_8specfile_8SpecFile_10generator1(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "specfile.pyx":698
+ * return specfile_wrapper.SfScanNo(self.handle)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next :class:`Scan` in a SpecFile each time this method
+ * is called.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_9__iter__(PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_8__iter__[] = "Return the next :class:`Scan` in a SpecFile each time this method\n is called.\n\n This usually happens when the python built-in function ``next()`` is\n called with a :class:`SpecFile` instance as a parameter, or when a\n :class:`SpecFile` instance is used as an iterator (e.g. in a ``for``\n loop).\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_8specfile_8SpecFile_8__iter__;
+#endif
+static PyObject *__pyx_pw_8specfile_8SpecFile_9__iter__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_8__iter__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_8__iter__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *__pyx_cur_scope;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__iter__", 0);
+ __pyx_cur_scope = (struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)__pyx_tp_new_8specfile___pyx_scope_struct_1___iter__(__pyx_ptype_8specfile___pyx_scope_struct_1___iter__, __pyx_empty_tuple, NULL);
+ if (unlikely(!__pyx_cur_scope)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_cur_scope);
+ __pyx_cur_scope->__pyx_v_self = __pyx_v_self;
+ __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+ __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+ {
+ __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_8specfile_8SpecFile_10generator1, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_SpecFile___iter); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_cur_scope);
+ __Pyx_RefNannyFinishContext();
+ return (PyObject *) gen;
+ }
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_gb_8specfile_8SpecFile_10generator1(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *__pyx_cur_scope = ((struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)__pyx_generator->closure);
+ PyObject *__pyx_r = NULL;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("None", 0);
+ switch (__pyx_generator->resume_label) {
+ case 0: goto __pyx_L3_first_run;
+ case 1: goto __pyx_L6_resume_from_yield;
+ default: /* CPython raises the right error here */
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __pyx_L3_first_run:;
+ if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":707
+ * loop).
+ * """
+ * for scan_index in range(len(self)): # <<<<<<<<<<<<<<
+ * yield Scan(self, scan_index)
+ *
+ */
+ __pyx_t_1 = PyObject_Length(((PyObject *)__pyx_cur_scope->__pyx_v_self)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_cur_scope->__pyx_v_scan_index = __pyx_t_2;
+
+ /* "specfile.pyx":708
+ * """
+ * for scan_index in range(len(self)):
+ * yield Scan(self, scan_index) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, key):
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_Scan); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyInt_FromSsize_t(__pyx_cur_scope->__pyx_v_scan_index); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_6) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ }
+ __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, ((PyObject *)__pyx_cur_scope->__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
+ __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ /* return from generator, yielding value */
+ __pyx_generator->resume_label = 1;
+ return __pyx_r;
+ __pyx_L6_resume_from_yield:;
+ __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
+ __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
+ if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":698
+ * return specfile_wrapper.SfScanNo(self.handle)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next :class:`Scan` in a SpecFile each time this method
+ * is called.
+ */
+
+ /* function exit code */
+ PyErr_SetNone(PyExc_StopIteration);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_generator->resume_label = -1;
+ __Pyx_Generator_clear((PyObject*)__pyx_generator);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+}
+
+/* "specfile.pyx":710
+ * yield Scan(self, scan_index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a :class:`Scan` object.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_12__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_11__getitem__[] = "Return a :class:`Scan` object.\n\n This special method is called when a :class:`SpecFile` instance is\n accessed as a dictionary (e.g. ``sf[key]``).\n\n :param key: 0-based scan index or ``\"n.m\"`` key, where ``n`` is the scan\n number defined on the ``#S`` header line and ``m`` is the order\n :type key: int or str\n\n :return: Scan defined by its 0-based index or its ``\"n.m\"`` key\n :rtype: :class:`Scan`\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_8specfile_8SpecFile_11__getitem__;
+#endif
+static PyObject *__pyx_pw_8specfile_8SpecFile_12__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_11__getitem__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_11__getitem__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_v_msg = NULL;
+ PyObject *__pyx_v_scan_index = NULL;
+ PyObject *__pyx_v_number = NULL;
+ PyObject *__pyx_v_order = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *(*__pyx_t_11)(PyObject *);
+ int __pyx_t_12;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "specfile.pyx":723
+ * :rtype: :class:`Scan`
+ * """
+ * msg = "The scan identification key can be an integer representing " # <<<<<<<<<<<<<<
+ * msg += "the unique scan index or a string 'N.M' with N being the scan"
+ * msg += " number and M the order (eg '2.3')."
+ */
+ __Pyx_INCREF(__pyx_kp_s_The_scan_identification_key_can);
+ __pyx_v_msg = __pyx_kp_s_The_scan_identification_key_can;
+
+ /* "specfile.pyx":724
+ * """
+ * msg = "The scan identification key can be an integer representing "
+ * msg += "the unique scan index or a string 'N.M' with N being the scan" # <<<<<<<<<<<<<<
+ * msg += " number and M the order (eg '2.3')."
+ *
+ */
+ __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_msg, __pyx_kp_s_the_unique_scan_index_or_a_strin); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 724; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":725
+ * msg = "The scan identification key can be an integer representing "
+ * msg += "the unique scan index or a string 'N.M' with N being the scan"
+ * msg += " number and M the order (eg '2.3')." # <<<<<<<<<<<<<<
+ *
+ * if isinstance(key, int):
+ */
+ __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_msg, __pyx_kp_s_number_and_M_the_order_eg_2_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":727
+ * msg += " number and M the order (eg '2.3')."
+ *
+ * if isinstance(key, int): # <<<<<<<<<<<<<<
+ * scan_index = key
+ * # allow negative index, like lists
+ */
+ __pyx_t_2 = PyInt_Check(__pyx_v_key);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":728
+ *
+ * if isinstance(key, int):
+ * scan_index = key # <<<<<<<<<<<<<<
+ * # allow negative index, like lists
+ * if scan_index < 0:
+ */
+ __Pyx_INCREF(__pyx_v_key);
+ __pyx_v_scan_index = __pyx_v_key;
+
+ /* "specfile.pyx":730
+ * scan_index = key
+ * # allow negative index, like lists
+ * if scan_index < 0: # <<<<<<<<<<<<<<
+ * scan_index = len(self) + scan_index
+ * else:
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_scan_index, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":731
+ * # allow negative index, like lists
+ * if scan_index < 0:
+ * scan_index = len(self) + scan_index # <<<<<<<<<<<<<<
+ * else:
+ * try:
+ */
+ __pyx_t_4 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = PyNumber_Add(__pyx_t_1, __pyx_v_scan_index); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF_SET(__pyx_v_scan_index, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":733
+ * scan_index = len(self) + scan_index
+ * else:
+ * try: # <<<<<<<<<<<<<<
+ * (number, order) = map(int, key.split("."))
+ * scan_index = self.index(number, order)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ /*try:*/ {
+
+ /* "specfile.pyx":734
+ * else:
+ * try:
+ * (number, order) = map(int, key.split(".")) # <<<<<<<<<<<<<<
+ * scan_index = self.index(number, order)
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_key, __pyx_n_s_split); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+ PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
+ __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_map, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_5 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_9 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_9);
+ #else
+ __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_11 = Py_TYPE(__pyx_t_10)->tp_iternext;
+ index = 0; __pyx_t_5 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_5)) goto __pyx_L13_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_5);
+ index = 1; __pyx_t_9 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L13_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __pyx_t_11 = NULL;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ goto __pyx_L14_unpacking_done;
+ __pyx_L13_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_11 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __pyx_L14_unpacking_done:;
+ }
+ __pyx_v_number = __pyx_t_5;
+ __pyx_t_5 = 0;
+ __pyx_v_order = __pyx_t_9;
+ __pyx_t_9 = 0;
+
+ /* "specfile.pyx":735
+ * try:
+ * (number, order) = map(int, key.split("."))
+ * scan_index = self.index(number, order) # <<<<<<<<<<<<<<
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ * # int() can raise a value error
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_index); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_5 = NULL;
+ __pyx_t_4 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ __pyx_t_4 = 1;
+ }
+ }
+ __pyx_t_10 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_number);
+ PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_4, __pyx_v_number);
+ __Pyx_GIVEREF(__pyx_v_number);
+ __Pyx_INCREF(__pyx_v_order);
+ PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_4, __pyx_v_order);
+ __Pyx_GIVEREF(__pyx_v_order);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_scan_index = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L12_try_end;
+ __pyx_L5_error:;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":736
+ * (number, order) = map(int, key.split("."))
+ * scan_index = self.index(number, order)
+ * except (ValueError, SfErrScanNotFound, KeyError): # <<<<<<<<<<<<<<
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" +
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrScanNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_builtin_ValueError) || PyErr_ExceptionMatches(__pyx_t_1) || PyErr_ExceptionMatches(__pyx_builtin_KeyError);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("specfile.SpecFile.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_9, &__pyx_t_10) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_GOTREF(__pyx_t_10);
+
+ /* "specfile.pyx":738
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" + # <<<<<<<<<<<<<<
+ * "', '".join( self.keys()) + "'")
+ * except AttributeError:
+ */
+ __pyx_t_5 = PyNumber_Add(__pyx_v_msg, __pyx_kp_s_Valid_keys); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "specfile.pyx":739
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" +
+ * "', '".join( self.keys()) + "'") # <<<<<<<<<<<<<<
+ * except AttributeError:
+ * # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ */
+ __pyx_t_14 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_keys); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __pyx_t_15 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_14))) {
+ __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_14);
+ if (likely(__pyx_t_15)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_14);
+ __Pyx_INCREF(__pyx_t_15);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_14, function);
+ }
+ }
+ if (__pyx_t_15) {
+ __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_15); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+ } else {
+ __pyx_t_13 = __Pyx_PyObject_CallNoArg(__pyx_t_14); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_13);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ __pyx_t_14 = __Pyx_PyString_Join(__pyx_kp_s__27, __pyx_t_13); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+
+ /* "specfile.pyx":738
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" + # <<<<<<<<<<<<<<
+ * "', '".join( self.keys()) + "'")
+ * except AttributeError:
+ */
+ __pyx_t_13 = PyNumber_Add(__pyx_t_5, __pyx_t_14); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+
+ /* "specfile.pyx":739
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" +
+ * "', '".join( self.keys()) + "'") # <<<<<<<<<<<<<<
+ * except AttributeError:
+ * # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ */
+ __pyx_t_14 = PyNumber_Add(__pyx_t_13, __pyx_kp_s__28); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+
+ /* "specfile.pyx":738
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" + # <<<<<<<<<<<<<<
+ * "', '".join( self.keys()) + "'")
+ * except AttributeError:
+ */
+ __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ __pyx_t_14 = 0;
+ __pyx_t_14 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_13, NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ __Pyx_Raise(__pyx_t_14, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ }
+
+ /* "specfile.pyx":740
+ * raise KeyError(msg + "\nValid keys: '" +
+ * "', '".join( self.keys()) + "'")
+ * except AttributeError: # <<<<<<<<<<<<<<
+ * # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ * raise TypeError(msg)
+ */
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_builtin_AttributeError);
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("specfile.SpecFile.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_10, &__pyx_t_9, &__pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "specfile.pyx":742
+ * except AttributeError:
+ * # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ * raise TypeError(msg) # <<<<<<<<<<<<<<
+ *
+ * if not 0 <= scan_index < len(self):
+ */
+ __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 742; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_v_msg);
+ __Pyx_GIVEREF(__pyx_v_msg);
+ __pyx_t_13 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_14, NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 742; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ __Pyx_Raise(__pyx_t_13, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 742; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ }
+ goto __pyx_L7_except_error;
+ __pyx_L7_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ goto __pyx_L1_error;
+ __pyx_L12_try_end:;
+ }
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":744
+ * raise TypeError(msg)
+ *
+ * if not 0 <= scan_index < len(self): # <<<<<<<<<<<<<<
+ * msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ * raise IndexError(msg)
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_int_0, __pyx_v_scan_index, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__Pyx_PyObject_IsTrue(__pyx_t_1)) {
+ __Pyx_DECREF(__pyx_t_1);
+ __pyx_t_4 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_scan_index, __pyx_t_9, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_2 = ((!__pyx_t_3) != 0);
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":745
+ *
+ * if not 0 <= scan_index < len(self):
+ * msg = "Scan index must be in range 0-%d" % (len(self) - 1) # <<<<<<<<<<<<<<
+ * raise IndexError(msg)
+ *
+ */
+ __pyx_t_4 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 745; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = PyInt_FromSsize_t((__pyx_t_4 - 1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 745; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Scan_index_must_be_in_range_0_d, __pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 745; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_9);
+ __pyx_t_9 = 0;
+
+ /* "specfile.pyx":746
+ * if not 0 <= scan_index < len(self):
+ * msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ * raise IndexError(msg) # <<<<<<<<<<<<<<
+ *
+ * return Scan(self, scan_index)
+ */
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_msg);
+ __Pyx_GIVEREF(__pyx_v_msg);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":748
+ * raise IndexError(msg)
+ *
+ * return Scan(self, scan_index) # <<<<<<<<<<<<<<
+ *
+ * def keys(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_Scan); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = NULL;
+ __pyx_t_4 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ __pyx_t_4 = 1;
+ }
+ }
+ __pyx_t_13 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ if (__pyx_t_10) {
+ PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ }
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_13, 0+__pyx_t_4, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_INCREF(__pyx_v_scan_index);
+ PyTuple_SET_ITEM(__pyx_t_13, 1+__pyx_t_4, __pyx_v_scan_index);
+ __Pyx_GIVEREF(__pyx_v_scan_index);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_13, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":710
+ * yield Scan(self, scan_index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a :class:`Scan` object.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_AddTraceback("specfile.SpecFile.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_msg);
+ __Pyx_XDECREF(__pyx_v_scan_index);
+ __Pyx_XDECREF(__pyx_v_number);
+ __Pyx_XDECREF(__pyx_v_order);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":750
+ * return Scan(self, scan_index)
+ *
+ * def keys(self): # <<<<<<<<<<<<<<
+ * """Returns list of scan keys (eg ``['1.1', '2.1',...]``).
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_14keys(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_13keys[] = "SpecFile.keys(self)\nReturns list of scan keys (eg ``['1.1', '2.1',...]``).\n\n :return: list of scan keys\n :rtype: list of strings\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_14keys(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("keys (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_13keys(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_13keys(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ PyObject *__pyx_v_ret_list = NULL;
+ PyObject *__pyx_v_list_of_numbers = NULL;
+ PyObject *__pyx_v_count = NULL;
+ PyObject *__pyx_v_number = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ Py_ssize_t __pyx_t_4;
+ PyObject *(*__pyx_t_5)(PyObject *);
+ int __pyx_t_6;
+ int __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("keys", 0);
+
+ /* "specfile.pyx":756
+ * :rtype: list of strings
+ * """
+ * ret_list = [] # <<<<<<<<<<<<<<
+ * list_of_numbers = self._list()
+ * count = {}
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 756; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_ret_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":757
+ * """
+ * ret_list = []
+ * list_of_numbers = self._list() # <<<<<<<<<<<<<<
+ * count = {}
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_list); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_list_of_numbers = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":758
+ * ret_list = []
+ * list_of_numbers = self._list()
+ * count = {} # <<<<<<<<<<<<<<
+ *
+ * for number in list_of_numbers:
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_count = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":760
+ * count = {}
+ *
+ * for number in list_of_numbers: # <<<<<<<<<<<<<<
+ * if not number in count:
+ * count[number] = 1
+ */
+ if (likely(PyList_CheckExact(__pyx_v_list_of_numbers)) || PyTuple_CheckExact(__pyx_v_list_of_numbers)) {
+ __pyx_t_1 = __pyx_v_list_of_numbers; __Pyx_INCREF(__pyx_t_1); __pyx_t_4 = 0;
+ __pyx_t_5 = NULL;
+ } else {
+ __pyx_t_4 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_list_of_numbers); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_5)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_2 = __pyx_t_5(__pyx_t_1);
+ if (unlikely(!__pyx_t_2)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_number, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":761
+ *
+ * for number in list_of_numbers:
+ * if not number in count: # <<<<<<<<<<<<<<
+ * count[number] = 1
+ * else:
+ */
+ __pyx_t_6 = (__Pyx_PyDict_Contains(__pyx_v_number, __pyx_v_count, Py_NE)); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 761; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = (__pyx_t_6 != 0);
+ if (__pyx_t_7) {
+
+ /* "specfile.pyx":762
+ * for number in list_of_numbers:
+ * if not number in count:
+ * count[number] = 1 # <<<<<<<<<<<<<<
+ * else:
+ * count[number] += 1
+ */
+ if (unlikely(PyDict_SetItem(__pyx_v_count, __pyx_v_number, __pyx_int_1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":764
+ * count[number] = 1
+ * else:
+ * count[number] += 1 # <<<<<<<<<<<<<<
+ * ret_list.append(u'%d.%d' % (number, count[number]))
+ *
+ */
+ __Pyx_INCREF(__pyx_v_number);
+ __pyx_t_2 = __pyx_v_number;
+ __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_count, __pyx_t_2); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (unlikely(PyDict_SetItem(__pyx_v_count, __pyx_t_2, __pyx_t_8) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L5:;
+
+ /* "specfile.pyx":765
+ * else:
+ * count[number] += 1
+ * ret_list.append(u'%d.%d' % (number, count[number])) # <<<<<<<<<<<<<<
+ *
+ * return ret_list
+ */
+ __pyx_t_2 = __Pyx_PyDict_GetItem(__pyx_v_count, __pyx_v_number); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_number);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_number);
+ __Pyx_GIVEREF(__pyx_v_number);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = PyUnicode_Format(__pyx_kp_u_d_d, __pyx_t_8); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_ret_list, __pyx_t_2); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":760
+ * count = {}
+ *
+ * for number in list_of_numbers: # <<<<<<<<<<<<<<
+ * if not number in count:
+ * count[number] = 1
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":767
+ * ret_list.append(u'%d.%d' % (number, count[number]))
+ *
+ * return ret_list # <<<<<<<<<<<<<<
+ *
+ * def __contains__(self, key):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_ret_list);
+ __pyx_r = __pyx_v_ret_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":750
+ * return Scan(self, scan_index)
+ *
+ * def keys(self): # <<<<<<<<<<<<<<
+ * """Returns list of scan keys (eg ``['1.1', '2.1',...]``).
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.keys", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_ret_list);
+ __Pyx_XDECREF(__pyx_v_list_of_numbers);
+ __Pyx_XDECREF(__pyx_v_count);
+ __Pyx_XDECREF(__pyx_v_number);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":769
+ * return ret_list
+ *
+ * def __contains__(self, key): # <<<<<<<<<<<<<<
+ * """Return ``True`` if ``key`` is a valid scan key.
+ * Valid keys can be a string such as ``"1.1"`` or a 0-based scan index.
+ */
+
+/* Python wrapper */
+static int __pyx_pw_8specfile_8SpecFile_16__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_15__contains__[] = "Return ``True`` if ``key`` is a valid scan key.\n Valid keys can be a string such as ``\"1.1\"`` or a 0-based scan index.\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_8specfile_8SpecFile_15__contains__;
+#endif
+static int __pyx_pw_8specfile_8SpecFile_16__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_15__contains__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_8specfile_8SpecFile_15__contains__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_key) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ Py_ssize_t __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__contains__", 0);
+
+ /* "specfile.pyx":773
+ * Valid keys can be a string such as ``"1.1"`` or a 0-based scan index.
+ * """
+ * return key in (self.keys() + list(range(len(self)))) # <<<<<<<<<<<<<<
+ *
+ * def _get_error_string(self, error_code):
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_keys); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_5 = (__Pyx_PySequence_Contains(__pyx_v_key, __pyx_t_3, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_5;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":769
+ * return ret_list
+ *
+ * def __contains__(self, key): # <<<<<<<<<<<<<<
+ * """Return ``True`` if ``key`` is a valid scan key.
+ * Valid keys can be a string such as ``"1.1"`` or a 0-based scan index.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.SpecFile.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":775
+ * return key in (self.keys() + list(range(len(self))))
+ *
+ * def _get_error_string(self, error_code): # <<<<<<<<<<<<<<
+ * """Returns the error message corresponding to the error code.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_18_get_error_string(PyObject *__pyx_v_self, PyObject *__pyx_v_error_code); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_17_get_error_string[] = "SpecFile._get_error_string(self, error_code)\nReturns the error message corresponding to the error code.\n \n :param code: Error code\n :type code: int\n :return: Human readable error message\n :rtype: str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_18_get_error_string(PyObject *__pyx_v_self, PyObject *__pyx_v_error_code) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_get_error_string (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_17_get_error_string(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_error_code));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_17_get_error_string(CYTHON_UNUSED struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_error_code) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_get_error_string", 0);
+
+ /* "specfile.pyx":783
+ * :rtype: str
+ * """
+ * return (<bytes> specfile_wrapper.SfError(error_code)).decode() # <<<<<<<<<<<<<<
+ *
+ * def _handle_error(self, error_code):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_error_code); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyBytes_FromString(SfError(__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (unlikely(__pyx_t_2 == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "decode");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = __Pyx_decode_bytes(((PyObject*)__pyx_t_2), 0, PY_SSIZE_T_MAX, NULL, NULL, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":775
+ * return key in (self.keys() + list(range(len(self))))
+ *
+ * def _get_error_string(self, error_code): # <<<<<<<<<<<<<<
+ * """Returns the error message corresponding to the error code.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.SpecFile._get_error_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":785
+ * return (<bytes> specfile_wrapper.SfError(error_code)).decode()
+ *
+ * def _handle_error(self, error_code): # <<<<<<<<<<<<<<
+ * """Inspect error code, raise adequate error type if necessary.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_20_handle_error(PyObject *__pyx_v_self, PyObject *__pyx_v_error_code); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_19_handle_error[] = "SpecFile._handle_error(self, error_code)\nInspect error code, raise adequate error type if necessary.\n \n :param code: Error code\n :type code: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_20_handle_error(PyObject *__pyx_v_self, PyObject *__pyx_v_error_code) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_handle_error (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_19_handle_error(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_error_code));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_19_handle_error(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_error_code) {
+ PyObject *__pyx_v_error_message = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_handle_error", 0);
+
+ /* "specfile.pyx":791
+ * :type code: int
+ * """
+ * error_message = self._get_error_string(error_code) # <<<<<<<<<<<<<<
+ * if error_code in ERRORS:
+ * raise ERRORS[error_code](error_message)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_error_string); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_error_code); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(__pyx_v_error_code);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_error_code);
+ __Pyx_GIVEREF(__pyx_v_error_code);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_error_message = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":792
+ * """
+ * error_message = self._get_error_string(error_code)
+ * if error_code in ERRORS: # <<<<<<<<<<<<<<
+ * raise ERRORS[error_code](error_message)
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = (__Pyx_PySequence_Contains(__pyx_v_error_code, __pyx_t_1, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = (__pyx_t_5 != 0);
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":793
+ * error_message = self._get_error_string(error_code)
+ * if error_code in ERRORS:
+ * raise ERRORS[error_code](error_message) # <<<<<<<<<<<<<<
+ *
+ * def index(self, scan_number, scan_order=1):
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_ERRORS); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = PyObject_GetItem(__pyx_t_2, __pyx_v_error_code); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_error_message); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ __Pyx_INCREF(__pyx_v_error_message);
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_error_message);
+ __Pyx_GIVEREF(__pyx_v_error_message);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":785
+ * return (<bytes> specfile_wrapper.SfError(error_code)).decode()
+ *
+ * def _handle_error(self, error_code): # <<<<<<<<<<<<<<
+ * """Inspect error code, raise adequate error type if necessary.
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("specfile.SpecFile._handle_error", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_error_message);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":795
+ * raise ERRORS[error_code](error_message)
+ *
+ * def index(self, scan_number, scan_order=1): # <<<<<<<<<<<<<<
+ * """Returns scan index from scan number and order.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_22index(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_21index[] = "SpecFile.index(self, scan_number, scan_order=1)\nReturns scan index from scan number and order.\n \n :param scan_number: Scan number (possibly non-unique). \n :type scan_number: int\n :param scan_order: Scan order. \n :type scan_order: int default 1\n\n :return: Unique scan index\n :rtype: int\n \n \n Scan indices are increasing from ``0`` to ``len(self)-1`` in the\n order in which they appear in the file.\n Scan numbers are defined by users and are not necessarily unique.\n The scan order for a given scan number increments each time the scan \n number appers in a given file.\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_22index(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_number = 0;
+ PyObject *__pyx_v_scan_order = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("index (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_number,&__pyx_n_s_scan_order,0};
+ PyObject* values[2] = {0,0};
+ values[1] = ((PyObject *)__pyx_int_1);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_number)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_order);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "index") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_scan_number = values[0];
+ __pyx_v_scan_order = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("index", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_21index(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_number, __pyx_v_scan_order);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_21index(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_number, PyObject *__pyx_v_scan_order) {
+ PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ long __pyx_t_1;
+ long __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("index", 0);
+
+ /* "specfile.pyx":813
+ * number appers in a given file.
+ * """
+ * idx = specfile_wrapper.SfIndex(self.handle, scan_number, scan_order) # <<<<<<<<<<<<<<
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ */
+ __pyx_t_1 = __Pyx_PyInt_As_long(__pyx_v_scan_number); if (unlikely((__pyx_t_1 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyInt_As_long(__pyx_v_scan_order); if (unlikely((__pyx_t_2 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __Pyx_PyInt_From_long(SfIndex(__pyx_v_self->handle, __pyx_t_1, __pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_idx = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "specfile.pyx":814
+ * """
+ * idx = specfile_wrapper.SfIndex(self.handle, scan_number, scan_order)
+ * if idx == -1: # <<<<<<<<<<<<<<
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return idx - 1
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_idx, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":815
+ * idx = specfile_wrapper.SfIndex(self.handle, scan_number, scan_order)
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND) # <<<<<<<<<<<<<<
+ * return idx - 1
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_SCAN_NOT_FOUND); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":816
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return idx - 1 # <<<<<<<<<<<<<<
+ *
+ * def number(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_idx, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":795
+ * raise ERRORS[error_code](error_message)
+ *
+ * def index(self, scan_number, scan_order=1): # <<<<<<<<<<<<<<
+ * """Returns scan index from scan number and order.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":818
+ * return idx - 1
+ *
+ * def number(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns scan number from scan index.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_24number(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_23number[] = "SpecFile.number(self, scan_index)\nReturns scan number from scan index.\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: User defined scan number.\n :rtype: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_24number(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("number (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_23number(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_23number(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ long __pyx_v_idx;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ long __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("number", 0);
+
+ /* "specfile.pyx":828
+ * :rtype: int
+ * """
+ * idx = specfile_wrapper.SfNumber(self.handle, scan_index + 1) # <<<<<<<<<<<<<<
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_2 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_idx = SfNumber(__pyx_v_self->handle, __pyx_t_2);
+
+ /* "specfile.pyx":829
+ * """
+ * idx = specfile_wrapper.SfNumber(self.handle, scan_index + 1)
+ * if idx == -1: # <<<<<<<<<<<<<<
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return idx
+ */
+ __pyx_t_3 = ((__pyx_v_idx == -1) != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":830
+ * idx = specfile_wrapper.SfNumber(self.handle, scan_index + 1)
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND) # <<<<<<<<<<<<<<
+ * return idx
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_SCAN_NOT_FOUND); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":831
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return idx # <<<<<<<<<<<<<<
+ *
+ * def order(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_idx); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":818
+ * return idx - 1
+ *
+ * def number(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns scan number from scan index.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.number", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":833
+ * return idx
+ *
+ * def order(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns scan order from scan index.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_26order(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_25order[] = "SpecFile.order(self, scan_index)\nReturns scan order from scan index.\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Scan order (sequential number incrementing each time a\n non-unique occurrence of a scan number is encountered).\n :rtype: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_26order(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("order (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_25order(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_25order(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ long __pyx_v_ordr;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ long __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("order", 0);
+
+ /* "specfile.pyx":844
+ * :rtype: int
+ * """
+ * ordr = specfile_wrapper.SfOrder(self.handle, scan_index + 1) # <<<<<<<<<<<<<<
+ * if ordr == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_2 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_ordr = SfOrder(__pyx_v_self->handle, __pyx_t_2);
+
+ /* "specfile.pyx":845
+ * """
+ * ordr = specfile_wrapper.SfOrder(self.handle, scan_index + 1)
+ * if ordr == -1: # <<<<<<<<<<<<<<
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return ordr
+ */
+ __pyx_t_3 = ((__pyx_v_ordr == -1) != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":846
+ * ordr = specfile_wrapper.SfOrder(self.handle, scan_index + 1)
+ * if ordr == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND) # <<<<<<<<<<<<<<
+ * return ordr
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_SCAN_NOT_FOUND); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":847
+ * if ordr == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return ordr # <<<<<<<<<<<<<<
+ *
+ * def _list(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_ordr); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":833
+ * return idx
+ *
+ * def order(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns scan order from scan index.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.order", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":849
+ * return ordr
+ *
+ * def _list(self): # <<<<<<<<<<<<<<
+ * """see documentation of :meth:`list`
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_28_list(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_27_list[] = "SpecFile._list(self)\nsee documentation of :meth:`list`\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_28_list(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_list (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_27_list(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_27_list(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ long *__pyx_v_scan_numbers;
+ int __pyx_v_error;
+ PyObject *__pyx_v_ret_list = NULL;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_list", 0);
+
+ /* "specfile.pyx":854
+ * cdef:
+ * long *scan_numbers
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * scan_numbers = specfile_wrapper.SfList(self.handle, &error)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":856
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * scan_numbers = specfile_wrapper.SfList(self.handle, &error) # <<<<<<<<<<<<<<
+ * self._handle_error(error)
+ *
+ */
+ __pyx_v_scan_numbers = SfList(__pyx_v_self->handle, (&__pyx_v_error));
+
+ /* "specfile.pyx":857
+ *
+ * scan_numbers = specfile_wrapper.SfList(self.handle, &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * ret_list = []
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":859
+ * self._handle_error(error)
+ *
+ * ret_list = [] # <<<<<<<<<<<<<<
+ * for i in range(len(self)):
+ * ret_list.append(scan_numbers[i])
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_ret_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":860
+ *
+ * ret_list = []
+ * for i in range(len(self)): # <<<<<<<<<<<<<<
+ * ret_list.append(scan_numbers[i])
+ *
+ */
+ __pyx_t_7 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":861
+ * ret_list = []
+ * for i in range(len(self)):
+ * ret_list.append(scan_numbers[i]) # <<<<<<<<<<<<<<
+ *
+ * free(scan_numbers)
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_long((__pyx_v_scan_numbers[__pyx_v_i])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_ret_list, __pyx_t_1); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":863
+ * ret_list.append(scan_numbers[i])
+ *
+ * free(scan_numbers) # <<<<<<<<<<<<<<
+ * return ret_list
+ *
+ */
+ free(__pyx_v_scan_numbers);
+
+ /* "specfile.pyx":864
+ *
+ * free(scan_numbers)
+ * return ret_list # <<<<<<<<<<<<<<
+ *
+ * def list(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_ret_list);
+ __pyx_r = __pyx_v_ret_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":849
+ * return ordr
+ *
+ * def _list(self): # <<<<<<<<<<<<<<
+ * """see documentation of :meth:`list`
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("specfile.SpecFile._list", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_ret_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":866
+ * return ret_list
+ *
+ * def list(self): # <<<<<<<<<<<<<<
+ * """Returns list (1D numpy array) of scan numbers in SpecFile.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_30list(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_29list[] = "SpecFile.list(self)\nReturns list (1D numpy array) of scan numbers in SpecFile.\n\n :return: list of scan numbers (from `` #S`` lines) in the same order\n as in the original SpecFile (e.g ``[1, 1, 2, 3, \342\200\246]``).\n :rtype: numpy array\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_30list(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("list (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_29list(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_29list(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("list", 0);
+
+ /* "specfile.pyx":875
+ * # this method is overloaded in specfilewrapper to output a string
+ * # representation of the list
+ * return self._list() # <<<<<<<<<<<<<<
+ *
+ * def data(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_list); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":866
+ * return ret_list
+ *
+ * def list(self): # <<<<<<<<<<<<<<
+ * """Returns list (1D numpy array) of scan numbers in SpecFile.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.SpecFile.list", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":877
+ * return self._list()
+ *
+ * def data(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns data for the specified scan index.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_32data(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_31data[] = "SpecFile.data(self, scan_index)\nReturns data for the specified scan index.\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Complete scan data as a 2D array of doubles\n :rtype: numpy.ndarray\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_32data(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_31data(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_31data(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ double **__pyx_v_mydata;
+ long *__pyx_v_data_info;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_v_error;
+ long __pyx_v_nlines;
+ long __pyx_v_ncolumns;
+ CYTHON_UNUSED long __pyx_v_regular;
+ CYTHON_UNUSED int __pyx_v_sfdata_error;
+ PyArrayObject *__pyx_v_ret_array = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_t_8;
+ long __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data", 0);
+
+ /* "specfile.pyx":891
+ * long* data_info
+ * int i, j
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ * long nlines, ncolumns, regular
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":895
+ *
+ * sfdata_error = specfile_wrapper.SfData(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &mydata,
+ * &data_info,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":894
+ * long nlines, ncolumns, regular
+ *
+ * sfdata_error = specfile_wrapper.SfData(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &mydata,
+ */
+ __pyx_v_sfdata_error = SfData(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_mydata), (&__pyx_v_data_info), (&__pyx_v_error));
+
+ /* "specfile.pyx":899
+ * &data_info,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * if <long>data_info != 0:
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":901
+ * self._handle_error(error)
+ *
+ * if <long>data_info != 0: # <<<<<<<<<<<<<<
+ * nlines = data_info[0]
+ * ncolumns = data_info[1]
+ */
+ __pyx_t_8 = ((((long)__pyx_v_data_info) != 0) != 0);
+ if (__pyx_t_8) {
+
+ /* "specfile.pyx":902
+ *
+ * if <long>data_info != 0:
+ * nlines = data_info[0] # <<<<<<<<<<<<<<
+ * ncolumns = data_info[1]
+ * regular = data_info[2]
+ */
+ __pyx_v_nlines = (__pyx_v_data_info[0]);
+
+ /* "specfile.pyx":903
+ * if <long>data_info != 0:
+ * nlines = data_info[0]
+ * ncolumns = data_info[1] # <<<<<<<<<<<<<<
+ * regular = data_info[2]
+ * else:
+ */
+ __pyx_v_ncolumns = (__pyx_v_data_info[1]);
+
+ /* "specfile.pyx":904
+ * nlines = data_info[0]
+ * ncolumns = data_info[1]
+ * regular = data_info[2] # <<<<<<<<<<<<<<
+ * else:
+ * nlines = 0
+ */
+ __pyx_v_regular = (__pyx_v_data_info[2]);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":906
+ * regular = data_info[2]
+ * else:
+ * nlines = 0 # <<<<<<<<<<<<<<
+ * ncolumns = 0
+ * regular = 0
+ */
+ __pyx_v_nlines = 0;
+
+ /* "specfile.pyx":907
+ * else:
+ * nlines = 0
+ * ncolumns = 0 # <<<<<<<<<<<<<<
+ * regular = 0
+ *
+ */
+ __pyx_v_ncolumns = 0;
+
+ /* "specfile.pyx":908
+ * nlines = 0
+ * ncolumns = 0
+ * regular = 0 # <<<<<<<<<<<<<<
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns),
+ */
+ __pyx_v_regular = 0;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":910
+ * regular = 0
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_nlines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = __Pyx_PyInt_From_long(__pyx_v_ncolumns); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_1 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "specfile.pyx":911
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns),
+ * dtype=numpy.double) # <<<<<<<<<<<<<<
+ * for i in range(nlines):
+ * for j in range(ncolumns):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "specfile.pyx":910
+ * regular = 0
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_ret_array = ((PyArrayObject *)__pyx_t_6);
+ __pyx_t_6 = 0;
+
+ /* "specfile.pyx":912
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns),
+ * dtype=numpy.double)
+ * for i in range(nlines): # <<<<<<<<<<<<<<
+ * for j in range(ncolumns):
+ * ret_array[i, j] = mydata[i][j]
+ */
+ __pyx_t_3 = __pyx_v_nlines;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "specfile.pyx":913
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ * for j in range(ncolumns): # <<<<<<<<<<<<<<
+ * ret_array[i, j] = mydata[i][j]
+ *
+ */
+ __pyx_t_9 = __pyx_v_ncolumns;
+ for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
+ __pyx_v_j = __pyx_t_10;
+
+ /* "specfile.pyx":914
+ * for i in range(nlines):
+ * for j in range(ncolumns):
+ * ret_array[i, j] = mydata[i][j] # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines)
+ */
+ __pyx_t_6 = PyFloat_FromDouble(((__pyx_v_mydata[__pyx_v_i])[__pyx_v_j])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_j); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_5 = 0;
+ __pyx_t_7 = 0;
+ if (unlikely(PyObject_SetItem(((PyObject *)__pyx_v_ret_array), __pyx_t_4, __pyx_t_6) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ }
+
+ /* "specfile.pyx":916
+ * ret_array[i, j] = mydata[i][j]
+ *
+ * specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines) # <<<<<<<<<<<<<<
+ * free(data_info)
+ * return ret_array
+ */
+ freeArrNZ(((void ***)(&__pyx_v_mydata)), __pyx_v_nlines);
+
+ /* "specfile.pyx":917
+ *
+ * specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines)
+ * free(data_info) # <<<<<<<<<<<<<<
+ * return ret_array
+ *
+ */
+ free(__pyx_v_data_info);
+
+ /* "specfile.pyx":918
+ * specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines)
+ * free(data_info)
+ * return ret_array # <<<<<<<<<<<<<<
+ *
+ * def data_column_by_name(self, scan_index, label):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_ret_array));
+ __pyx_r = ((PyObject *)__pyx_v_ret_array);
+ goto __pyx_L0;
+
+ /* "specfile.pyx":877
+ * return self._list()
+ *
+ * def data(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns data for the specified scan index.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_ret_array);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":920
+ * return ret_array
+ *
+ * def data_column_by_name(self, scan_index, label): # <<<<<<<<<<<<<<
+ * """Returns data column for the specified scan index and column label.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_34data_column_by_name(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_33data_column_by_name[] = "SpecFile.data_column_by_name(self, scan_index, label)\nReturns data column for the specified scan index and column label.\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n :param label: Label of data column, as defined in the ``#L`` line\n of the scan header.\n :type label: str\n\n :return: Data column as a 1D array of doubles\n :rtype: numpy.ndarray\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_34data_column_by_name(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ PyObject *__pyx_v_label = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data_column_by_name (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,&__pyx_n_s_label,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_label)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("data_column_by_name", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "data_column_by_name") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_scan_index = values[0];
+ __pyx_v_label = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("data_column_by_name", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_33data_column_by_name(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index, __pyx_v_label);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_33data_column_by_name(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_label) {
+ double *__pyx_v_data_column;
+ long __pyx_v_i;
+ long __pyx_v_nlines;
+ int __pyx_v_error;
+ PyArrayObject *__pyx_v_ret_array = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ long __pyx_t_6;
+ char *__pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ long __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data_column_by_name", 0);
+ __Pyx_INCREF(__pyx_v_label);
+
+ /* "specfile.pyx":936
+ * double* data_column
+ * long i, nlines
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * label = _string_to_char_star(label)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":938
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * label = _string_to_char_star(label) # <<<<<<<<<<<<<<
+ *
+ * nlines = specfile_wrapper.SfDataColByName(self.handle,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_string_to_char_star); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_label); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_label);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_label);
+ __Pyx_GIVEREF(__pyx_v_label);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_label, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":941
+ *
+ * nlines = specfile_wrapper.SfDataColByName(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * label,
+ * &data_column,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_6 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":942
+ * nlines = specfile_wrapper.SfDataColByName(self.handle,
+ * scan_index + 1,
+ * label, # <<<<<<<<<<<<<<
+ * &data_column,
+ * &error)
+ */
+ __pyx_t_7 = __Pyx_PyObject_AsString(__pyx_v_label); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":940
+ * label = _string_to_char_star(label)
+ *
+ * nlines = specfile_wrapper.SfDataColByName(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * label,
+ */
+ __pyx_v_nlines = SfDataColByName(__pyx_v_self->handle, __pyx_t_6, __pyx_t_7, (&__pyx_v_data_column), (&__pyx_v_error));
+
+ /* "specfile.pyx":945
+ * &data_column,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,),
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":947
+ * self._handle_error(error)
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_nlines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = PyDict_New(); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+
+ /* "specfile.pyx":948
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,),
+ * dtype=numpy.double) # <<<<<<<<<<<<<<
+ * for i in range(nlines):
+ * ret_array[i] = data_column[i]
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":947
+ * self._handle_error(error)
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_1, __pyx_t_8); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_ret_array = ((PyArrayObject *)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":949
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,),
+ * dtype=numpy.double)
+ * for i in range(nlines): # <<<<<<<<<<<<<<
+ * ret_array[i] = data_column[i]
+ *
+ */
+ __pyx_t_6 = __pyx_v_nlines;
+ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_6; __pyx_t_9+=1) {
+ __pyx_v_i = __pyx_t_9;
+
+ /* "specfile.pyx":950
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ * ret_array[i] = data_column[i] # <<<<<<<<<<<<<<
+ *
+ * free(data_column)
+ */
+ __pyx_t_4 = PyFloat_FromDouble((__pyx_v_data_column[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_ret_array), __pyx_v_i, __pyx_t_4, long, 1, __Pyx_PyInt_From_long, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+
+ /* "specfile.pyx":952
+ * ret_array[i] = data_column[i]
+ *
+ * free(data_column) # <<<<<<<<<<<<<<
+ * return ret_array
+ *
+ */
+ free(__pyx_v_data_column);
+
+ /* "specfile.pyx":953
+ *
+ * free(data_column)
+ * return ret_array # <<<<<<<<<<<<<<
+ *
+ * def scan_header(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_ret_array));
+ __pyx_r = ((PyObject *)__pyx_v_ret_array);
+ goto __pyx_L0;
+
+ /* "specfile.pyx":920
+ * return ret_array
+ *
+ * def data_column_by_name(self, scan_index, label): # <<<<<<<<<<<<<<
+ * """Returns data column for the specified scan index and column label.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_ret_array);
+ __Pyx_XDECREF(__pyx_v_label);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":955
+ * return ret_array
+ *
+ * def scan_header(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return list of scan header lines.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_36scan_header(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_35scan_header[] = "SpecFile.scan_header(self, scan_index)\nReturn list of scan header lines.\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: List of raw scan header lines\n :rtype: list of str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_36scan_header(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("scan_header (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_35scan_header(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_35scan_header(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ char **__pyx_v_lines;
+ int __pyx_v_error;
+ long __pyx_v_nlines;
+ PyObject *__pyx_v_lines_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("scan_header", 0);
+
+ /* "specfile.pyx":967
+ * cdef:
+ * char** lines
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nlines = specfile_wrapper.SfHeader(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":970
+ *
+ * nlines = specfile_wrapper.SfHeader(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * "", # no pattern matching
+ * &lines,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":969
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nlines = specfile_wrapper.SfHeader(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * "", # no pattern matching
+ */
+ __pyx_v_nlines = SfHeader(__pyx_v_self->handle, __pyx_t_3, __pyx_k__29, (&__pyx_v_lines), (&__pyx_v_error));
+
+ /* "specfile.pyx":975
+ * &error)
+ *
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * lines_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":977
+ * self._handle_error(error)
+ *
+ * lines_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode()
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_lines_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":978
+ *
+ * lines_list = []
+ * for i in range(nlines): # <<<<<<<<<<<<<<
+ * line = <bytes>lines[i].decode()
+ * lines_list.append(line)
+ */
+ __pyx_t_3 = __pyx_v_nlines;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":979
+ * lines_list = []
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode() # <<<<<<<<<<<<<<
+ * lines_list.append(line)
+ *
+ */
+ __pyx_t_9 = (__pyx_v_lines[__pyx_v_i]);
+ __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_9, 0, strlen(__pyx_t_9), NULL, NULL, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1;
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_line, ((PyObject*)__pyx_t_4));
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":980
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode()
+ * lines_list.append(line) # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ */
+ __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_lines_list, __pyx_v_line); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":982
+ * lines_list.append(line)
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines) # <<<<<<<<<<<<<<
+ * return lines_list
+ *
+ */
+ freeArrNZ(((void ***)(&__pyx_v_lines)), __pyx_v_nlines);
+
+ /* "specfile.pyx":983
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ * return lines_list # <<<<<<<<<<<<<<
+ *
+ * def file_header(self, scan_index=0):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_lines_list);
+ __pyx_r = __pyx_v_lines_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":955
+ * return ret_array
+ *
+ * def scan_header(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return list of scan header lines.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.scan_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_lines_list);
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":985
+ * return lines_list
+ *
+ * def file_header(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return list of file header lines.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_38file_header(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_37file_header[] = "SpecFile.file_header(self, scan_index=0)\nReturn list of file header lines.\n \n A file header contains all lines between a ``#F`` header line and\n a ``#S`` header line (start of scan). We need to specify a scan\n number because there can be more than one file header in a given file.\n A file header applies to all subsequent scans, until a new file\n header is defined.\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: List of raw file header lines\n :rtype: list of str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_38file_header(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("file_header (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,0};
+ PyObject* values[1] = {0};
+ values[0] = ((PyObject *)__pyx_int_0);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index);
+ if (value) { values[0] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "file_header") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_scan_index = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("file_header", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.file_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_37file_header(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_37file_header(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ char **__pyx_v_lines;
+ int __pyx_v_error;
+ long __pyx_v_nlines;
+ PyObject *__pyx_v_lines_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("file_header", 0);
+
+ /* "specfile.pyx":1003
+ * cdef:
+ * char** lines
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nlines = specfile_wrapper.SfFileHeader(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1006
+ *
+ * nlines = specfile_wrapper.SfFileHeader(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * "", # no pattern matching
+ * &lines,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1005
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nlines = specfile_wrapper.SfFileHeader(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * "", # no pattern matching
+ */
+ __pyx_v_nlines = SfFileHeader(__pyx_v_self->handle, __pyx_t_3, __pyx_k__29, (&__pyx_v_lines), (&__pyx_v_error));
+
+ /* "specfile.pyx":1010
+ * &lines,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * lines_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1012
+ * self._handle_error(error)
+ *
+ * lines_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode()
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_lines_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1013
+ *
+ * lines_list = []
+ * for i in range(nlines): # <<<<<<<<<<<<<<
+ * line = <bytes>lines[i].decode()
+ * lines_list.append(line)
+ */
+ __pyx_t_3 = __pyx_v_nlines;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":1014
+ * lines_list = []
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode() # <<<<<<<<<<<<<<
+ * lines_list.append(line)
+ *
+ */
+ __pyx_t_9 = (__pyx_v_lines[__pyx_v_i]);
+ __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_9, 0, strlen(__pyx_t_9), NULL, NULL, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1;
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_line, ((PyObject*)__pyx_t_4));
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1015
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode()
+ * lines_list.append(line) # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ */
+ __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_lines_list, __pyx_v_line); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":1017
+ * lines_list.append(line)
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines) # <<<<<<<<<<<<<<
+ * return lines_list
+ *
+ */
+ freeArrNZ(((void ***)(&__pyx_v_lines)), __pyx_v_nlines);
+
+ /* "specfile.pyx":1018
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ * return lines_list # <<<<<<<<<<<<<<
+ *
+ * def columns(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_lines_list);
+ __pyx_r = __pyx_v_lines_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":985
+ * return lines_list
+ *
+ * def file_header(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return list of file header lines.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.file_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_lines_list);
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1020
+ * return lines_list
+ *
+ * def columns(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return number of columns in a scan from the ``#N`` header line
+ * (without ``#N`` and scan number)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_40columns(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_39columns[] = "SpecFile.columns(self, scan_index)\nReturn number of columns in a scan from the ``#N`` header line\n (without ``#N`` and scan number)\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Number of columns in scan from ``#N`` line\n :rtype: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_40columns(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("columns (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_39columns(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_39columns(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ long __pyx_v_ncolumns;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("columns", 0);
+
+ /* "specfile.pyx":1032
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * ncolumns = specfile_wrapper.SfNoColumns(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1035
+ *
+ * ncolumns = specfile_wrapper.SfNoColumns(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &error)
+ * self._handle_error(error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1034
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * ncolumns = specfile_wrapper.SfNoColumns(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &error)
+ */
+ __pyx_v_ncolumns = SfNoColumns(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_error));
+
+ /* "specfile.pyx":1037
+ * scan_index + 1,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * return ncolumns
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1039
+ * self._handle_error(error)
+ *
+ * return ncolumns # <<<<<<<<<<<<<<
+ *
+ * def command(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_ncolumns); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1020
+ * return lines_list
+ *
+ * def columns(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return number of columns in a scan from the ``#N`` header line
+ * (without ``#N`` and scan number)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.columns", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1041
+ * return ncolumns
+ *
+ * def command(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return ``#S`` line (without ``#S`` and scan number)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_42command(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_41command[] = "SpecFile.command(self, scan_index)\nReturn ``#S`` line (without ``#S`` and scan number)\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: S line\n :rtype: str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_42command(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("command (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_41command(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_41command(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ PyObject *__pyx_v_s_record = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("command", 0);
+
+ /* "specfile.pyx":1052
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * s_record = <bytes> specfile_wrapper.SfCommand(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1055
+ *
+ * s_record = <bytes> specfile_wrapper.SfCommand(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &error)
+ * self._handle_error(error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1054
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * s_record = <bytes> specfile_wrapper.SfCommand(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &error)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromString(SfCommand(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_error))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1;
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_s_record = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1057
+ * scan_index + 1,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * return s_record.decode()
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1059
+ * self._handle_error(error)
+ *
+ * return s_record.decode() # <<<<<<<<<<<<<<
+ *
+ * def date(self, scan_index=0):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (unlikely(__pyx_v_s_record == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "decode");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_4 = __Pyx_decode_bytes(__pyx_v_s_record, 0, PY_SSIZE_T_MAX, NULL, NULL, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1041
+ * return ncolumns
+ *
+ * def command(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return ``#S`` line (without ``#S`` and scan number)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.command", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_s_record);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1061
+ * return s_record.decode()
+ *
+ * def date(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return date from ``#D`` line
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_44date(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_43date[] = "SpecFile.date(self, scan_index=0)\nReturn date from ``#D`` line\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Date from ``#D`` line\n :rtype: str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_44date(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("date (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,0};
+ PyObject* values[1] = {0};
+ values[0] = ((PyObject *)__pyx_int_0);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index);
+ if (value) { values[0] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "date") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1061; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_scan_index = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("date", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1061; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.date", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_43date(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_43date(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ PyObject *__pyx_v_d_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("date", 0);
+
+ /* "specfile.pyx":1072
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * d_line = <bytes> specfile_wrapper.SfDate(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1075
+ *
+ * d_line = <bytes> specfile_wrapper.SfDate(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &error)
+ * self._handle_error(error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1074
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * d_line = <bytes> specfile_wrapper.SfDate(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &error)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromString(SfDate(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_error))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1;
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_d_line = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1077
+ * scan_index + 1,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * return d_line.decode()
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1079
+ * self._handle_error(error)
+ *
+ * return d_line.decode() # <<<<<<<<<<<<<<
+ *
+ * def labels(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (unlikely(__pyx_v_d_line == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "decode");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_4 = __Pyx_decode_bytes(__pyx_v_d_line, 0, PY_SSIZE_T_MAX, NULL, NULL, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1061
+ * return s_record.decode()
+ *
+ * def date(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return date from ``#D`` line
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.date", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_d_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1081
+ * return d_line.decode()
+ *
+ * def labels(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return all labels from ``#L`` line
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_46labels(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_45labels[] = "SpecFile.labels(self, scan_index)\nReturn all labels from ``#L`` line\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: All labels from ``#L`` line\n :rtype: list of strings\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_46labels(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("labels (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_45labels(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_45labels(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ char **__pyx_v_all_labels;
+ int __pyx_v_error;
+ long __pyx_v_nlabels;
+ PyObject *__pyx_v_labels_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("labels", 0);
+
+ /* "specfile.pyx":1093
+ * cdef:
+ * char** all_labels
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nlabels = specfile_wrapper.SfAllLabels(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1096
+ *
+ * nlabels = specfile_wrapper.SfAllLabels(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &all_labels,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1096; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1096; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1095
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nlabels = specfile_wrapper.SfAllLabels(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &all_labels,
+ */
+ __pyx_v_nlabels = SfAllLabels(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_all_labels), (&__pyx_v_error));
+
+ /* "specfile.pyx":1099
+ * &all_labels,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * labels_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1101
+ * self._handle_error(error)
+ *
+ * labels_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nlabels):
+ * labels_list.append(<bytes>all_labels[i].decode())
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_labels_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1102
+ *
+ * labels_list = []
+ * for i in range(nlabels): # <<<<<<<<<<<<<<
+ * labels_list.append(<bytes>all_labels[i].decode())
+ *
+ */
+ __pyx_t_3 = __pyx_v_nlabels;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":1103
+ * labels_list = []
+ * for i in range(nlabels):
+ * labels_list.append(<bytes>all_labels[i].decode()) # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_labels, nlabels)
+ */
+ __pyx_t_9 = (__pyx_v_all_labels[__pyx_v_i]);
+ __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_9, 0, strlen(__pyx_t_9), NULL, NULL, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_labels_list, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":1105
+ * labels_list.append(<bytes>all_labels[i].decode())
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_labels, nlabels) # <<<<<<<<<<<<<<
+ * return labels_list
+ *
+ */
+ freeArrNZ(((void ***)(&__pyx_v_all_labels)), __pyx_v_nlabels);
+
+ /* "specfile.pyx":1106
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_labels, nlabels)
+ * return labels_list # <<<<<<<<<<<<<<
+ *
+ * def motor_names(self, scan_index=0):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_labels_list);
+ __pyx_r = __pyx_v_labels_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1081
+ * return d_line.decode()
+ *
+ * def labels(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return all labels from ``#L`` line
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.labels", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_labels_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1108
+ * return labels_list
+ *
+ * def motor_names(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return all motor names from ``#O`` lines
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_48motor_names(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_47motor_names[] = "SpecFile.motor_names(self, scan_index=0)\nReturn all motor names from ``#O`` lines\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.If not specified, defaults to 0 (meaning the\n function returns motors names associated with the first scan).\n This parameter makes a difference only if there are more than\n on file header in the file, in which case the file header applies\n to all following scans until a new file header appears.\n :type scan_index: int\n\n :return: All motor names\n :rtype: list of strings\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_48motor_names(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_names (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,0};
+ PyObject* values[1] = {0};
+ values[0] = ((PyObject *)__pyx_int_0);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index);
+ if (value) { values[0] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "motor_names") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_scan_index = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("motor_names", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.motor_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_47motor_names(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_47motor_names(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ char **__pyx_v_all_motors;
+ int __pyx_v_error;
+ long __pyx_v_nmotors;
+ PyObject *__pyx_v_motors_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_names", 0);
+
+ /* "specfile.pyx":1124
+ * cdef:
+ * char** all_motors
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nmotors = specfile_wrapper.SfAllMotors(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1127
+ *
+ * nmotors = specfile_wrapper.SfAllMotors(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &all_motors,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1126
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nmotors = specfile_wrapper.SfAllMotors(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &all_motors,
+ */
+ __pyx_v_nmotors = SfAllMotors(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_all_motors), (&__pyx_v_error));
+
+ /* "specfile.pyx":1130
+ * &all_motors,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * motors_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1132
+ * self._handle_error(error)
+ *
+ * motors_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nmotors):
+ * motors_list.append(<bytes>all_motors[i].decode())
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_motors_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1133
+ *
+ * motors_list = []
+ * for i in range(nmotors): # <<<<<<<<<<<<<<
+ * motors_list.append(<bytes>all_motors[i].decode())
+ *
+ */
+ __pyx_t_3 = __pyx_v_nmotors;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":1134
+ * motors_list = []
+ * for i in range(nmotors):
+ * motors_list.append(<bytes>all_motors[i].decode()) # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_motors, nmotors)
+ */
+ __pyx_t_9 = (__pyx_v_all_motors[__pyx_v_i]);
+ __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_9, 0, strlen(__pyx_t_9), NULL, NULL, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_motors_list, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":1136
+ * motors_list.append(<bytes>all_motors[i].decode())
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_motors, nmotors) # <<<<<<<<<<<<<<
+ * return motors_list
+ *
+ */
+ freeArrNZ(((void ***)(&__pyx_v_all_motors)), __pyx_v_nmotors);
+
+ /* "specfile.pyx":1137
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_motors, nmotors)
+ * return motors_list # <<<<<<<<<<<<<<
+ *
+ * def motor_positions(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_motors_list);
+ __pyx_r = __pyx_v_motors_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1108
+ * return labels_list
+ *
+ * def motor_names(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return all motor names from ``#O`` lines
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.motor_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_motors_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1139
+ * return motors_list
+ *
+ * def motor_positions(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return all motor positions
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_50motor_positions(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_49motor_positions[] = "SpecFile.motor_positions(self, scan_index)\nReturn all motor positions\n \n :param scan_index: Unique scan index between ``0``\n and ``len(self)-1``.\n :type scan_index: int\n\n :return: All motor positions\n :rtype: list of double\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_50motor_positions(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_positions (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_49motor_positions(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_49motor_positions(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ double *__pyx_v_motor_positions;
+ int __pyx_v_error;
+ long __pyx_v_nmotors;
+ PyObject *__pyx_v_motor_positions_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_positions", 0);
+
+ /* "specfile.pyx":1151
+ * cdef:
+ * double* motor_positions
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nmotors = specfile_wrapper.SfAllMotorPos(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1154
+ *
+ * nmotors = specfile_wrapper.SfAllMotorPos(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &motor_positions,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1153
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nmotors = specfile_wrapper.SfAllMotorPos(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &motor_positions,
+ */
+ __pyx_v_nmotors = SfAllMotorPos(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_motor_positions), (&__pyx_v_error));
+
+ /* "specfile.pyx":1157
+ * &motor_positions,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * motor_positions_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1159
+ * self._handle_error(error)
+ *
+ * motor_positions_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nmotors):
+ * motor_positions_list.append(motor_positions[i])
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_motor_positions_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1160
+ *
+ * motor_positions_list = []
+ * for i in range(nmotors): # <<<<<<<<<<<<<<
+ * motor_positions_list.append(motor_positions[i])
+ *
+ */
+ __pyx_t_3 = __pyx_v_nmotors;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":1161
+ * motor_positions_list = []
+ * for i in range(nmotors):
+ * motor_positions_list.append(motor_positions[i]) # <<<<<<<<<<<<<<
+ *
+ * free(motor_positions)
+ */
+ __pyx_t_1 = PyFloat_FromDouble((__pyx_v_motor_positions[__pyx_v_i])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_motor_positions_list, __pyx_t_1); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":1163
+ * motor_positions_list.append(motor_positions[i])
+ *
+ * free(motor_positions) # <<<<<<<<<<<<<<
+ * return motor_positions_list
+ *
+ */
+ free(__pyx_v_motor_positions);
+
+ /* "specfile.pyx":1164
+ *
+ * free(motor_positions)
+ * return motor_positions_list # <<<<<<<<<<<<<<
+ *
+ * def motor_position_by_name(self, scan_index, name):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_motor_positions_list);
+ __pyx_r = __pyx_v_motor_positions_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1139
+ * return motors_list
+ *
+ * def motor_positions(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return all motor positions
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.motor_positions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_motor_positions_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1166
+ * return motor_positions_list
+ *
+ * def motor_position_by_name(self, scan_index, name): # <<<<<<<<<<<<<<
+ * """Return motor position
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_52motor_position_by_name(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_51motor_position_by_name[] = "SpecFile.motor_position_by_name(self, scan_index, name)\nReturn motor position\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Specified motor position\n :rtype: double\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_52motor_position_by_name(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_position_by_name (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,&__pyx_n_s_name,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("motor_position_by_name", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "motor_position_by_name") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_scan_index = values[0];
+ __pyx_v_name = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("motor_position_by_name", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.motor_position_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_51motor_position_by_name(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index, __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_51motor_position_by_name(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_name) {
+ int __pyx_v_error;
+ double __pyx_v_motor_position;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ long __pyx_t_6;
+ char *__pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_position_by_name", 0);
+ __Pyx_INCREF(__pyx_v_name);
+
+ /* "specfile.pyx":1177
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * name = _string_to_char_star(name)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1179
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * name = _string_to_char_star(name) # <<<<<<<<<<<<<<
+ *
+ * motor_position = specfile_wrapper.SfMotorPosByName(self.handle,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_string_to_char_star); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_name); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_name);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_name, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1182
+ *
+ * motor_position = specfile_wrapper.SfMotorPosByName(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * name,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_6 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1183
+ * motor_position = specfile_wrapper.SfMotorPosByName(self.handle,
+ * scan_index + 1,
+ * name, # <<<<<<<<<<<<<<
+ * &error)
+ * self._handle_error(error)
+ */
+ __pyx_t_7 = __Pyx_PyObject_AsString(__pyx_v_name); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":1181
+ * name = _string_to_char_star(name)
+ *
+ * motor_position = specfile_wrapper.SfMotorPosByName(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * name,
+ */
+ __pyx_v_motor_position = SfMotorPosByName(__pyx_v_self->handle, __pyx_t_6, __pyx_t_7, (&__pyx_v_error));
+
+ /* "specfile.pyx":1185
+ * name,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * return motor_position
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1187
+ * self._handle_error(error)
+ *
+ * return motor_position # <<<<<<<<<<<<<<
+ *
+ * def number_of_mca(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyFloat_FromDouble(__pyx_v_motor_position); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1166
+ * return motor_positions_list
+ *
+ * def motor_position_by_name(self, scan_index, name): # <<<<<<<<<<<<<<
+ * """Return motor position
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.motor_position_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_name);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1189
+ * return motor_position
+ *
+ * def number_of_mca(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return number of mca spectra in a scan.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_54number_of_mca(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_53number_of_mca[] = "SpecFile.number_of_mca(self, scan_index)\nReturn number of mca spectra in a scan.\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Number of mca spectra.\n :rtype: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_54number_of_mca(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("number_of_mca (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_53number_of_mca(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_53number_of_mca(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ long __pyx_v_num_mca;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("number_of_mca", 0);
+
+ /* "specfile.pyx":1200
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * num_mca = specfile_wrapper.SfNoMca(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1203
+ *
+ * num_mca = specfile_wrapper.SfNoMca(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &error)
+ * # error code updating isn't implemented in SfNoMCA
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1202
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * num_mca = specfile_wrapper.SfNoMca(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &error)
+ */
+ __pyx_v_num_mca = SfNoMca(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_error));
+
+ /* "specfile.pyx":1206
+ * &error)
+ * # error code updating isn't implemented in SfNoMCA
+ * if num_mca == -1: # <<<<<<<<<<<<<<
+ * raise SfNoMcaError("Failed to retrieve number of MCA " +
+ * "(SfNoMca returned -1)")
+ */
+ __pyx_t_4 = ((__pyx_v_num_mca == -1) != 0);
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":1207
+ * # error code updating isn't implemented in SfNoMCA
+ * if num_mca == -1:
+ * raise SfNoMcaError("Failed to retrieve number of MCA " + # <<<<<<<<<<<<<<
+ * "(SfNoMca returned -1)")
+ * return num_mca
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfNoMcaError); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyNumber_Add(__pyx_kp_s_Failed_to_retrieve_number_of_MCA, __pyx_kp_s_SfNoMca_returned_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":1209
+ * raise SfNoMcaError("Failed to retrieve number of MCA " +
+ * "(SfNoMca returned -1)")
+ * return num_mca # <<<<<<<<<<<<<<
+ *
+ * def mca_calibration(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_num_mca); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1189
+ * return motor_position
+ *
+ * def number_of_mca(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return number of mca spectra in a scan.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.number_of_mca", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1211
+ * return num_mca
+ *
+ * def mca_calibration(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return MCA calibration in the form :math:`a + b x + c x`
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_56mca_calibration(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_55mca_calibration[] = "SpecFile.mca_calibration(self, scan_index)\nReturn MCA calibration in the form :math:`a + b x + c x\302\262`\n\n Raise a KeyError if there is no ``@CALIB`` line in the scan header.\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: MCA calibration as a list of 3 values :math:`(a, b, c)`\n :rtype: list of floats\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_56mca_calibration(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("mca_calibration (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_55mca_calibration(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_55mca_calibration(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ double *__pyx_v_mca_calib;
+ long __pyx_v_mca_calib_error;
+ PyObject *__pyx_v_mca_calib_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("mca_calibration", 0);
+
+ /* "specfile.pyx":1224
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ * double* mca_calib
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1228
+ *
+ * mca_calib_error = specfile_wrapper.SfMcaCalib(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &mca_calib,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1227
+ * double* mca_calib
+ *
+ * mca_calib_error = specfile_wrapper.SfMcaCalib(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &mca_calib,
+ */
+ __pyx_v_mca_calib_error = SfMcaCalib(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_mca_calib), (&__pyx_v_error));
+
+ /* "specfile.pyx":1233
+ *
+ * # error code updating isn't implemented in SfMcaCalib
+ * if mca_calib_error: # <<<<<<<<<<<<<<
+ * raise KeyError("MCA calibration line (@CALIB) not found")
+ *
+ */
+ __pyx_t_4 = (__pyx_v_mca_calib_error != 0);
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":1234
+ * # error code updating isn't implemented in SfMcaCalib
+ * if mca_calib_error:
+ * raise KeyError("MCA calibration line (@CALIB) not found") # <<<<<<<<<<<<<<
+ *
+ * mca_calib_list = []
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":1236
+ * raise KeyError("MCA calibration line (@CALIB) not found")
+ *
+ * mca_calib_list = [] # <<<<<<<<<<<<<<
+ * for i in range(3):
+ * mca_calib_list.append(mca_calib[i])
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_mca_calib_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1237
+ *
+ * mca_calib_list = []
+ * for i in range(3): # <<<<<<<<<<<<<<
+ * mca_calib_list.append(mca_calib[i])
+ *
+ */
+ for (__pyx_t_3 = 0; __pyx_t_3 < 3; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "specfile.pyx":1238
+ * mca_calib_list = []
+ * for i in range(3):
+ * mca_calib_list.append(mca_calib[i]) # <<<<<<<<<<<<<<
+ *
+ * free(mca_calib)
+ */
+ __pyx_t_1 = PyFloat_FromDouble((__pyx_v_mca_calib[__pyx_v_i])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyList_Append(__pyx_v_mca_calib_list, __pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":1240
+ * mca_calib_list.append(mca_calib[i])
+ *
+ * free(mca_calib) # <<<<<<<<<<<<<<
+ * return mca_calib_list
+ *
+ */
+ free(__pyx_v_mca_calib);
+
+ /* "specfile.pyx":1241
+ *
+ * free(mca_calib)
+ * return mca_calib_list # <<<<<<<<<<<<<<
+ *
+ * def get_mca(self, scan_index, mca_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_mca_calib_list);
+ __pyx_r = __pyx_v_mca_calib_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1211
+ * return num_mca
+ *
+ * def mca_calibration(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return MCA calibration in the form :math:`a + b x + c x`
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.SpecFile.mca_calibration", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_mca_calib_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1243
+ * return mca_calib_list
+ *
+ * def get_mca(self, scan_index, mca_index): # <<<<<<<<<<<<<<
+ * """Return one MCA spectrum
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_58get_mca(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_57get_mca[] = "SpecFile.get_mca(self, scan_index, mca_index)\nReturn one MCA spectrum\n\n :param scan_index: Unique scan index between ``0`` and ``len(self)-1``.\n :type scan_index: int\n :param mca_index: Index of MCA in the scan\n :type mca_index: int\n\n :return: MCA spectrum\n :rtype: 1D numpy array\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_58get_mca(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ PyObject *__pyx_v_mca_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("get_mca (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,&__pyx_n_s_mca_index,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mca_index)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("get_mca", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1243; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_mca") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1243; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_scan_index = values[0];
+ __pyx_v_mca_index = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("get_mca", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1243; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.get_mca", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_57get_mca(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index, __pyx_v_mca_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_57get_mca(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_mca_index) {
+ int __pyx_v_error;
+ double *__pyx_v_mca_data;
+ long __pyx_v_len_mca;
+ PyArrayObject *__pyx_v_ret_array = 0;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_mca", 0);
+
+ /* "specfile.pyx":1255
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ * double* mca_data
+ * long len_mca
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1260
+ *
+ * len_mca = specfile_wrapper.SfGetMca(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * mca_index + 1,
+ * &mca_data,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1261
+ * len_mca = specfile_wrapper.SfGetMca(self.handle,
+ * scan_index + 1,
+ * mca_index + 1, # <<<<<<<<<<<<<<
+ * &mca_data,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_mca_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_4 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1259
+ * long len_mca
+ *
+ * len_mca = specfile_wrapper.SfGetMca(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * mca_index + 1,
+ */
+ __pyx_v_len_mca = SfGetMca(__pyx_v_self->handle, __pyx_t_3, __pyx_t_4, (&__pyx_v_mca_data), (&__pyx_v_error));
+
+ /* "specfile.pyx":1264
+ * &mca_data,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1267
+ *
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((len_mca,), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(len_mca):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_len_mca); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = PyDict_New(); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+
+ /* "specfile.pyx":1268
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((len_mca,),
+ * dtype=numpy.double) # <<<<<<<<<<<<<<
+ * for i in range(len_mca):
+ * ret_array[i] = mca_data[i]
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_double); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "specfile.pyx":1267
+ *
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((len_mca,), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(len_mca):
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_1, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_ret_array = ((PyArrayObject *)__pyx_t_7);
+ __pyx_t_7 = 0;
+
+ /* "specfile.pyx":1269
+ * cdef numpy.ndarray ret_array = numpy.empty((len_mca,),
+ * dtype=numpy.double)
+ * for i in range(len_mca): # <<<<<<<<<<<<<<
+ * ret_array[i] = mca_data[i]
+ *
+ */
+ __pyx_t_4 = __pyx_v_len_mca;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_4; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "specfile.pyx":1270
+ * dtype=numpy.double)
+ * for i in range(len_mca):
+ * ret_array[i] = mca_data[i] # <<<<<<<<<<<<<<
+ *
+ * free(mca_data)
+ */
+ __pyx_t_7 = PyFloat_FromDouble((__pyx_v_mca_data[__pyx_v_i])); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_ret_array), __pyx_v_i, __pyx_t_7, long, 1, __Pyx_PyInt_From_long, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+
+ /* "specfile.pyx":1272
+ * ret_array[i] = mca_data[i]
+ *
+ * free(mca_data) # <<<<<<<<<<<<<<
+ * return ret_array
+ */
+ free(__pyx_v_mca_data);
+
+ /* "specfile.pyx":1273
+ *
+ * free(mca_data)
+ * return ret_array # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_ret_array));
+ __pyx_r = ((PyObject *)__pyx_v_ret_array);
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1243
+ * return mca_calib_list
+ *
+ * def get_mca(self, scan_index, mca_index): # <<<<<<<<<<<<<<
+ * """Return one MCA spectrum
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.get_mca", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_ret_array);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_copy_shape;
+ int __pyx_v_i;
+ int __pyx_v_ndim;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ int __pyx_v_t;
+ char *__pyx_v_f;
+ PyArray_Descr *__pyx_v_descr = 0;
+ int __pyx_v_offset;
+ int __pyx_v_hasfields;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":200
+ * # of flags
+ *
+ * if info == NULL: return # <<<<<<<<<<<<<<
+ *
+ * cdef int copy_shape, i, ndim
+ */
+ __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+ if (__pyx_t_1) {
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":204
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ *
+ * ndim = PyArray_NDIM(self)
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<<
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":208
+ * ndim = PyArray_NDIM(self)
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * copy_shape = 1
+ * else:
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * copy_shape = 1 # <<<<<<<<<<<<<<
+ * else:
+ * copy_shape = 0
+ */
+ __pyx_v_copy_shape = 1;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ * copy_shape = 1
+ * else:
+ * copy_shape = 0 # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+ __pyx_v_copy_shape = 0;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":213
+ * copy_shape = 0
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L6_bool_binop_done;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L9_bool_binop_done;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<<
+ * info.ndim = ndim
+ * if copy_shape:
+ */
+ __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim # <<<<<<<<<<<<<<
+ * if copy_shape:
+ * # Allocate new buffer for strides and shape info.
+ */
+ __pyx_v_info->ndim = __pyx_v_ndim;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":223
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim
+ * if copy_shape: # <<<<<<<<<<<<<<
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ */
+ __pyx_t_1 = (__pyx_v_copy_shape != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2) # <<<<<<<<<<<<<<
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":227
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+ __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":228
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ */
+ __pyx_t_4 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<<
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ */
+ (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+ (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+ }
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self) # <<<<<<<<<<<<<<
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self) # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ */
+ __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+ }
+ __pyx_L11:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":234
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<<
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ *
+ */
+ __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<<
+ *
+ * cdef int t
+ */
+ __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *
+ * cdef int t
+ * cdef char* f = NULL # <<<<<<<<<<<<<<
+ * cdef dtype descr = self.descr
+ * cdef list stack
+ */
+ __pyx_v_f = NULL;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":240
+ * cdef int t
+ * cdef char* f = NULL
+ * cdef dtype descr = self.descr # <<<<<<<<<<<<<<
+ * cdef list stack
+ * cdef int offset
+ */
+ __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":244
+ * cdef int offset
+ *
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<<
+ *
+ * if not hasfields and not copy_shape:
+ */
+ __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":246
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ *
+ * if not hasfields and not copy_shape: # <<<<<<<<<<<<<<
+ * # do not call releasebuffer
+ * info.obj = None
+ */
+ __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":248
+ * if not hasfields and not copy_shape:
+ * # do not call releasebuffer
+ * info.obj = None # <<<<<<<<<<<<<<
+ * else:
+ * # need to call releasebuffer
+ */
+ __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = Py_None;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ * else:
+ * # need to call releasebuffer
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * if not hasfields:
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+ }
+ __pyx_L14:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":253
+ * info.obj = self
+ *
+ * if not hasfields: # <<<<<<<<<<<<<<
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *
+ * if not hasfields:
+ * t = descr.type_num # <<<<<<<<<<<<<<
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ */
+ __pyx_t_4 = __pyx_v_descr->type_num;
+ __pyx_v_t = __pyx_t_4;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":255
+ * if not hasfields:
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+ if (!__pyx_t_2) {
+ goto __pyx_L20_next_or;
+ } else {
+ }
+ __pyx_t_2 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_L20_next_or:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L19_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ switch (__pyx_v_t) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ */
+ case NPY_BYTE:
+ __pyx_v_f = __pyx_k_b;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ */
+ case NPY_UBYTE:
+ __pyx_v_f = __pyx_k_B;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ */
+ case NPY_SHORT:
+ __pyx_v_f = __pyx_k_h;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ */
+ case NPY_USHORT:
+ __pyx_v_f = __pyx_k_H;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ */
+ case NPY_INT:
+ __pyx_v_f = __pyx_k_i;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ */
+ case NPY_UINT:
+ __pyx_v_f = __pyx_k_I;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ */
+ case NPY_LONG:
+ __pyx_v_f = __pyx_k_l;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ */
+ case NPY_ULONG:
+ __pyx_v_f = __pyx_k_L;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ */
+ case NPY_LONGLONG:
+ __pyx_v_f = __pyx_k_q;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ */
+ case NPY_ULONGLONG:
+ __pyx_v_f = __pyx_k_Q;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ */
+ case NPY_FLOAT:
+ __pyx_v_f = __pyx_k_f;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ */
+ case NPY_DOUBLE:
+ __pyx_v_f = __pyx_k_d;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ */
+ case NPY_LONGDOUBLE:
+ __pyx_v_f = __pyx_k_g;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+ case NPY_CFLOAT:
+ __pyx_v_f = __pyx_k_Zf;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O"
+ */
+ case NPY_CDOUBLE:
+ __pyx_v_f = __pyx_k_Zd;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ */
+ case NPY_CLONGDOUBLE:
+ __pyx_v_f = __pyx_k_Zg;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ case NPY_OBJECT:
+ __pyx_v_f = __pyx_k_O;
+ break;
+ default:
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * info.format = f
+ * return
+ */
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ break;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f # <<<<<<<<<<<<<<
+ * return
+ * else:
+ */
+ __pyx_v_info->format = __pyx_v_f;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":278
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f
+ * return # <<<<<<<<<<<<<<
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ * return
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<<
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ */
+ __pyx_v_info->format = ((char *)malloc(255));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<<
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1,
+ */
+ (__pyx_v_info->format[0]) = '^';
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":282
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0 # <<<<<<<<<<<<<<
+ * f = _util_dtypestring(descr, info.format + 1,
+ * info.format + _buffer_format_string_len,
+ */
+ __pyx_v_offset = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<<
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ */
+ __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_7;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<<
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+ (__pyx_v_f[0]) = '\x00';
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+ __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<<
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":290
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format) # <<<<<<<<<<<<<<
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides)
+ */
+ free(__pyx_v_info->format);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * stdlib.free(info.strides)
+ * # info.shape was stored after info.strides in the same block
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides) # <<<<<<<<<<<<<<
+ * # info.shape was stored after info.strides in the same block
+ *
+ */
+ free(__pyx_v_info->strides);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ * return PyArray_MultiIterNew(1, <void*>a) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e) # <<<<<<<<<<<<<<
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+ PyArray_Descr *__pyx_v_child = 0;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ PyObject *__pyx_v_fields = 0;
+ PyObject *__pyx_v_childname = NULL;
+ PyObject *__pyx_v_new_offset = NULL;
+ PyObject *__pyx_v_t = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":790
+ * cdef int delta_offset
+ * cdef tuple i
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * cdef tuple fields
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":791
+ * cdef tuple i
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ * cdef tuple fields
+ *
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ if (unlikely(__pyx_v_descr->names == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+ for (;;) {
+ if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":795
+ *
+ * for childname in descr.names:
+ * fields = descr.fields[childname] # <<<<<<<<<<<<<<
+ * child, new_offset = fields
+ *
+ */
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":796
+ * for childname in descr.names:
+ * fields = descr.fields[childname]
+ * child, new_offset = fields # <<<<<<<<<<<<<<
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+ if (likely(__pyx_v_fields != Py_None)) {
+ PyObject* sequence = __pyx_v_fields;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ #else
+ __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ #endif
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+ __pyx_t_3 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * child, new_offset = fields
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__34, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+ if (!__pyx_t_7) {
+ goto __pyx_L8_next_or;
+ } else {
+ }
+ __pyx_t_7 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_L8_next_or:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * # One could encode it in the format string and have Cython
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__35, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":813
+ *
+ * # Output padding bytes
+ * while offset[0] < new_offset: # <<<<<<<<<<<<<<
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ */
+ while (1) {
+ __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!__pyx_t_6) break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":814
+ * # Output padding bytes
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<<
+ * f += 1
+ * offset[0] += 1
+ */
+ (__pyx_v_f[0]) = 120;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":815
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte
+ * f += 1 # <<<<<<<<<<<<<<
+ * offset[0] += 1
+ *
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ * offset[0] += 1 # <<<<<<<<<<<<<<
+ *
+ * offset[0] += child.itemsize
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ * offset[0] += 1
+ *
+ * offset[0] += child.itemsize # <<<<<<<<<<<<<<
+ *
+ * if not PyDataType_HASFIELDS(child):
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":820
+ * offset[0] += child.itemsize
+ *
+ * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<<
+ * t = child.type_num
+ * if end - f < 5:
+ */
+ __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num # <<<<<<<<<<<<<<
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.")
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":822
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num
+ * if end - f < 5: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short.")
+ *
+ */
+ __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 98;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":827
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 66;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":828
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 104;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 72;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 105;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 73;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 108;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 76;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 113;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 81;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 102;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 100;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 103;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 102;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 100;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 103;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 79;
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * f += 1
+ * else:
+ */
+ __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L15:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * f += 1 # <<<<<<<<<<<<<<
+ * else:
+ * # Cython ignores struct boundary information ("T{...}"),
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":849
+ * # Cython ignores struct boundary information ("T{...}"),
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<<
+ * return f
+ *
+ */
+ __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_9;
+ }
+ __pyx_L13:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":850
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset)
+ * return f # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_f;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_child);
+ __Pyx_XDECREF(__pyx_v_fields);
+ __Pyx_XDECREF(__pyx_v_childname);
+ __Pyx_XDECREF(__pyx_v_new_offset);
+ __Pyx_XDECREF(__pyx_v_t);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+ PyObject *__pyx_v_baseptr;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("set_array_base", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ * cdef PyObject* baseptr
+ * if base is None: # <<<<<<<<<<<<<<
+ * baseptr = NULL
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_base == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * cdef PyObject* baseptr
+ * if base is None:
+ * baseptr = NULL # <<<<<<<<<<<<<<
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ */
+ __pyx_v_baseptr = NULL;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * baseptr = NULL
+ * else:
+ * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<<
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ */
+ Py_INCREF(__pyx_v_base);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base # <<<<<<<<<<<<<<
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr
+ */
+ __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":973
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base) # <<<<<<<<<<<<<<
+ * arr.base = baseptr
+ *
+ */
+ Py_XDECREF(__pyx_v_arr->base);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr # <<<<<<<<<<<<<<
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ */
+ __pyx_v_arr->base = __pyx_v_baseptr;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("get_array_base", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL: # <<<<<<<<<<<<<<
+ * return None
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL:
+ * return None # <<<<<<<<<<<<<<
+ * else:
+ * return <object>arr.base
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * return None
+ * else:
+ * return <object>arr.base # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+ __pyx_r = ((PyObject *)__pyx_v_arr->base);
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_8specfile_SpecFile(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_obj_8specfile_SpecFile *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_obj_8specfile_SpecFile *)o);
+ p->filename = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_pw_8specfile_8SpecFile_1__cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_8specfile_SpecFile(PyObject *o) {
+ struct __pyx_obj_8specfile_SpecFile *p = (struct __pyx_obj_8specfile_SpecFile *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_pw_8specfile_8SpecFile_5__dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->filename);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_8specfile_SpecFile(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static PyMethodDef __pyx_methods_8specfile_SpecFile[] = {
+ {"keys", (PyCFunction)__pyx_pw_8specfile_8SpecFile_14keys, METH_NOARGS, __pyx_doc_8specfile_8SpecFile_13keys},
+ {"_get_error_string", (PyCFunction)__pyx_pw_8specfile_8SpecFile_18_get_error_string, METH_O, __pyx_doc_8specfile_8SpecFile_17_get_error_string},
+ {"_handle_error", (PyCFunction)__pyx_pw_8specfile_8SpecFile_20_handle_error, METH_O, __pyx_doc_8specfile_8SpecFile_19_handle_error},
+ {"index", (PyCFunction)__pyx_pw_8specfile_8SpecFile_22index, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_21index},
+ {"number", (PyCFunction)__pyx_pw_8specfile_8SpecFile_24number, METH_O, __pyx_doc_8specfile_8SpecFile_23number},
+ {"order", (PyCFunction)__pyx_pw_8specfile_8SpecFile_26order, METH_O, __pyx_doc_8specfile_8SpecFile_25order},
+ {"_list", (PyCFunction)__pyx_pw_8specfile_8SpecFile_28_list, METH_NOARGS, __pyx_doc_8specfile_8SpecFile_27_list},
+ {"list", (PyCFunction)__pyx_pw_8specfile_8SpecFile_30list, METH_NOARGS, __pyx_doc_8specfile_8SpecFile_29list},
+ {"data", (PyCFunction)__pyx_pw_8specfile_8SpecFile_32data, METH_O, __pyx_doc_8specfile_8SpecFile_31data},
+ {"data_column_by_name", (PyCFunction)__pyx_pw_8specfile_8SpecFile_34data_column_by_name, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_33data_column_by_name},
+ {"scan_header", (PyCFunction)__pyx_pw_8specfile_8SpecFile_36scan_header, METH_O, __pyx_doc_8specfile_8SpecFile_35scan_header},
+ {"file_header", (PyCFunction)__pyx_pw_8specfile_8SpecFile_38file_header, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_37file_header},
+ {"columns", (PyCFunction)__pyx_pw_8specfile_8SpecFile_40columns, METH_O, __pyx_doc_8specfile_8SpecFile_39columns},
+ {"command", (PyCFunction)__pyx_pw_8specfile_8SpecFile_42command, METH_O, __pyx_doc_8specfile_8SpecFile_41command},
+ {"date", (PyCFunction)__pyx_pw_8specfile_8SpecFile_44date, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_43date},
+ {"labels", (PyCFunction)__pyx_pw_8specfile_8SpecFile_46labels, METH_O, __pyx_doc_8specfile_8SpecFile_45labels},
+ {"motor_names", (PyCFunction)__pyx_pw_8specfile_8SpecFile_48motor_names, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_47motor_names},
+ {"motor_positions", (PyCFunction)__pyx_pw_8specfile_8SpecFile_50motor_positions, METH_O, __pyx_doc_8specfile_8SpecFile_49motor_positions},
+ {"motor_position_by_name", (PyCFunction)__pyx_pw_8specfile_8SpecFile_52motor_position_by_name, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_51motor_position_by_name},
+ {"number_of_mca", (PyCFunction)__pyx_pw_8specfile_8SpecFile_54number_of_mca, METH_O, __pyx_doc_8specfile_8SpecFile_53number_of_mca},
+ {"mca_calibration", (PyCFunction)__pyx_pw_8specfile_8SpecFile_56mca_calibration, METH_O, __pyx_doc_8specfile_8SpecFile_55mca_calibration},
+ {"get_mca", (PyCFunction)__pyx_pw_8specfile_8SpecFile_58get_mca, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_57get_mca},
+ {0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_SpecFile = {
+ __pyx_pw_8specfile_8SpecFile_7__len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_8specfile_SpecFile, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ __pyx_pw_8specfile_8SpecFile_16__contains__, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_SpecFile = {
+ __pyx_pw_8specfile_8SpecFile_7__len__, /*mp_length*/
+ __pyx_pw_8specfile_8SpecFile_12__getitem__, /*mp_subscript*/
+ 0, /*mp_ass_subscript*/
+};
+
+static PyTypeObject __pyx_type_8specfile_SpecFile = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "specfile.SpecFile", /*tp_name*/
+ sizeof(struct __pyx_obj_8specfile_SpecFile), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_8specfile_SpecFile, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_SpecFile, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_SpecFile, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "SpecFile(filename)\n\n\n :param filename: Path of the SpecFile to read\n\n This class wraps the main data and header access functions of the C\n SpecFile library.\n ", /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ __pyx_pw_8specfile_8SpecFile_9__iter__, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_8specfile_SpecFile, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_pw_8specfile_8SpecFile_3__init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_8specfile_SpecFile, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *__pyx_freelist_8specfile___pyx_scope_struct____iter__[8];
+static int __pyx_freecount_8specfile___pyx_scope_struct____iter__ = 0;
+
+static PyObject *__pyx_tp_new_8specfile___pyx_scope_struct____iter__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ PyObject *o;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_8specfile___pyx_scope_struct____iter__ > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_8specfile___pyx_scope_struct____iter__)))) {
+ o = (PyObject*)__pyx_freelist_8specfile___pyx_scope_struct____iter__[--__pyx_freecount_8specfile___pyx_scope_struct____iter__];
+ memset(o, 0, sizeof(struct __pyx_obj_8specfile___pyx_scope_struct____iter__));
+ (void) PyObject_INIT(o, t);
+ PyObject_GC_Track(o);
+ } else {
+ o = (*t->tp_alloc)(t, 0);
+ if (unlikely(!o)) return 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_8specfile___pyx_scope_struct____iter__(PyObject *o) {
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)o;
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->__pyx_v_self);
+ if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_8specfile___pyx_scope_struct____iter__ < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_8specfile___pyx_scope_struct____iter__)))) {
+ __pyx_freelist_8specfile___pyx_scope_struct____iter__[__pyx_freecount_8specfile___pyx_scope_struct____iter__++] = ((struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)o);
+ } else {
+ (*Py_TYPE(o)->tp_free)(o);
+ }
+}
+
+static int __pyx_tp_traverse_8specfile___pyx_scope_struct____iter__(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)o;
+ if (p->__pyx_v_self) {
+ e = (*v)(p->__pyx_v_self, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_8specfile___pyx_scope_struct____iter__(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)o;
+ tmp = ((PyObject*)p->__pyx_v_self);
+ p->__pyx_v_self = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyTypeObject __pyx_type_8specfile___pyx_scope_struct____iter__ = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "specfile.__pyx_scope_struct____iter__", /*tp_name*/
+ sizeof(struct __pyx_obj_8specfile___pyx_scope_struct____iter__), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_8specfile___pyx_scope_struct____iter__, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_8specfile___pyx_scope_struct____iter__, /*tp_traverse*/
+ __pyx_tp_clear_8specfile___pyx_scope_struct____iter__, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_8specfile___pyx_scope_struct____iter__, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *__pyx_freelist_8specfile___pyx_scope_struct_1___iter__[8];
+static int __pyx_freecount_8specfile___pyx_scope_struct_1___iter__ = 0;
+
+static PyObject *__pyx_tp_new_8specfile___pyx_scope_struct_1___iter__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ PyObject *o;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_8specfile___pyx_scope_struct_1___iter__ > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__)))) {
+ o = (PyObject*)__pyx_freelist_8specfile___pyx_scope_struct_1___iter__[--__pyx_freecount_8specfile___pyx_scope_struct_1___iter__];
+ memset(o, 0, sizeof(struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__));
+ (void) PyObject_INIT(o, t);
+ PyObject_GC_Track(o);
+ } else {
+ o = (*t->tp_alloc)(t, 0);
+ if (unlikely(!o)) return 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_8specfile___pyx_scope_struct_1___iter__(PyObject *o) {
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)o;
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->__pyx_v_self);
+ if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_8specfile___pyx_scope_struct_1___iter__ < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__)))) {
+ __pyx_freelist_8specfile___pyx_scope_struct_1___iter__[__pyx_freecount_8specfile___pyx_scope_struct_1___iter__++] = ((struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)o);
+ } else {
+ (*Py_TYPE(o)->tp_free)(o);
+ }
+}
+
+static int __pyx_tp_traverse_8specfile___pyx_scope_struct_1___iter__(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)o;
+ if (p->__pyx_v_self) {
+ e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_8specfile___pyx_scope_struct_1___iter__(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)o;
+ tmp = ((PyObject*)p->__pyx_v_self);
+ p->__pyx_v_self = ((struct __pyx_obj_8specfile_SpecFile *)Py_None); Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyTypeObject __pyx_type_8specfile___pyx_scope_struct_1___iter__ = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "specfile.__pyx_scope_struct_1___iter__", /*tp_name*/
+ sizeof(struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_8specfile___pyx_scope_struct_1___iter__, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_8specfile___pyx_scope_struct_1___iter__, /*tp_traverse*/
+ __pyx_tp_clear_8specfile___pyx_scope_struct_1___iter__, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_8specfile___pyx_scope_struct_1___iter__, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "specfile",
+ __pyx_k_This_module_is_a_cython_binding, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_, __pyx_k_, sizeof(__pyx_k_), 0, 0, 1, 0},
+ {&__pyx_kp_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 0},
+ {&__pyx_kp_s_27_09_2016, __pyx_k_27_09_2016, sizeof(__pyx_k_27_09_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+ {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Base_exception_inherited_by_all, __pyx_k_Base_exception_inherited_by_all, sizeof(__pyx_k_Base_exception_inherited_by_all), 0, 0, 1, 0},
+ {&__pyx_n_s_CALIB, __pyx_k_CALIB, sizeof(__pyx_k_CALIB), 0, 0, 1, 1},
+ {&__pyx_n_s_CHANN, __pyx_k_CHANN, sizeof(__pyx_k_CHANN), 0, 0, 1, 1},
+ {&__pyx_kp_s_Cannot_get_data_column_s_in_scan, __pyx_k_Cannot_get_data_column_s_in_scan, sizeof(__pyx_k_Cannot_get_data_column_s_in_scan), 0, 0, 1, 0},
+ {&__pyx_kp_s_Custom_exception_raised_when_SfN, __pyx_k_Custom_exception_raised_when_SfN, sizeof(__pyx_k_Custom_exception_raised_when_SfN), 0, 0, 1, 0},
+ {&__pyx_n_s_ERRORS, __pyx_k_ERRORS, sizeof(__pyx_k_ERRORS), 0, 0, 1, 1},
+ {&__pyx_kp_s_Error_while_closing_SpecFile, __pyx_k_Error_while_closing_SpecFile, sizeof(__pyx_k_Error_while_closing_SpecFile), 0, 0, 1, 0},
+ {&__pyx_n_s_Exception, __pyx_k_Exception, sizeof(__pyx_k_Exception), 0, 0, 1, 1},
+ {&__pyx_kp_s_F, __pyx_k_F, sizeof(__pyx_k_F), 0, 0, 1, 0},
+ {&__pyx_kp_s_Failed_to_retrieve_number_of_MCA, __pyx_k_Failed_to_retrieve_number_of_MCA, sizeof(__pyx_k_Failed_to_retrieve_number_of_MCA), 0, 0, 1, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1},
+ {&__pyx_n_s_L, __pyx_k_L, sizeof(__pyx_k_L), 0, 0, 1, 1},
+ {&__pyx_n_s_L_header, __pyx_k_L_header, sizeof(__pyx_k_L_header), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA, __pyx_k_MCA, sizeof(__pyx_k_MCA), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA___getitem, __pyx_k_MCA___getitem, sizeof(__pyx_k_MCA___getitem), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA___init, __pyx_k_MCA___init, sizeof(__pyx_k_MCA___init), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA___iter, __pyx_k_MCA___iter, sizeof(__pyx_k_MCA___iter), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA___len, __pyx_k_MCA___len, sizeof(__pyx_k_MCA___len), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA__parse_calibration, __pyx_k_MCA__parse_calibration, sizeof(__pyx_k_MCA__parse_calibration), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA__parse_channels, __pyx_k_MCA__parse_channels, sizeof(__pyx_k_MCA__parse_channels), 0, 0, 1, 1},
+ {&__pyx_kp_s_MCA_calibration_line_CALIB_not_f, __pyx_k_MCA_calibration_line_CALIB_not_f, sizeof(__pyx_k_MCA_calibration_line_CALIB_not_f), 0, 0, 1, 0},
+ {&__pyx_kp_s_MCA_index_must_be_in_range_0_d, __pyx_k_MCA_index_must_be_in_range_0_d, sizeof(__pyx_k_MCA_index_must_be_in_range_0_d), 0, 0, 1, 0},
+ {&__pyx_kp_s_MCA_index_should_be_an_integer_s, __pyx_k_MCA_index_should_be_an_integer_s, sizeof(__pyx_k_MCA_index_should_be_an_integer_s), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_kp_s_No_MCA_spectrum_found_in_this_sc, __pyx_k_No_MCA_spectrum_found_in_this_sc, sizeof(__pyx_k_No_MCA_spectrum_found_in_this_sc), 0, 0, 1, 0},
+ {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+ {&__pyx_kp_s_P_Knobel, __pyx_k_P_Knobel, sizeof(__pyx_k_P_Knobel), 0, 0, 1, 0},
+ {&__pyx_kp_s_Parameter_value_must_be_a_string, __pyx_k_Parameter_value_must_be_a_string, sizeof(__pyx_k_Parameter_value_must_be_a_string), 0, 0, 1, 0},
+ {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_S, __pyx_k_S, sizeof(__pyx_k_S), 0, 0, 1, 0},
+ {&__pyx_n_s_SF_ERR_FILE_OPEN, __pyx_k_SF_ERR_FILE_OPEN, sizeof(__pyx_k_SF_ERR_FILE_OPEN), 0, 0, 1, 1},
+ {&__pyx_n_s_SF_ERR_NO_ERRORS, __pyx_k_SF_ERR_NO_ERRORS, sizeof(__pyx_k_SF_ERR_NO_ERRORS), 0, 0, 1, 1},
+ {&__pyx_n_s_SF_ERR_SCAN_NOT_FOUND, __pyx_k_SF_ERR_SCAN_NOT_FOUND, sizeof(__pyx_k_SF_ERR_SCAN_NOT_FOUND), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan, __pyx_k_Scan, sizeof(__pyx_k_Scan), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan___init, __pyx_k_Scan___init, sizeof(__pyx_k_Scan___init), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_data, __pyx_k_Scan_data, sizeof(__pyx_k_Scan_data), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_data_column_by_name, __pyx_k_Scan_data_column_by_name, sizeof(__pyx_k_Scan_data_column_by_name), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_data_line, __pyx_k_Scan_data_line, sizeof(__pyx_k_Scan_data_line), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_file_header, __pyx_k_Scan_file_header, sizeof(__pyx_k_Scan_file_header), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_file_header_dict, __pyx_k_Scan_file_header_dict, sizeof(__pyx_k_Scan_file_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_header, __pyx_k_Scan_header, sizeof(__pyx_k_Scan_header), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_index, __pyx_k_Scan_index, sizeof(__pyx_k_Scan_index), 0, 0, 1, 1},
+ {&__pyx_kp_s_Scan_index_must_be_in_range_0_d, __pyx_k_Scan_index_must_be_in_range_0_d, sizeof(__pyx_k_Scan_index_must_be_in_range_0_d), 0, 0, 1, 0},
+ {&__pyx_n_s_Scan_labels, __pyx_k_Scan_labels, sizeof(__pyx_k_Scan_labels), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_mca, __pyx_k_Scan_mca, sizeof(__pyx_k_Scan_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_mca_header_dict, __pyx_k_Scan_mca_header_dict, sizeof(__pyx_k_Scan_mca_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_motor_names, __pyx_k_Scan_motor_names, sizeof(__pyx_k_Scan_motor_names), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_motor_position_by_name, __pyx_k_Scan_motor_position_by_name, sizeof(__pyx_k_Scan_motor_position_by_name), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_motor_positions, __pyx_k_Scan_motor_positions, sizeof(__pyx_k_Scan_motor_positions), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_number, __pyx_k_Scan_number, sizeof(__pyx_k_Scan_number), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_order, __pyx_k_Scan_order, sizeof(__pyx_k_Scan_order), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_record_exists_in_hdr, __pyx_k_Scan_record_exists_in_hdr, sizeof(__pyx_k_Scan_record_exists_in_hdr), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_scan_header, __pyx_k_Scan_scan_header, sizeof(__pyx_k_Scan_scan_header), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_scan_header_dict, __pyx_k_Scan_scan_header_dict, sizeof(__pyx_k_Scan_scan_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrColNotFound, __pyx_k_SfErrColNotFound, sizeof(__pyx_k_SfErrColNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrFileClose, __pyx_k_SfErrFileClose, sizeof(__pyx_k_SfErrFileClose), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrFileOpen, __pyx_k_SfErrFileOpen, sizeof(__pyx_k_SfErrFileOpen), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrFileRead, __pyx_k_SfErrFileRead, sizeof(__pyx_k_SfErrFileRead), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrFileWrite, __pyx_k_SfErrFileWrite, sizeof(__pyx_k_SfErrFileWrite), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrHeaderNotFound, __pyx_k_SfErrHeaderNotFound, sizeof(__pyx_k_SfErrHeaderNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrLabelNotFound, __pyx_k_SfErrLabelNotFound, sizeof(__pyx_k_SfErrLabelNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrLineEmpty, __pyx_k_SfErrLineEmpty, sizeof(__pyx_k_SfErrLineEmpty), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrLineNotFound, __pyx_k_SfErrLineNotFound, sizeof(__pyx_k_SfErrLineNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrMcaNotFound, __pyx_k_SfErrMcaNotFound, sizeof(__pyx_k_SfErrMcaNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrMemoryAlloc, __pyx_k_SfErrMemoryAlloc, sizeof(__pyx_k_SfErrMemoryAlloc), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrMotorNotFound, __pyx_k_SfErrMotorNotFound, sizeof(__pyx_k_SfErrMotorNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrPositionNotFound, __pyx_k_SfErrPositionNotFound, sizeof(__pyx_k_SfErrPositionNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrScanNotFound, __pyx_k_SfErrScanNotFound, sizeof(__pyx_k_SfErrScanNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrUserNotFound, __pyx_k_SfErrUserNotFound, sizeof(__pyx_k_SfErrUserNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfError, __pyx_k_SfError, sizeof(__pyx_k_SfError), 0, 0, 1, 1},
+ {&__pyx_n_s_SfNoMcaError, __pyx_k_SfNoMcaError, sizeof(__pyx_k_SfNoMcaError), 0, 0, 1, 1},
+ {&__pyx_kp_s_SfNoMca_returned_1, __pyx_k_SfNoMca_returned_1, sizeof(__pyx_k_SfNoMca_returned_1), 0, 0, 1, 0},
+ {&__pyx_n_s_SpecFile___iter, __pyx_k_SpecFile___iter, sizeof(__pyx_k_SpecFile___iter), 0, 0, 1, 1},
+ {&__pyx_kp_s_The_scan_identification_key_can, __pyx_k_The_scan_identification_key_can, sizeof(__pyx_k_The_scan_identification_key_can), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_parse_file_header_line, __pyx_k_Unable_to_parse_file_header_line, sizeof(__pyx_k_Unable_to_parse_file_header_line), 0, 0, 1, 0},
+ {&__pyx_kp_s_Unable_to_parse_scan_header_line, __pyx_k_Unable_to_parse_scan_header_line, sizeof(__pyx_k_Unable_to_parse_scan_header_line), 0, 0, 1, 0},
+ {&__pyx_kp_s_Valid_keys, __pyx_k_Valid_keys, sizeof(__pyx_k_Valid_keys), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_kp_s__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 0, 1, 0},
+ {&__pyx_kp_s__25, __pyx_k__25, sizeof(__pyx_k__25), 0, 0, 1, 0},
+ {&__pyx_kp_s__27, __pyx_k__27, sizeof(__pyx_k__27), 0, 0, 1, 0},
+ {&__pyx_kp_s__28, __pyx_k__28, sizeof(__pyx_k__28), 0, 0, 1, 0},
+ {&__pyx_kp_s__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 0, 1, 0},
+ {&__pyx_n_s_add_or_concatenate, __pyx_k_add_or_concatenate, sizeof(__pyx_k_add_or_concatenate), 0, 0, 1, 1},
+ {&__pyx_n_s_all_calib_values, __pyx_k_all_calib_values, sizeof(__pyx_k_all_calib_values), 0, 0, 1, 1},
+ {&__pyx_n_s_all_chann_values, __pyx_k_all_chann_values, sizeof(__pyx_k_all_chann_values), 0, 0, 1, 1},
+ {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1},
+ {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1},
+ {&__pyx_n_s_ascii, __pyx_k_ascii, sizeof(__pyx_k_ascii), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_basicConfig, __pyx_k_basicConfig, sizeof(__pyx_k_basicConfig), 0, 0, 1, 1},
+ {&__pyx_n_s_calib_line, __pyx_k_calib_line, sizeof(__pyx_k_calib_line), 0, 0, 1, 1},
+ {&__pyx_n_s_calib_lines, __pyx_k_calib_lines, sizeof(__pyx_k_calib_lines), 0, 0, 1, 1},
+ {&__pyx_n_s_calibration, __pyx_k_calibration, sizeof(__pyx_k_calibration), 0, 0, 1, 1},
+ {&__pyx_n_s_chann_line, __pyx_k_chann_line, sizeof(__pyx_k_chann_line), 0, 0, 1, 1},
+ {&__pyx_n_s_chann_lines, __pyx_k_chann_lines, sizeof(__pyx_k_chann_lines), 0, 0, 1, 1},
+ {&__pyx_n_s_channels, __pyx_k_channels, sizeof(__pyx_k_channels), 0, 0, 1, 1},
+ {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1},
+ {&__pyx_kp_u_d_d, __pyx_k_d_d, sizeof(__pyx_k_d_d), 0, 1, 0, 0},
+ {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+ {&__pyx_n_s_data_2, __pyx_k_data_2, sizeof(__pyx_k_data_2), 0, 0, 1, 1},
+ {&__pyx_n_s_data_column_by_name, __pyx_k_data_column_by_name, sizeof(__pyx_k_data_column_by_name), 0, 0, 1, 1},
+ {&__pyx_n_s_data_line, __pyx_k_data_line, sizeof(__pyx_k_data_line), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_decode, __pyx_k_decode, sizeof(__pyx_k_decode), 0, 0, 1, 1},
+ {&__pyx_n_s_dictionary, __pyx_k_dictionary, sizeof(__pyx_k_dictionary), 0, 0, 1, 1},
+ {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1},
+ {&__pyx_n_s_double, __pyx_k_double, sizeof(__pyx_k_double), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+ {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_f, __pyx_k_f, sizeof(__pyx_k_f), 0, 0, 1, 1},
+ {&__pyx_n_s_file_header, __pyx_k_file_header, sizeof(__pyx_k_file_header), 0, 0, 1, 1},
+ {&__pyx_n_s_file_header_dict, __pyx_k_file_header_dict, sizeof(__pyx_k_file_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_file_header_dict_2, __pyx_k_file_header_dict_2, sizeof(__pyx_k_file_header_dict_2), 0, 0, 1, 1},
+ {&__pyx_n_s_file_header_lines, __pyx_k_file_header_lines, sizeof(__pyx_k_file_header_lines), 0, 0, 1, 1},
+ {&__pyx_n_s_filename, __pyx_k_filename, sizeof(__pyx_k_filename), 0, 0, 1, 1},
+ {&__pyx_n_s_getLogger, __pyx_k_getLogger, sizeof(__pyx_k_getLogger), 0, 0, 1, 1},
+ {&__pyx_n_s_get_error_string, __pyx_k_get_error_string, sizeof(__pyx_k_get_error_string), 0, 0, 1, 1},
+ {&__pyx_n_s_get_mca, __pyx_k_get_mca, sizeof(__pyx_k_get_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_getitem, __pyx_k_getitem, sizeof(__pyx_k_getitem), 0, 0, 1, 1},
+ {&__pyx_n_s_group, __pyx_k_group, sizeof(__pyx_k_group), 0, 0, 1, 1},
+ {&__pyx_n_s_handle_error, __pyx_k_handle_error, sizeof(__pyx_k_handle_error), 0, 0, 1, 1},
+ {&__pyx_n_s_header, __pyx_k_header, sizeof(__pyx_k_header), 0, 0, 1, 1},
+ {&__pyx_n_s_header_2, __pyx_k_header_2, sizeof(__pyx_k_header_2), 0, 0, 1, 1},
+ {&__pyx_n_s_hkey, __pyx_k_hkey, sizeof(__pyx_k_hkey), 0, 0, 1, 1},
+ {&__pyx_n_s_hvalue, __pyx_k_hvalue, sizeof(__pyx_k_hvalue), 0, 0, 1, 1},
+ {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_increment, __pyx_k_increment, sizeof(__pyx_k_increment), 0, 0, 1, 1},
+ {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1},
+ {&__pyx_n_s_index_2, __pyx_k_index_2, sizeof(__pyx_k_index_2), 0, 0, 1, 1},
+ {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1},
+ {&__pyx_n_s_is_specfile, __pyx_k_is_specfile, sizeof(__pyx_k_is_specfile), 0, 0, 1, 1},
+ {&__pyx_n_s_isfile, __pyx_k_isfile, sizeof(__pyx_k_isfile), 0, 0, 1, 1},
+ {&__pyx_n_s_iter, __pyx_k_iter, sizeof(__pyx_k_iter), 0, 0, 1, 1},
+ {&__pyx_n_s_join, __pyx_k_join, sizeof(__pyx_k_join), 0, 0, 1, 1},
+ {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1},
+ {&__pyx_n_s_keys, __pyx_k_keys, sizeof(__pyx_k_keys), 0, 0, 1, 1},
+ {&__pyx_n_s_label, __pyx_k_label, sizeof(__pyx_k_label), 0, 0, 1, 1},
+ {&__pyx_n_s_labels, __pyx_k_labels, sizeof(__pyx_k_labels), 0, 0, 1, 1},
+ {&__pyx_n_s_labels_2, __pyx_k_labels_2, sizeof(__pyx_k_labels_2), 0, 0, 1, 1},
+ {&__pyx_n_s_len, __pyx_k_len, sizeof(__pyx_k_len), 0, 0, 1, 1},
+ {&__pyx_n_s_length, __pyx_k_length, sizeof(__pyx_k_length), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_line, __pyx_k_line, sizeof(__pyx_k_line), 0, 0, 1, 1},
+ {&__pyx_n_s_line_index, __pyx_k_line_index, sizeof(__pyx_k_line_index), 0, 0, 1, 1},
+ {&__pyx_n_s_list, __pyx_k_list, sizeof(__pyx_k_list), 0, 0, 1, 1},
+ {&__pyx_n_s_logger, __pyx_k_logger, sizeof(__pyx_k_logger), 0, 0, 1, 1},
+ {&__pyx_n_s_logging, __pyx_k_logging, sizeof(__pyx_k_logging), 0, 0, 1, 1},
+ {&__pyx_n_s_lstrip, __pyx_k_lstrip, sizeof(__pyx_k_lstrip), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_map, __pyx_k_map, sizeof(__pyx_k_map), 0, 0, 1, 1},
+ {&__pyx_n_s_match, __pyx_k_match, sizeof(__pyx_k_match), 0, 0, 1, 1},
+ {&__pyx_n_s_match_mca, __pyx_k_match_mca, sizeof(__pyx_k_match_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_mca, __pyx_k_mca, sizeof(__pyx_k_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_mca_2, __pyx_k_mca_2, sizeof(__pyx_k_mca_2), 0, 0, 1, 1},
+ {&__pyx_n_s_mca_header_dict, __pyx_k_mca_header_dict, sizeof(__pyx_k_mca_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_mca_header_dict_2, __pyx_k_mca_header_dict_2, sizeof(__pyx_k_mca_header_dict_2), 0, 0, 1, 1},
+ {&__pyx_n_s_mca_index, __pyx_k_mca_index, sizeof(__pyx_k_mca_index), 0, 0, 1, 1},
+ {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1},
+ {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_names, __pyx_k_motor_names, sizeof(__pyx_k_motor_names), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_names_2, __pyx_k_motor_names_2, sizeof(__pyx_k_motor_names_2), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_position_by_name, __pyx_k_motor_position_by_name, sizeof(__pyx_k_motor_position_by_name), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_positions, __pyx_k_motor_positions, sizeof(__pyx_k_motor_positions), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_positions_2, __pyx_k_motor_positions_2, sizeof(__pyx_k_motor_positions_2), 0, 0, 1, 1},
+ {&__pyx_n_s_msg, __pyx_k_msg, sizeof(__pyx_k_msg), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+ {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+ {&__pyx_n_s_number, __pyx_k_number, sizeof(__pyx_k_number), 0, 0, 1, 1},
+ {&__pyx_n_s_number_2, __pyx_k_number_2, sizeof(__pyx_k_number_2), 0, 0, 1, 1},
+ {&__pyx_kp_s_number_and_M_the_order_eg_2_3, __pyx_k_number_and_M_the_order_eg_2_3, sizeof(__pyx_k_number_and_M_the_order_eg_2_3), 0, 0, 1, 0},
+ {&__pyx_n_s_number_of_mca, __pyx_k_number_of_mca, sizeof(__pyx_k_number_of_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_object, __pyx_k_object, sizeof(__pyx_k_object), 0, 0, 1, 1},
+ {&__pyx_n_s_one_line_calib_values, __pyx_k_one_line_calib_values, sizeof(__pyx_k_one_line_calib_values), 0, 0, 1, 1},
+ {&__pyx_n_s_one_line_chann_values, __pyx_k_one_line_chann_values, sizeof(__pyx_k_one_line_chann_values), 0, 0, 1, 1},
+ {&__pyx_n_s_open, __pyx_k_open, sizeof(__pyx_k_open), 0, 0, 1, 1},
+ {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1},
+ {&__pyx_n_s_order_2, __pyx_k_order_2, sizeof(__pyx_k_order_2), 0, 0, 1, 1},
+ {&__pyx_n_s_os, __pyx_k_os, sizeof(__pyx_k_os), 0, 0, 1, 1},
+ {&__pyx_n_s_os_path, __pyx_k_os_path, sizeof(__pyx_k_os_path), 0, 0, 1, 1},
+ {&__pyx_kp_s_param_scan_Parent_Scan_instance, __pyx_k_param_scan_Parent_Scan_instance, sizeof(__pyx_k_param_scan_Parent_Scan_instance), 0, 0, 1, 0},
+ {&__pyx_kp_s_param_specfile_Parent_SpecFile, __pyx_k_param_specfile_Parent_SpecFile, sizeof(__pyx_k_param_specfile_Parent_SpecFile), 0, 0, 1, 0},
+ {&__pyx_n_s_parse_calibration, __pyx_k_parse_calibration, sizeof(__pyx_k_parse_calibration), 0, 0, 1, 1},
+ {&__pyx_n_s_parse_channels, __pyx_k_parse_channels, sizeof(__pyx_k_parse_channels), 0, 0, 1, 1},
+ {&__pyx_n_s_path, __pyx_k_path, sizeof(__pyx_k_path), 0, 0, 1, 1},
+ {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1},
+ {&__pyx_n_s_property, __pyx_k_property, sizeof(__pyx_k_property), 0, 0, 1, 1},
+ {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_re, __pyx_k_re, sizeof(__pyx_k_re), 0, 0, 1, 1},
+ {&__pyx_n_s_record, __pyx_k_record, sizeof(__pyx_k_record), 0, 0, 1, 1},
+ {&__pyx_n_s_record_exists_in_hdr, __pyx_k_record_exists_in_hdr, sizeof(__pyx_k_record_exists_in_hdr), 0, 0, 1, 1},
+ {&__pyx_n_s_ret, __pyx_k_ret, sizeof(__pyx_k_ret), 0, 0, 1, 1},
+ {&__pyx_n_s_scan, __pyx_k_scan, sizeof(__pyx_k_scan), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_2, __pyx_k_scan_2, sizeof(__pyx_k_scan_2), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_header, __pyx_k_scan_header, sizeof(__pyx_k_scan_header), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_header_dict, __pyx_k_scan_header_dict, sizeof(__pyx_k_scan_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_header_dict_2, __pyx_k_scan_header_dict_2, sizeof(__pyx_k_scan_header_dict_2), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_header_lines, __pyx_k_scan_header_lines, sizeof(__pyx_k_scan_header_lines), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_index, __pyx_k_scan_index, sizeof(__pyx_k_scan_index), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_number, __pyx_k_scan_number, sizeof(__pyx_k_scan_number), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_order, __pyx_k_scan_order, sizeof(__pyx_k_scan_order), 0, 0, 1, 1},
+ {&__pyx_n_s_search, __pyx_k_search, sizeof(__pyx_k_search), 0, 0, 1, 1},
+ {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1},
+ {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_specfile, __pyx_k_specfile, sizeof(__pyx_k_specfile), 0, 0, 1, 1},
+ {&__pyx_n_s_specfile_2, __pyx_k_specfile_2, sizeof(__pyx_k_specfile_2), 0, 0, 1, 1},
+ {&__pyx_n_s_split, __pyx_k_split, sizeof(__pyx_k_split), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_startswith, __pyx_k_startswith, sizeof(__pyx_k_startswith), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_n_s_string, __pyx_k_string, sizeof(__pyx_k_string), 0, 0, 1, 1},
+ {&__pyx_n_s_string_to_char_star, __pyx_k_string_to_char_star, sizeof(__pyx_k_string_to_char_star), 0, 0, 1, 1},
+ {&__pyx_n_s_strip, __pyx_k_strip, sizeof(__pyx_k_strip), 0, 0, 1, 1},
+ {&__pyx_n_s_sub, __pyx_k_sub, sizeof(__pyx_k_sub), 0, 0, 1, 1},
+ {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_kp_s_the_unique_scan_index_or_a_strin, __pyx_k_the_unique_scan_index_or_a_strin, sizeof(__pyx_k_the_unique_scan_index_or_a_strin), 0, 0, 1, 0},
+ {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1},
+ {&__pyx_n_s_transpose, __pyx_k_transpose, sizeof(__pyx_k_transpose), 0, 0, 1, 1},
+ {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+ {&__pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_k_users_payno_Documents_dev_esrf, sizeof(__pyx_k_users_payno_Documents_dev_esrf), 0, 0, 1, 0},
+ {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1},
+ {&__pyx_n_s_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 0, 1, 1},
+ {&__pyx_n_s_version_info, __pyx_k_version_info, sizeof(__pyx_k_version_info), 0, 0, 1, 1},
+ {&__pyx_kp_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 0},
+ {&__pyx_kp_s_w_2, __pyx_k_w_2, sizeof(__pyx_k_w_2), 0, 0, 1, 0},
+ {&__pyx_n_s_warning, __pyx_k_warning, sizeof(__pyx_k_warning), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_Exception = __Pyx_GetBuiltinName(__pyx_n_s_Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_n_s_property); if (!__pyx_builtin_property) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_map = __Pyx_GetBuiltinName(__pyx_n_s_map); if (!__pyx_builtin_map) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_open = __Pyx_GetBuiltinName(__pyx_n_s_open); if (!__pyx_builtin_open) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "specfile.pyx":256
+ * # Channels list
+ * if "CHANN" in self._header:
+ * chann_lines = self._header["CHANN"].split("\n") # <<<<<<<<<<<<<<
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values:
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "specfile.pyx":271
+ * # Channels list
+ * if "CALIB" in self._header:
+ * calib_lines = self._header["CALIB"].split("\n") # <<<<<<<<<<<<<<
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values:
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "specfile.pyx":297
+ * """
+ * if not len(self):
+ * raise IndexError("No MCA spectrum found in this scan") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(key, int):
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_No_MCA_spectrum_found_in_this_sc); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "specfile.pyx":335
+ * dictionary[key] += "\n" + value
+ * except TypeError:
+ * raise TypeError("Parameter value must be a string.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_Parameter_value_must_be_a_string); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "specfile.pyx":383
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s__7); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "specfile.pyx":384
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca:
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "specfile.pyx":387
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match_mca.group(2).strip()
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s__7); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "specfile.pyx":388
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ * hvalue = match_mca.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ * else:
+ */
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+
+ /* "specfile.pyx":395
+ *
+ * self._labels = []
+ * if self.record_exists_in_hdr('L'): # <<<<<<<<<<<<<<
+ * try:
+ * self._labels = self._specfile.labels(self._index)
+ */
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_n_s_L); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+
+ /* "specfile.pyx":403
+ * L_header = re.sub(r" {2,}", " ", # max. 2 spaces
+ * self._scan_header_dict["L"])
+ * self._labels = L_header.split(" ") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s__14); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "specfile.pyx":411
+ * if match:
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ */
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s__7); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+
+ /* "specfile.pyx":412
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ * else:
+ */
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "specfile.pyx":583
+ * # attribute data corresponds to a transposed version of the original
+ * # specfile data (where detectors correspond to columns)
+ * return self.data[:, line_index] # <<<<<<<<<<<<<<
+ *
+ * def data_column_by_name(self, label):
+ */
+ __pyx_slice__19 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__19);
+ __Pyx_GIVEREF(__pyx_slice__19);
+
+ /* "specfile.pyx":601
+ * _logger.warning("Cannot get data column %s in scan %d.%d",
+ * label, self.number, self.order)
+ * ret = numpy.empty((0, ), numpy.double) # <<<<<<<<<<<<<<
+ * return ret
+ *
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_int_0); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+
+ /* "specfile.pyx":620
+ * def _string_to_char_star(string_):
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes): # <<<<<<<<<<<<<<
+ * return bytes(string_, "ascii")
+ * return string_
+ */
+ __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_3); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__21);
+ __Pyx_GIVEREF(__pyx_tuple__21);
+
+ /* "specfile.pyx":638
+ * f = open(filename)
+ * for i, line in enumerate(f):
+ * if line.startswith("#S ") or line.startswith("#F "): # <<<<<<<<<<<<<<
+ * f.close()
+ * return True
+ */
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_S); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+ __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_F); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__23);
+ __Pyx_GIVEREF(__pyx_tuple__23);
+
+ /* "specfile.pyx":691
+ * if not self.__open_failed:
+ * if specfile_wrapper.SfClose(self.handle):
+ * _logger.warning("Error while closing SpecFile") # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_Error_while_closing_SpecFile); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "specfile.pyx":734
+ * else:
+ * try:
+ * (number, order) = map(int, key.split(".")) # <<<<<<<<<<<<<<
+ * scan_index = self.index(number, order)
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ */
+ __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s__25); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__26);
+ __Pyx_GIVEREF(__pyx_tuple__26);
+
+ /* "specfile.pyx":1234
+ * # error code updating isn't implemented in SfMcaCalib
+ * if mca_calib_error:
+ * raise KeyError("MCA calibration line (@CALIB) not found") # <<<<<<<<<<<<<<
+ *
+ * mca_calib_list = []
+ */
+ __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_MCA_calibration_line_CALIB_not_f); if (unlikely(!__pyx_tuple__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__30);
+ __Pyx_GIVEREF(__pyx_tuple__30);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__31);
+ __Pyx_GIVEREF(__pyx_tuple__31);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__32)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__32);
+ __Pyx_GIVEREF(__pyx_tuple__32);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__33);
+ __Pyx_GIVEREF(__pyx_tuple__33);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_tuple__34 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__34)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__34);
+ __Pyx_GIVEREF(__pyx_tuple__34);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_tuple__35 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__35)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__35);
+ __Pyx_GIVEREF(__pyx_tuple__35);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_tuple__36 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__36)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__36);
+ __Pyx_GIVEREF(__pyx_tuple__36);
+
+ /* "specfile.pyx":234
+ *
+ * """
+ * def __init__(self, scan): # <<<<<<<<<<<<<<
+ * self._scan = scan
+ *
+ */
+ __pyx_tuple__37 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_scan); if (unlikely(!__pyx_tuple__37)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__37);
+ __Pyx_GIVEREF(__pyx_tuple__37);
+ __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_init, 234, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":252
+ * self._parse_channels()
+ *
+ * def _parse_channels(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ */
+ __pyx_tuple__39 = PyTuple_Pack(9, __pyx_n_s_self, __pyx_n_s_chann_lines, __pyx_n_s_all_chann_values, __pyx_n_s_one_line_chann_values, __pyx_n_s_length, __pyx_n_s_start, __pyx_n_s_stop, __pyx_n_s_increment, __pyx_n_s_chann_line); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__39);
+ __Pyx_GIVEREF(__pyx_tuple__39);
+ __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_parse_channels, 252, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":267
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ * def _parse_calibration(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ */
+ __pyx_tuple__41 = PyTuple_Pack(5, __pyx_n_s_self, __pyx_n_s_calib_lines, __pyx_n_s_all_calib_values, __pyx_n_s_one_line_calib_values, __pyx_n_s_calib_line); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__41);
+ __Pyx_GIVEREF(__pyx_tuple__41);
+ __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_parse_calibration, 267, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":279
+ * self.calibration.append([0., 1., 0.])
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_tuple__43 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__43);
+ __Pyx_GIVEREF(__pyx_tuple__43);
+ __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_len, 279, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":287
+ * return self._scan._specfile.number_of_mca(self._scan.index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a single MCA data line
+ *
+ */
+ __pyx_tuple__45 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_key, __pyx_n_s_mca_index, __pyx_n_s_msg); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__45);
+ __Pyx_GIVEREF(__pyx_tuple__45);
+ __pyx_codeobj__46 = (PyObject*)__Pyx_PyCode_New(2, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__45, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_getitem, 287, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+ __pyx_tuple__47 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_mca_index); if (unlikely(!__pyx_tuple__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__47);
+ __Pyx_GIVEREF(__pyx_tuple__47);
+ __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(1, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__47, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_iter, 315, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":325
+ *
+ *
+ * def _add_or_concatenate(dictionary, key, value): # <<<<<<<<<<<<<<
+ * """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ * Else append/concatenate the new value to the existing one
+ */
+ __pyx_tuple__49 = PyTuple_Pack(3, __pyx_n_s_dictionary, __pyx_n_s_key, __pyx_n_s_value); if (unlikely(!__pyx_tuple__49)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__49);
+ __Pyx_GIVEREF(__pyx_tuple__49);
+ __pyx_codeobj__50 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__49, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_add_or_concatenate, 325, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__50)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":363
+ * scan2 = sf["3.1"]
+ * """
+ * def __init__(self, specfile, scan_index): # <<<<<<<<<<<<<<
+ * self._specfile = specfile
+ *
+ */
+ __pyx_tuple__51 = PyTuple_Pack(9, __pyx_n_s_self, __pyx_n_s_specfile_2, __pyx_n_s_scan_index, __pyx_n_s_line, __pyx_n_s_match, __pyx_n_s_match_mca, __pyx_n_s_hkey, __pyx_n_s_hvalue, __pyx_n_s_L_header); if (unlikely(!__pyx_tuple__51)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__51);
+ __Pyx_GIVEREF(__pyx_tuple__51);
+ __pyx_codeobj__52 = (PyObject*)__Pyx_PyCode_New(3, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__51, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_init, 363, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__52)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":425
+ * @cython.embedsignature(False)
+ * @property
+ * def index(self): # <<<<<<<<<<<<<<
+ * """Unique scan index 0 - len(specfile)-1
+ *
+ */
+ __pyx_tuple__53 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__53)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__53);
+ __Pyx_GIVEREF(__pyx_tuple__53);
+ __pyx_codeobj__54 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__53, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_index, 425, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__54)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":435
+ * @cython.embedsignature(False)
+ * @property
+ * def number(self): # <<<<<<<<<<<<<<
+ * """First value on #S line (as int)"""
+ * return self._number
+ */
+ __pyx_tuple__55 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__55)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__55);
+ __Pyx_GIVEREF(__pyx_tuple__55);
+ __pyx_codeobj__56 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__55, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_number, 435, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__56)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":441
+ * @cython.embedsignature(False)
+ * @property
+ * def order(self): # <<<<<<<<<<<<<<
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order
+ */
+ __pyx_tuple__57 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__57)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__57);
+ __Pyx_GIVEREF(__pyx_tuple__57);
+ __pyx_codeobj__58 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__57, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_order, 441, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__58)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":447
+ * @cython.embedsignature(False)
+ * @property
+ * def header(self): # <<<<<<<<<<<<<<
+ * """List of raw header lines (as a list of strings).
+ *
+ */
+ __pyx_tuple__59 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__59)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__59);
+ __Pyx_GIVEREF(__pyx_tuple__59);
+ __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_header_2, 447, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":457
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header(self): # <<<<<<<<<<<<<<
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ */
+ __pyx_tuple__61 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__61)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__61);
+ __Pyx_GIVEREF(__pyx_tuple__61);
+ __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_scan_header, 457, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":464
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header(self): # <<<<<<<<<<<<<<
+ * """List of raw file header lines (as a list of strings).
+ * """
+ */
+ __pyx_tuple__63 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__63)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__63);
+ __Pyx_GIVEREF(__pyx_tuple__63);
+ __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_file_header, 464, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":471
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of scan header strings, keys without the leading``#``
+ */
+ __pyx_tuple__65 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__65)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__65);
+ __Pyx_GIVEREF(__pyx_tuple__65);
+ __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_scan_header_dict_2, 471, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":481
+ * @cython.embedsignature(False)
+ * @property
+ * def mca_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of MCA header strings, keys without the leading ``#@``
+ */
+ __pyx_tuple__67 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__67)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__67);
+ __Pyx_GIVEREF(__pyx_tuple__67);
+ __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_mca_header_dict, 481, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":490
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of file header strings, keys without the leading ``#``
+ */
+ __pyx_tuple__69 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__69)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__69);
+ __Pyx_GIVEREF(__pyx_tuple__69);
+ __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_file_header_dict_2, 490, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":499
+ * @cython.embedsignature(False)
+ * @property
+ * def labels(self): # <<<<<<<<<<<<<<
+ * """
+ * List of data column headers from ``#L`` scan header
+ */
+ __pyx_tuple__71 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__71)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__71);
+ __Pyx_GIVEREF(__pyx_tuple__71);
+ __pyx_codeobj__72 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__71, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_labels_2, 499, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__72)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":507
+ * @cython.embedsignature(False)
+ * @property
+ * def data(self): # <<<<<<<<<<<<<<
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ * (e.g. data.shape).
+ */
+ __pyx_tuple__73 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__73)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__73);
+ __Pyx_GIVEREF(__pyx_tuple__73);
+ __pyx_codeobj__74 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__73, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_data_2, 507, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__74)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":520
+ * @cython.embedsignature(False)
+ * @property
+ * def mca(self): # <<<<<<<<<<<<<<
+ * """MCA data in this scan.
+ *
+ */
+ __pyx_tuple__75 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__75)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__75);
+ __Pyx_GIVEREF(__pyx_tuple__75);
+ __pyx_codeobj__76 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__75, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_mca_2, 520, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__76)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":534
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_names(self): # <<<<<<<<<<<<<<
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ */
+ __pyx_tuple__77 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__77)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__77);
+ __Pyx_GIVEREF(__pyx_tuple__77);
+ __pyx_codeobj__78 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__77, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_motor_names, 534, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__78)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":541
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_positions(self): # <<<<<<<<<<<<<<
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ */
+ __pyx_tuple__79 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__79)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__79);
+ __Pyx_GIVEREF(__pyx_tuple__79);
+ __pyx_codeobj__80 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_motor_positions, 541, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__80)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":546
+ * return self._motor_positions
+ *
+ * def record_exists_in_hdr(self, record): # <<<<<<<<<<<<<<
+ * """Check whether a scan header line exists.
+ *
+ */
+ __pyx_tuple__81 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_record, __pyx_n_s_line); if (unlikely(!__pyx_tuple__81)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__81);
+ __Pyx_GIVEREF(__pyx_tuple__81);
+ __pyx_codeobj__82 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__81, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_record_exists_in_hdr, 546, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__82)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":565
+ * return False
+ *
+ * def data_line(self, line_index): # <<<<<<<<<<<<<<
+ * """Returns data for a given line of this scan.
+ *
+ */
+ __pyx_tuple__83 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_line_index); if (unlikely(!__pyx_tuple__83)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__83);
+ __Pyx_GIVEREF(__pyx_tuple__83);
+ __pyx_codeobj__84 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__83, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_data_line, 565, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__84)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":585
+ * return self.data[:, line_index]
+ *
+ * def data_column_by_name(self, label): # <<<<<<<<<<<<<<
+ * """Returns a data column
+ *
+ */
+ __pyx_tuple__85 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_label, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__85)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__85);
+ __Pyx_GIVEREF(__pyx_tuple__85);
+ __pyx_codeobj__86 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__85, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_data_column_by_name, 585, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__86)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":605
+ *
+ *
+ * def motor_position_by_name(self, name): # <<<<<<<<<<<<<<
+ * """Returns the position for a given motor
+ *
+ */
+ __pyx_tuple__87 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_name); if (unlikely(!__pyx_tuple__87)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__87);
+ __Pyx_GIVEREF(__pyx_tuple__87);
+ __pyx_codeobj__88 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__87, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_motor_position_by_name, 605, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__88)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":618
+ *
+ *
+ * def _string_to_char_star(string_): # <<<<<<<<<<<<<<
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ */
+ __pyx_tuple__89 = PyTuple_Pack(1, __pyx_n_s_string); if (unlikely(!__pyx_tuple__89)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__89);
+ __Pyx_GIVEREF(__pyx_tuple__89);
+ __pyx_codeobj__90 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__89, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_string_to_char_star, 618, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__90)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":625
+ *
+ *
+ * def is_specfile(filename): # <<<<<<<<<<<<<<
+ * """Test if a file is a SPEC file, by checking if one of the first two
+ * lines starts with *#F* (SPEC file header) or *#S* (scan header).
+ */
+ __pyx_tuple__91 = PyTuple_Pack(4, __pyx_n_s_filename, __pyx_n_s_f, __pyx_n_s_i, __pyx_n_s_line); if (unlikely(!__pyx_tuple__91)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__91);
+ __Pyx_GIVEREF(__pyx_tuple__91);
+ __pyx_codeobj__92 = (PyObject*)__Pyx_PyCode_New(1, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__91, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_is_specfile, 625, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__92)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_float_0_ = PyFloat_FromDouble(0.); if (unlikely(!__pyx_float_0_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_float_1_ = PyFloat_FromDouble(1.); if (unlikely(!__pyx_float_1_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_6 = PyInt_FromLong(6); if (unlikely(!__pyx_int_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_7 = PyInt_FromLong(7); if (unlikely(!__pyx_int_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_9 = PyInt_FromLong(9); if (unlikely(!__pyx_int_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_10 = PyInt_FromLong(10); if (unlikely(!__pyx_int_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_11 = PyInt_FromLong(11); if (unlikely(!__pyx_int_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_12 = PyInt_FromLong(12); if (unlikely(!__pyx_int_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_13 = PyInt_FromLong(13); if (unlikely(!__pyx_int_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_14 = PyInt_FromLong(14); if (unlikely(!__pyx_int_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_15 = PyInt_FromLong(15); if (unlikely(!__pyx_int_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initspecfile(void); /*proto*/
+PyMODINIT_FUNC initspecfile(void)
+#else
+PyMODINIT_FUNC PyInit_specfile(void); /*proto*/
+PyMODINIT_FUNC PyInit_specfile(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_specfile(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("specfile", __pyx_methods, __pyx_k_This_module_is_a_cython_binding, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_specfile) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "specfile")) {
+ if (unlikely(PyDict_SetItemString(modules, "specfile", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type_8specfile_SpecFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_8specfile_SpecFile.tp_print = 0;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_8specfile_SpecFile, "__len__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_8specfile_8SpecFile_6__len__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_8specfile_8SpecFile_6__len__.doc = __pyx_doc_8specfile_8SpecFile_6__len__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_8specfile_8SpecFile_6__len__;
+ }
+ }
+ #endif
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_8specfile_SpecFile, "__iter__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_8specfile_8SpecFile_8__iter__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_8specfile_8SpecFile_8__iter__.doc = __pyx_doc_8specfile_8SpecFile_8__iter__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_8specfile_8SpecFile_8__iter__;
+ }
+ }
+ #endif
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_8specfile_SpecFile, "__getitem__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_8specfile_8SpecFile_11__getitem__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_8specfile_8SpecFile_11__getitem__.doc = __pyx_doc_8specfile_8SpecFile_11__getitem__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_8specfile_8SpecFile_11__getitem__;
+ }
+ }
+ #endif
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_8specfile_SpecFile, "__contains__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_8specfile_8SpecFile_15__contains__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_8specfile_8SpecFile_15__contains__.doc = __pyx_doc_8specfile_8SpecFile_15__contains__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_8specfile_8SpecFile_15__contains__;
+ }
+ }
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "SpecFile", (PyObject *)&__pyx_type_8specfile_SpecFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_8specfile_SpecFile = &__pyx_type_8specfile_SpecFile;
+ if (PyType_Ready(&__pyx_type_8specfile___pyx_scope_struct____iter__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_8specfile___pyx_scope_struct____iter__.tp_print = 0;
+ __pyx_ptype_8specfile___pyx_scope_struct____iter__ = &__pyx_type_8specfile___pyx_scope_struct____iter__;
+ if (PyType_Ready(&__pyx_type_8specfile___pyx_scope_struct_1___iter__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_8specfile___pyx_scope_struct_1___iter__.tp_print = 0;
+ __pyx_ptype_8specfile___pyx_scope_struct_1___iter__ = &__pyx_type_8specfile___pyx_scope_struct_1___iter__;
+ /*--- Type import code ---*/
+ __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type",
+ #if CYTHON_COMPILING_IN_PYPY
+ sizeof(PyTypeObject),
+ #else
+ sizeof(PyHeapTypeObject),
+ #endif
+ 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "specfile.pyx":106
+ * """
+ *
+ * __authors__ = ["P. Knobel"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "27/09/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_P_Knobel);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_P_Knobel);
+ __Pyx_GIVEREF(__pyx_kp_s_P_Knobel);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":107
+ *
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "27/09/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":108
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT"
+ * __date__ = "27/09/2016" # <<<<<<<<<<<<<<
+ *
+ * import os.path
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_27_09_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":110
+ * __date__ = "27/09/2016"
+ *
+ * import os.path # <<<<<<<<<<<<<<
+ * import logging
+ * import numpy
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_os_path, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":111
+ *
+ * import os.path
+ * import logging # <<<<<<<<<<<<<<
+ * import numpy
+ * import re
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":112
+ * import os.path
+ * import logging
+ * import numpy # <<<<<<<<<<<<<<
+ * import re
+ * import sys
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":113
+ * import logging
+ * import numpy
+ * import re # <<<<<<<<<<<<<<
+ * import sys
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_re, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_re, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":114
+ * import numpy
+ * import re
+ * import sys # <<<<<<<<<<<<<<
+ *
+ * logging.basicConfig()
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":116
+ * import sys
+ *
+ * logging.basicConfig() # <<<<<<<<<<<<<<
+ * _logger = logging.getLogger(__name__)
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_basicConfig); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":117
+ *
+ * logging.basicConfig()
+ * _logger = logging.getLogger(__name__) # <<<<<<<<<<<<<<
+ *
+ * cimport numpy
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_getLogger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_name_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logger, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":132
+ * void import_umath()
+ *
+ * if FALSE: # <<<<<<<<<<<<<<
+ * import_array()
+ * import_umath()
+ */
+ __pyx_t_6 = (0 != 0);
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":133
+ *
+ * if FALSE:
+ * import_array() # <<<<<<<<<<<<<<
+ * import_umath()
+ *
+ */
+ import_array();
+
+ /* "specfile.pyx":134
+ * if FALSE:
+ * import_array()
+ * import_umath() # <<<<<<<<<<<<<<
+ *
+ * numpy.import_array()
+ */
+ import_umath();
+ goto __pyx_L2;
+ }
+ __pyx_L2:;
+
+ /* "specfile.pyx":136
+ * import_umath()
+ *
+ * numpy.import_array() # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ import_array();
+
+ /* "specfile.pyx":139
+ *
+ *
+ * SF_ERR_NO_ERRORS = 0 # <<<<<<<<<<<<<<
+ * SF_ERR_FILE_OPEN = 2
+ * SF_ERR_SCAN_NOT_FOUND = 7
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SF_ERR_NO_ERRORS, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":140
+ *
+ * SF_ERR_NO_ERRORS = 0
+ * SF_ERR_FILE_OPEN = 2 # <<<<<<<<<<<<<<
+ * SF_ERR_SCAN_NOT_FOUND = 7
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SF_ERR_FILE_OPEN, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":141
+ * SF_ERR_NO_ERRORS = 0
+ * SF_ERR_FILE_OPEN = 2
+ * SF_ERR_SCAN_NOT_FOUND = 7 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SF_ERR_SCAN_NOT_FOUND, __pyx_int_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":145
+ *
+ * # custom errors
+ * class SfError(Exception): # <<<<<<<<<<<<<<
+ * """Base exception inherited by all exceptions raised when a
+ * C function from the legacy SpecFile library returns an error
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_builtin_Exception);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_builtin_Exception);
+ __Pyx_GIVEREF(__pyx_builtin_Exception);
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfError, __pyx_n_s_SfError, (PyObject *) NULL, __pyx_n_s_specfile_2, __pyx_kp_s_Base_exception_inherited_by_all); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfError, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfError, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":152
+ * pass
+ *
+ * class SfErrMemoryAlloc(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrFileOpen(SfError): pass
+ * class SfErrFileClose(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrMemoryAlloc, __pyx_n_s_SfErrMemoryAlloc, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrMemoryAlloc, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrMemoryAlloc, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":153
+ *
+ * class SfErrMemoryAlloc(SfError): pass
+ * class SfErrFileOpen(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrFileClose(SfError): pass
+ * class SfErrFileRead(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrFileOpen, __pyx_n_s_SfErrFileOpen, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrFileOpen, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrFileOpen, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":154
+ * class SfErrMemoryAlloc(SfError): pass
+ * class SfErrFileOpen(SfError): pass
+ * class SfErrFileClose(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrFileRead(SfError): pass
+ * class SfErrFileWrite(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrFileClose, __pyx_n_s_SfErrFileClose, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrFileClose, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrFileClose, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":155
+ * class SfErrFileOpen(SfError): pass
+ * class SfErrFileClose(SfError): pass
+ * class SfErrFileRead(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrFileWrite(SfError): pass
+ * class SfErrLineNotFound(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrFileRead, __pyx_n_s_SfErrFileRead, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrFileRead, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrFileRead, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":156
+ * class SfErrFileClose(SfError): pass
+ * class SfErrFileRead(SfError): pass
+ * class SfErrFileWrite(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrLineNotFound(SfError): pass
+ * class SfErrScanNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrFileWrite, __pyx_n_s_SfErrFileWrite, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrFileWrite, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrFileWrite, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":157
+ * class SfErrFileRead(SfError): pass
+ * class SfErrFileWrite(SfError): pass
+ * class SfErrLineNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrScanNotFound(SfError): pass
+ * class SfErrHeaderNotFound(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrLineNotFound, __pyx_n_s_SfErrLineNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrLineNotFound, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrLineNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":158
+ * class SfErrFileWrite(SfError): pass
+ * class SfErrLineNotFound(SfError): pass
+ * class SfErrScanNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrHeaderNotFound(SfError): pass
+ * class SfErrLabelNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrScanNotFound, __pyx_n_s_SfErrScanNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrScanNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrScanNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":159
+ * class SfErrLineNotFound(SfError): pass
+ * class SfErrScanNotFound(SfError): pass
+ * class SfErrHeaderNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrLabelNotFound(SfError): pass
+ * class SfErrMotorNotFound(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrHeaderNotFound, __pyx_n_s_SfErrHeaderNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrHeaderNotFound, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrHeaderNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":160
+ * class SfErrScanNotFound(SfError): pass
+ * class SfErrHeaderNotFound(SfError): pass
+ * class SfErrLabelNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrMotorNotFound(SfError): pass
+ * class SfErrPositionNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrLabelNotFound, __pyx_n_s_SfErrLabelNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrLabelNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrLabelNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":161
+ * class SfErrHeaderNotFound(SfError): pass
+ * class SfErrLabelNotFound(SfError): pass
+ * class SfErrMotorNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrPositionNotFound(SfError): pass
+ * class SfErrLineEmpty(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrMotorNotFound, __pyx_n_s_SfErrMotorNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrMotorNotFound, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrMotorNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":162
+ * class SfErrLabelNotFound(SfError): pass
+ * class SfErrMotorNotFound(SfError): pass
+ * class SfErrPositionNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrLineEmpty(SfError): pass
+ * class SfErrUserNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrPositionNotFound, __pyx_n_s_SfErrPositionNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrPositionNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrPositionNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":163
+ * class SfErrMotorNotFound(SfError): pass
+ * class SfErrPositionNotFound(SfError): pass
+ * class SfErrLineEmpty(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrUserNotFound(SfError): pass
+ * class SfErrColNotFound(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrLineEmpty, __pyx_n_s_SfErrLineEmpty, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrLineEmpty, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrLineEmpty, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":164
+ * class SfErrPositionNotFound(SfError): pass
+ * class SfErrLineEmpty(SfError): pass
+ * class SfErrUserNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrColNotFound(SfError): pass
+ * class SfErrMcaNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrUserNotFound, __pyx_n_s_SfErrUserNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrUserNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrUserNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":165
+ * class SfErrLineEmpty(SfError): pass
+ * class SfErrUserNotFound(SfError): pass
+ * class SfErrColNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrMcaNotFound(SfError): pass
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrColNotFound, __pyx_n_s_SfErrColNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrColNotFound, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrColNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":166
+ * class SfErrUserNotFound(SfError): pass
+ * class SfErrColNotFound(SfError): pass
+ * class SfErrMcaNotFound(SfError): pass # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrMcaNotFound, __pyx_n_s_SfErrMcaNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrMcaNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrMcaNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":169
+ *
+ *
+ * ERRORS = { # <<<<<<<<<<<<<<
+ * 1: SfErrMemoryAlloc,
+ * 2: SfErrFileOpen,
+ */
+ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+
+ /* "specfile.pyx":170
+ *
+ * ERRORS = {
+ * 1: SfErrMemoryAlloc, # <<<<<<<<<<<<<<
+ * 2: SfErrFileOpen,
+ * 3: SfErrFileClose,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrMemoryAlloc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_1, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":171
+ * ERRORS = {
+ * 1: SfErrMemoryAlloc,
+ * 2: SfErrFileOpen, # <<<<<<<<<<<<<<
+ * 3: SfErrFileClose,
+ * 4: SfErrFileRead,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrFileOpen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_2, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":172
+ * 1: SfErrMemoryAlloc,
+ * 2: SfErrFileOpen,
+ * 3: SfErrFileClose, # <<<<<<<<<<<<<<
+ * 4: SfErrFileRead,
+ * 5: SfErrFileWrite,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrFileClose); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_3, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":173
+ * 2: SfErrFileOpen,
+ * 3: SfErrFileClose,
+ * 4: SfErrFileRead, # <<<<<<<<<<<<<<
+ * 5: SfErrFileWrite,
+ * 6: SfErrLineNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrFileRead); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_4, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":174
+ * 3: SfErrFileClose,
+ * 4: SfErrFileRead,
+ * 5: SfErrFileWrite, # <<<<<<<<<<<<<<
+ * 6: SfErrLineNotFound,
+ * 7: SfErrScanNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrFileWrite); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_5, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":175
+ * 4: SfErrFileRead,
+ * 5: SfErrFileWrite,
+ * 6: SfErrLineNotFound, # <<<<<<<<<<<<<<
+ * 7: SfErrScanNotFound,
+ * 8: SfErrHeaderNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLineNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_6, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":176
+ * 5: SfErrFileWrite,
+ * 6: SfErrLineNotFound,
+ * 7: SfErrScanNotFound, # <<<<<<<<<<<<<<
+ * 8: SfErrHeaderNotFound,
+ * 9: SfErrLabelNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrScanNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_7, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":177
+ * 6: SfErrLineNotFound,
+ * 7: SfErrScanNotFound,
+ * 8: SfErrHeaderNotFound, # <<<<<<<<<<<<<<
+ * 9: SfErrLabelNotFound,
+ * 10: SfErrMotorNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrHeaderNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_8, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":178
+ * 7: SfErrScanNotFound,
+ * 8: SfErrHeaderNotFound,
+ * 9: SfErrLabelNotFound, # <<<<<<<<<<<<<<
+ * 10: SfErrMotorNotFound,
+ * 11: SfErrPositionNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLabelNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_9, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":179
+ * 8: SfErrHeaderNotFound,
+ * 9: SfErrLabelNotFound,
+ * 10: SfErrMotorNotFound, # <<<<<<<<<<<<<<
+ * 11: SfErrPositionNotFound,
+ * 12: SfErrLineEmpty,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrMotorNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_10, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":180
+ * 9: SfErrLabelNotFound,
+ * 10: SfErrMotorNotFound,
+ * 11: SfErrPositionNotFound, # <<<<<<<<<<<<<<
+ * 12: SfErrLineEmpty,
+ * 13: SfErrUserNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrPositionNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_11, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":181
+ * 10: SfErrMotorNotFound,
+ * 11: SfErrPositionNotFound,
+ * 12: SfErrLineEmpty, # <<<<<<<<<<<<<<
+ * 13: SfErrUserNotFound,
+ * 14: SfErrColNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLineEmpty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_12, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":182
+ * 11: SfErrPositionNotFound,
+ * 12: SfErrLineEmpty,
+ * 13: SfErrUserNotFound, # <<<<<<<<<<<<<<
+ * 14: SfErrColNotFound,
+ * 15: SfErrMcaNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrUserNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":183
+ * 12: SfErrLineEmpty,
+ * 13: SfErrUserNotFound,
+ * 14: SfErrColNotFound, # <<<<<<<<<<<<<<
+ * 15: SfErrMcaNotFound,
+ * }
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrColNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_14, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":184
+ * 13: SfErrUserNotFound,
+ * 14: SfErrColNotFound,
+ * 15: SfErrMcaNotFound, # <<<<<<<<<<<<<<
+ * }
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrMcaNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_15, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERRORS, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":188
+ *
+ *
+ * class SfNoMcaError(SfError): # <<<<<<<<<<<<<<
+ * """Custom exception raised when ``SfNoMca()`` returns ``-1``
+ * """
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfNoMcaError, __pyx_n_s_SfNoMcaError, (PyObject *) NULL, __pyx_n_s_specfile_2, __pyx_kp_s_Custom_exception_raised_when_SfN); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfNoMcaError, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfNoMcaError, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":194
+ *
+ *
+ * class MCA(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_builtin_object);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_builtin_object);
+ __Pyx_GIVEREF(__pyx_builtin_object);
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_MCA, __pyx_n_s_MCA, (PyObject *) NULL, __pyx_n_s_specfile_2, __pyx_kp_s_param_scan_Parent_Scan_instance); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "specfile.pyx":234
+ *
+ * """
+ * def __init__(self, scan): # <<<<<<<<<<<<<<
+ * self._scan = scan
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_1__init__, 0, __pyx_n_s_MCA___init, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__38)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_init, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":252
+ * self._parse_channels()
+ *
+ * def _parse_channels(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_3_parse_channels, 0, __pyx_n_s_MCA__parse_channels, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__40)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_parse_channels, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":267
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ * def _parse_calibration(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_5_parse_calibration, 0, __pyx_n_s_MCA__parse_calibration, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__42)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_parse_calibration, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":279
+ * self.calibration.append([0., 1., 0.])
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_7__len__, 0, __pyx_n_s_MCA___len, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__44)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_len, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":287
+ * return self._scan._specfile.number_of_mca(self._scan.index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a single MCA data line
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_9__getitem__, 0, __pyx_n_s_MCA___getitem, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_getitem, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_11__iter__, 0, __pyx_n_s_MCA___iter, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_iter, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":194
+ *
+ *
+ * class MCA(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_MCA, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_MCA, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":325
+ *
+ *
+ * def _add_or_concatenate(dictionary, key, value): # <<<<<<<<<<<<<<
+ * """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ * Else append/concatenate the new value to the existing one
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8specfile_1_add_or_concatenate, NULL, __pyx_n_s_specfile_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_add_or_concatenate, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":338
+ *
+ *
+ * class Scan(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_builtin_object);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_builtin_object);
+ __Pyx_GIVEREF(__pyx_builtin_object);
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_Scan, __pyx_n_s_Scan, (PyObject *) NULL, __pyx_n_s_specfile_2, __pyx_kp_s_param_specfile_Parent_SpecFile); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "specfile.pyx":363
+ * scan2 = sf["3.1"]
+ * """
+ * def __init__(self, specfile, scan_index): # <<<<<<<<<<<<<<
+ * self._specfile = specfile
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_1__init__, 0, __pyx_n_s_Scan___init, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__52)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_init, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":425
+ * @cython.embedsignature(False)
+ * @property
+ * def index(self): # <<<<<<<<<<<<<<
+ * """Unique scan index 0 - len(specfile)-1
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_3index, 0, __pyx_n_s_Scan_index, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__54)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":424
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def index(self):
+ * """Unique scan index 0 - len(specfile)-1
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_index, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":435
+ * @cython.embedsignature(False)
+ * @property
+ * def number(self): # <<<<<<<<<<<<<<
+ * """First value on #S line (as int)"""
+ * return self._number
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_5number, 0, __pyx_n_s_Scan_number, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__56)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":434
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def number(self):
+ * """First value on #S line (as int)"""
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_number, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":441
+ * @cython.embedsignature(False)
+ * @property
+ * def order(self): # <<<<<<<<<<<<<<
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_7order, 0, __pyx_n_s_Scan_order, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__58)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":440
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def order(self):
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":447
+ * @cython.embedsignature(False)
+ * @property
+ * def header(self): # <<<<<<<<<<<<<<
+ * """List of raw header lines (as a list of strings).
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_9header, 0, __pyx_n_s_Scan_header, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__60)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":446
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def header(self):
+ * """List of raw header lines (as a list of strings).
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_header_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":457
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header(self): # <<<<<<<<<<<<<<
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_11scan_header, 0, __pyx_n_s_Scan_scan_header, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__62)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":456
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def scan_header(self):
+ * """List of raw scan header lines (as a list of strings).
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_scan_header, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":464
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header(self): # <<<<<<<<<<<<<<
+ * """List of raw file header lines (as a list of strings).
+ * """
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_13file_header, 0, __pyx_n_s_Scan_file_header, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__64)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":463
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def file_header(self):
+ * """List of raw file header lines (as a list of strings).
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_file_header, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":471
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of scan header strings, keys without the leading``#``
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_15scan_header_dict, 0, __pyx_n_s_Scan_scan_header_dict, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__66)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":470
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def scan_header_dict(self):
+ * """
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_scan_header_dict_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":481
+ * @cython.embedsignature(False)
+ * @property
+ * def mca_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of MCA header strings, keys without the leading ``#@``
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_17mca_header_dict, 0, __pyx_n_s_Scan_mca_header_dict, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__68)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":480
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def mca_header_dict(self):
+ * """
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_mca_header_dict, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":490
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of file header strings, keys without the leading ``#``
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_19file_header_dict, 0, __pyx_n_s_Scan_file_header_dict, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":489
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def file_header_dict(self):
+ * """
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_file_header_dict_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":499
+ * @cython.embedsignature(False)
+ * @property
+ * def labels(self): # <<<<<<<<<<<<<<
+ * """
+ * List of data column headers from ``#L`` scan header
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_21labels, 0, __pyx_n_s_Scan_labels, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__72)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":498
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def labels(self):
+ * """
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_labels_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":507
+ * @cython.embedsignature(False)
+ * @property
+ * def data(self): # <<<<<<<<<<<<<<
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ * (e.g. data.shape).
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_23data, 0, __pyx_n_s_Scan_data, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__74)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":506
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def data(self):
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_data_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":520
+ * @cython.embedsignature(False)
+ * @property
+ * def mca(self): # <<<<<<<<<<<<<<
+ * """MCA data in this scan.
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_25mca, 0, __pyx_n_s_Scan_mca, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__76)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":519
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def mca(self):
+ * """MCA data in this scan.
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_mca_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":534
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_names(self): # <<<<<<<<<<<<<<
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_27motor_names, 0, __pyx_n_s_Scan_motor_names, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__78)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":533
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def motor_names(self):
+ * """List of motor names from the ``#O`` file header line.
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_motor_names, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":541
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_positions(self): # <<<<<<<<<<<<<<
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_29motor_positions, 0, __pyx_n_s_Scan_motor_positions, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__80)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":540
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def motor_positions(self):
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_motor_positions, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":546
+ * return self._motor_positions
+ *
+ * def record_exists_in_hdr(self, record): # <<<<<<<<<<<<<<
+ * """Check whether a scan header line exists.
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_31record_exists_in_hdr, 0, __pyx_n_s_Scan_record_exists_in_hdr, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__82)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_record_exists_in_hdr, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":565
+ * return False
+ *
+ * def data_line(self, line_index): # <<<<<<<<<<<<<<
+ * """Returns data for a given line of this scan.
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_33data_line, 0, __pyx_n_s_Scan_data_line, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__84)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_data_line, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":585
+ * return self.data[:, line_index]
+ *
+ * def data_column_by_name(self, label): # <<<<<<<<<<<<<<
+ * """Returns a data column
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_35data_column_by_name, 0, __pyx_n_s_Scan_data_column_by_name, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__86)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_data_column_by_name, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":605
+ *
+ *
+ * def motor_position_by_name(self, name): # <<<<<<<<<<<<<<
+ * """Returns the position for a given motor
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_37motor_position_by_name, 0, __pyx_n_s_Scan_motor_position_by_name, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__88)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_motor_position_by_name, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":338
+ *
+ *
+ * class Scan(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_Scan, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_Scan, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":618
+ *
+ *
+ * def _string_to_char_star(string_): # <<<<<<<<<<<<<<
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8specfile_3_string_to_char_star, NULL, __pyx_n_s_specfile_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_string_to_char_star, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":625
+ *
+ *
+ * def is_specfile(filename): # <<<<<<<<<<<<<<
+ * """Test if a file is a SPEC file, by checking if one of the first two
+ * lines starts with *#F* (SPEC file header) or *#S* (scan header).
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8specfile_5is_specfile, NULL, __pyx_n_s_specfile_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_is_specfile, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * # /[inserted by cython to avoid comment start]*##########################################################################
+ * # Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init specfile", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init specfile");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* exc_type = tstate->curexc_type;
+ if (unlikely(exc_type)) {
+ if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+ PyObject *exc_value, *exc_tb;
+ exc_value = tstate->curexc_value;
+ exc_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+ Py_DECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#else
+ if (unlikely(PyErr_Occurred())) {
+ if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+ PyErr_Clear();
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+ if (unlikely(retval)) {
+ Py_DECREF(retval);
+ __Pyx_RaiseTooManyValuesError(expected);
+ return -1;
+ } else {
+ return __Pyx_IterFinish();
+ }
+ return 0;
+}
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
+ PyObject *method, *result = NULL;
+ method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+ if (unlikely(!method)) goto bad;
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyMethod_Check(method))) {
+ PyObject *self = PyMethod_GET_SELF(method);
+ if (likely(self)) {
+ PyObject *args;
+ PyObject *function = PyMethod_GET_FUNCTION(method);
+ args = PyTuple_New(2);
+ if (unlikely(!args)) goto bad;
+ Py_INCREF(self);
+ PyTuple_SET_ITEM(args, 0, self);
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 1, arg);
+ Py_INCREF(function);
+ Py_DECREF(method); method = NULL;
+ result = __Pyx_PyObject_Call(function, args, NULL);
+ Py_DECREF(args);
+ Py_DECREF(function);
+ return result;
+ }
+ }
+#endif
+ result = __Pyx_PyObject_CallOneArg(method, arg);
+bad:
+ Py_XDECREF(method);
+ return result;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+ if (likely(PyList_CheckExact(L))) {
+ if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1;
+ } else {
+ PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x);
+ if (unlikely(!retval))
+ return -1;
+ Py_DECREF(retval);
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+#if !CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) {
+ return PyObject_CallMethodObjArgs(sep, __pyx_n_s_join, values, NULL);
+}
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
+ const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ if (unlikely((start < 0) | (stop < 0))) {
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ if (stop > length)
+ stop = length;
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+ int r;
+ if (!j) return -1;
+ r = PyObject_SetItem(o, j, v);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
+ if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+ PyObject* old = PyList_GET_ITEM(o, n);
+ Py_INCREF(v);
+ PyList_SET_ITEM(o, n, v);
+ Py_DECREF(old);
+ return 1;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_ass_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return -1;
+ }
+ }
+ return m->sq_ass_item(o, i, v);
+ }
+ }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+ if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
+#else
+ if (is_list || PySequence_Check(o)) {
+#endif
+ return PySequence_SetItem(o, i, v);
+ }
+#endif
+ return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) {
+ Py_ssize_t i, nbases = PyTuple_GET_SIZE(bases);
+ for (i=0; i < nbases; i++) {
+ PyTypeObject *tmptype;
+ PyObject *tmp = PyTuple_GET_ITEM(bases, i);
+ tmptype = Py_TYPE(tmp);
+#if PY_MAJOR_VERSION < 3
+ if (tmptype == &PyClass_Type)
+ continue;
+#endif
+ if (!metaclass) {
+ metaclass = tmptype;
+ continue;
+ }
+ if (PyType_IsSubtype(metaclass, tmptype))
+ continue;
+ if (PyType_IsSubtype(tmptype, metaclass)) {
+ metaclass = tmptype;
+ continue;
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "metaclass conflict: "
+ "the metaclass of a derived class "
+ "must be a (non-strict) subclass "
+ "of the metaclasses of all its bases");
+ return NULL;
+ }
+ if (!metaclass) {
+#if PY_MAJOR_VERSION < 3
+ metaclass = &PyClass_Type;
+#else
+ metaclass = &PyType_Type;
+#endif
+ }
+ Py_INCREF((PyObject*) metaclass);
+ return (PyObject*) metaclass;
+}
+
+static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name,
+ PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) {
+ PyObject *ns;
+ if (metaclass) {
+ PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, __pyx_n_s_prepare);
+ if (prep) {
+ PyObject *pargs = PyTuple_Pack(2, name, bases);
+ if (unlikely(!pargs)) {
+ Py_DECREF(prep);
+ return NULL;
+ }
+ ns = PyObject_Call(prep, pargs, mkw);
+ Py_DECREF(prep);
+ Py_DECREF(pargs);
+ } else {
+ if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError)))
+ return NULL;
+ PyErr_Clear();
+ ns = PyDict_New();
+ }
+ } else {
+ ns = PyDict_New();
+ }
+ if (unlikely(!ns))
+ return NULL;
+ if (unlikely(PyObject_SetItem(ns, __pyx_n_s_module, modname) < 0)) goto bad;
+ if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad;
+ if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc, doc) < 0)) goto bad;
+ return ns;
+bad:
+ Py_DECREF(ns);
+ return NULL;
+}
+static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases,
+ PyObject *dict, PyObject *mkw,
+ int calculate_metaclass, int allow_py2_metaclass) {
+ PyObject *result, *margs;
+ PyObject *owned_metaclass = NULL;
+ if (allow_py2_metaclass) {
+ owned_metaclass = PyObject_GetItem(dict, __pyx_n_s_metaclass);
+ if (owned_metaclass) {
+ metaclass = owned_metaclass;
+ } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) {
+ PyErr_Clear();
+ } else {
+ return NULL;
+ }
+ }
+ if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) {
+ metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases);
+ Py_XDECREF(owned_metaclass);
+ if (unlikely(!metaclass))
+ return NULL;
+ owned_metaclass = metaclass;
+ }
+ margs = PyTuple_Pack(3, name, bases, dict);
+ if (unlikely(!margs)) {
+ result = NULL;
+ } else {
+ result = PyObject_Call(metaclass, margs, mkw);
+ Py_DECREF(margs);
+ }
+ Py_XDECREF(owned_metaclass);
+ return result;
+}
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
+ PyObject* fake_module;
+ PyTypeObject* cached_type = NULL;
+ fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+ if (!fake_module) return NULL;
+ Py_INCREF(fake_module);
+ cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
+ if (cached_type) {
+ if (!PyType_Check((PyObject*)cached_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s is not a type object",
+ type->tp_name);
+ goto bad;
+ }
+ if (cached_type->tp_basicsize != type->tp_basicsize) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s has the wrong size, try recompiling",
+ type->tp_name);
+ goto bad;
+ }
+ } else {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+ PyErr_Clear();
+ if (PyType_Ready(type) < 0) goto bad;
+ if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
+ goto bad;
+ Py_INCREF(type);
+ cached_type = type;
+ }
+done:
+ Py_DECREF(fake_module);
+ return cached_type;
+bad:
+ Py_XDECREF(cached_type);
+ cached_type = NULL;
+ goto done;
+}
+
+static PyObject *
+__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
+{
+ if (unlikely(op->func_doc == NULL)) {
+ if (op->func.m_ml->ml_doc) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
+#else
+ op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
+#endif
+ if (unlikely(op->func_doc == NULL))
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ Py_INCREF(op->func_doc);
+ return op->func_doc;
+}
+static int
+__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp = op->func_doc;
+ if (value == NULL) {
+ value = Py_None;
+ }
+ Py_INCREF(value);
+ op->func_doc = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_name == NULL)) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
+#else
+ op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
+#endif
+ if (unlikely(op->func_name == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_name);
+ return op->func_name;
+}
+static int
+__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__name__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_name;
+ Py_INCREF(value);
+ op->func_name = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_qualname);
+ return op->func_qualname;
+}
+static int
+__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__qualname__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_qualname;
+ Py_INCREF(value);
+ op->func_qualname = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
+{
+ PyObject *self;
+ self = m->func_closure;
+ if (self == NULL)
+ self = Py_None;
+ Py_INCREF(self);
+ return self;
+}
+static PyObject *
+__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_dict == NULL)) {
+ op->func_dict = PyDict_New();
+ if (unlikely(op->func_dict == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_dict);
+ return op->func_dict;
+}
+static int
+__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+ if (unlikely(value == NULL)) {
+ PyErr_SetString(PyExc_TypeError,
+ "function's dictionary may not be deleted");
+ return -1;
+ }
+ if (unlikely(!PyDict_Check(value))) {
+ PyErr_SetString(PyExc_TypeError,
+ "setting function's dictionary to a non-dict");
+ return -1;
+ }
+ tmp = op->func_dict;
+ Py_INCREF(value);
+ op->func_dict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_globals);
+ return op->func_globals;
+}
+static PyObject *
+__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op)
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject *
+__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op)
+{
+ PyObject* result = (op->func_code) ? op->func_code : Py_None;
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) {
+ PyObject *res = op->defaults_getter((PyObject *) op);
+ if (unlikely(!res))
+ return -1;
+ op->defaults_tuple = PyTuple_GET_ITEM(res, 0);
+ Py_INCREF(op->defaults_tuple);
+ op->defaults_kwdict = PyTuple_GET_ITEM(res, 1);
+ Py_INCREF(op->defaults_kwdict);
+ Py_DECREF(res);
+ return 0;
+}
+static int
+__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyTuple_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__defaults__ must be set to a tuple object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_tuple;
+ op->defaults_tuple = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_tuple;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_tuple;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__kwdefaults__ must be set to a dict object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_kwdict;
+ op->defaults_kwdict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_kwdict;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_kwdict;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value || value == Py_None) {
+ value = NULL;
+ } else if (!PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__annotations__ must be set to a dict object");
+ return -1;
+ }
+ Py_XINCREF(value);
+ tmp = op->func_annotations;
+ op->func_annotations = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->func_annotations;
+ if (unlikely(!result)) {
+ result = PyDict_New();
+ if (unlikely(!result)) return NULL;
+ op->func_annotations = result;
+ }
+ Py_INCREF(result);
+ return result;
+}
+static PyGetSetDef __pyx_CyFunction_getsets[] = {
+ {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0},
+ {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0},
+ {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0},
+ {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+#ifndef PY_WRITE_RESTRICTED
+#define PY_WRITE_RESTRICTED WRITE_RESTRICTED
+#endif
+static PyMemberDef __pyx_CyFunction_members[] = {
+ {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0},
+ {0, 0, 0, 0, 0}
+};
+static PyObject *
+__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromString(m->func.m_ml->ml_name);
+#else
+ return PyString_FromString(m->func.m_ml->ml_name);
+#endif
+}
+static PyMethodDef __pyx_CyFunction_methods[] = {
+ {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0},
+ {0, 0, 0, 0}
+};
+#if PY_VERSION_HEX < 0x030500A0
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
+#else
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
+#endif
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
+ PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
+ __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
+ if (op == NULL)
+ return NULL;
+ op->flags = flags;
+ __Pyx_CyFunction_weakreflist(op) = NULL;
+ op->func.m_ml = ml;
+ op->func.m_self = (PyObject *) op;
+ Py_XINCREF(closure);
+ op->func_closure = closure;
+ Py_XINCREF(module);
+ op->func.m_module = module;
+ op->func_dict = NULL;
+ op->func_name = NULL;
+ Py_INCREF(qualname);
+ op->func_qualname = qualname;
+ op->func_doc = NULL;
+ op->func_classobj = NULL;
+ op->func_globals = globals;
+ Py_INCREF(op->func_globals);
+ Py_XINCREF(code);
+ op->func_code = code;
+ op->defaults_pyobjects = 0;
+ op->defaults = NULL;
+ op->defaults_tuple = NULL;
+ op->defaults_kwdict = NULL;
+ op->defaults_getter = NULL;
+ op->func_annotations = NULL;
+ PyObject_GC_Track(op);
+ return (PyObject *) op;
+}
+static int
+__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
+{
+ Py_CLEAR(m->func_closure);
+ Py_CLEAR(m->func.m_module);
+ Py_CLEAR(m->func_dict);
+ Py_CLEAR(m->func_name);
+ Py_CLEAR(m->func_qualname);
+ Py_CLEAR(m->func_doc);
+ Py_CLEAR(m->func_globals);
+ Py_CLEAR(m->func_code);
+ Py_CLEAR(m->func_classobj);
+ Py_CLEAR(m->defaults_tuple);
+ Py_CLEAR(m->defaults_kwdict);
+ Py_CLEAR(m->func_annotations);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_XDECREF(pydefaults[i]);
+ PyMem_Free(m->defaults);
+ m->defaults = NULL;
+ }
+ return 0;
+}
+static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
+{
+ PyObject_GC_UnTrack(m);
+ if (__Pyx_CyFunction_weakreflist(m) != NULL)
+ PyObject_ClearWeakRefs((PyObject *) m);
+ __Pyx_CyFunction_clear(m);
+ PyObject_GC_Del(m);
+}
+static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
+{
+ Py_VISIT(m->func_closure);
+ Py_VISIT(m->func.m_module);
+ Py_VISIT(m->func_dict);
+ Py_VISIT(m->func_name);
+ Py_VISIT(m->func_qualname);
+ Py_VISIT(m->func_doc);
+ Py_VISIT(m->func_globals);
+ Py_VISIT(m->func_code);
+ Py_VISIT(m->func_classobj);
+ Py_VISIT(m->defaults_tuple);
+ Py_VISIT(m->defaults_kwdict);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_VISIT(pydefaults[i]);
+ }
+ return 0;
+}
+static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+ Py_INCREF(func);
+ return func;
+ }
+ if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
+ if (type == NULL)
+ type = (PyObject *)(Py_TYPE(obj));
+ return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type)));
+ }
+ if (obj == Py_None)
+ obj = NULL;
+ return __Pyx_PyMethod_New(func, obj, type);
+}
+static PyObject*
+__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromFormat("<cyfunction %U at %p>",
+ op->func_qualname, (void *)op);
+#else
+ return PyString_FromFormat("<cyfunction %s at %p>",
+ PyString_AsString(op->func_qualname), (void *)op);
+#endif
+}
+#if CYTHON_COMPILING_IN_PYPY
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyCFunctionObject* f = (PyCFunctionObject*)func;
+ PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ PyObject *self = PyCFunction_GET_SELF(func);
+ Py_ssize_t size;
+ switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+ case METH_VARARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0)
+ return (*meth)(self, arg);
+ break;
+ case METH_VARARGS | METH_KEYWORDS:
+ return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+ case METH_NOARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 0)
+ return (*meth)(self, NULL);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ case METH_O:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 1)
+ return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes exactly one argument (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "Bad call flags in "
+ "__Pyx_CyFunction_Call. METH_OLDARGS is no "
+ "longer supported!");
+ return NULL;
+ }
+ PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+ f->m_ml->ml_name);
+ return NULL;
+}
+#else
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ return PyCFunction_Call(func, arg, kw);
+}
+#endif
+static PyTypeObject __pyx_CyFunctionType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "cython_function_or_method",
+ sizeof(__pyx_CyFunctionObject),
+ 0,
+ (destructor) __Pyx_CyFunction_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ (reprfunc) __Pyx_CyFunction_repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ __Pyx_CyFunction_Call,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ 0,
+ (traverseproc) __Pyx_CyFunction_traverse,
+ (inquiry) __Pyx_CyFunction_clear,
+ 0,
+#if PY_VERSION_HEX < 0x030500A0
+ offsetof(__pyx_CyFunctionObject, func_weakreflist),
+#else
+ offsetof(PyCFunctionObject, m_weakreflist),
+#endif
+ 0,
+ 0,
+ __pyx_CyFunction_methods,
+ __pyx_CyFunction_members,
+ __pyx_CyFunction_getsets,
+ 0,
+ 0,
+ __Pyx_CyFunction_descr_get,
+ 0,
+ offsetof(__pyx_CyFunctionObject, func_dict),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#endif
+};
+static int __Pyx_CyFunction_init(void) {
+#if !CYTHON_COMPILING_IN_PYPY
+ __pyx_CyFunctionType_type.tp_call = PyCFunction_Call;
+#endif
+ __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
+ if (__pyx_CyFunctionType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults = PyMem_Malloc(size);
+ if (!m->defaults)
+ return PyErr_NoMemory();
+ memset(m->defaults, 0, size);
+ m->defaults_pyobjects = pyobjects;
+ return m->defaults;
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_tuple = tuple;
+ Py_INCREF(tuple);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_kwdict = dict;
+ Py_INCREF(dict);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->func_annotations = dict;
+ Py_INCREF(dict);
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return ::std::complex< float >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return x + y*(__pyx_t_float_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ __pyx_t_float_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrtf(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypotf(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ float denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(a, a);
+ case 3:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, a);
+ case 4:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_absf(a);
+ theta = atan2f(a.imag, a.real);
+ }
+ lnr = logf(r);
+ z_r = expf(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cosf(z_theta);
+ z.imag = z_r * sinf(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return ::std::complex< double >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return x + y*(__pyx_t_double_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ __pyx_t_double_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrt(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypot(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ double denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(a, a);
+ case 3:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, a);
+ case 4:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_abs(a);
+ theta = atan2(a.imag, a.real);
+ }
+ lnr = log(r);
+ z_r = exp(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cos(z_theta);
+ z.imag = z_r * sin(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static PyObject *__Pyx_Generator_Next(PyObject *self);
+static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
+static PyObject *__Pyx_Generator_Close(PyObject *self);
+static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args);
+static PyTypeObject *__pyx_GeneratorType = 0;
+#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
+#define __Pyx_Generator_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
+#if 1 || PY_VERSION_HEX < 0x030300B0
+static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
+ PyObject *et, *ev, *tb;
+ PyObject *value = NULL;
+ __Pyx_ErrFetch(&et, &ev, &tb);
+ if (!et) {
+ Py_XDECREF(tb);
+ Py_XDECREF(ev);
+ Py_INCREF(Py_None);
+ *pvalue = Py_None;
+ return 0;
+ }
+ if (unlikely(et != PyExc_StopIteration) &&
+ unlikely(!PyErr_GivenExceptionMatches(et, PyExc_StopIteration))) {
+ __Pyx_ErrRestore(et, ev, tb);
+ return -1;
+ }
+ if (likely(et == PyExc_StopIteration)) {
+ if (likely(!ev) || !PyObject_IsInstance(ev, PyExc_StopIteration)) {
+ if (!ev) {
+ Py_INCREF(Py_None);
+ ev = Py_None;
+ }
+ Py_XDECREF(tb);
+ Py_DECREF(et);
+ *pvalue = ev;
+ return 0;
+ }
+ }
+ PyErr_NormalizeException(&et, &ev, &tb);
+ if (unlikely(!PyObject_IsInstance(ev, PyExc_StopIteration))) {
+ __Pyx_ErrRestore(et, ev, tb);
+ return -1;
+ }
+ Py_XDECREF(tb);
+ Py_DECREF(et);
+#if PY_VERSION_HEX >= 0x030300A0
+ value = ((PyStopIterationObject *)ev)->value;
+ Py_INCREF(value);
+ Py_DECREF(ev);
+#else
+ {
+ PyObject* args = PyObject_GetAttr(ev, __pyx_n_s_args);
+ Py_DECREF(ev);
+ if (likely(args)) {
+ value = PyObject_GetItem(args, 0);
+ Py_DECREF(args);
+ }
+ if (unlikely(!value)) {
+ __Pyx_ErrRestore(NULL, NULL, NULL);
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+ }
+#endif
+ *pvalue = value;
+ return 0;
+}
+#endif
+static CYTHON_INLINE
+void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) {
+ PyObject *exc_type = self->exc_type;
+ PyObject *exc_value = self->exc_value;
+ PyObject *exc_traceback = self->exc_traceback;
+ self->exc_type = NULL;
+ self->exc_value = NULL;
+ self->exc_traceback = NULL;
+ Py_XDECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_traceback);
+}
+static CYTHON_INLINE
+int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) {
+ if (unlikely(gen->is_running)) {
+ PyErr_SetString(PyExc_ValueError,
+ "generator already executing");
+ return 1;
+ }
+ return 0;
+}
+static CYTHON_INLINE
+PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
+ PyObject *retval;
+ assert(!self->is_running);
+ if (unlikely(self->resume_label == 0)) {
+ if (unlikely(value && value != Py_None)) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't send non-None value to a "
+ "just-started generator");
+ return NULL;
+ }
+ }
+ if (unlikely(self->resume_label == -1)) {
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
+ }
+ if (value) {
+#if CYTHON_COMPILING_IN_PYPY
+#else
+ if (self->exc_traceback) {
+ PyThreadState *tstate = PyThreadState_GET();
+ PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
+ PyFrameObject *f = tb->tb_frame;
+ Py_XINCREF(tstate->frame);
+ assert(f->f_back == NULL);
+ f->f_back = tstate->frame;
+ }
+#endif
+ __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
+ &self->exc_traceback);
+ } else {
+ __Pyx_Generator_ExceptionClear(self);
+ }
+ self->is_running = 1;
+ retval = self->body((PyObject *) self, value);
+ self->is_running = 0;
+ if (retval) {
+ __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
+ &self->exc_traceback);
+#if CYTHON_COMPILING_IN_PYPY
+#else
+ if (self->exc_traceback) {
+ PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
+ PyFrameObject *f = tb->tb_frame;
+ Py_CLEAR(f->f_back);
+ }
+#endif
+ } else {
+ __Pyx_Generator_ExceptionClear(self);
+ }
+ return retval;
+}
+static CYTHON_INLINE
+PyObject *__Pyx_Generator_FinishDelegation(__pyx_GeneratorObject *gen) {
+ PyObject *ret;
+ PyObject *val = NULL;
+ __Pyx_Generator_Undelegate(gen);
+ __Pyx_PyGen_FetchStopIterationValue(&val);
+ ret = __Pyx_Generator_SendEx(gen, val);
+ Py_XDECREF(val);
+ return ret;
+}
+static PyObject *__Pyx_Generator_Next(PyObject *self) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
+ PyObject *yf = gen->yieldfrom;
+ if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+ return NULL;
+ if (yf) {
+ PyObject *ret;
+ gen->is_running = 1;
+ ret = Py_TYPE(yf)->tp_iternext(yf);
+ gen->is_running = 0;
+ if (likely(ret)) {
+ return ret;
+ }
+ return __Pyx_Generator_FinishDelegation(gen);
+ }
+ return __Pyx_Generator_SendEx(gen, Py_None);
+}
+static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
+ PyObject *yf = gen->yieldfrom;
+ if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+ return NULL;
+ if (yf) {
+ PyObject *ret;
+ gen->is_running = 1;
+ if (__Pyx_Generator_CheckExact(yf)) {
+ ret = __Pyx_Generator_Send(yf, value);
+ } else {
+ if (value == Py_None)
+ ret = PyIter_Next(yf);
+ else
+ ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value);
+ }
+ gen->is_running = 0;
+ if (likely(ret)) {
+ return ret;
+ }
+ return __Pyx_Generator_FinishDelegation(gen);
+ }
+ return __Pyx_Generator_SendEx(gen, value);
+}
+static int __Pyx_Generator_CloseIter(__pyx_GeneratorObject *gen, PyObject *yf) {
+ PyObject *retval = NULL;
+ int err = 0;
+ if (__Pyx_Generator_CheckExact(yf)) {
+ retval = __Pyx_Generator_Close(yf);
+ if (!retval)
+ return -1;
+ } else {
+ PyObject *meth;
+ gen->is_running = 1;
+ meth = PyObject_GetAttr(yf, __pyx_n_s_close);
+ if (unlikely(!meth)) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_WriteUnraisable(yf);
+ }
+ PyErr_Clear();
+ } else {
+ retval = PyObject_CallFunction(meth, NULL);
+ Py_DECREF(meth);
+ if (!retval)
+ err = -1;
+ }
+ gen->is_running = 0;
+ }
+ Py_XDECREF(retval);
+ return err;
+}
+static PyObject *__Pyx_Generator_Close(PyObject *self) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ PyObject *retval, *raised_exception;
+ PyObject *yf = gen->yieldfrom;
+ int err = 0;
+ if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+ return NULL;
+ if (yf) {
+ Py_INCREF(yf);
+ err = __Pyx_Generator_CloseIter(gen, yf);
+ __Pyx_Generator_Undelegate(gen);
+ Py_DECREF(yf);
+ }
+ if (err == 0)
+ PyErr_SetNone(PyExc_GeneratorExit);
+ retval = __Pyx_Generator_SendEx(gen, NULL);
+ if (retval) {
+ Py_DECREF(retval);
+ PyErr_SetString(PyExc_RuntimeError,
+ "generator ignored GeneratorExit");
+ return NULL;
+ }
+ raised_exception = PyErr_Occurred();
+ if (!raised_exception
+ || raised_exception == PyExc_StopIteration
+ || raised_exception == PyExc_GeneratorExit
+ || PyErr_GivenExceptionMatches(raised_exception, PyExc_GeneratorExit)
+ || PyErr_GivenExceptionMatches(raised_exception, PyExc_StopIteration))
+ {
+ if (raised_exception) PyErr_Clear();
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return NULL;
+}
+static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ PyObject *typ;
+ PyObject *tb = NULL;
+ PyObject *val = NULL;
+ PyObject *yf = gen->yieldfrom;
+ if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
+ return NULL;
+ if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+ return NULL;
+ if (yf) {
+ PyObject *ret;
+ Py_INCREF(yf);
+ if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
+ int err = __Pyx_Generator_CloseIter(gen, yf);
+ Py_DECREF(yf);
+ __Pyx_Generator_Undelegate(gen);
+ if (err < 0)
+ return __Pyx_Generator_SendEx(gen, NULL);
+ goto throw_here;
+ }
+ gen->is_running = 1;
+ if (__Pyx_Generator_CheckExact(yf)) {
+ ret = __Pyx_Generator_Throw(yf, args);
+ } else {
+ PyObject *meth = PyObject_GetAttr(yf, __pyx_n_s_throw);
+ if (unlikely(!meth)) {
+ Py_DECREF(yf);
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ gen->is_running = 0;
+ return NULL;
+ }
+ PyErr_Clear();
+ __Pyx_Generator_Undelegate(gen);
+ gen->is_running = 0;
+ goto throw_here;
+ }
+ ret = PyObject_CallObject(meth, args);
+ Py_DECREF(meth);
+ }
+ gen->is_running = 0;
+ Py_DECREF(yf);
+ if (!ret) {
+ ret = __Pyx_Generator_FinishDelegation(gen);
+ }
+ return ret;
+ }
+throw_here:
+ __Pyx_Raise(typ, val, tb, NULL);
+ return __Pyx_Generator_SendEx(gen, NULL);
+}
+static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ Py_VISIT(gen->closure);
+ Py_VISIT(gen->classobj);
+ Py_VISIT(gen->yieldfrom);
+ Py_VISIT(gen->exc_type);
+ Py_VISIT(gen->exc_value);
+ Py_VISIT(gen->exc_traceback);
+ return 0;
+}
+static int __Pyx_Generator_clear(PyObject *self) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ Py_CLEAR(gen->closure);
+ Py_CLEAR(gen->classobj);
+ Py_CLEAR(gen->yieldfrom);
+ Py_CLEAR(gen->exc_type);
+ Py_CLEAR(gen->exc_value);
+ Py_CLEAR(gen->exc_traceback);
+ Py_CLEAR(gen->gi_name);
+ Py_CLEAR(gen->gi_qualname);
+ return 0;
+}
+static void __Pyx_Generator_dealloc(PyObject *self) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ PyObject_GC_UnTrack(gen);
+ if (gen->gi_weakreflist != NULL)
+ PyObject_ClearWeakRefs(self);
+ if (gen->resume_label > 0) {
+ PyObject_GC_Track(self);
+#if PY_VERSION_HEX >= 0x030400a1
+ if (PyObject_CallFinalizerFromDealloc(self))
+#else
+ Py_TYPE(gen)->tp_del(self);
+ if (self->ob_refcnt > 0)
+#endif
+ {
+ return;
+ }
+ PyObject_GC_UnTrack(self);
+ }
+ __Pyx_Generator_clear(self);
+ PyObject_GC_Del(gen);
+}
+static void __Pyx_Generator_del(PyObject *self) {
+ PyObject *res;
+ PyObject *error_type, *error_value, *error_traceback;
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ if (gen->resume_label <= 0)
+ return ;
+#if PY_VERSION_HEX < 0x030400a1
+ assert(self->ob_refcnt == 0);
+ self->ob_refcnt = 1;
+#endif
+ __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
+ res = __Pyx_Generator_Close(self);
+ if (res == NULL)
+ PyErr_WriteUnraisable(self);
+ else
+ Py_DECREF(res);
+ __Pyx_ErrRestore(error_type, error_value, error_traceback);
+#if PY_VERSION_HEX < 0x030400a1
+ assert(self->ob_refcnt > 0);
+ if (--self->ob_refcnt == 0) {
+ return;
+ }
+ {
+ Py_ssize_t refcnt = self->ob_refcnt;
+ _Py_NewReference(self);
+ self->ob_refcnt = refcnt;
+ }
+#if CYTHON_COMPILING_IN_CPYTHON
+ assert(PyType_IS_GC(self->ob_type) &&
+ _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+ _Py_DEC_REFTOTAL;
+#endif
+#ifdef COUNT_ALLOCS
+ --Py_TYPE(self)->tp_frees;
+ --Py_TYPE(self)->tp_allocs;
+#endif
+#endif
+}
+static PyObject *
+__Pyx_Generator_get_name(__pyx_GeneratorObject *self)
+{
+ Py_INCREF(self->gi_name);
+ return self->gi_name;
+}
+static int
+__Pyx_Generator_set_name(__pyx_GeneratorObject *self, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__name__ must be set to a string object");
+ return -1;
+ }
+ tmp = self->gi_name;
+ Py_INCREF(value);
+ self->gi_name = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_Generator_get_qualname(__pyx_GeneratorObject *self)
+{
+ Py_INCREF(self->gi_qualname);
+ return self->gi_qualname;
+}
+static int
+__Pyx_Generator_set_qualname(__pyx_GeneratorObject *self, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__qualname__ must be set to a string object");
+ return -1;
+ }
+ tmp = self->gi_qualname;
+ Py_INCREF(value);
+ self->gi_qualname = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyGetSetDef __pyx_Generator_getsets[] = {
+ {(char *) "__name__", (getter)__Pyx_Generator_get_name, (setter)__Pyx_Generator_set_name,
+ (char*) PyDoc_STR("name of the generator"), 0},
+ {(char *) "__qualname__", (getter)__Pyx_Generator_get_qualname, (setter)__Pyx_Generator_set_qualname,
+ (char*) PyDoc_STR("qualified name of the generator"), 0},
+ {0, 0, 0, 0, 0}
+};
+static PyMemberDef __pyx_Generator_memberlist[] = {
+ {(char *) "gi_running", T_BOOL, offsetof(__pyx_GeneratorObject, is_running), READONLY, NULL},
+ {0, 0, 0, 0, 0}
+};
+static PyMethodDef __pyx_Generator_methods[] = {
+ {"send", (PyCFunction) __Pyx_Generator_Send, METH_O, 0},
+ {"throw", (PyCFunction) __Pyx_Generator_Throw, METH_VARARGS, 0},
+ {"close", (PyCFunction) __Pyx_Generator_Close, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+static PyTypeObject __pyx_GeneratorType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "generator",
+ sizeof(__pyx_GeneratorObject),
+ 0,
+ (destructor) __Pyx_Generator_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
+ 0,
+ (traverseproc) __Pyx_Generator_traverse,
+ 0,
+ 0,
+ offsetof(__pyx_GeneratorObject, gi_weakreflist),
+ 0,
+ (iternextfunc) __Pyx_Generator_Next,
+ __pyx_Generator_methods,
+ __pyx_Generator_memberlist,
+ __pyx_Generator_getsets,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#else
+ __Pyx_Generator_del,
+#endif
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ __Pyx_Generator_del,
+#endif
+};
+static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
+ PyObject *closure, PyObject *name, PyObject *qualname) {
+ __pyx_GeneratorObject *gen =
+ PyObject_GC_New(__pyx_GeneratorObject, &__pyx_GeneratorType_type);
+ if (gen == NULL)
+ return NULL;
+ gen->body = body;
+ gen->closure = closure;
+ Py_XINCREF(closure);
+ gen->is_running = 0;
+ gen->resume_label = 0;
+ gen->classobj = NULL;
+ gen->yieldfrom = NULL;
+ gen->exc_type = NULL;
+ gen->exc_value = NULL;
+ gen->exc_traceback = NULL;
+ gen->gi_weakreflist = NULL;
+ Py_XINCREF(qualname);
+ gen->gi_qualname = qualname;
+ Py_XINCREF(name);
+ gen->gi_name = name;
+ PyObject_GC_Track(gen);
+ return gen;
+}
+static int __pyx_Generator_init(void) {
+ __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr;
+ __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
+ __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
+ if (__pyx_GeneratorType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+ PyObject *py_name = 0;
+ PyObject *py_module = 0;
+ py_name = __Pyx_PyIdentifier_FromString(name);
+ if (!py_name)
+ goto bad;
+ py_module = PyImport_Import(py_name);
+ Py_DECREF(py_name);
+ return py_module;
+bad:
+ Py_XDECREF(py_name);
+ return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+ size_t size, int strict)
+{
+ PyObject *py_module = 0;
+ PyObject *result = 0;
+ PyObject *py_name = 0;
+ char warning[200];
+ Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+ PyObject *py_basicsize;
+#endif
+ py_module = __Pyx_ImportModule(module_name);
+ if (!py_module)
+ goto bad;
+ py_name = __Pyx_PyIdentifier_FromString(class_name);
+ if (!py_name)
+ goto bad;
+ result = PyObject_GetAttr(py_module, py_name);
+ Py_DECREF(py_name);
+ py_name = 0;
+ Py_DECREF(py_module);
+ py_module = 0;
+ if (!result)
+ goto bad;
+ if (!PyType_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.%.200s is not a type object",
+ module_name, class_name);
+ goto bad;
+ }
+#ifndef Py_LIMITED_API
+ basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+ py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+ if (!py_basicsize)
+ goto bad;
+ basicsize = PyLong_AsSsize_t(py_basicsize);
+ Py_DECREF(py_basicsize);
+ py_basicsize = 0;
+ if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+ goto bad;
+#endif
+ if (!strict && (size_t)basicsize > size) {
+ PyOS_snprintf(warning, sizeof(warning),
+ "%s.%s size changed, may indicate binary incompatibility",
+ module_name, class_name);
+ if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+ }
+ else if ((size_t)basicsize != size) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.%.200s has the wrong size, try recompiling",
+ module_name, class_name);
+ goto bad;
+ }
+ return (PyTypeObject *)result;
+bad:
+ Py_XDECREF(py_module);
+ Py_XDECREF(result);
+ return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/io/specfile/specfile.pyx b/silx/io/specfile/specfile.pyx
new file mode 100644
index 0000000..a465aa6
--- /dev/null
+++ b/silx/io/specfile/specfile.pyx
@@ -0,0 +1,1273 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""
+This module is a cython binding to wrap the C SpecFile library, to access
+SpecFile data within a python program.
+
+Documentation for the original C library SpecFile can be found on the ESRF
+website:
+`The manual for the SpecFile Library <http://www.esrf.eu/files/live/sites/www/files/Instrumentation/software/beamline-control/BLISS/documentation/SpecFileManual.pdf>`_
+
+Examples
+========
+
+Start by importing :class:`SpecFile` and instantiate it:
+
+.. code-block:: python
+
+ from silx.io.specfile import SpecFile
+
+ sf = SpecFile("test.dat")
+
+A :class:`SpecFile` instance can be accessed like a dictionary to obtain a
+:class:`Scan` instance.
+
+If the key is a string representing two values
+separated by a dot (e.g. ``"1.2"``), they will be treated as the scan number
+(``#S`` header line) and the scan order::
+
+ # get second occurrence of scan "#S 1"
+ myscan = sf["1.2"]
+
+ # access scan data as a numpy array
+ nlines, ncolumns = myscan.data.shape
+
+If the key is an integer, it will be treated as a 0-based index::
+
+ first_scan = sf[0]
+ second_scan = sf[1]
+
+It is also possible to browse through all scans using :class:`SpecFile` as
+an iterator::
+
+ for scan in sf:
+ print(scan.scan_header_dict['S'])
+
+MCA spectra can be selectively loaded using an instance of :class:`MCA`
+provided by :class:`Scan`::
+
+ # Only one MCA spectrum is loaded in memory
+ second_mca = first_scan.mca[1]
+
+ # Iterating trough all MCA spectra in a scan:
+ for mca_data in first_scan.mca:
+ print(sum(mca_data))
+
+Classes
+=======
+
+- :class:`SpecFile`
+- :class:`Scan`
+- :class:`MCA`
+
+Exceptions
+==========
+
+- :class:`SfError`
+- :class:`SfErrMemoryAlloc`
+- :class:`SfErrFileOpen`
+- :class:`SfErrFileClose`
+- :class:`SfErrFileRead`
+- :class:`SfErrFileWrite`
+- :class:`SfErrLineNotFound`
+- :class:`SfErrScanNotFound`
+- :class:`SfErrHeaderNotFound`
+- :class:`SfErrLabelNotFound`
+- :class:`SfErrMotorNotFound`
+- :class:`SfErrPositionNotFound`
+- :class:`SfErrLineEmpty`
+- :class:`SfErrUserNotFound`
+- :class:`SfErrColNotFound`
+- :class:`SfErrMcaNotFound`
+
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "27/09/2016"
+
+import os.path
+import logging
+import numpy
+import re
+import sys
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+cimport numpy
+cimport cython
+from libc.stdlib cimport free
+
+cimport specfile_wrapper
+
+# hack to avoid C compiler warnings about unused functions in the NumPy header files
+# Sources: Cython test suite.
+cdef extern from *:
+ bint FALSE "0"
+ void import_array()
+ void import_umath()
+
+if FALSE:
+ import_array()
+ import_umath()
+
+numpy.import_array()
+
+
+SF_ERR_NO_ERRORS = 0
+SF_ERR_FILE_OPEN = 2
+SF_ERR_SCAN_NOT_FOUND = 7
+
+
+# custom errors
+class SfError(Exception):
+ """Base exception inherited by all exceptions raised when a
+ C function from the legacy SpecFile library returns an error
+ code.
+ """
+ pass
+
+class SfErrMemoryAlloc(SfError): pass
+class SfErrFileOpen(SfError): pass
+class SfErrFileClose(SfError): pass
+class SfErrFileRead(SfError): pass
+class SfErrFileWrite(SfError): pass
+class SfErrLineNotFound(SfError): pass
+class SfErrScanNotFound(SfError): pass
+class SfErrHeaderNotFound(SfError): pass
+class SfErrLabelNotFound(SfError): pass
+class SfErrMotorNotFound(SfError): pass
+class SfErrPositionNotFound(SfError): pass
+class SfErrLineEmpty(SfError): pass
+class SfErrUserNotFound(SfError): pass
+class SfErrColNotFound(SfError): pass
+class SfErrMcaNotFound(SfError): pass
+
+
+ERRORS = {
+ 1: SfErrMemoryAlloc,
+ 2: SfErrFileOpen,
+ 3: SfErrFileClose,
+ 4: SfErrFileRead,
+ 5: SfErrFileWrite,
+ 6: SfErrLineNotFound,
+ 7: SfErrScanNotFound,
+ 8: SfErrHeaderNotFound,
+ 9: SfErrLabelNotFound,
+ 10: SfErrMotorNotFound,
+ 11: SfErrPositionNotFound,
+ 12: SfErrLineEmpty,
+ 13: SfErrUserNotFound,
+ 14: SfErrColNotFound,
+ 15: SfErrMcaNotFound,
+}
+
+
+class SfNoMcaError(SfError):
+ """Custom exception raised when ``SfNoMca()`` returns ``-1``
+ """
+ pass
+
+
+class MCA(object):
+ """
+
+ :param scan: Parent Scan instance
+ :type scan: :class:`Scan`
+
+ :var calibration: MCA calibration :math:`(a, b, c)` (as in
+ :math:`a + b x + c x²`) from ``#@CALIB`` scan header.
+ :type calibration: list of 3 floats, default ``[0., 1., 0.]``
+ :var channels: MCA channels list from ``#@CHANN`` scan header.
+ In the absence of a ``#@CHANN`` header, this attribute is a list
+ ``[0, …, N-1]`` where ``N`` is the length of the first spectrum.
+ In the absence of MCA spectra, this attribute defaults to ``None``.
+ :type channels: list of int
+
+ This class provides access to Multi-Channel Analysis data. A :class:`MCA`
+ instance can be indexed to access 1D numpy arrays representing single
+ MCA spectra.
+
+ To create a :class:`MCA` instance, you must provide a parent :class:`Scan`
+ instance, which in turn will provide a reference to the original
+ :class:`SpecFile` instance::
+
+ sf = SpecFile("/path/to/specfile.dat")
+ scan2 = Scan(sf, scan_index=2)
+ mcas_in_scan2 = MCA(scan2)
+ for i in len(mcas_in_scan2):
+ mca_data = mcas_in_scan2[i]
+ ... # do some something with mca_data (1D numpy array)
+
+ A more pythonic way to do the same work, without having to explicitly
+ instantiate ``scan`` and ``mcas_in_scan``, would be::
+
+ sf = SpecFile("specfilename.dat")
+ # scan2 from previous example can be referred to as sf[2]
+ # mcas_in_scan2 from previous example can be referred to as scan2.mca
+ for mca_data in sf[2].mca:
+ ... # do some something with mca_data (1D numpy array)
+
+ """
+ def __init__(self, scan):
+ self._scan = scan
+
+ # Header dict
+ self._header = scan.mca_header_dict
+
+ self.calibration = []
+ """List of lists of calibration values,
+ one list of 3 floats per MCA device or a single list applying to
+ all devices """
+ self._parse_calibration()
+
+ self.channels = []
+ """List of lists of channels,
+ one list of integers per MCA device or a single list applying to
+ all devices"""
+ self._parse_channels()
+
+ def _parse_channels(self):
+ """Fill :attr:`channels`"""
+ # Channels list
+ if "CHANN" in self._header:
+ chann_lines = self._header["CHANN"].split("\n")
+ all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ for one_line_chann_values in all_chann_values:
+ length, start, stop, increment = map(int, one_line_chann_values)
+ self.channels.append(list(range(start, stop + 1, increment)))
+ elif len(self):
+ # in the absence of #@CHANN, use shape of first MCA
+ length = self[0].shape[0]
+ start, stop, increment = (0, length - 1, 1)
+ self.channels.append(list(range(start, stop + 1, increment)))
+
+ def _parse_calibration(self):
+ """Fill :attr:`calibration`"""
+ # Channels list
+ if "CALIB" in self._header:
+ calib_lines = self._header["CALIB"].split("\n")
+ all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ for one_line_calib_values in all_calib_values:
+ self.calibration.append(list(map(float, one_line_calib_values)))
+ else:
+ # in the absence of #@calib, use default
+ self.calibration.append([0., 1., 0.])
+
+ def __len__(self):
+ """
+
+ :return: Number of mca in Scan
+ :rtype: int
+ """
+ return self._scan._specfile.number_of_mca(self._scan.index)
+
+ def __getitem__(self, key):
+ """Return a single MCA data line
+
+ :param key: 0-based index of MCA within Scan
+ :type key: int
+
+ :return: Single MCA
+ :rtype: 1D numpy array
+ """
+ if not len(self):
+ raise IndexError("No MCA spectrum found in this scan")
+
+ if isinstance(key, int):
+ mca_index = key
+ # allow negative index, like lists
+ if mca_index < 0:
+ mca_index = len(self) + mca_index
+ else:
+ raise TypeError("MCA index should be an integer (%s provided)" %
+ (type(key)))
+
+ if not 0 <= mca_index < len(self):
+ msg = "MCA index must be in range 0-%d" % (len(self) - 1)
+ raise IndexError(msg)
+
+ return self._scan._specfile.get_mca(self._scan.index,
+ mca_index)
+
+ def __iter__(self):
+ """Return the next MCA data line each time this method is called.
+
+ :return: Single MCA
+ :rtype: 1D numpy array
+ """
+ for mca_index in range(len(self)):
+ yield self._scan._specfile.get_mca(self._scan.index, mca_index)
+
+
+def _add_or_concatenate(dictionary, key, value):
+ """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ Else append/concatenate the new value to the existing one
+ """
+ try:
+ if not key in dictionary:
+ dictionary[key] = value
+ else:
+ dictionary[key] += "\n" + value
+ except TypeError:
+ raise TypeError("Parameter value must be a string.")
+
+
+class Scan(object):
+ """
+
+ :param specfile: Parent SpecFile from which this scan is extracted.
+ :type specfile: :class:`SpecFile`
+ :param scan_index: Unique index defining the scan in the SpecFile
+ :type scan_index: int
+
+ Interface to access a SpecFile scan
+
+ A scan is a block of descriptive header lines followed by a 2D data array.
+
+ Following three ways of accessing a scan are equivalent::
+
+ sf = SpecFile("/path/to/specfile.dat")
+
+ # Explicit class instantiation
+ scan2 = Scan(sf, scan_index=2)
+
+ # 0-based index on a SpecFile object
+ scan2 = sf[2]
+
+ # Using a "n.m" key (scan number starting with 1, scan order)
+ scan2 = sf["3.1"]
+ """
+ def __init__(self, specfile, scan_index):
+ self._specfile = specfile
+
+ self._index = scan_index
+ self._number = specfile.number(scan_index)
+ self._order = specfile.order(scan_index)
+
+ self._scan_header_lines = self._specfile.scan_header(self._index)
+ self._file_header_lines = self._specfile.file_header(self._index)
+
+ if self._file_header_lines == self._scan_header_lines:
+ self._file_header_lines = []
+ self._header = self._file_header_lines + self._scan_header_lines
+
+ self._scan_header_dict = {}
+ self._mca_header_dict = {}
+ for line in self._scan_header_lines:
+ match = re.search(r"#(\w+) *(.*)", line)
+ match_mca = re.search(r"#@(\w+) *(.*)", line)
+ if match:
+ hkey = match.group(1).lstrip("#").strip()
+ hvalue = match.group(2).strip()
+ _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ elif match_mca:
+ hkey = match_mca.group(1).lstrip("#").strip()
+ hvalue = match_mca.group(2).strip()
+ _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ else:
+ # this shouldn't happen
+ _logger.warning("Unable to parse scan header line " + line)
+
+ self._labels = []
+ if self.record_exists_in_hdr('L'):
+ try:
+ self._labels = self._specfile.labels(self._index)
+ except SfErrLineNotFound:
+ # SpecFile.labels raises an IndexError when encountering
+ # a Scan with no data, even if the header exists.
+ L_header = re.sub(r" {2,}", " ", # max. 2 spaces
+ self._scan_header_dict["L"])
+ self._labels = L_header.split(" ")
+
+
+ self._file_header_dict = {}
+ for line in self._file_header_lines:
+ match = re.search(r"#(\w+) *(.*)", line)
+ if match:
+ # header type
+ hkey = match.group(1).lstrip("#").strip()
+ hvalue = match.group(2).strip()
+ _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ else:
+ _logger.warning("Unable to parse file header line " + line)
+
+ self._motor_names = self._specfile.motor_names(self._index)
+ self._motor_positions = self._specfile.motor_positions(self._index)
+
+ self._data = None
+ self._mca = None
+
+ @cython.embedsignature(False)
+ @property
+ def index(self):
+ """Unique scan index 0 - len(specfile)-1
+
+ This attribute is implemented as a read-only property as changing
+ its value may cause nasty side-effects (such as loading data from a
+ different scan without updating the header accordingly."""
+ return self._index
+
+ @cython.embedsignature(False)
+ @property
+ def number(self):
+ """First value on #S line (as int)"""
+ return self._number
+
+ @cython.embedsignature(False)
+ @property
+ def order(self):
+ """Order can be > 1 if the same number is repeated in a specfile"""
+ return self._order
+
+ @cython.embedsignature(False)
+ @property
+ def header(self):
+ """List of raw header lines (as a list of strings).
+
+ This includes the file header, the scan header and possibly a MCA
+ header.
+ """
+ return self._header
+
+ @cython.embedsignature(False)
+ @property
+ def scan_header(self):
+ """List of raw scan header lines (as a list of strings).
+ """
+ return self._scan_header_lines
+
+ @cython.embedsignature(False)
+ @property
+ def file_header(self):
+ """List of raw file header lines (as a list of strings).
+ """
+ return self._file_header_lines
+
+ @cython.embedsignature(False)
+ @property
+ def scan_header_dict(self):
+ """
+ Dictionary of scan header strings, keys without the leading``#``
+ (e.g. ``scan_header_dict["S"]``).
+ Note: this does not include MCA header lines starting with ``#@``.
+ """
+ return self._scan_header_dict
+
+ @cython.embedsignature(False)
+ @property
+ def mca_header_dict(self):
+ """
+ Dictionary of MCA header strings, keys without the leading ``#@``
+ (e.g. ``mca_header_dict["CALIB"]``).
+ """
+ return self._mca_header_dict
+
+ @cython.embedsignature(False)
+ @property
+ def file_header_dict(self):
+ """
+ Dictionary of file header strings, keys without the leading ``#``
+ (e.g. ``file_header_dict["F"]``).
+ """
+ return self._file_header_dict
+
+ @cython.embedsignature(False)
+ @property
+ def labels(self):
+ """
+ List of data column headers from ``#L`` scan header
+ """
+ return self._labels
+
+ @cython.embedsignature(False)
+ @property
+ def data(self):
+ """Scan data as a 2D numpy.ndarray with the usual attributes
+ (e.g. data.shape).
+
+ The first index is the detector, the second index is the sample index.
+ """
+ if self._data is None:
+ self._data = numpy.transpose(self._specfile.data(self._index))
+
+ return self._data
+
+ @cython.embedsignature(False)
+ @property
+ def mca(self):
+ """MCA data in this scan.
+
+ Each multichannel analysis is a 1D numpy array. Metadata about
+ MCA data is to be found in :py:attr:`mca_header`.
+
+ :rtype: :class:`MCA`
+ """
+ if self._mca is None:
+ self._mca = MCA(self)
+ return self._mca
+
+ @cython.embedsignature(False)
+ @property
+ def motor_names(self):
+ """List of motor names from the ``#O`` file header line.
+ """
+ return self._motor_names
+
+ @cython.embedsignature(False)
+ @property
+ def motor_positions(self):
+ """List of motor positions as floats from the ``#P`` scan header line.
+ """
+ return self._motor_positions
+
+ def record_exists_in_hdr(self, record):
+ """Check whether a scan header line exists.
+
+ This should be used before attempting to retrieve header information
+ using a C function that may crash with a *segmentation fault* if the
+ header isn't defined in the SpecFile.
+
+ :param record: single upper case letter corresponding to the
+ header you want to test (e.g. ``L`` for labels)
+ :type record: str
+
+ :return: True or False
+ :rtype: boolean
+ """
+ for line in self._header:
+ if line.startswith("#" + record):
+ return True
+ return False
+
+ def data_line(self, line_index):
+ """Returns data for a given line of this scan.
+
+ .. note::
+
+ A data line returned by this method, corresponds to a data line
+ in the original specfile (a series of data points, one per
+ detector). In the :attr:`data` array, this line index corresponds
+ to the index in the second dimension (~ column) of the array.
+
+ :param line_index: Index of data line to retrieve (starting with 0)
+ :type line_index: int
+
+ :return: Line data as a 1D array of doubles
+ :rtype: numpy.ndarray
+ """
+ # attribute data corresponds to a transposed version of the original
+ # specfile data (where detectors correspond to columns)
+ return self.data[:, line_index]
+
+ def data_column_by_name(self, label):
+ """Returns a data column
+
+ :param label: Label of data column to retrieve, as defined on the
+ ``#L`` line of the scan header.
+ :type label: str
+
+ :return: Line data as a 1D array of doubles
+ :rtype: numpy.ndarray
+ """
+ try:
+ ret = self._specfile.data_column_by_name(self._index, label)
+ except SfErrLineNotFound:
+ # Could be a "#C Scan aborted after 0 points"
+ _logger.warning("Cannot get data column %s in scan %d.%d",
+ label, self.number, self.order)
+ ret = numpy.empty((0, ), numpy.double)
+ return ret
+
+
+ def motor_position_by_name(self, name):
+ """Returns the position for a given motor
+
+ :param name: Name of motor, as defined on the ``#O`` line of the
+ file header.
+ :type name: str
+
+ :return: Motor position
+ :rtype: float
+ """
+ return self._specfile.motor_position_by_name(self._index, name)
+
+
+def _string_to_char_star(string_):
+ """Convert a string to ASCII encoded bytes when using python3"""
+ if sys.version.startswith("3") and not isinstance(string_, bytes):
+ return bytes(string_, "ascii")
+ return string_
+
+
+def is_specfile(filename):
+ """Test if a file is a SPEC file, by checking if one of the first two
+ lines starts with *#F* (SPEC file header) or *#S* (scan header).
+
+ :param str filename: File path
+ :return: *True* if file is a SPEC file, *False* if it is not a SPEC file
+ :rtype: bool
+ """
+ if not os.path.isfile(filename):
+ return False
+ # test for presence of #S or #F in first two lines
+ f = open(filename)
+ for i, line in enumerate(f):
+ if line.startswith("#S ") or line.startswith("#F "):
+ f.close()
+ return True
+ if i >= 10:
+ break
+ f.close()
+ return False
+
+
+cdef class SpecFile(object):
+ """
+
+ :param filename: Path of the SpecFile to read
+
+ This class wraps the main data and header access functions of the C
+ SpecFile library.
+ """
+
+ cdef:
+ specfile_wrapper.SpecFileHandle *handle
+ str filename
+ int __open_failed
+
+ def __cinit__(self, filename):
+ cdef int error = SF_ERR_NO_ERRORS
+ self.__open_failed = 0
+
+ if is_specfile(filename):
+ filename = _string_to_char_star(filename)
+ self.handle = specfile_wrapper.SfOpen(filename, &error)
+ else:
+ self.__open_failed = 1
+ self._handle_error(SF_ERR_FILE_OPEN)
+ if error:
+ self.__open_failed = 1
+ self._handle_error(error)
+
+ def __init__(self, filename):
+ if not isinstance(filename, str):
+ # encode unicode to str in python 2
+ if sys.version_info[0] < 3:
+ self.filename = filename.encode()
+ # decode bytes to str in python 3
+ elif sys.version_info[0] >= 3:
+ self.filename = filename.decode()
+ else:
+ self.filename = filename
+
+ def __dealloc__(self):
+ """Destructor: Calls SfClose(self.handle)"""
+ #SfClose makes a segmentation fault if file failed to open
+ if not self.__open_failed:
+ if specfile_wrapper.SfClose(self.handle):
+ _logger.warning("Error while closing SpecFile")
+
+ def __len__(self):
+ """Return the number of scans in the SpecFile
+ """
+ return specfile_wrapper.SfScanNo(self.handle)
+
+ def __iter__(self):
+ """Return the next :class:`Scan` in a SpecFile each time this method
+ is called.
+
+ This usually happens when the python built-in function ``next()`` is
+ called with a :class:`SpecFile` instance as a parameter, or when a
+ :class:`SpecFile` instance is used as an iterator (e.g. in a ``for``
+ loop).
+ """
+ for scan_index in range(len(self)):
+ yield Scan(self, scan_index)
+
+ def __getitem__(self, key):
+ """Return a :class:`Scan` object.
+
+ This special method is called when a :class:`SpecFile` instance is
+ accessed as a dictionary (e.g. ``sf[key]``).
+
+ :param key: 0-based scan index or ``"n.m"`` key, where ``n`` is the scan
+ number defined on the ``#S`` header line and ``m`` is the order
+ :type key: int or str
+
+ :return: Scan defined by its 0-based index or its ``"n.m"`` key
+ :rtype: :class:`Scan`
+ """
+ msg = "The scan identification key can be an integer representing "
+ msg += "the unique scan index or a string 'N.M' with N being the scan"
+ msg += " number and M the order (eg '2.3')."
+
+ if isinstance(key, int):
+ scan_index = key
+ # allow negative index, like lists
+ if scan_index < 0:
+ scan_index = len(self) + scan_index
+ else:
+ try:
+ (number, order) = map(int, key.split("."))
+ scan_index = self.index(number, order)
+ except (ValueError, SfErrScanNotFound, KeyError):
+ # int() can raise a value error
+ raise KeyError(msg + "\nValid keys: '" +
+ "', '".join( self.keys()) + "'")
+ except AttributeError:
+ # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ raise TypeError(msg)
+
+ if not 0 <= scan_index < len(self):
+ msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ raise IndexError(msg)
+
+ return Scan(self, scan_index)
+
+ def keys(self):
+ """Returns list of scan keys (eg ``['1.1', '2.1',...]``).
+
+ :return: list of scan keys
+ :rtype: list of strings
+ """
+ ret_list = []
+ list_of_numbers = self._list()
+ count = {}
+
+ for number in list_of_numbers:
+ if not number in count:
+ count[number] = 1
+ else:
+ count[number] += 1
+ ret_list.append(u'%d.%d' % (number, count[number]))
+
+ return ret_list
+
+ def __contains__(self, key):
+ """Return ``True`` if ``key`` is a valid scan key.
+ Valid keys can be a string such as ``"1.1"`` or a 0-based scan index.
+ """
+ return key in (self.keys() + list(range(len(self))))
+
+ def _get_error_string(self, error_code):
+ """Returns the error message corresponding to the error code.
+
+ :param code: Error code
+ :type code: int
+ :return: Human readable error message
+ :rtype: str
+ """
+ return (<bytes> specfile_wrapper.SfError(error_code)).decode()
+
+ def _handle_error(self, error_code):
+ """Inspect error code, raise adequate error type if necessary.
+
+ :param code: Error code
+ :type code: int
+ """
+ error_message = self._get_error_string(error_code)
+ if error_code in ERRORS:
+ raise ERRORS[error_code](error_message)
+
+ def index(self, scan_number, scan_order=1):
+ """Returns scan index from scan number and order.
+
+ :param scan_number: Scan number (possibly non-unique).
+ :type scan_number: int
+ :param scan_order: Scan order.
+ :type scan_order: int default 1
+
+ :return: Unique scan index
+ :rtype: int
+
+
+ Scan indices are increasing from ``0`` to ``len(self)-1`` in the
+ order in which they appear in the file.
+ Scan numbers are defined by users and are not necessarily unique.
+ The scan order for a given scan number increments each time the scan
+ number appers in a given file.
+ """
+ idx = specfile_wrapper.SfIndex(self.handle, scan_number, scan_order)
+ if idx == -1:
+ self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ return idx - 1
+
+ def number(self, scan_index):
+ """Returns scan number from scan index.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: User defined scan number.
+ :rtype: int
+ """
+ idx = specfile_wrapper.SfNumber(self.handle, scan_index + 1)
+ if idx == -1:
+ self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ return idx
+
+ def order(self, scan_index):
+ """Returns scan order from scan index.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Scan order (sequential number incrementing each time a
+ non-unique occurrence of a scan number is encountered).
+ :rtype: int
+ """
+ ordr = specfile_wrapper.SfOrder(self.handle, scan_index + 1)
+ if ordr == -1:
+ self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ return ordr
+
+ def _list(self):
+ """see documentation of :meth:`list`
+ """
+ cdef:
+ long *scan_numbers
+ int error = SF_ERR_NO_ERRORS
+
+ scan_numbers = specfile_wrapper.SfList(self.handle, &error)
+ self._handle_error(error)
+
+ ret_list = []
+ for i in range(len(self)):
+ ret_list.append(scan_numbers[i])
+
+ free(scan_numbers)
+ return ret_list
+
+ def list(self):
+ """Returns list (1D numpy array) of scan numbers in SpecFile.
+
+ :return: list of scan numbers (from `` #S`` lines) in the same order
+ as in the original SpecFile (e.g ``[1, 1, 2, 3, …]``).
+ :rtype: numpy array
+ """
+ # this method is overloaded in specfilewrapper to output a string
+ # representation of the list
+ return self._list()
+
+ def data(self, scan_index):
+ """Returns data for the specified scan index.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Complete scan data as a 2D array of doubles
+ :rtype: numpy.ndarray
+ """
+ cdef:
+ double** mydata
+ long* data_info
+ int i, j
+ int error = SF_ERR_NO_ERRORS
+ long nlines, ncolumns, regular
+
+ sfdata_error = specfile_wrapper.SfData(self.handle,
+ scan_index + 1,
+ &mydata,
+ &data_info,
+ &error)
+ self._handle_error(error)
+
+ if <long>data_info != 0:
+ nlines = data_info[0]
+ ncolumns = data_info[1]
+ regular = data_info[2]
+ else:
+ nlines = 0
+ ncolumns = 0
+ regular = 0
+
+ cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns),
+ dtype=numpy.double)
+ for i in range(nlines):
+ for j in range(ncolumns):
+ ret_array[i, j] = mydata[i][j]
+
+ specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines)
+ free(data_info)
+ return ret_array
+
+ def data_column_by_name(self, scan_index, label):
+ """Returns data column for the specified scan index and column label.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+ :param label: Label of data column, as defined in the ``#L`` line
+ of the scan header.
+ :type label: str
+
+ :return: Data column as a 1D array of doubles
+ :rtype: numpy.ndarray
+ """
+ cdef:
+ double* data_column
+ long i, nlines
+ int error = SF_ERR_NO_ERRORS
+
+ label = _string_to_char_star(label)
+
+ nlines = specfile_wrapper.SfDataColByName(self.handle,
+ scan_index + 1,
+ label,
+ &data_column,
+ &error)
+ self._handle_error(error)
+
+ cdef numpy.ndarray ret_array = numpy.empty((nlines,),
+ dtype=numpy.double)
+ for i in range(nlines):
+ ret_array[i] = data_column[i]
+
+ free(data_column)
+ return ret_array
+
+ def scan_header(self, scan_index):
+ """Return list of scan header lines.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: List of raw scan header lines
+ :rtype: list of str
+ """
+ cdef:
+ char** lines
+ int error = SF_ERR_NO_ERRORS
+
+ nlines = specfile_wrapper.SfHeader(self.handle,
+ scan_index + 1,
+ "", # no pattern matching
+ &lines,
+ &error)
+
+ self._handle_error(error)
+
+ lines_list = []
+ for i in range(nlines):
+ line = <bytes>lines[i].decode()
+ lines_list.append(line)
+
+ specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ return lines_list
+
+ def file_header(self, scan_index=0):
+ """Return list of file header lines.
+
+ A file header contains all lines between a ``#F`` header line and
+ a ``#S`` header line (start of scan). We need to specify a scan
+ number because there can be more than one file header in a given file.
+ A file header applies to all subsequent scans, until a new file
+ header is defined.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: List of raw file header lines
+ :rtype: list of str
+ """
+ cdef:
+ char** lines
+ int error = SF_ERR_NO_ERRORS
+
+ nlines = specfile_wrapper.SfFileHeader(self.handle,
+ scan_index + 1,
+ "", # no pattern matching
+ &lines,
+ &error)
+ self._handle_error(error)
+
+ lines_list = []
+ for i in range(nlines):
+ line = <bytes>lines[i].decode()
+ lines_list.append(line)
+
+ specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ return lines_list
+
+ def columns(self, scan_index):
+ """Return number of columns in a scan from the ``#N`` header line
+ (without ``#N`` and scan number)
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Number of columns in scan from ``#N`` line
+ :rtype: int
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ ncolumns = specfile_wrapper.SfNoColumns(self.handle,
+ scan_index + 1,
+ &error)
+ self._handle_error(error)
+
+ return ncolumns
+
+ def command(self, scan_index):
+ """Return ``#S`` line (without ``#S`` and scan number)
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: S line
+ :rtype: str
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ s_record = <bytes> specfile_wrapper.SfCommand(self.handle,
+ scan_index + 1,
+ &error)
+ self._handle_error(error)
+
+ return s_record.decode()
+
+ def date(self, scan_index=0):
+ """Return date from ``#D`` line
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Date from ``#D`` line
+ :rtype: str
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ d_line = <bytes> specfile_wrapper.SfDate(self.handle,
+ scan_index + 1,
+ &error)
+ self._handle_error(error)
+
+ return d_line.decode()
+
+ def labels(self, scan_index):
+ """Return all labels from ``#L`` line
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: All labels from ``#L`` line
+ :rtype: list of strings
+ """
+ cdef:
+ char** all_labels
+ int error = SF_ERR_NO_ERRORS
+
+ nlabels = specfile_wrapper.SfAllLabels(self.handle,
+ scan_index + 1,
+ &all_labels,
+ &error)
+ self._handle_error(error)
+
+ labels_list = []
+ for i in range(nlabels):
+ labels_list.append(<bytes>all_labels[i].decode())
+
+ specfile_wrapper.freeArrNZ(<void***>&all_labels, nlabels)
+ return labels_list
+
+ def motor_names(self, scan_index=0):
+ """Return all motor names from ``#O`` lines
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.If not specified, defaults to 0 (meaning the
+ function returns motors names associated with the first scan).
+ This parameter makes a difference only if there are more than
+ on file header in the file, in which case the file header applies
+ to all following scans until a new file header appears.
+ :type scan_index: int
+
+ :return: All motor names
+ :rtype: list of strings
+ """
+ cdef:
+ char** all_motors
+ int error = SF_ERR_NO_ERRORS
+
+ nmotors = specfile_wrapper.SfAllMotors(self.handle,
+ scan_index + 1,
+ &all_motors,
+ &error)
+ self._handle_error(error)
+
+ motors_list = []
+ for i in range(nmotors):
+ motors_list.append(<bytes>all_motors[i].decode())
+
+ specfile_wrapper.freeArrNZ(<void***>&all_motors, nmotors)
+ return motors_list
+
+ def motor_positions(self, scan_index):
+ """Return all motor positions
+
+ :param scan_index: Unique scan index between ``0``
+ and ``len(self)-1``.
+ :type scan_index: int
+
+ :return: All motor positions
+ :rtype: list of double
+ """
+ cdef:
+ double* motor_positions
+ int error = SF_ERR_NO_ERRORS
+
+ nmotors = specfile_wrapper.SfAllMotorPos(self.handle,
+ scan_index + 1,
+ &motor_positions,
+ &error)
+ self._handle_error(error)
+
+ motor_positions_list = []
+ for i in range(nmotors):
+ motor_positions_list.append(motor_positions[i])
+
+ free(motor_positions)
+ return motor_positions_list
+
+ def motor_position_by_name(self, scan_index, name):
+ """Return motor position
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Specified motor position
+ :rtype: double
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ name = _string_to_char_star(name)
+
+ motor_position = specfile_wrapper.SfMotorPosByName(self.handle,
+ scan_index + 1,
+ name,
+ &error)
+ self._handle_error(error)
+
+ return motor_position
+
+ def number_of_mca(self, scan_index):
+ """Return number of mca spectra in a scan.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Number of mca spectra.
+ :rtype: int
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ num_mca = specfile_wrapper.SfNoMca(self.handle,
+ scan_index + 1,
+ &error)
+ # error code updating isn't implemented in SfNoMCA
+ if num_mca == -1:
+ raise SfNoMcaError("Failed to retrieve number of MCA " +
+ "(SfNoMca returned -1)")
+ return num_mca
+
+ def mca_calibration(self, scan_index):
+ """Return MCA calibration in the form :math:`a + b x + c x²`
+
+ Raise a KeyError if there is no ``@CALIB`` line in the scan header.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: MCA calibration as a list of 3 values :math:`(a, b, c)`
+ :rtype: list of floats
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+ double* mca_calib
+
+ mca_calib_error = specfile_wrapper.SfMcaCalib(self.handle,
+ scan_index + 1,
+ &mca_calib,
+ &error)
+
+ # error code updating isn't implemented in SfMcaCalib
+ if mca_calib_error:
+ raise KeyError("MCA calibration line (@CALIB) not found")
+
+ mca_calib_list = []
+ for i in range(3):
+ mca_calib_list.append(mca_calib[i])
+
+ free(mca_calib)
+ return mca_calib_list
+
+ def get_mca(self, scan_index, mca_index):
+ """Return one MCA spectrum
+
+ :param scan_index: Unique scan index between ``0`` and ``len(self)-1``.
+ :type scan_index: int
+ :param mca_index: Index of MCA in the scan
+ :type mca_index: int
+
+ :return: MCA spectrum
+ :rtype: 1D numpy array
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+ double* mca_data
+ long len_mca
+
+ len_mca = specfile_wrapper.SfGetMca(self.handle,
+ scan_index + 1,
+ mca_index + 1,
+ &mca_data,
+ &error)
+ self._handle_error(error)
+
+
+ cdef numpy.ndarray ret_array = numpy.empty((len_mca,),
+ dtype=numpy.double)
+ for i in range(len_mca):
+ ret_array[i] = mca_data[i]
+
+ free(mca_data)
+ return ret_array
diff --git a/silx/io/specfile/specfile_wrapper.pxd b/silx/io/specfile/specfile_wrapper.pxd
new file mode 100644
index 0000000..6770f7e
--- /dev/null
+++ b/silx/io/specfile/specfile_wrapper.pxd
@@ -0,0 +1,77 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "17/03/2016"
+
+cimport cython
+
+cdef extern from "SpecFileCython.h":
+ struct _SpecFile:
+ pass
+# Renaming struct because we have too many SpecFile items (files, classes…)
+ctypedef _SpecFile SpecFileHandle
+
+cdef extern from "SpecFileCython.h":
+ # sfinit
+ SpecFileHandle* SfOpen(char*, int*)
+ int SfClose(SpecFileHandle*)
+ char* SfError(int)
+
+ # sfindex
+ long* SfList(SpecFileHandle*, int*)
+ long SfScanNo(SpecFileHandle*)
+ long SfIndex(SpecFileHandle*, long, long)
+ long SfNumber(SpecFileHandle*, long)
+ long SfOrder(SpecFileHandle*, long)
+
+ # sfdata
+ int SfData(SpecFileHandle*, long, double***, long**, int*)
+ long SfDataLine(SpecFileHandle*, long, long, double**, int*)
+ long SfDataColByName(SpecFileHandle*, long, char*, double**, int*)
+
+ # sfheader
+ #char* SfTitle(SpecFileHandle*, long, int*)
+ long SfHeader(SpecFileHandle*, long, char*, char***, int*)
+ long SfFileHeader(SpecFileHandle*, long, char*, char***, int*)
+ char* SfCommand(SpecFileHandle*, long, int*)
+ long SfNoColumns(SpecFileHandle*, long, int*)
+ char* SfDate(SpecFileHandle*, long, int*)
+
+ # sflabel
+ long SfAllLabels(SpecFileHandle*, long, char***, int*)
+ char* SfLabel(SpecFileHandle*, long, long, int *)
+ long SfAllMotors(SpecFileHandle*, long, char***, int*)
+ long SfAllMotorPos(SpecFileHandle*, long, double**, int*)
+ double SfMotorPosByName(SpecFileHandle*, long, char*, int*)
+
+ # sftools
+ void freeArrNZ(void***, long)
+
+ # sfmca
+ long SfNoMca(SpecFileHandle*, long, int*)
+ int SfGetMca(SpecFileHandle*, long, long , double**, int*)
+ long SfMcaCalib(SpecFileHandle*, long, double**, int*)
+
diff --git a/silx/io/specfile/src/locale_management.c b/silx/io/specfile/src/locale_management.c
new file mode 100644
index 0000000..1e6a196
--- /dev/null
+++ b/silx/io/specfile/src/locale_management.c
@@ -0,0 +1,64 @@
+#/*##########################################################################
+# Copyright (C) 2012-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+#include <locale_management.h>
+#include <stdlib.h>
+
+#ifdef _GNU_SOURCE
+#include <xlocale.h>
+#include <locale.h>
+#else
+#ifdef PYMCA_POSIX
+#else
+#ifdef SPECFILE_POSIX
+#include <locale.h>
+#endif
+#endif
+#endif
+
+#include <string.h>
+
+double PyMcaAtof(const char * inputString)
+{
+#ifdef _GNU_SOURCE
+ double result;
+ locale_t newLocale;
+ newLocale = newlocale(LC_NUMERIC_MASK, "C", NULL);
+ result = strtod_l(inputString, NULL, newLocale);
+ freelocale(newLocale);
+ return result;
+#else
+#ifdef PYMCA_POSIX
+ return atof(inputString);
+#else
+#ifdef SPECFILE_POSIX
+ char *currentLocaleBuffer;
+ char *restoredLocaleBuffer;
+ char localeBuffer[21];
+ double result;
+ currentLocaleBuffer = setlocale(LC_NUMERIC, NULL);
+ strcpy(localeBuffer, currentLocaleBuffer);
+ setlocale(LC_NUMERIC, "C\0");
+ result = atof(inputString);
+ restoredLocaleBuffer = setlocale(LC_NUMERIC, localeBuffer);
+ return(result);
+#else
+ return atof(inputString);
+#endif
+#endif
+#endif
+}
diff --git a/silx/io/specfile/src/sfdata.c b/silx/io/specfile/src/sfdata.c
new file mode 100644
index 0000000..229f4e6
--- /dev/null
+++ b/silx/io/specfile/src/sfdata.c
@@ -0,0 +1,775 @@
+#/*##########################################################################
+# Copyright (C) 2004-2014 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfdata.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions for getting data
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2005/07/04 15:02:38 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfdata.c,v $
+ * Log: Revision 1.8 2005/07/04 15:02:38 ahoms
+ * Log: Fixed memory leak in SfNoDataLines
+ * Log:
+ * Log: Revision 1.7 2004/01/20 09:23:50 sole
+ * Log: Small change in sfdata (ptr < (to-1)) changed to (ptr <= (to-1))
+ * Log:
+ * Log: Revision 1.6 2003/03/06 16:56:40 sole
+ * Log: Check if to is beyond the scan size in SfData (still not finished but it seems to solve a crash)
+ * Log:
+ * Log: Revision 1.5 2002/12/09 13:04:05 sole
+ * Log: Added a check in SfNoDataLines
+ * Log:
+ * Log: Revision 1.4 2002/11/13 15:02:38 sole
+ * Log: Removed some printing in SfData
+ * Log:
+ * Log: Revision 1.3 2002/11/12 16:22:07 sole
+ * Log: WARNING: Developing version - Improved MCA reading and reading properly the end of the file.
+ * Log:
+ * Log: Revision 1.2 2002/11/12 13:15:52 sole
+ * Log: 1st version from Armando. The idea behind is to take the last line only if it ends with \n
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:11 19:05:11 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ *
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#include <locale_management.h>
+
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+#include <locale.h>
+#endif
+#endif
+
+#include <ctype.h>
+/*
+ * Define macro
+ */
+#define isnumber(this) ( isdigit(this) || this == '-' || this == '+' || this == '.' || this == 'E' || this == 'e')
+
+/*
+ * Mca continuation character
+ */
+#define MCA_CONT '\\'
+#define D_INFO 3
+
+/*
+ * Declarations
+ */
+DllExport long SfNoDataLines ( SpecFile *sf, long index, int *error );
+DllExport int SfData ( SpecFile *sf, long index, double ***retdata,
+ long **retinfo, int *error );
+DllExport long SfDataAsString ( SpecFile *sf, long index,
+ char ***data, int *error );
+DllExport long SfDataLine ( SpecFile *sf, long index, long line,
+ double **data_line, int *error );
+DllExport long SfDataCol ( SpecFile *sf, long index, long col,
+ double **data_col, int *error );
+DllExport long SfDataColByName( SpecFile *sf, long index,
+ char *label, double **data_col, int *error );
+
+
+/*********************************************************************
+ * Function: long SfNoDataLines( sf, index, error )
+ *
+ * Description: Gets number of data lines in a scan
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of data lines ,
+ * ( -1 ) => errors.
+ * Possible errors:
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfNoDataLines( SpecFile *sf, long index, int *error )
+{
+ long *dinfo = NULL;
+ double **data = NULL;
+ long nrlines = 0;
+ int ret, i;
+
+ ret = SfData(sf,index,&data,&dinfo,error);
+
+ if (ret == -1) {
+ return(-1);
+ }
+ if (dinfo == (long *) NULL){
+ return(-1);
+ }
+ if (dinfo[ROW] < 0){
+ printf("Negative number of points!\n");
+ /*free(dinfo);*/
+ return(-1);
+ }
+
+ nrlines = dinfo[ROW];
+
+ /* now free all stuff that SfData allocated */
+ for (i = 0; i < nrlines; i++)
+ free(data[i]);
+ free(data);
+ free(dinfo);
+
+ return nrlines;
+}
+
+
+
+/*********************************************************************
+ * Function: int SfData(sf, index, data, data_info, error)
+ *
+ * Description: Gets data.
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) Data array
+ * (4) Data info : [0] => no_lines
+ * [1] => no_columns
+ * [2] = ( 0 ) => regular
+ * ( 1 ) => not regular !
+ * (5) error number
+ * Returns:
+ * ( 0 ) => OK
+ * ( -1 ) => errors occured
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport int
+SfData( SpecFile *sf, long index, double ***retdata, long **retinfo, int *error )
+{
+ long *dinfo = NULL;
+ double **data = NULL;
+ double *dataline = NULL;
+ long headersize;
+
+ char *ptr,
+ *from,
+ *to;
+
+ char strval[100];
+ double val;
+ double valline[512];
+ long cols,
+ maxcol=512;
+ long rows;
+ int i;
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ char *currentLocaleBuffer;
+ char localeBuffer[21];
+#endif
+#endif
+
+ if (index <= 0 ){
+ return(-1);
+ }
+
+ if (sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+
+ /*
+ * Copy if already there
+ */
+ if (sf->data_info != (long *)NULL) {
+ dinfo = ( long * ) malloc ( sizeof(long) * D_INFO);
+ dinfo[ROW] = sf->data_info[ROW];
+ dinfo[COL] = sf->data_info[COL];
+ dinfo[REG] = sf->data_info[REG];
+ data = ( double **) malloc ( sizeof(double *) * dinfo[ROW]);
+ for (i=0;i<dinfo[ROW];i++) {
+ data[i] = (double *)malloc (sizeof(double) * dinfo[COL]);
+ memcpy(data[i],sf->data[i],sizeof(double) * dinfo[COL]);
+ }
+ *retdata = data;
+ *retinfo = dinfo;
+ return(0);
+ }
+ /*
+ * else do the job
+ */
+
+ if ( ((SpecScan *)sf->current->contents)->data_offset == -1 ) {
+ *retdata = data;
+ *retinfo = dinfo;
+ return(-1);
+ }
+
+ headersize = ((SpecScan *)sf->current->contents)->data_offset
+ - ((SpecScan *)sf->current->contents)->offset;
+
+ from = sf->scanbuffer + headersize;
+ to = sf->scanbuffer + ((SpecScan *)sf->current->contents)->size;
+ if (to > sf->scanbuffer+sf->scansize){
+ /* the -32 found "experimentaly" */
+ ptr = sf->scanbuffer+sf->scansize - 32;
+ while (*ptr != '\n') ptr--;
+ to=ptr;
+ /*printf("I let it crash ...\n");*/
+ }
+ i=0;
+ ptr = from;
+ rows = -1;
+ cols = -1;
+ /*
+ * Alloc memory
+ */
+ if ( (data = (double **) malloc (sizeof(double *)) ) == (double **)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ if ( (dinfo = (long *) malloc(sizeof(long) * D_INFO) ) == (long *)NULL) {
+ free(data);
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+ ptr = from;
+ dinfo[ROW] = dinfo[COL] = dinfo[REG] = 0;
+if(0){
+ /*
+ * first characters of buffer
+ */
+ while (*ptr == ' ') ptr++; /* get rid of empty spaces */
+
+ if (*ptr == '@') {
+ /*
+ * read all mca block: go while in buffer ( ptr < to - 1 )
+ * and while a newline is preceded by a slash
+ */
+ for ( ptr = ptr + 2;
+ (*ptr != '\n' || (*(ptr-1) == MCA_CONT)) && ptr < to ;
+ ptr++);
+ }
+ if ( *ptr == '#') { /* Comment --> pass one line */
+ for (ptr = ptr + 1; *ptr != '\n';ptr++);
+ }
+
+ /*
+ * continue
+ */
+ ptr++;
+}
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ currentLocaleBuffer = setlocale(LC_NUMERIC, NULL);
+ strcpy(localeBuffer, currentLocaleBuffer);
+ setlocale(LC_NUMERIC, "C\0");
+#endif
+#endif
+ for ( ; ptr < to; ptr++) {
+ /* get a complete line */
+ i=0;
+ cols=0;
+ /*I should be at the start of a line */
+ while(*(ptr) != '\n'){
+ if (*(ptr-1) == '\n'){
+ /*I am at the start of a line */
+ while(*ptr == '#'){
+ if (ptr >= to)
+ break;
+ for (ptr = ptr; ptr < to;ptr++){
+ if (*ptr == '\n'){
+ break;
+ }
+ };
+ /* on exit is equal to newline */
+ if (ptr < to) {
+ ptr++;
+ }
+ }
+ if (*ptr == '@') {
+ /*
+ * read all mca block: go while in buffer ( ptr < to - 1 )
+ * and while a newline is preceded by a slash
+ */
+ for ( ptr = ptr + 2;
+ (*ptr != '\n' || (*(ptr-1) == MCA_CONT)) && ptr < to ;
+ ptr++);
+ if (ptr >= to){
+ break;
+ }
+ }
+ while(*ptr == '#'){
+ if (ptr >= to)
+ break;
+ for (ptr = ptr; ptr < to;ptr++){
+ if (*ptr == '\n'){
+ break;
+ }
+ };
+ /* on exit is equal to newline */
+ if (ptr < to) {
+ ptr++;
+ }
+ }
+ /* first characters of buffer
+ */
+ while (*ptr == ' ' && ptr < to) ptr++; /* get rid of empty spaces */
+ }
+ /*
+ * in the middle of a line
+ */
+ if (*ptr == ' ' || *ptr == '\t' ) {
+ strval[i] = '\0';
+ i = 0;
+ val = PyMcaAtof(strval);
+ valline[cols] = val;
+ cols++;
+ if (cols >= maxcol) return(-1);
+ while(*(ptr+1) == ' ' || *(ptr+1) == '\t') ptr++;
+ } else {
+ if isnumber(*ptr){
+ strval[i] = *ptr;
+ i++;
+ }
+ }
+ if (ptr >= (to-1)){
+ break;
+ }
+ ptr++;
+ }
+ if ((*(ptr)== '\n') && (i != 0)){
+ strval[i] = '\0';
+ val = PyMcaAtof(strval);
+ valline[cols] = val;
+ cols++;
+ if (cols >= maxcol) return(-1);
+ /*while(*(ptr+1) == ' ' || *(ptr+1) == '\t') ptr++;*/
+ }
+ /*printf("%c",*ptr);*/
+ /* diffract31 crash -> changed from i!=0 to i==0 */
+ /*cols>0 necessary scan 59 of 31oct98 */
+ if ((ptr < to) && (cols >0)) {
+ rows++;
+ /*cols++;*/
+ if (cols >= maxcol) return(-1);
+ /* printf("Adding a new row, nrows = %ld, ncols= %ld\n",rows,cols);*/
+ /*printf("info col = %d cols = %d\n", dinfo[COL], cols);*/
+ if (dinfo[COL] != 0 && cols != dinfo[COL]) {
+ ;
+ /*diffract31 crash -> nextline uncommented */
+ dinfo[REG] = 1;
+ } else {
+ dinfo[COL] = cols;
+ }
+ if(dinfo[COL]==cols){
+ dataline = (double *)malloc(sizeof(double) * cols);
+ memcpy(dataline,valline,sizeof(double) * cols);
+ data = (double **) realloc ( data, sizeof(double) * (rows+1));
+ data[rows] = dataline;
+ dinfo[ROW]=rows+1;
+ }else{
+ printf("Error on scan %d line %d\n", (int) index, (int) (rows+1));
+ /* just ignore the line instead of stopping there with a
+ break; */
+ rows--;
+ }
+ }
+ }
+
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ setlocale(LC_NUMERIC, localeBuffer);
+#endif
+#endif
+ /*
+ * make a copy in specfile structure
+ */
+ if ( dinfo[ROW] != 0 && dinfo[REG] == 0) {
+ if (sf->data_info != (long *)NULL){
+ printf("I should not be here!/n");
+ sf->data_info[ROW] = dinfo[ROW];
+ sf->data_info[COL] = dinfo[COL];
+ sf->data_info[REG] = dinfo[REG];
+ for (i=0;i<dinfo[ROW];i++) {
+ sf->data[i]= (double *)realloc (sf->data[i],sizeof(double) * dinfo[COL]);
+ if (sf->data[i] == (double *) NULL){
+ printf("Realloc problem");
+ return (-1);
+ }
+ memcpy(sf->data[i],data[i],sizeof(double) * dinfo[COL]);
+ }
+ *retdata = data;
+ *retinfo = dinfo;
+ return(0);
+ }else{
+ sf->data_info = ( long * ) malloc ( sizeof(long) * D_INFO);
+ sf->data_info[ROW] = dinfo[ROW];
+ sf->data_info[COL] = dinfo[COL];
+ sf->data_info[REG] = dinfo[REG];
+ sf->data = ( double **) malloc ( sizeof(double *) * dinfo[ROW]);
+ if (sf->data == (double **) NULL){
+ printf("malloc1 problem");
+ return (-1);
+ }
+ for (i=0;i<dinfo[ROW];i++) {
+ sf->data[i] = (double *)malloc (sizeof(double) * dinfo[COL]);
+ if (sf->data[i] == (double *) NULL){
+ printf("malloc2 problem");
+ return (-1);
+ }
+ memcpy(sf->data[i],data[i],sizeof(double) * dinfo[COL]);
+ }
+ }
+ } else {
+ if (dinfo[REG] == 0) {
+ ;
+ /*printf("Not Freeing data:!\n");*/
+ /* I can be in the case of an mca without scan points */
+ /*free(data);
+ return(-1);*/
+ }
+ }
+ *retinfo = dinfo;
+ *retdata = data;
+ return( 0 );
+}
+
+
+DllExport long
+SfDataCol ( SpecFile *sf, long index, long col, double **retdata, int *error )
+{
+ double *datacol=NULL;
+
+ long *dinfo = NULL;
+ double **data = NULL;
+
+ long selection;
+ int i,ret;
+
+ ret = SfData(sf,index,&data,&dinfo,error);
+
+ if (ret == -1) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ *retdata = datacol;
+ return(-1);
+ }
+
+ if (col < 0) {
+ selection = dinfo[COL] + col;
+ } else {
+ selection = col - 1;
+ }
+if (selection > dinfo[COL] - 1) {
+selection=dinfo[COL] - 1;
+}
+ if ( selection < 0 || selection > dinfo[COL] - 1) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ if ( dinfo != (long *)NULL) {
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ }
+ free(dinfo);
+ return(-1);
+ }
+
+ datacol = (double *) malloc( sizeof(double) * dinfo[ROW]);
+ if (datacol == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+ return(-1);
+ }
+
+ for (i=0;i<dinfo[ROW];i++) {
+ datacol[i] = data[i][selection];
+ }
+
+ ret = dinfo[ROW];
+
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+
+ *retdata = datacol;
+ return(ret);
+}
+
+
+DllExport long
+SfDataLine( SpecFile *sf, long index, long line, double **retdata, int *error )
+{
+ double *datarow=NULL;
+
+ long *dinfo = NULL;
+ double **data = NULL;
+
+ long selection;
+ int ret;
+
+ ret = SfData(sf,index,&data,&dinfo,error);
+
+ if (ret == -1) {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ *retdata = datarow;
+ return(-1);
+ }
+
+ if (line < 0) {
+ selection = dinfo[ROW] + line;
+ } else {
+ selection = line - 1;
+ }
+
+ if ( selection < 0 || selection > dinfo[ROW] - 1) {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ if ( dinfo != (long *)NULL) {
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ }
+ free(dinfo);
+ return(-1);
+ }
+
+ datarow = (double *) malloc( sizeof(double) * dinfo[COL]);
+ if (datarow == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+ return(-1);
+ }
+
+
+ memcpy(datarow,data[selection],sizeof(double) * dinfo[COL]);
+
+ ret = dinfo[COL];
+
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+
+ *retdata = datarow;
+ return(ret);
+}
+
+
+DllExport long
+SfDataColByName( SpecFile *sf, long index, char *label, double **retdata, int *error )
+{
+
+ double *datacol;
+
+ long *dinfo = NULL;
+ double **data = NULL;
+
+ int i,ret;
+
+ char **labels = NULL;
+
+ long nb_lab,
+ idx;
+
+ short tofree=0;
+
+ if ( sfSetCurrent(sf,index,error) == -1) {
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ if ( sf->no_labels != -1 ) {
+ nb_lab = sf->no_labels;
+ labels = sf->labels;
+ } else {
+ nb_lab = SfAllLabels(sf,index,&labels,error);
+ tofree = 1;
+ }
+
+ if ( nb_lab == 0 || nb_lab == -1) {
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ for (idx=0;idx<nb_lab;idx++)
+ if (!strcmp(label,labels[idx])) break;
+
+ if ( idx == nb_lab ) {
+ if (tofree) freeArrNZ((void ***)&labels,nb_lab);
+ *error = SF_ERR_COL_NOT_FOUND;
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ ret = SfData(sf,index,&data,&dinfo,error);
+
+ if (ret == -1) {
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ datacol = (double *) malloc( sizeof(double) * dinfo[ROW]);
+ if (datacol == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ for (i=0;i<dinfo[ROW];i++) {
+ datacol[i] = data[i][idx];
+ }
+
+ ret = dinfo[ROW];
+
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+
+ *retdata = datacol;
+
+ return(ret);
+}
+
+
+DllExport long
+SfDataAsString( SpecFile *sf, long index, char ***retdata, int *error )
+{
+ char **data=NULL;
+ char oneline[300];
+
+ char *from,
+ *to,
+ *ptr,
+ *dataline;
+
+ long headersize,rows;
+ int i;
+
+ if (sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+ if ( ((SpecScan *)sf->current->contents)->data_offset == -1 ) {
+ *retdata = data;
+ return(-1);
+ }
+
+ data = (char **) malloc (sizeof(char *));
+
+ headersize = ((SpecScan *)sf->current->contents)->data_offset
+ - ((SpecScan *)sf->current->contents)->offset;
+
+ from = sf->scanbuffer + headersize;
+ to = sf->scanbuffer + ((SpecScan *)sf->current->contents)->size;
+
+ rows = -1;
+ i = 0;
+
+ /*
+ * first characters of buffer
+ */
+
+ ptr = from;
+
+ if (isnumber(*ptr)) {
+ rows++;
+ oneline[i] = *ptr;
+ i++;
+ } else if (*ptr == '@') {
+ /*
+ * read all mca block: go while in buffer ( ptr < to - 1 )
+ * and while a newline is preceded by a slash
+ */
+ for ( ptr = ptr + 2;
+ (*(ptr+1) != '\n' || (*ptr == MCA_CONT)) && ptr < to - 1 ;
+ ptr++);
+ }
+
+ /*
+ * continue
+ */
+ ptr++;
+
+ for ( ; ptr < to - 1; ptr++) {
+ /*
+ * check for lines and for mca
+ */
+ if ( *(ptr-1) == '\n' ) {
+
+ if ( i != 0 ) {
+ oneline[i-1] = '\0';
+ i = 0;
+
+ dataline = (char *)strdup(oneline);
+ data = (char **) realloc ( data, sizeof(char *) * (rows +1));
+ data[rows] = dataline;
+ }
+
+ if ( *ptr == '@') { /* Mca --> pass it all */
+ for ( ptr = ptr + 2;
+ (*ptr != '\n' || (*(ptr-1) == MCA_CONT)) && ptr < to ;
+ ptr++);
+ } else if ( *ptr == '#') { /* Comment --> pass one line */
+ for (ptr = ptr + 1; *ptr != '\n';ptr++);
+ } else if ( isnumber(*ptr) ) {
+ rows++;
+ oneline[i] = *ptr;
+ i++;
+ }
+ } else {
+ if (rows == -1) continue;
+
+ oneline[i] = *ptr;
+ i++;
+ }
+ }
+
+ /*
+ * last line
+ */
+
+ if (rows != -1 && i) {
+ oneline[i-1] = '\0';
+ dataline = (char *)strdup(oneline);
+ data = (char **) realloc ( data, sizeof(char *) * (rows+1));
+ data[rows] = dataline;
+ }
+
+ *retdata = data;
+ return(rows+1);
+}
diff --git a/silx/io/specfile/src/sfheader.c b/silx/io/specfile/src/sfheader.c
new file mode 100644
index 0000000..424eb08
--- /dev/null
+++ b/silx/io/specfile/src/sfheader.c
@@ -0,0 +1,787 @@
+#/*##########################################################################
+# Copyright (C) 2004-2016 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfheader.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions to access file and scan headers
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2002/11/20 09:01:29 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfheader.c,v $
+ * Log: Revision 1.3 2002/11/20 09:01:29 sole
+ * Log: Added free(line); in SfTitle
+ * Log:
+ * Log: Revision 1.2 2002/11/14 16:18:48 sole
+ * Log: stupid bug removed
+ * Log:
+ * Log: Revision 1.1 2002/11/14 15:25:39 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:09 19:05:09 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+
+/*
+ * Function Declaration
+ */
+DllExport char * SfCommand ( SpecFile *sf, long index, int *error );
+DllExport long SfNoColumns ( SpecFile *sf, long index, int *error );
+DllExport char * SfDate ( SpecFile *sf, long index, int *error );
+DllExport double * SfHKL ( SpecFile *sf, long index, int *error );
+
+DllExport long SfEpoch ( SpecFile *sf, long index, int *error );
+DllExport char * SfUser ( SpecFile *sf, long index, int *error );
+DllExport char * SfTitle ( SpecFile *sf, long index, int *error );
+DllExport char * SfFileDate ( SpecFile *sf, long index, int *error );
+DllExport long SfNoHeaderBefore ( SpecFile *sf, long index, int *error );
+DllExport long SfGeometry ( SpecFile *sf, long index,
+ char ***lines, int *error);
+DllExport long SfHeader ( SpecFile *sf, long index, char *string,
+ char ***lines, int *error);
+DllExport long SfFileHeader ( SpecFile *sf, long index, char *string,
+ char ***lines, int *error);
+
+int sfGetHeaderLine ( SpecFile *sf, int from, char character,
+ char **buf,int *error);
+/*
+ * Internal functions
+ */
+static char *sfFindWord ( char *line, char *word, int *error );
+static long sfFindLines ( char *from, char *to,char *string,
+ char ***lines,int *error);
+static char *sfOneLine ( char *from, char *end, int *error);
+
+
+/*********************************************************************
+ * Function: char *SfCommand( sf, index, error )
+ *
+ * Description: Reads '#S' line ( without #S and scan number ).
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * String pointer,
+ * NULL => errors.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport char *
+SfCommand( SpecFile *sf, long index, int *error )
+{
+ char *ret_line=NULL;
+ long cnt,start,length;
+ char *ptr;
+
+ /*
+ * Choose scan
+ */
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(ret_line);
+
+ cnt = 3;
+ for ( ptr = sf->scanbuffer + cnt; *ptr != ' ' ; ptr++,cnt++);
+ for ( ptr = sf->scanbuffer + cnt; *ptr == ' ' || *ptr == '\t'; ptr++,cnt++);
+
+ start = cnt;
+ for ( ptr = sf->scanbuffer + cnt; *ptr != '\n' ; ptr++,cnt++);
+
+ length = cnt - start;
+
+ /*
+ * Return the rest .
+ */
+ ret_line = (char *) malloc ( sizeof(char) * ( length + 1) );
+ if (ret_line == (char *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(ret_line);
+ }
+
+ ptr = sf->scanbuffer + start;
+ memcpy(ret_line,ptr,sizeof(char) * length );
+ ret_line[length] = '\0';
+
+ return( ret_line );
+}
+
+
+/*********************************************************************
+ * Function: long SfNoColumns( sf, index, error )
+ *
+ * Description: Gets number of columns in a scan
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of scan columns.(From #N line !)
+ * ( -1 ) if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfNoColumns( SpecFile *sf, long index, int *error )
+{
+ long col = -1;
+ char *buf=NULL;
+
+ if ( sfSetCurrent(sf,index,error) == -1)
+ return(-1);
+
+ if ( sfGetHeaderLine( sf, FROM_SCAN, SF_COLUMNS, &buf, error) == -1)
+ return(-1);
+ col = atol( buf );
+ free(buf);
+ return( col );
+}
+
+
+/*********************************************************************
+ * Function: char *SfDate( sf, index, error )
+ *
+ * Description: Gets date from scan header
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Date.(From #D line !),
+ * NULL => errors.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport char *
+SfDate(SpecFile *sf, long index, int *error )
+{
+ char *line=NULL;
+
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return(line);
+
+ if ( sfGetHeaderLine( sf, FROM_SCAN, SF_DATE, &line, error))
+ return((char *)NULL);
+
+ return( line );
+}
+
+
+/*********************************************************************
+ * Function: double *SfHKL( sf, index, error )
+ *
+ * Description: Reads '#Q' line.
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Poiter to a 3x1 dbl. array( HKL[0]=HKL[H]=H_value,
+ * HKL[1]=HKL[K]=K_value,
+ * HKL[2]=HKL[L]=L_value.
+ * NULL => errors.
+ *
+ * Possible errors:
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_MEMORY_ALLOC | => mulstrtod()
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport double *
+SfHKL( SpecFile *sf, long index, int *error )
+{
+ char *line=NULL;
+ double *HKL = NULL;
+ long i;
+
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return((double *)NULL);
+
+ if ( sfGetHeaderLine( sf, FROM_SCAN, SF_RECIP_SPACE, &line, error) == -1 )
+ return((double *)NULL);
+
+ /*
+ * Convert into double .
+ */
+ i = mulstrtod( line, &HKL, error );
+ free(line);
+
+ if ( i < 0)
+ return( (double *)NULL );
+
+ if ( i != 3 ) {
+ *error = SF_ERR_LINE_EMPTY;
+ free( HKL );
+ return( (double *)NULL );
+ }
+
+ return( HKL );
+}
+
+
+/*********************************************************************
+ * Function: long SfEpoch( sf, index, error )
+ *
+ * Description: Gets epoch from the last file header.
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Epoch.(From #E line !)
+ * ( -1 ) if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_FILE_READ
+ * SF_ERR_HEADER_NOT_FOUND
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfEpoch( SpecFile *sf, long index, int *error )
+{
+ char *buf=NULL;
+ long epoch = -1;
+
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+ if ( sfGetHeaderLine(sf,FROM_FILE,SF_EPOCH,&buf,error) == -1 )
+ return(-1);
+
+ epoch = atol( buf );
+ free(buf);
+
+ return( epoch );
+}
+
+
+/*********************************************************************
+ * Function: char SfFileDate( sf, index, error )
+ *
+ * Description: Gets date from the last file header
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Date.(From #D line !)
+ * NULL => errors.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_FILE_READ
+ * SF_ERR_HEADER_NOT_FOUND
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport char *
+SfFileDate( SpecFile *sf, long index, int *error )
+{
+ char *date = NULL;
+
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return((char *)NULL);
+
+ if ( sfGetHeaderLine(sf,FROM_FILE,SF_DATE,&date,error) == -1 )
+ return((char *)NULL);
+
+ return( date );
+}
+
+
+/*********************************************************************
+ * Function: long SfNoHeaderBefore( sf, index, error )
+ *
+ * Description: Gets number of scan header lines before data.
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Scan index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of scan header lines before data ,
+ * ( -1 ) => errors.
+ * Possible errors:
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfNoHeaderBefore( SpecFile *sf, long index, int *error )
+{
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+ /*
+ * Obsolete... give some reasonable!
+ */
+ return(-1);
+}
+
+
+/*********************************************************************
+ * Function: char *SfUser( sf, index, error )
+ *
+ * Description: Gets spec user information from the last file header
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * User.(From 1st #C line !)
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC ||=> findWordInLine()
+ * SF_ERR_LINE_NOT_FOUND |
+ * SF_ERR_FILE_READ |
+ * SF_ERR_SCAN_NOT_FOUND | => getFirstFileC()
+ * SF_ERR_HEADER_NOT_FOUND |
+ * SF_ERR_USER_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport char *
+SfUser( SpecFile *sf, long index, int *error )
+{
+
+ char *line=NULL;
+ char *user;
+ char word[] = "User =";
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return((char *)NULL);
+
+ if (sfGetHeaderLine( sf, FROM_FILE, SF_COMMENT, &line, error) == -1)
+ return((char *)NULL);
+
+ /*
+ * Find user.
+ */
+ user = sfFindWord( line, word, error );
+
+ if ( user == (char *) NULL) {
+ *error = SF_ERR_USER_NOT_FOUND;
+ return((char *)NULL);
+ }
+
+ free(line);
+ return( user );
+}
+
+
+/*********************************************************************
+ * Function: long SfTitle( sf, index, error )
+ *
+ * Description: Gets spec title information from the last file header
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Title.(From 1st #C line !)
+ * NULL => errors.
+ * Possible errors:
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_LINE_NOT_FOUND |
+ * SF_ERR_FILE_READ |
+ * SF_ERR_SCAN_NOT_FOUND | => getFirstFileC()
+ * SF_ERR_HEADER_NOT_FOUND |
+ *
+ *********************************************************************/
+DllExport char *
+SfTitle( SpecFile *sf, long index, int *error )
+{
+ char *line=NULL;
+ char *title;
+ char *ptr;
+ long i;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return((char *)NULL);
+
+ if (sfGetHeaderLine( sf, FROM_FILE, SF_COMMENT, &line, error) == -1)
+ return((char *)NULL);
+
+ /*
+ * Get title.( first word )
+ */
+ ptr = line;
+
+ for ( i=0,ptr=line ; *ptr!='\t' && *ptr!='\n' && *ptr!='\0' ; i++ ) {
+ if ( *ptr==' ' ) {
+ if ( *(++ptr)==' ' ) {
+ break;
+ } else ptr--;
+ }
+ ptr++;
+ }
+
+ if ( i==0 ) {
+ *error = SF_ERR_LINE_EMPTY;
+ return( (char *)NULL );
+ }
+
+ title = (char *)malloc( sizeof(char) * ( i+1 ) );
+
+ if ( title == (char *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( title );
+ }
+
+ memcpy( title, line, sizeof(char) * i );
+ /* Next line added by Armando, it may be wrong */
+ free(line);
+ title[i] = '\0';
+
+ return( title );
+}
+
+
+DllExport long
+SfGeometry ( SpecFile *sf, long index, char ***lines, int *error)
+{
+ char string[] = " \0";
+
+ string[0] = SF_GEOMETRY;
+
+ return(SfHeader(sf,index,string,lines,error));
+}
+
+
+DllExport long
+SfHeader ( SpecFile *sf, long index, char *string, char ***lines, int *error)
+{
+ char *headbuf,
+ *endheader;
+
+ long nb_found;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(-1);
+
+ headbuf = sf->scanbuffer;
+ endheader = sf->scanbuffer + sf->scansize;
+
+ nb_found = sfFindLines(headbuf, endheader,string, lines,error);
+
+ if (nb_found == 0) {
+ return SfFileHeader(sf,index,string,lines,error);
+ } else {
+ return nb_found;
+ }
+}
+
+
+
+DllExport long
+SfFileHeader ( SpecFile *sf, long index, char *string, char ***lines, int *error)
+{
+ char *headbuf,
+ *endheader;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(-1);
+ if (sf->filebuffersize > 0)
+ {
+ headbuf = sf->filebuffer;
+ endheader = sf->filebuffer + sf->filebuffersize;
+
+ return(sfFindLines(headbuf,endheader,string,lines,error));
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+static long
+sfFindLines(char *from,char *to,char *string,char ***ret,int *error)
+{
+ char **lines;
+ long found;
+ unsigned long j;
+ char *ptr;
+ short all=0;
+
+ found = 0;
+ ptr = from;
+
+ if ( string == (char *) NULL || strlen(string) == 0)
+ all = 1;
+
+ /*
+ * Allocate memory for an array of strings
+ */
+ if ( (lines = (char **)malloc( sizeof(char *) )) == (char **)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return ( -1 );
+ }
+
+ /*
+ * First line
+ */
+ if ( ptr[0] == '#' ) {
+ if ( all ) {
+ lines = (char **) realloc ( lines, (found+1) * sizeof(char *) );
+ lines[found] = sfOneLine(ptr,to,error);
+ found++;
+ } else if ( ptr[1] == string[0]) {
+ for ( j=0; j < strlen(string) && ptr+j< to;j++)
+ if ( ptr[j+1] != string[j]) break;
+ if ( j == strlen(string)) {
+ lines = (char **) realloc ( lines, (found+1) * sizeof(char *) );
+ lines[found] = sfOneLine(ptr,to,error);
+ found++;
+ }
+ }
+ }
+
+ /*
+ * The rest
+ */
+ for ( ptr = from + 1;ptr < to - 1;ptr++) {
+ if ( *(ptr - 1) == '\n' && *ptr == '#' ) {
+ if ( all ) {
+ lines = (char **) realloc ( lines, (found+1) * sizeof(char *) );
+ lines[found] = sfOneLine(ptr,to,error);
+ found++;
+ } else if ( *(ptr+1) == string[0]) {
+ for ( j=0; j < strlen(string) && (ptr + j) < to;j++)
+ if ( ptr[j+1] != string[j]) break;
+ if ( j == strlen(string)) {
+ lines = (char **) realloc ( lines, (found+1) * sizeof(char *) );
+ lines[found] = sfOneLine(ptr,to,error);
+ found++;
+ }
+ }
+ }
+ }
+
+ if (found) *ret = lines;
+ else free(lines);
+
+ return(found);
+}
+
+
+/*********************************************************************
+ * Function: char *sfGetHeaderLine( SpecFile *sf, sf_char, end, error )
+ *
+ * Description: Gets one '#sf_char' line.
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) sf_character
+ * (3) end ( where to stop the search )
+ * Output:
+ * (4) error number
+ * Returns:
+ * Pointer to the line ,
+ * NULL in case of errors.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_FILE_READ | => findLine()
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+int
+sfGetHeaderLine( SpecFile *sf, int from , char sf_char, char **buf, int *error)
+{
+
+ char *ptr,*headbuf;
+ char *endheader;
+ int found;
+
+ found = 0;
+
+ if ( from == FROM_SCAN ) {
+ headbuf = sf->scanbuffer;
+ endheader = sf->scanbuffer + sf->scanheadersize;
+ } else if ( from == FROM_FILE ) {
+ if ( sf->filebuffersize == 0 ) {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ return(-1);
+ }
+ headbuf = sf->filebuffer;
+ endheader = sf->filebuffer + sf->filebuffersize;
+ } else {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ return(-1);
+ }
+
+ if ( headbuf[0] == '#' && headbuf[1] == sf_char) {
+ found = 1;
+ ptr = headbuf;
+ } else {
+ for ( ptr = headbuf + 1;ptr < endheader - 1;ptr++) {
+ if ( *(ptr - 1) == '\n' && *ptr == '#' && *(ptr+1) == sf_char) {
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ return(-1);
+ }
+
+ /*
+ * Beginning of the thing after '#X '
+ */
+ ptr = ptr + 3;
+
+ *buf = sfOneLine(ptr,endheader,error);
+
+ return( 0 );
+}
+
+static char *
+sfOneLine(char *from,char *end,int *error)
+{
+ static char linebuf[5000];
+
+ char *ptr,*buf;
+ long i;
+
+ ptr = from;
+
+ for(i=0;*ptr != '\n' && ptr < end;ptr++,i++) {
+ linebuf[i] = *ptr;
+ }
+
+ linebuf[i]='\0';
+
+ buf = (char *) malloc ( i+1 );
+
+ if (buf == ( char * ) NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return((char *)NULL);
+ }
+ strcpy(buf,(char *)linebuf);
+
+ return(buf);
+}
+
+
+/*********************************************************************
+ * Function: char *sfFindWord( line, word, error )
+ *
+ * Description: Looks for 'word' in given line and returns a
+ * copy of the rest of the line after the found word .
+ *
+ * Parameters:
+ * Input : (1) Line pointer
+ * (2) Word pointer
+ * Output:
+ * (3) error number
+ * Returns:
+ * Rest of the line after word.
+ * NULL => not found.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+static char *
+sfFindWord( char *line, char *word, int *error )
+{
+ char *ret;
+
+ line = strstr( line, word );
+
+ if ( line == (char *)NULL ) {
+ return( line );
+ }
+
+ line += strlen( word );
+
+ /*
+ * Delete blanks.
+ */
+ while ( *line == ' ' || *line == '\t' ) line++;
+
+ /*
+ * Copy the rest.
+ */
+ ret = (char *)malloc( sizeof(char) * ( 1 + strlen( line )) );
+
+ if ( ret == (char *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(ret);
+ }
+
+ memcpy( ret, line, sizeof(char) * ( 1 + strlen( line )) );
+
+ return( ret );
+}
+
diff --git a/silx/io/specfile/src/sfindex.c b/silx/io/specfile/src/sfindex.c
new file mode 100644
index 0000000..fd0c7c3
--- /dev/null
+++ b/silx/io/specfile/src/sfindex.c
@@ -0,0 +1,551 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfindex.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: functions for scan numbering
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2004/05/12 16:56:47 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfindex.c,v $
+ * Log: Revision 1.2 2004/05/12 16:56:47 sole
+ * Log: Support for windows
+ * Log:
+ * Log: Revision 1.1 2003/03/06 16:59:05 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:15 19:05:15 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+/*
+ * File: sfindex.c
+ *
+ * Description:
+ *
+ * Project:
+ *
+ * Author: Vicente Rey Bakaikoa
+ *
+ * Date: March 2000
+ */
+/*
+ * $Log: sfindex.c,v $
+ * Revision 1.2 2004/05/12 16:56:47 sole
+ * Support for windows
+ *
+ * Revision 1.1 2003/03/06 16:59:05 sole
+ * Initial revision
+ *
+ * Revision 3.0 2000/12/20 14:17:19 rey
+ * Python version available
+ *
+ * Revision 2.1 2000/07/31 19:05:15 19:05:15 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:26:55 13:26:55 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ *
+ */
+
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#else
+#include <unistd.h>
+#endif
+#include <ctype.h>
+
+#define ON_COMMENT 0
+#define ON_ABO 1
+#define ON_RES 2
+/*
+ * Declarations
+ */
+DllExport long * SfList ( SpecFile *sf, int *error );
+DllExport long SfIndexes ( SpecFile *sf, long number, long **idxlist );
+DllExport long SfIndex ( SpecFile *sf, long number, long order );
+DllExport long SfCondList ( SpecFile *sf, long cond, long **scan_list,
+ int *error );
+DllExport long SfScanNo ( SpecFile *sf );
+DllExport int SfNumberOrder ( SpecFile *sf, long index, long *number,
+ long *order );
+DllExport long SfNumber ( SpecFile *sf, long index );
+DllExport long SfOrder ( SpecFile *sf, long index );
+
+/*
+ * Internal Functions
+ */
+static int checkAborted( SpecFile *sf, ObjectList *ptr, int *error );
+
+
+/*********************************************************************
+ * Function: long *SfList( sf, error )
+ *
+ * Description: Creates an array with all scan numbers.
+ *
+ * Parameters:
+ * Input : SpecFile pointer
+ * Returns:
+ * Array with scan numbers.
+ * NULL if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long *
+SfList( SpecFile *sf, int *error )
+{
+ register ObjectList *ptr;
+ long *scan_list;
+ long i = 0;
+
+ scan_list = (long *)malloc( sizeof(long) * (sf->no_scans) );
+
+ if ( scan_list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( scan_list );
+ }
+
+ for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ,i++) {
+ scan_list[i] = ( ((SpecScan *)(ptr->contents))->scan_no );
+ }
+ /*printf("scanlist[%li] = %li\n",i-1,scan_list[i-1]);*/
+ return( scan_list );
+}
+
+
+/*********************************************************************
+ * Function: long SfIndexes( sf, number , idxlist)
+ *
+ * Description: Creates an array with all indexes with the same scan
+ * number.
+ *
+ * Parameters:
+ * Input : SpecFile pointer
+ * scan number
+ * Output : array with scan indexes
+ * Returns:
+ * Number of indexes found
+ * Possible errors:
+ * None possible
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfIndexes( SpecFile *sf, long number, long **idxlist )
+{
+ ObjectList *ptr;
+ long i;
+ long *indexes;
+ long *arr;
+
+ i = 0;
+ indexes = (long *)malloc(sf->no_scans * sizeof(long));
+
+ for (ptr = sf->list.first; ptr; ptr=ptr->next ) {
+ if ( number == ((SpecScan *)(ptr->contents))->scan_no) {
+ indexes[i] = ((SpecScan *)(ptr->contents))->index;
+ i++;
+ }
+ }
+
+ if (i == 0)
+ arr = (long *) NULL;
+ else {
+ arr = (long *)malloc(sizeof(long) * i);
+ memcpy(arr,indexes,sizeof(long) * i);
+ }
+
+ *idxlist = arr;
+ free(indexes);
+ return( i );
+}
+
+
+/*********************************************************************
+ * Function: long SfIndex( sf, number, order )
+ *
+ * Description: Gets scan index from scan number and order.
+ *
+ * Parameters:
+ * Input : (1) Scan number
+ * (2) Scan order
+ * Returns:
+ * Index number.
+ * (-1) if not found.
+ *
+ *********************************************************************/
+DllExport long
+SfIndex( SpecFile *sf, long number, long order )
+{
+ ObjectList *ptr;
+
+ ptr = findScanByNo( &(sf->list), number, order );
+ if ( ptr != (ObjectList *)NULL )
+ return( ((SpecScan *)(ptr->contents))->index );
+
+ return( -1 );
+}
+
+
+/*********************************************************************
+ * Function: long SfCondList( sf, cond, scan_list, error )
+ *
+ * Description: Creates an array with all scan numbers.
+ *
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) Condition : 0 => not aborted scans ( NOT_ABORTED )
+ * -1 => aborted scans ( ABORTED )
+ * nn => more than 'nn' data lines
+ * Output: (3) Scan list
+ * (4) error code
+ * Returns:
+ * Number of found scans.
+ * ( -1 ) if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfCondList( SpecFile *sf, long cond, long **scan_list, int *error )
+{
+ register ObjectList *ptr;
+ long *list;
+ long i = 0;
+ int retcheck;
+ long index;
+
+ *scan_list = (long *)NULL;
+
+ list = (long *)malloc( sizeof(long) * (sf->no_scans) );
+
+ if ( list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+
+ /*
+ * Aborted scans .
+ */
+ if ( cond < 0 ) { /* aborted scans */
+ for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) {
+
+ retcheck = checkAborted( sf, ptr, error );
+
+ if ( retcheck < 0 ) {
+ free( list );
+ return( -1 );
+ } else if ( retcheck > 0) {
+ list[i] = ( ((SpecScan *)(ptr->contents))->scan_no );
+ i++;
+ }
+ }
+ } else if ( cond == 0 ) { /* not aborted scans */
+ for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) {
+
+ retcheck = checkAborted( sf, ptr, error );
+
+ if ( retcheck < 0 ) {
+ free( list );
+ return( -1 );
+ } else if ( retcheck == 0 ) {
+ list[i] = ( ((SpecScan *)(ptr->contents))->scan_no );
+ i++;
+ }
+ }
+ } else { /* cond > 0 - more than n data_lines */
+ for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) {
+
+ index = ( ((SpecScan *)(ptr->contents))->index );
+ if ( SfNoDataLines(sf,index,error) <= cond ) continue;
+
+ list[i] = ( ((SpecScan *)(ptr->contents))->scan_no );
+ i++;
+ }
+ }
+
+ *scan_list = ( long * ) malloc ( i * sizeof(long));
+
+ if ( *scan_list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+
+ memcpy(*scan_list,list, i * sizeof(long));
+ free(list);
+
+ return( i );
+}
+
+
+/*********************************************************************
+ * Function: long SfScanNo( sf )
+ *
+ * Description: Gets number of scans.
+ *
+ * Parameters:
+ * Input :(1) SpecFile pointer
+ * Returns:
+ * Number of scans.
+ *
+ *********************************************************************/
+DllExport long
+SfScanNo( SpecFile *sf )
+{
+ return( sf->no_scans );
+}
+
+
+/*********************************************************************
+ * Function: int SfNumberOrder( sf, index, number, order )
+ *
+ * Description: Gets scan number and order from index.
+ *
+ * Parameters:
+ * Input :
+ * (1) SpecFile pointer
+ * (2) Scan index
+ * Output:
+ * (3) Scan number
+ * (4) Scan order
+ * Returns:
+ * ( -1 ) => not found
+ * ( 0 ) => found
+ *
+ *********************************************************************/
+DllExport int
+SfNumberOrder( SpecFile *sf, long index, long *number, long *order )
+{
+ register ObjectList *list;
+
+ *number = -1;
+ *order = -1;
+
+ /*
+ * Find scan .
+ */
+ list = findScanByIndex( &(sf->list), index );
+ if ( list == (ObjectList *)NULL ) return( -1 );
+
+ *number = ((SpecScan *)list->contents)->scan_no;
+ *order = ((SpecScan *)list->contents)->order;
+
+ return( 0 );
+}
+
+
+/*********************************************************************
+ * Function: long SfNumber( sf, index )
+ *
+ * Description: Gets scan number from index.
+ *
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) Scan index
+ * Returns:
+ * Scan number.
+ * ( -1 ) => not found
+ *
+ *********************************************************************/
+DllExport long
+SfNumber( SpecFile *sf, long index )
+{
+ register ObjectList *list;
+
+ /*
+ * Find scan .
+ */
+ list = findScanByIndex( &(sf->list), index );
+ if ( list == (ObjectList *)NULL ) return( -1 );
+
+ return( ((SpecScan *)list->contents)->scan_no );
+}
+
+
+/*********************************************************************
+ * Function: long SfOrder( sf, index )
+ *
+ * Description: Gets scan order from index.
+ *
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) Scan index
+ * Returns:
+ * Scan order.
+ * ( -1 ) => not found
+ *
+ *********************************************************************/
+DllExport long
+SfOrder( SpecFile *sf, long index )
+{
+ register ObjectList *list;
+
+
+ /*
+ * Find scan .
+ */
+ list = findScanByIndex( &(sf->list), index );
+ if ( list == (ObjectList *)NULL ) return( -1 );
+
+ return( ((SpecScan *)list->contents)->order );
+}
+
+/*********************************************************************
+ * Function: int checkAborted( sf, ptr, error )
+ *
+ * Description: Checks if scan was aborted or not .
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) Pointer to the scan
+ * Output: (3) Error number
+ * Returns:
+ * (-1 ) : error
+ * ( 0 ) : not aborted
+ * ( 1 ) : aborted
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_FILE_READ
+ *
+ *********************************************************************/
+static int
+checkAborted( SpecFile *sf, ObjectList *ptr, int *error )
+{
+ long nbytes;
+ long data_lines,size,from;
+ SpecScan *scan;
+ char *buffer,*cptr,next;
+ int state=ON_COMMENT;
+ int aborted=0;
+ long index;
+
+ scan = ptr->contents;
+ index = scan->index;
+
+ data_lines = SfNoDataLines(sf,index,error);
+
+ if ( scan->hdafter_offset == -1 && data_lines > 0) {
+ return(0);
+ } else if ( data_lines <= 0 ) {
+ /*
+ * maybe aborted on first point
+ * we have to all to know ( but no data anyway )
+ */
+ size = scan->size;
+ from = scan->offset;
+ } else {
+ size = scan->last - scan->hdafter_offset;
+ from = scan->hdafter_offset;
+ }
+
+ lseek(sf->fd,from,SEEK_SET);
+ buffer = ( char * ) malloc (size);
+ nbytes = read(sf->fd,buffer,size);
+
+ if (nbytes == -1 ) {
+ *error = SF_ERR_FILE_READ;
+ return(-1);
+ }
+
+ if (buffer[0] == '#' && buffer[1] == 'C') {
+ state = ON_COMMENT;
+ }
+
+ for ( cptr = buffer + 1; cptr < buffer + nbytes - 1; cptr++) {
+ /*
+ * Comment line
+ */
+ if ( *cptr == '#' && *(cptr+1) == 'C' && *(cptr-1) == '\n') {
+ state = ON_COMMENT;
+ }
+ /*
+ * Check aborted
+ */
+ if ( *(cptr-1) == 'a' && *cptr == 'b' && *(cptr+1) == 'o') {
+ if ( state == ON_COMMENT ) {
+ state = ON_ABO;
+ }
+ }
+ if ( *(cptr-1) == 'r' && *cptr == 't' && *(cptr+1) == 'e') {
+ if ( state == ON_ABO) {
+ aborted = 1;
+ }
+ }
+ /*
+ * Check resume line
+ */
+ if ( *(cptr-1) == 'r' && *cptr == 'e' && *(cptr+1) == 's') {
+ if ( state == ON_COMMENT ) {
+ state = ON_RES;
+ }
+ }
+ if ( *(cptr-1) == 'u' && *cptr == 'm' && *(cptr+1) == 'e') {
+ if ( state == ON_RES) {
+ aborted = 0;
+ }
+ }
+
+ /*
+ * If data line... aborted is aborted
+ */
+ if ( *cptr == '\n' ) {
+ next = *(cptr+1);
+ if (isdigit(next) || next == '+' || next == '-' || next == '@') {
+ aborted = 0;
+ }
+ }
+ }
+ free(buffer);
+ return(aborted);
+
+/*
+ * To be implemented
+ * - return 0 = not aborted
+ * - return 1 = aborted
+ * - return -1 = error
+ *
+ * implementation: read whole scan
+ * - go to header after offset
+ * - read all till end of scan with size
+ * - search for a line with a) #C ( comment ) then "aborted"
+ */
+ return( 0 );
+}
diff --git a/silx/io/specfile/src/sfinit.c b/silx/io/specfile/src/sfinit.c
new file mode 100644
index 0000000..6f88078
--- /dev/null
+++ b/silx/io/specfile/src/sfinit.c
@@ -0,0 +1,827 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfinit.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Initialization routines ( open/update/close )
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2005/05/25 13:01:32 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfinit.c,v $
+ * Log: Revision 1.5 2005/05/25 13:01:32 sole
+ * Log: Back to revision 1.3
+ * Log:
+ * Log: Revision 1.3 2004/05/12 16:57:32 sole
+ * Log: windows support
+ * Log:
+ * Log: Revision 1.2 2002/11/12 13:23:43 sole
+ * Log: Version with added support for the new sf->updating flag
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Log: Revision 2.2 2000/12/20 12:12:08 rey
+ * Log: bug corrected with SfAllMotors
+ * Log:
+ * Revision 2.1 2000/07/31 19:04:42 19:04:42 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+/*
+ * File: sfinit.c
+ *
+ * Description: This file implements basic routines on SPEC datafiles
+ * SfOpen / SfClose / SfError
+ *
+ * SfUpdate is kept but it is obsolete
+ *
+ * Version: 2.0
+ *
+ * Date: March 2000
+ *
+ * Author: Vicente REY
+ *
+ * Copyright: E.S.R.F. European Synchrotron Radiation Facility (c) 2000
+ */
+/*
+ * $Log: sfinit.c,v $
+ * Revision 1.5 2005/05/25 13:01:32 sole
+ * Back to revision 1.3
+ *
+ * Revision 1.3 2004/05/12 16:57:32 sole
+ * windows support
+ *
+ * Revision 1.2 2002/11/12 13:23:43 sole
+ * Version with added support for the new sf->updating flag
+ *
+ * Revision 3.0 2000/12/20 14:17:19 rey
+ * Python version available
+ *
+ * Revision 2.2 2000/12/20 12:12:08 rey
+ * bug corrected with SfAllMotors
+ *
+ * Revision 2.1 2000/07/31 19:04:42 19:04:42 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:27:19 13:27:19 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ *
+ *
+ *********************************************************************/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <SpecFile.h>
+#include <SpecFileP.h>
+
+/*
+ * Defines
+ */
+
+#define ANY 0
+#define NEWLINE 1
+#define COMMENT 2
+
+#define SF_ISFX ".sfI"
+
+#define SF_INIT 0
+#define SF_READY 1
+#define SF_MODIFIED 2
+
+/*
+ * Function declaration
+ */
+
+DllExport SpecFile * SfOpen ( char *name,int *error);
+DllExport SpecFile * SfOpen2 ( int fd, char *name,int *error);
+DllExport int SfClose ( SpecFile *sf);
+DllExport short SfUpdate ( SpecFile *sf, int *error);
+DllExport char * SfError ( int error);
+
+
+#ifdef linux
+char SF_SIGNATURE[] = "Linux 2ruru Sf2.0";
+#else
+char SF_SIGNATURE[] = "2ruru Sf2.0";
+#endif
+
+/*
+ * Internal functions
+ */
+static short statusEnd ( char c2, char c1);
+static void sfStartBuffer ( SpecFile *sf, SfCursor *cursor, short status,char c0, char c1,int *error);
+static void sfNewLine ( SpecFile *sf, SfCursor *cursor, char c0,char c1,int *error);
+static void sfHeaderLine ( SpecFile *sf, SfCursor *cursor, char c,int *error);
+static void sfNewBlock ( SpecFile *sf, SfCursor *cursor, short how,int *error);
+static void sfSaveScan ( SpecFile *sf, SfCursor *cursor, int *error);
+static void sfAssignScanNumbers (SpecFile *sf);
+static void sfReadFile ( SpecFile *sf, SfCursor *cursor, int *error);
+static void sfResumeRead ( SpecFile *sf, SfCursor *cursor, int *error);
+#ifdef SPECFILE_USE_INDEX_FILE
+static short sfOpenIndex ( SpecFile *sf, SfCursor *cursor, int *error);
+static short sfReadIndex ( int sfi, SpecFile *sf, SfCursor *cursor, int *error);
+static void sfWriteIndex ( SpecFile *sf, SfCursor *cursor, int *error);
+#endif
+
+/*
+ * errors
+ */
+typedef struct _errors {
+ int code;
+ char *message;
+} sf_errors ;
+
+static
+sf_errors errors[]={
+{ SF_ERR_MEMORY_ALLOC , "Memory allocation error ( SpecFile )" },
+{ SF_ERR_FILE_OPEN , "File open error ( SpecFile )" },
+{ SF_ERR_FILE_CLOSE , "File close error ( SpecFile )" },
+{ SF_ERR_FILE_READ , "File read error ( SpecFile )" },
+{ SF_ERR_FILE_WRITE , "File write error ( SpecFile )" },
+{ SF_ERR_LINE_NOT_FOUND , "Line not found error ( SpecFile )" },
+{ SF_ERR_SCAN_NOT_FOUND , "Scan not found error ( SpecFile )" },
+{ SF_ERR_HEADER_NOT_FOUND , "Header not found error ( SpecFile )" },
+{ SF_ERR_LABEL_NOT_FOUND , "Label not found error ( SpecFile )" },
+{ SF_ERR_MOTOR_NOT_FOUND , "Motor not found error ( SpecFile )" },
+{ SF_ERR_POSITION_NOT_FOUND , "Position not found error ( SpecFile )" },
+{ SF_ERR_LINE_EMPTY , "Line empty or wrong data error ( SpecFile )"},
+{ SF_ERR_USER_NOT_FOUND , "User not found error ( SpecFile )" },
+{ SF_ERR_COL_NOT_FOUND , "Column not found error ( SpecFile )" },
+{ SF_ERR_MCA_NOT_FOUND , "Mca not found ( SpecFile )" },
+/* MUST be always the last one : */
+{ SF_ERR_NO_ERRORS , "OK ( SpecFile )" },
+};
+
+
+
+
+
+/*********************************************************************
+ * Function: SpecFile *SfOpen( name, error)
+ *
+ * Description: Opens connection to Spec data file.
+ * Creates index list in memory.
+ *
+ * Parameters:
+ * Input :
+ * (1) Filename
+ * Output:
+ * (2) error number
+ * Returns:
+ * SpecFile pointer.
+ * NULL if not successful.
+ *
+ * Possible errors:
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+
+DllExport SpecFile *
+SfOpen(char *name, int *error) {
+
+ int fd;
+ fd = open(name,SF_OPENFLAG);
+ return (SfOpen2(fd, name, error));
+}
+
+
+
+/*********************************************************************
+ * Function: SpecFile *SfOpen2( fd, name, error)
+ *
+ * Description: Opens connection to Spec data file.
+ * Creates index list in memory.
+ *
+ * Parameters:
+ * Input :
+ * (1) Integer file handle
+ * (2) Filename
+ * Output:
+ * (3) error number
+ * Returns:
+ * SpecFile pointer.
+ * NULL if not successful.
+ *
+ * Possible errors:
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+
+DllExport SpecFile *
+SfOpen2(int fd, char *name,int *error) {
+ SpecFile *sf;
+ short idxret;
+ SfCursor cursor;
+ struct stat mystat;
+
+ if ( fd == -1 ) {
+ *error = SF_ERR_FILE_OPEN;
+ return ( (SpecFile *) NULL );
+ }
+
+ /*
+ * Init specfile strucure
+ */
+#ifdef _WINDOWS
+ static HANDLE hglb;
+ hglb = GlobalAlloc(GPTR,sizeof(SpecFile));
+ sf = (SpecFile * ) GlobalLock(hglb);
+#else
+ sf = (SpecFile *) malloc ( sizeof(SpecFile ));
+#endif
+ stat(name,&mystat);
+
+ sf->fd = fd;
+ sf->m_time = mystat.st_mtime;
+ sf->sfname = (char *)strdup(name);
+
+ sf->list.first = (ObjectList *)NULL;
+ sf->list.last = (ObjectList *)NULL;
+ sf->no_scans = 0;
+ sf->current = (ObjectList *)NULL;
+ sf->scanbuffer = (char *)NULL;
+ sf->scanheadersize = 0;
+ sf->filebuffer = (char *)NULL;
+ sf->filebuffersize = 0;
+
+ sf->no_labels = -1;
+ sf->labels = (char **)NULL;
+ sf->no_motor_names = -1;
+ sf->motor_names = (char **)NULL;
+ sf->no_motor_pos = -1;
+ sf->motor_pos = (double *)NULL;
+ sf->data = (double **)NULL;
+ sf->data_info = (long *)NULL;
+ sf->updating = 0;
+
+ /*
+ * Init cursor
+ */
+ cursor.bytecnt = 0;
+ cursor.cursor = 0;
+ cursor.scanno = 0;
+ cursor.hdafoffset = -1;
+ cursor.dataoffset = -1;
+ cursor.mcaspectra = 0;
+ cursor.what = 0;
+ cursor.data = 0;
+ cursor.file_header = 0;
+
+
+#ifdef SPECFILE_USE_INDEX_FILE
+ /*
+ * Check if index file
+ * open it and continue from there
+ */
+ idxret = sfOpenIndex(sf,&cursor,error);
+#else
+ idxret = SF_INIT;
+#endif
+
+ switch(idxret) {
+ case SF_MODIFIED:
+ sfResumeRead(sf,&cursor,error);
+ sfReadFile(sf,&cursor,error);
+ break;
+
+ case SF_INIT:
+ sfReadFile(sf,&cursor,error);
+ break;
+
+ case SF_READY:
+ break;
+
+ default:
+ break;
+ }
+
+ sf->cursor = cursor;
+
+ /*
+ * Once is all done assign scan numbers and orders
+ */
+ sfAssignScanNumbers(sf);
+
+#ifdef SPECFILE_USE_INDEX_FILE
+ if (idxret != SF_READY) sfWriteIndex(sf,&cursor,error);
+#endif
+ return(sf);
+}
+
+
+
+
+/*********************************************************************
+ *
+ * Function: int SfClose( sf )
+ *
+ * Description: Closes a file previously opened with SfOpen()
+ * and frees all memory .
+ * Parameters:
+ * Input:
+ * File pointer
+ * Returns:
+ * 0 : close successful
+ * -1 : errors occured
+ *
+ *********************************************************************/
+DllExport int
+SfClose( SpecFile *sf )
+{
+ register ObjectList *ptr;
+ register ObjectList *prevptr;
+
+ freeAllData(sf);
+
+ for( ptr=sf->list.last ; ptr ; ptr=prevptr ) {
+ free( (SpecScan *)ptr->contents );
+ prevptr = ptr->prev;
+ free( (ObjectList *)ptr );
+ }
+
+ free ((char *)sf->sfname);
+ if (sf->scanbuffer != NULL)
+ free ((char *)sf->scanbuffer);
+
+ if (sf->filebuffer != NULL)
+ free ((char *)sf->filebuffer);
+
+ if( close(sf->fd) ) {
+ return( -1 ) ;
+ }
+
+ free ( sf );
+ sf = (SpecFile *)NULL;
+
+ return ( 0 );
+}
+
+
+/*********************************************************************
+ *
+ * Function: short SfUpdate( sf, error )
+ *
+ * Description: Updates connection to Spec data file .
+ * Appends to index list in memory.
+ *
+ * Parameters:
+ * Input :
+ * (1) sf (pointer to the index list in memory)
+ * Output:
+ * (2) error number
+ * Returns:
+ * ( 0 ) => Nothing done.
+ * ( 1 ) => File was updated
+ *
+ * Possible errors:
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport short
+SfUpdate ( SpecFile *sf, int *error )
+{
+ struct stat mystat;
+ long mtime;
+ /*printf("In SfUpdate\n");
+ __asm("int3");*/
+ stat(sf->sfname,&mystat);
+
+ mtime = mystat.st_mtime;
+
+ if (sf->m_time != mtime) {
+ sfResumeRead (sf,&(sf->cursor),error);
+ sfReadFile (sf,&(sf->cursor),error);
+
+ sf->m_time = mtime;
+ sfAssignScanNumbers(sf);
+#ifdef SPECFILE_USE_INDEX_FILE
+ sfWriteIndex (sf,&(sf->cursor),error);
+#endif
+ return(1);
+ }else{
+ return(0);
+ }
+}
+
+
+/*********************************************************************
+ *
+ * Function: char *SfError( code )
+ *
+ * Description: Returns the message associated with error 'code'.
+ *
+ * Parameters:
+ * Input : error code
+ *
+ *********************************************************************/
+DllExport char *
+SfError(int code ) {
+ int i;
+
+ for ( i=0 ; errors[i].code!=0 ; i++ ) {
+ if ( errors[i].code == code ) break;
+ }
+ return( errors[i].message );
+}
+
+
+static void
+sfReadFile(SpecFile *sf,SfCursor *cursor,int *error) {
+
+ int fd;
+
+ char *buffer,*ptr;
+
+ long size,bytesread;
+
+ short status;
+
+ fd = sf->fd;
+
+ size = 1024*1024;
+
+
+ if ( (buffer = (char *) malloc(size)) == NULL ) {
+ /*
+ * Try smaller buffer
+ */
+ size = 128 * 128;
+ if ( (buffer = (char *) malloc(size)) == NULL ) {
+ /*
+ * Uhmmm
+ */
+ *error = SF_ERR_MEMORY_ALLOC;
+ free(sf->sfname);
+ free(sf);
+ sf = (SpecFile *)NULL;
+ return;
+ }
+ }
+
+ status = NEWLINE;
+ while ((bytesread = read(fd,buffer,size)) > 0 ) {
+
+ sfStartBuffer(sf,cursor,status,buffer[0],buffer[1],error);
+
+ cursor->bytecnt++;
+ for (ptr=buffer+1;ptr < buffer + bytesread -1; ptr++,cursor->bytecnt++) {
+ if (*(ptr-1) == '\n' ) {
+ sfNewLine(sf,cursor,*ptr,*(ptr+1),error);
+ }
+ }
+
+ cursor->bytecnt++;
+ status = statusEnd(buffer[bytesread-2],buffer[bytesread-1]);
+ }
+
+ free(buffer);
+
+ sf->no_scans = cursor->scanno;
+ /*
+ * Save last
+ */
+ sfSaveScan(sf,cursor,error);
+
+ return;
+
+}
+
+
+static void
+sfResumeRead ( SpecFile *sf, SfCursor *cursor, int *error) {
+ cursor->bytecnt = cursor->cursor;
+ cursor->what = 0;
+ cursor->hdafoffset = -1;
+ cursor->dataoffset = -1;
+ cursor->mcaspectra = 0;
+ cursor->data = 0;
+ cursor->scanno--;
+ sf->updating = 1;
+ lseek(sf->fd,cursor->bytecnt,SEEK_SET);
+ return;
+}
+
+
+#ifdef SPECFILE_USE_INDEX_FILE
+static short
+sfOpenIndex ( SpecFile *sf, SfCursor *cursor, int *error) {
+ char *idxname;
+ short namelength;
+ int sfi;
+
+ namelength = strlen(sf->sfname) + strlen(SF_ISFX) + 1;
+
+ idxname = (char *)malloc(sizeof(char) * namelength);
+
+ sprintf(idxname,"%s%s",sf->sfname,SF_ISFX);
+
+ if ((sfi = open(idxname,SF_OPENFLAG)) == -1) {
+ free(idxname);
+ return(SF_INIT);
+ } else {
+ free(idxname);
+ return(sfReadIndex(sfi,sf,cursor,error));
+ }
+}
+
+
+static short
+sfReadIndex ( int sfi, SpecFile *sf, SfCursor *cursor, int *error) {
+ SfCursor filecurs;
+ char buffer[200];
+ long bytesread,i=0;
+ SpecScan scan;
+ short modif = 0;
+ long mtime;
+
+ /*
+ * read signature
+ */
+ bytesread = read(sfi,buffer,sizeof(SF_SIGNATURE));
+ if (strcmp(buffer,SF_SIGNATURE) || bytesread == 0 ) {
+ return(SF_INIT);
+ }
+
+ /*
+ * read cursor and specfile structure
+ */
+ if ( read(sfi,&mtime, sizeof(long)) == 0) return(SF_INIT);
+ if ( read(sfi,&filecurs, sizeof(SfCursor)) == 0) return(SF_INIT);
+
+ if (sf->m_time != mtime) modif = 1;
+
+ while(read(sfi,&scan, sizeof(SpecScan))) {
+ addToList(&(sf->list), (void *)&scan, (long)sizeof(SpecScan));
+ i++;
+ }
+ sf->no_scans = i;
+
+ memcpy(cursor,&filecurs,sizeof(SfCursor));
+
+ if (modif) return(SF_MODIFIED);
+
+ return(SF_READY);
+}
+
+
+static void
+sfWriteIndex ( SpecFile *sf, SfCursor *cursor, int *error) {
+
+ int fdi;
+ char *idxname;
+ short namelength;
+ ObjectList *obj;
+ long mtime;
+
+ namelength = strlen(sf->sfname) + strlen(SF_ISFX) + 1;
+
+ idxname = (char *)malloc(sizeof(char) * namelength);
+
+ sprintf(idxname,"%s%s",sf->sfname,SF_ISFX);
+
+ /* if ((fdi = open(idxname,SF_WRITEFLAG,SF_UMASK)) == -1) { */
+ if ((fdi = open(idxname,O_CREAT | O_WRONLY,SF_UMASK)) == -1) {
+ printf(" - cannot open. Error: (%d)\n",errno);
+ free(idxname);
+ return;
+ } else {
+ mtime = sf->m_time;
+ write(fdi,SF_SIGNATURE,sizeof(SF_SIGNATURE));
+ /*
+ * Swap bytes for linux
+ */
+ write(fdi, (void *) &mtime, sizeof(long));
+ write(fdi, (void *) cursor, sizeof(SfCursor));
+ for( obj = sf->list.first; obj ; obj = obj->next)
+ write(fdi,(void *) obj->contents, sizeof(SpecScan));
+ close(fdi);
+ free(idxname);
+ return;
+ }
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function: static void sfStartBuffer()
+ *
+ * Description: start analyzing file buffer and takes into account the last
+ * bytes of previous reading as defined in variable status
+ *
+ *****************************************************************************/
+static void
+sfStartBuffer(SpecFile *sf,SfCursor *cursor,short status,char c0,char c1,int *error) {
+
+ if ( status == ANY ) {
+ return;
+ } else if ( status == NEWLINE ) {
+ sfNewLine(sf,cursor,c0,c1,error);
+ } else if ( status == COMMENT ) {
+ cursor->bytecnt--;
+ sfHeaderLine(sf,cursor,c0,error);
+ cursor->bytecnt++;
+ }
+
+}
+
+
+/*******************************************************************************
+ *
+ * Function: static void statusEnd()
+ *
+ * Description: ends analysis of file buffer and returns a variable
+ * indicating staus ( last character is COMMENT,NEWLINE of ANY )
+ *
+ *******************************************************************************/
+static short
+statusEnd(char c2,char c1) {
+
+ if (c2=='\n' && c1=='#') {
+ return(COMMENT);
+ } else if (c1=='\n') {
+ return(NEWLINE);
+ } else {
+ return(ANY);
+ }
+}
+
+
+static void
+sfNewLine(SpecFile *sf,SfCursor *cursor,char c0,char c1,int *error) {
+ if (c0 == '#') {
+ sfHeaderLine(sf,cursor,c1,error);
+ } else if (c0 == '@') {
+ if ( cursor->data == 0 ) {
+ cursor->dataoffset = cursor->bytecnt;
+ cursor->data = 1;
+ }
+ cursor->mcaspectra++;
+ } else if ( isdigit(c0) || c0 == '-' || c0 == '+' || c0 == ' ' || c0 == '\t') {
+ if ( cursor->data == 0 ) {
+ cursor->dataoffset = cursor->bytecnt;
+ cursor->data = 1;
+ }
+ }
+}
+
+
+static void
+sfHeaderLine(SpecFile *sf,SfCursor *cursor,char c,int *error) {
+ if ( c == 'S') {
+ sfNewBlock(sf,cursor,SCAN,error);
+ } else if ( c == 'F') {
+ sfNewBlock(sf,cursor,FILE_HEADER,error);
+ } else {
+ if (cursor->data && cursor->hdafoffset == -1 )
+ cursor->hdafoffset = cursor->bytecnt;
+ }
+}
+
+
+static void
+sfNewBlock(SpecFile *sf,SfCursor *cursor,short newblock,int *error) {
+
+ /*
+ * Dispatch opened block
+ */
+ if (cursor->what == SCAN) {
+ sfSaveScan(sf,cursor,error);
+ } else if ( cursor->what == FILE_HEADER) {
+ cursor->fileh_size = cursor->bytecnt - cursor->cursor + 1;
+ }
+
+ /*
+ * Open new block
+ */
+ if (newblock == SCAN) {
+ cursor->scanno++;
+ cursor->what = SCAN;
+ } else {
+ cursor->file_header = cursor->bytecnt;
+ }
+ cursor->what = newblock;
+ cursor->hdafoffset = -1;
+ cursor->dataoffset = -1;
+ cursor->mcaspectra = 0;
+ cursor->data = 0;
+ cursor->cursor = cursor->bytecnt;
+}
+
+
+static void
+sfSaveScan(SpecFile *sf, SfCursor *cursor,int *error) {
+ SpecScan scan;
+ SpecScan *oldscan;
+ register ObjectList *ptr;
+
+
+ scan.index = cursor->scanno;
+ scan.offset = cursor->cursor;
+ scan.size = cursor->bytecnt - cursor->cursor;
+ scan.last = cursor->bytecnt - 1;
+ scan.data_offset = cursor->dataoffset;
+ scan.hdafter_offset = cursor->hdafoffset;
+ scan.mcaspectra = cursor->mcaspectra;
+ scan.file_header = cursor->file_header;
+
+ if(sf->updating == 1){
+ ptr = sf->list.last;
+ oldscan=(SpecScan *)(ptr->contents);
+ oldscan->index=scan.index;
+ oldscan->offset=scan.offset;
+ oldscan->size=scan.size;
+ oldscan->last=scan.last;
+ oldscan->data_offset=scan.data_offset;
+ oldscan->hdafter_offset=scan.hdafter_offset;
+ oldscan->mcaspectra=scan.mcaspectra;
+ oldscan->file_header=scan.file_header;
+ sf->updating=0;
+ }else{
+ addToList( &(sf->list), (void *)&scan, (long) sizeof(SpecScan));
+ }
+}
+
+
+static void
+sfAssignScanNumbers(SpecFile *sf) {
+
+ int size,i;
+ char *buffer,*ptr;
+
+ char buffer2[50];
+
+ register ObjectList *object,
+ *object2;
+ SpecScan *scan,
+ *scan2;
+
+ size = 50;
+ buffer = (char *) malloc(size);
+
+ for ( object = (sf->list).first; object; object=object->next) {
+ scan = (SpecScan *) object->contents;
+
+ lseek(sf->fd,scan->offset,SEEK_SET);
+ read(sf->fd,buffer,size);
+ buffer[49] = '\0';
+
+ for ( ptr = buffer+3,i=0; *ptr != ' ';ptr++,i++) buffer2[i] = *ptr;
+
+ buffer2[i] = '\0';
+
+ scan->scan_no = atol(buffer2);
+ scan->order = 1;
+ for ( object2 = (sf->list).first; object2 != object; object2=object2->next) {
+ scan2 = (SpecScan *) object2->contents;
+ if (scan2->scan_no == scan->scan_no) scan->order++;
+ }
+ }
+}
+
+void
+printCursor(SfCursor *cursor) {
+ printf("<Cursor>\n");
+ printf(" - Bytecnt: %ld\n",cursor->bytecnt);
+ printf(" - Cursor: %ld\n",cursor->cursor);
+ printf(" - Scanno: %ld\n",cursor->scanno);
+}
diff --git a/silx/io/specfile/src/sflabel.c b/silx/io/specfile/src/sflabel.c
new file mode 100644
index 0000000..70af965
--- /dev/null
+++ b/silx/io/specfile/src/sflabel.c
@@ -0,0 +1,649 @@
+#/*##########################################################################
+# Copyright (C) 2004-2014 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sflabel.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Access to labels and motors
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2003/02/03 13:15:35 $
+ *
+ ************************************************************************/
+/*
+ * Log:
+ * $Log: sflabel.c,v $
+ * Revision 1.3 2003/02/03 13:15:35 rey
+ * Small change in handling of empty spaces at the beginning of the label buffer
+ *
+ * Revision 1.2 2002/11/20 09:56:31 sole
+ * Some macros leave more than 1 space between #L and the first label.
+ * Routine modified to be able to deal with already collected data.
+ * The offending macro(s) should be re-written.
+ *
+ * Revision 1.1 2002/11/20 08:21:34 sole
+ * Initial revision
+ *
+ * Revision 3.0 2000/12/20 14:17:19 rey
+ * Python version available
+ *
+ * Revision 2.2 2000/12/20 12:12:08 rey
+ * bug corrected with SfAllMotors
+ *
+ * Revision 2.1 2000/07/31 19:05:10 19:05:10 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#include <locale_management.h>
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+#include <locale.h>
+#endif
+#endif
+
+/*
+ * Declarations
+ */
+DllExport char * SfLabel ( SpecFile *sf, long index, long column,
+ int *error );
+DllExport long SfAllLabels ( SpecFile *sf, long index, char ***labels,
+ int *error );
+DllExport char * SfMotor ( SpecFile *sf, long index, long number,
+ int *error );
+DllExport long SfAllMotors ( SpecFile *sf, long index, char ***names,
+ int *error );
+DllExport double SfMotorPos ( SpecFile *sf, long index, long number,
+ int *error );
+DllExport double SfMotorPosByName( SpecFile *sf, long index, char *name,
+ int *error );
+DllExport long SfAllMotorPos ( SpecFile *sf, long index, double **pos,
+ int *error );
+
+
+/*********************************************************************
+ * Function: char *SfLabel( sf, index, column, error )
+ *
+ * Description: Reads one label.
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) Scan index
+ * (3) Column number
+ * Output: (4) Error number
+ * Returns:
+ * Pointer to the label ,
+ * or NULL if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => getStrFromArr()
+ * SF_ERR_LABEL_NOT_FOUND
+ * SF_ERR_LINE_EMPTY |
+ * SF_ERR_LINE_NOT_FOUND |
+ * SF_ERR_SCAN_NOT_FOUND | => SfAllLabels()
+ * SF_ERR_FILE_READ |
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport char *
+SfLabel( SpecFile *sf, long index, long column, int *error )
+{
+
+ char **labels=NULL;
+ long no_labels;
+ char *label=NULL;
+ long selection;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return((char *)NULL);
+
+ if (sf->no_labels != -1 ) {
+ no_labels = sf->no_labels;
+ } else {
+ no_labels = SfAllLabels(sf,index,&labels,error);
+ }
+
+ if (no_labels == 0 || no_labels == -1) return((char *)NULL);
+
+ if ( column < 0 ) {
+ selection = no_labels + column;
+ } else {
+ selection = column - 1;
+ }
+
+ if (selection < 0 || selection > no_labels - 1 ) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ if (labels != (char **) NULL )
+ freeArrNZ((void ***)&labels,no_labels);
+ return((char *)NULL);
+ }
+
+ if (labels != (char **)NULL) {
+ label = (char *)strdup(labels[selection]);
+ freeArrNZ((void ***)&labels,no_labels);
+ } else {
+ label = (char *) strdup(sf->labels[selection]);
+ }
+ return( label );
+}
+
+
+/*********************************************************************
+ * Function: long SfAllLabels( sf, index, labels, error )
+ *
+ * Description: Reads all labels in #L lines
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) Scan index
+ * Output: (3) Labels
+ * (4) Error number
+ * Returns:
+ * Number of labels
+ * ( -1 ) if error.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC ||=> cpyStrArr(),lines2words()
+ * SF_ERR_SCAN_NOT_FOUND | => SfHeader()
+ * SF_ERR_FILE_READ |
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_LINE_NOT_FOUND
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfAllLabels( SpecFile *sf, long index, char ***labels, int *error )
+{
+ static char tmplab[40];
+
+ char **labarr;
+ char *onelabel;
+
+ char *ptr,
+ *buf=NULL;
+
+ long no_labels = 0;
+ short i;
+
+ /*
+ * select scan
+ */
+ if (sfSetCurrent(sf,index,error) == -1) {
+ *labels = NULL;
+ return(0);
+ }
+
+ /*
+ * Do not do it if already done
+ */
+ if (sf->labels != (char **)NULL ) {
+ labarr = (char **)malloc(sizeof(char *) * sf->no_labels);
+ for ( i=0;i<sf->no_labels;i++)
+ labarr[i] = (char *)strdup(sf->labels[i]);
+ *labels = labarr;
+ return(sf->no_labels);
+ }
+
+ /*
+ * else..
+ */
+ if (sfGetHeaderLine(sf,FROM_SCAN,SF_LABEL,&buf,error) == -1) {
+ *labels = NULL;
+ return(0);
+ }
+
+ if ( buf[0] == '\0') {
+ *labels = NULL;
+ return(0);
+ }
+
+ if ( (labarr = (char **)malloc( sizeof(char *))) == (char **)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ no_labels = 0;
+ i = 0;
+
+ /*
+ * avoid problem of having too many spaces at the beginning
+ * with bad written macros -> added check for empty string
+ *
+ * get rid of spaces at the beginning of the string buffer
+ */
+
+ ptr = buf;
+ while((ptr < buf + strlen(buf) -1) && (*ptr == ' ')) ptr++;
+
+ for (i=0;ptr < buf + strlen(buf) -1;ptr++,i++) {
+ if (*ptr==' ' && *(ptr+1) == ' ') { /* two spaces delimits one label */
+ tmplab[i] = '\0';
+
+ labarr = (char **)realloc( labarr, (no_labels+1) * sizeof(char *));
+ onelabel = (char *) malloc (i+2);
+ strcpy(onelabel,tmplab);
+ labarr[no_labels] = onelabel;
+
+ no_labels++;
+ i=-1;
+ for(;*(ptr+1) == ' ' && ptr < buf+strlen(buf)-1;ptr++);
+ } else {
+ tmplab[i] = *ptr;
+ }
+ }
+
+ if (*ptr != ' ') {
+ tmplab[i] = *ptr;
+ i++;
+ }
+ tmplab[i] = '\0';
+
+ labarr = (char **)realloc( labarr, (no_labels+1) * sizeof(char *));
+ onelabel = (char *) malloc (i+2);
+ strcpy(onelabel,tmplab);
+ labarr[no_labels] = onelabel;
+
+ no_labels++;
+
+ /*
+ * Save in specfile structure
+ */
+ sf->no_labels = no_labels;
+ sf->labels = (char **) malloc( sizeof(char *) * no_labels);
+ for (i=0;i<no_labels;i++)
+ sf->labels[i] = (char *) strdup(labarr[i]);
+
+ *labels = labarr;
+ return( no_labels );
+}
+
+
+/*********************************************************************
+ * Function: long SfAllMotors( sf, index, names, error )
+ *
+ * Description: Reads all motor names in #O lines (in file header)
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) Scan index
+ * Output: (3) Names
+ * (4) Error number
+ * Returns:
+ * Number of found names
+ * ( -1 ) if errors.
+ * Possible errors:
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_MEMORY_ALLOC || => cpyStrArr(),lines2words()
+ * SF_ERR_FILE_READ |
+ * SF_ERR_HEADER_NOT_FOUND | => SfFileHeader()
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfAllMotors( SpecFile *sf, long index, char ***names, int *error )
+{
+ char **lines;
+ char *thisline,
+ *endline;
+
+ char **motarr;
+ char *onemot;
+
+ static char tmpmot[40];
+
+ char *ptr;
+
+ long motct = 0;
+ long no_lines;
+ short i,j;
+
+ /*
+ * go to scan
+ */
+ if (sfSetCurrent(sf,index,error) == -1) {
+ *names = NULL;
+ return(0);
+ }
+
+ /*
+ * if motor names for this scan have already been read
+ */
+ if (sf->motor_names != (char **)NULL) {
+ motarr = (char **)malloc(sizeof(char *) * sf->no_motor_names);
+ for (i=0;i<sf->no_motor_names;i++) {
+ motarr[i] = (char *) strdup (sf->motor_names[i]);
+ }
+ *names = motarr;
+ return(sf->no_motor_names);
+ }
+
+ /*
+ * else
+ */
+ no_lines = SfHeader(sf, index,"O",&lines,error);
+ if (no_lines == -1 || no_lines == 0 ) {
+ *names = (char **) NULL;
+ return(-1);
+ }
+
+ if ( (motarr = (char **)malloc( sizeof(char *))) == (char **)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ motct = 0;
+
+ for (j=0;j<no_lines;j++) {
+ thisline = lines[j] + 4;
+ endline = thisline + strlen(thisline);
+ for(ptr=thisline;*ptr == ' ';ptr++);
+ for (i=0;ptr < endline -2;ptr++,i++) {
+ if (*ptr==' ' && *(ptr+1) == ' ') {
+ tmpmot[i] = '\0';
+
+ motarr = (char **)realloc( motarr, (motct+1) * sizeof(char *));
+ onemot = (char *) malloc (i+2);
+ strcpy(onemot,tmpmot);
+ motarr[motct] = onemot;
+
+ motct++;
+ i=-1;
+ for(;*(ptr+1) == ' ' && ptr < endline -1;ptr++);
+ } else {
+ tmpmot[i] = *ptr;
+ }
+ }
+ if (*ptr != ' ') { tmpmot[i] = *ptr; i++; }
+ ptr++;
+ if (*ptr != ' ') { tmpmot[i] = *ptr; i++; }
+
+ tmpmot[i] = '\0';
+ motarr = (char **)realloc( motarr, (motct+1) * sizeof(char *));
+
+ onemot = (char *) malloc (i+2);
+ strcpy(onemot,tmpmot);
+ motarr[motct] = onemot;
+
+ motct++;
+
+ }
+
+ /*
+ * Save in specfile structure
+ */
+ sf->no_motor_names = motct;
+ sf->motor_names = (char **)malloc(sizeof(char *) * motct);
+ for (i=0;i<motct;i++) {
+ sf->motor_names[i] = (char *)strdup(motarr[i]);
+ }
+
+ *names = motarr;
+ return( motct );
+
+}
+
+
+DllExport char *
+SfMotor( SpecFile *sf, long index, long motnum, int *error )
+{
+
+ char **motors=NULL;
+ long nb_mot;
+ char *motor=NULL;
+ long selection;
+
+ /*
+ * go to scan
+ */
+ if (sfSetCurrent(sf,index,error) == -1) {
+ return((char *)NULL);
+ }
+
+ if ( sf->no_motor_names != -1 ) {
+ nb_mot = sf->no_motor_names;
+ } else {
+ nb_mot = SfAllMotors(sf,index,&motors,error);
+ }
+
+ if (nb_mot == 0 || nb_mot == -1) return((char *)NULL);
+
+ if ( motnum < 0 ) {
+ selection = nb_mot + motnum;
+ } else {
+ selection = motnum - 1;
+ }
+
+ if (selection < 0 || selection > nb_mot - 1 ) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ if (motors != (char **) NULL)
+ freeArrNZ((void ***)&motors,nb_mot);
+ return((char *)NULL);
+ }
+
+ if (motors != (char **) NULL) {
+ motor = (char *)strdup(motors[selection]);
+ freeArrNZ((void ***)&motors,nb_mot);
+ } else {
+ motor = (char *)strdup(sf->motor_names[selection]);
+ }
+ return( motor );
+}
+
+
+DllExport long
+SfAllMotorPos ( SpecFile *sf, long index, double **retpos, int *error )
+{
+ char **lines;
+ char *thisline,
+ *endline;
+
+ double *posarr;
+
+ static double pos[200];
+ static char posstr[40];
+
+ char *ptr;
+
+ long motct = 0;
+ long no_lines;
+ short i,j;
+
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ char *currentLocaleBuffer;
+ char localeBuffer[21];
+#endif
+#endif
+
+ if (sfSetCurrent(sf,index,error) == -1) {
+ *retpos = (double *) NULL;
+ return(0);
+ }
+
+ /*
+ * if motors position for this scan have already been read
+ */
+ if (sf->motor_pos != (double *)NULL) {
+ posarr = (double *)malloc(sizeof(double) * sf->no_motor_pos);
+ for (i=0;i<sf->no_motor_pos;i++) {
+ posarr[i] = sf->motor_pos[i];
+ }
+ *retpos = posarr;
+ return(sf->no_motor_pos);
+ }
+
+ /*
+ * else
+ */
+ no_lines = SfHeader(sf, index,"P",&lines,error);
+
+ if (no_lines == -1 || no_lines == 0 ) {
+ *retpos = (double *) NULL;
+ return(-1);
+ }
+
+ motct = 0;
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ currentLocaleBuffer = setlocale(LC_NUMERIC, NULL);
+ strcpy(localeBuffer, currentLocaleBuffer);
+ setlocale(LC_NUMERIC, "C\0");
+#endif
+#endif
+ for (j=0;j<no_lines;j++) {
+ thisline = lines[j] + 4;
+ endline = thisline + strlen(thisline);
+ for(ptr=thisline;*ptr == ' ';ptr++);
+ for (i=0;ptr < endline -1;ptr++,i++) {
+ if (*ptr==' ') {
+ posstr[i] = '\0';
+
+ pos[motct] = PyMcaAtof(posstr);
+
+ motct++;
+ i=-1;
+ for(;*(ptr+1) == ' ' && ptr < endline -1;ptr++);
+ } else {
+ posstr[i] = *ptr;
+ }
+ }
+ if (*ptr != ' ') {
+ posstr[i] = *ptr;
+ i++;
+ }
+ posstr[i] = '\0';
+ pos[motct] = PyMcaAtof(posstr);
+
+ motct++;
+
+ }
+
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ setlocale(LC_NUMERIC, localeBuffer);
+#endif
+#endif
+
+ /*
+ * Save in specfile structure
+ */
+ sf->no_motor_pos = motct;
+ sf->motor_pos = (double *)malloc(sizeof(double) * motct);
+ memcpy(sf->motor_pos,pos,motct * sizeof(double));
+
+ /*
+ * and return
+ */
+ posarr = (double *) malloc ( sizeof(double) * motct ) ;
+ memcpy(posarr,pos,motct * sizeof(double));
+
+ *retpos = posarr;
+
+ return( motct );
+}
+
+
+DllExport double
+SfMotorPos( SpecFile *sf, long index, long motnum, int *error )
+{
+
+ double *motorpos=NULL;
+ long nb_mot;
+ double retpos;
+ long selection;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(HUGE_VAL);
+
+ if (sf->no_motor_pos != -1 ) {
+ nb_mot = sf->no_motor_pos;
+ } else {
+ nb_mot = SfAllMotorPos(sf,index,&motorpos,error);
+ }
+
+ if (nb_mot == 0 || nb_mot == -1) return(HUGE_VAL);
+
+ if ( motnum < 0 ) {
+ selection = nb_mot + motnum;
+ } else {
+ selection = motnum - 1;
+ }
+
+ if (selection < 0 || selection > nb_mot - 1 ) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ if (motorpos != (double *)NULL)
+ free(motorpos);
+ return(HUGE_VAL);
+ }
+
+ if (motorpos != (double *)NULL) {
+ retpos = motorpos[selection];
+ free(motorpos);
+ } else {
+ retpos = sf->motor_pos[selection];
+ }
+ return( retpos );
+}
+
+
+DllExport double
+SfMotorPosByName( SpecFile *sf, long index, char *name, int *error )
+{
+ char **motors=NULL;
+
+ long nb_mot,
+ idx,
+ selection;
+ short tofree=0;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(HUGE_VAL);
+
+ if ( sf->no_motor_names != -1 ) {
+ nb_mot = sf->no_motor_names;
+ motors = sf->motor_names;
+ } else {
+ nb_mot = SfAllMotors(sf,index,&motors,error);
+ tofree=1;
+ }
+
+ if (nb_mot == 0 || nb_mot == -1) return(HUGE_VAL);
+
+ for (idx = 0;idx<nb_mot;idx++) {
+ if (!strcmp(name,motors[idx])) break;
+ }
+
+ if (idx == nb_mot) {
+ if (tofree) freeArrNZ((void ***)&motors,nb_mot);
+ *error = SF_ERR_MOTOR_NOT_FOUND;
+ return(HUGE_VAL);
+ }
+
+ selection = idx+1;
+
+ return(SfMotorPos(sf,index,selection,error));
+}
diff --git a/silx/io/specfile/src/sflists.c b/silx/io/specfile/src/sflists.c
new file mode 100644
index 0000000..3fcb9a7
--- /dev/null
+++ b/silx/io/specfile/src/sflists.c
@@ -0,0 +1,184 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sflists.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions to handle lists
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2003/03/06 17:00:42 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sflists.c,v $
+ * Log: Revision 1.1 2003/03/06 17:00:42 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:03:25 19:03:25 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <Lists.h>
+
+/*
+ * Function declaration
+ */
+ObjectList * findInList ( ListHeader *list, int (*proc)(void *,void *), void *value );
+long addToList ( ListHeader *list, void *object, long size );
+void unlinkFromList ( ListHeader *list, ObjectList *element );
+
+static long linkToList ( ListHeader *list, void *object );
+
+
+/*********************************************************************
+ * Function: ObjectList *findInList( list, proc, value )
+ *
+ * Description: Looks for an list element.
+ *
+ * Parameters:
+ * Input : (1) ListHeader pointer
+ * (2) Comp. procedure
+ * (3) value
+ * Returns:
+ * Pointer to the found element ,
+ * NULL if not found .
+ *
+ *********************************************************************/
+ObjectList *
+findInList( ListHeader *list, int (*proc)(void * , void *), void *value )
+{
+ register ObjectList *ptr;
+
+ for ( ptr=list->first ; ptr ; ptr=ptr->next ) {
+ if ( (*proc)(ptr->contents, value) ) {
+ return( ptr );
+ }
+ }
+ return (ObjectList *)NULL;
+}
+
+
+/*********************************************************************
+ * Function: int addToList( list, object, size )
+ *
+ * Description: Adds an element to the list.
+ *
+ * Parameters:
+ * Input : (1) List pointer
+ * (2) Pointer to the new element
+ * (3) Size of the new element
+ * Returns:
+ * ( 0 ) => OK
+ * ( -1 ) => error
+ *
+ *********************************************************************/
+long
+addToList( ListHeader *list, void *object, long size )
+{
+ void *newobj;
+
+ if ( (newobj = (void *)malloc(size)) == (void *)NULL ) return( -1 );
+ memcpy(newobj, object, size);
+
+ return( linkToList( list, newobj ) );
+
+}
+
+
+/*********************************************************************
+ * Function: int linkToList( list, object )
+ *
+ * Description: Adds an element to the list.
+ *
+ * Parameters:
+ * Input: (1) ListHeader pointer
+ * (2) pointer to the new element
+ * Returns:
+ * ( 0 ) => OK
+ * ( -1 ) => error
+ *
+ *********************************************************************/
+static long
+linkToList( ListHeader *list, void *object )
+{
+ ObjectList *newobj;
+
+
+ if ((newobj = (ObjectList *) malloc(sizeof(ObjectList))) ==
+ (ObjectList *) NULL) return( -1 );
+
+ newobj->contents = object;
+ newobj->prev = list->last;
+ newobj->next = NULL;
+
+ if (list->first == (ObjectList *)NULL) {
+ list->first = newobj;
+ } else {
+ (list->last)->next = newobj;
+ }
+
+ list->last = newobj;
+ return( 0 );
+}
+
+
+/*********************************************************************
+ * Function: int unlinkFromList( list, element )
+ *
+ * Description: Removes an element from the list.
+ *
+ * Parameters:
+ * Input : (1) List pointer
+ * (2) Pointer to the element
+ *
+ *********************************************************************/
+void
+unlinkFromList( ListHeader *list, ObjectList *element )
+{
+
+ if ( element != (ObjectList *)NULL ) {
+ if ( element->next != (ObjectList *)NULL ) {
+ element->next->prev = element->prev;
+ }
+ else {
+ list->last = element->prev ;
+ }
+ if ( element->prev != (ObjectList *)NULL ) {
+ element->prev->next = element->next;
+ }
+ else {
+ list->first = element->next;
+ }
+ free( element->contents );
+ free( element );
+ }
+}
+
diff --git a/silx/io/specfile/src/sfmca.c b/silx/io/specfile/src/sfmca.c
new file mode 100644
index 0000000..22d1958
--- /dev/null
+++ b/silx/io/specfile/src/sfmca.c
@@ -0,0 +1,336 @@
+#/*##########################################################################
+# Copyright (C) 2004-2014 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfmca.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Access to MCA spectra
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2002/11/15 16:25:44 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfmca.c,v $
+ * Log: Revision 1.3 2002/11/15 16:25:44 sole
+ * Log: free(retline) replaced by freeArrNZ((void ***) &retline,nb_lines); to eliminate the memory leak when reading mca
+ * Log:
+ * Log: Revision 1.2 2002/11/15 10:44:36 sole
+ * Log: added free(retline) after call to SfHeader
+ * Log:
+ * Log: Revision 1.1 2002/11/15 10:17:38 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:12 19:05:12 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#include <locale_management.h>
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+#include <locale.h>
+#endif
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+/*
+ * Define macro
+ */
+#define isnumber(this) ( isdigit(this) || this == '-' || this == '+' || this =='e' || this == 'E' || this == '.' )
+
+/*
+ * Mca continuation character
+ */
+#define MCA_CONT '\\'
+#define D_INFO 3
+
+/*
+ * Declarations
+ */
+DllExport long SfNoMca ( SpecFile *sf, long index, int *error );
+DllExport int SfGetMca ( SpecFile *sf, long index, long mcano,
+ double **retdata, int *error );
+DllExport long SfMcaCalib ( SpecFile *sf, long index, double **calib,
+ int *error );
+
+
+/*********************************************************************
+ * Function: long SfNoMca( sf, index, error )
+ *
+ * Description: Gets number of mca spectra in a scan
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of data lines ,
+ * ( -1 ) => errors.
+ * Possible errors:
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfNoMca( SpecFile *sf, long index, int *error )
+{
+
+ if (sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+ return( ((SpecScan *)sf->current->contents)->mcaspectra );
+
+}
+
+
+/*********************************************************************
+ * Function: int SfGetMca(sf, index, number, data, error)
+ *
+ * Description: Gets data.
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) Data array
+ * (4) Data info : [0] => no_lines
+ * [1] => no_columns
+ * [2] = ( 0 ) => regular
+ * ( 1 ) => not regular !
+ * (5) error number
+ * Returns:
+ * ( 0 ) => OK
+ * ( -1 ) => errors occured
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport int
+SfGetMca( SpecFile *sf, long index, long number, double **retdata, int *error )
+{
+ double *data = NULL;
+ long headersize;
+ int old_fashion;
+ static char* last_from = NULL;
+ static char* last_pos = NULL;
+ static long last_number = 0;
+ long int scanno = 0;
+ static long int last_scanno = 0;
+ char *ptr,
+ *from,
+ *to;
+
+ char strval[100];
+ double val;
+
+ int i,spect_no=0;
+ long vals;
+
+ long blocks=1,
+ initsize=1024;
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ char *currentLocaleBuffer;
+ char localeBuffer[21];
+#endif
+#endif
+
+ headersize = ((SpecScan *)sf->current->contents)->data_offset
+ - ((SpecScan *)sf->current->contents)->offset;
+
+ scanno = ((SpecScan *)sf->current->contents)->scan_no;
+
+ /*
+ * check that mca number is available
+ */
+ if (number < 1) {
+ *error = SF_ERR_MCA_NOT_FOUND;
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ /*
+ * Get MCA info from header
+ */
+
+ from = sf->scanbuffer + headersize;
+ to = sf->scanbuffer + ((SpecScan *)sf->current->contents)->size;
+
+ old_fashion = 1;
+ if (last_scanno == scanno)
+ {
+ if (last_from == from)
+ {
+ /* same scan as before */
+ if (number > last_number)
+ {
+ spect_no = last_number;
+ old_fashion = 0;
+ }
+ }
+ }
+ if (old_fashion)
+ {
+ last_scanno = scanno;
+ last_from = from;
+ spect_no = 0;
+ last_pos = from;
+ }
+ /*
+ * go and find the beginning of spectrum
+ */
+ ptr = last_pos;
+
+ if ( *ptr == '@' ) {
+ spect_no++;
+ ptr++;
+ last_pos = ptr;
+ }
+
+ while ( spect_no != number && ptr < to ) {
+ if (*ptr == '@') spect_no++;
+ ptr++;
+ last_pos = ptr;
+ }
+ ptr++;
+
+ if ( spect_no != number ) {
+ *error = SF_ERR_MCA_NOT_FOUND;
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+ last_number = spect_no;
+ /*
+ * Calculate size and book memory
+ */
+ initsize = 2048;
+
+ i = 0;
+ vals = 0;
+
+ /*
+ * Alloc memory
+ */
+ if ((data = (double *)malloc (sizeof(double) * initsize)) == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ /*
+ * continue
+ */
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ currentLocaleBuffer = setlocale(LC_NUMERIC, NULL);
+ strcpy(localeBuffer, currentLocaleBuffer);
+ setlocale(LC_NUMERIC, "C\0");
+#endif
+#endif
+ for ( ;(*(ptr+1) != '\n' || (*ptr == MCA_CONT)) && ptr < to - 1 ; ptr++)
+ {
+ if (*ptr == ' ' || *ptr == '\t' || *ptr == '\\' || *ptr == '\n') {
+ if ( i ) {
+ if ( vals%initsize == 0 ) {
+ blocks++;
+ if ((data = (double *)realloc (data, sizeof(double) * blocks * initsize))
+ == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ setlocale(LC_NUMERIC, localeBuffer);
+#endif
+#endif
+ return(-1);
+ }
+
+ }
+ strval[i] = '\0';
+ i = 0;
+ val = PyMcaAtof(strval);
+ data[vals] = val;
+ vals++;
+ }
+ } else if (isnumber(*ptr)) {
+ strval[i] = *ptr;
+ i++;
+ }
+ }
+
+ if (isnumber(*ptr)) {
+ strval[i] = *ptr;
+ strval[i+1] = '\0';
+ val = PyMcaAtof(strval);
+ data[vals] = val;
+ vals++;
+ }
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ setlocale(LC_NUMERIC, localeBuffer);
+#endif
+#endif
+
+ *retdata = data;
+
+ return( vals );
+}
+
+
+DllExport long
+SfMcaCalib ( SpecFile *sf, long index, double **calib, int *error )
+{
+
+ long nb_lines;
+ char **retline;
+ char *strptr;
+
+ double val1,val2,val3;
+
+ double *retdata;
+
+ nb_lines = SfHeader(sf,index,"@CALIB",&retline,error);
+
+ if (nb_lines > 0) {
+ strptr = retline[0] + 8;
+ sscanf(strptr,"%lf %lf %lf",&val1,&val2,&val3);
+ } else {
+ *calib = (double *)NULL;
+ return(-1);
+ }
+
+ retdata = (double *) malloc(sizeof(double) * 3 );
+ retdata[0] = val1; retdata[1] = val2; retdata[2] = val3;
+
+ *calib = retdata;
+ return(0);
+}
diff --git a/silx/io/specfile/src/sftools.c b/silx/io/specfile/src/sftools.c
new file mode 100644
index 0000000..74ae311
--- /dev/null
+++ b/silx/io/specfile/src/sftools.c
@@ -0,0 +1,550 @@
+#/*##########################################################################
+# Copyright (C) 2004-2016 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sftools.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: General library tools
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2004/05/12 16:57:02 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sftools.c,v $
+ * Log: Revision 1.2 2004/05/12 16:57:02 sole
+ * Log: Windows support
+ * Log:
+ * Log: Revision 1.1 2003/09/12 10:34:11 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Log: Revision 2.2 2000/12/20 12:12:08 rey
+ * Log: bug corrected with SfAllMotors
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:07 19:05:07 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#else
+#include <unistd.h>
+#endif
+
+/*
+ * Library Functions
+ */
+DllExport void freePtr ( void *ptr );
+DllExport void freeArrNZ ( void ***ptr, long lines );
+DllExport void SfShow (SpecFile *sf);
+DllExport void SfShowScan (SpecFile *sf, long index);
+
+/*
+ * Function declaration
+ */
+void freeArr ( void ***ptr, long lines );
+
+int sfSetCurrent ( SpecFile *sf, long index, int *error );
+int sfSameFile ( SpecFile *sf, ObjectList *list );
+int sfSameScan ( SpecFile *sf, long index );
+
+int findIndex ( void *scan, void *number );
+int findNoAndOr ( void *scan, void *number );
+int findFirst ( void *scan, void *file_offset );
+ObjectList *findScanByIndex ( ListHeader *list, long index );
+ObjectList *findFirstInFile ( ListHeader *list, long file_offset );
+ObjectList *findScanByNo ( ListHeader *list, long scan_no, long order );
+
+long mulstrtod ( char *str, double **arr, int *error );
+void freeAllData ( SpecFile *sf );
+
+/*
+ * Globals
+ */
+
+
+/*********************************************************************
+ * Function: void sfSetCurrent( sf, list )
+ *
+ * Description: Sets 'list' to current scan.
+ * Updates SpecFile structure.
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) New scan
+ *
+ *********************************************************************/
+int
+sfSetCurrent( SpecFile *sf, long index,int *error )
+{
+ ObjectList *list,
+ *flist;
+ SpecScan *scan,
+ *fscan;
+ long nbytes;
+ long fileheadsize,start;
+
+ /*
+ * If same scan nothing to do
+ */
+ if (sfSameScan(sf,index)) return(0);
+
+ /*
+ * It is a new scan. Free memory allocated for previous one.
+ */
+ freeAllData(sf);
+
+ /*
+ * Find scan
+ */
+ list = findScanByIndex(&(sf->list),index);
+
+ if (list == (ObjectList *)NULL) {
+ *error = SF_ERR_SCAN_NOT_FOUND;
+ return(-1);
+ }
+
+ /*
+ * Read full scan into buffer
+ */
+ scan = list->contents;
+
+ if (sf->scanbuffer != ( char * ) NULL) free(sf->scanbuffer);
+
+ sf->scanbuffer = ( char *) malloc(scan->size);
+
+ if (sf->scanbuffer == (char *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ lseek(sf->fd,scan->offset,SEEK_SET);
+
+ nbytes = read(sf->fd,sf->scanbuffer,scan->size);
+ if ( nbytes == -1) {
+ *error = SF_ERR_FILE_READ;
+ return(-1);
+ }
+ if ( sf->scanbuffer[0] != '#' || sf->scanbuffer[1] != 'S') {
+ *error = SF_ERR_FILE_READ;
+ return(-1);
+ }
+ sf->scanheadersize = scan->data_offset - scan->offset;
+
+ /*
+ * if different file read fileheader also
+ */
+ if (!sfSameFile(sf,list)) {
+ if (sf->filebuffer != ( char * ) NULL) free(sf->filebuffer);
+
+ start = scan->file_header;
+ flist = findFirstInFile(&(sf->list),scan->file_header);
+ if (flist == (ObjectList *) NULL) {
+ fileheadsize = 0;
+ sf->filebuffersize = fileheadsize;
+ }
+ else
+ {
+ fscan = flist->contents;
+ fileheadsize = fscan->offset - start;
+ }
+
+ if (fileheadsize > 0) {
+ sf->filebuffer = ( char *) malloc(fileheadsize);
+ if (sf->filebuffer == (char *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+ lseek(sf->fd,start,SEEK_SET);
+ read(sf->fd,sf->filebuffer,fileheadsize);
+ if ( nbytes == -1) {
+ *error = SF_ERR_FILE_READ;
+ return(-1);
+ }
+ sf->filebuffersize = fileheadsize;
+ }
+ }
+ sf->scansize = scan->size;
+ sf->current = list;
+
+ return(1);
+}
+
+
+/*********************************************************************
+ * Function: int sfSameFile( sf, list )
+ *
+ * Description: Checks if the current scan file header and
+ * the new scan file header are the same.
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) New scan
+ * Returns:
+ * 1 - the same
+ * 0 - not the same
+ *
+ *********************************************************************/
+int
+sfSameFile( SpecFile *sf, ObjectList *list )
+{
+ if (sf->current) {
+ return ( ((SpecScan *)sf->current->contents)->file_header ==
+ ((SpecScan *)list->contents)->file_header );
+ } else return(0);
+}
+
+
+/*********************************************************************
+ * Function: int sfSameScan( sf, index )
+ *
+ * Description: Checks if the current scan and
+ * the new scan are the same.
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) New scan index
+ * Returns:
+ * 1 - the same
+ * 0 - not the same
+ *
+ *********************************************************************/
+int
+sfSameScan( SpecFile *sf, long index )
+{
+ if ( sf->current == (ObjectList *)NULL) return(0);
+
+ return ( ((SpecScan *)sf->current->contents)->index == index );
+}
+
+
+/*********************************************************************
+ * Function: freePtr( ptr );
+ *
+ * Description: Frees memory pointed to by 'ptr'.
+ *
+ * Parameters:
+ * Input : (1) Pointer
+ *
+ *********************************************************************/
+void
+freePtr( void *ptr )
+{
+ free( ptr );
+}
+
+
+/*********************************************************************
+ * Function: freeArrNZ( ptr, lines );
+ *
+ * Description: Frees an array if 'lines' > zero.
+ *
+ * Parameters:
+ * Input : (1) Array pointer
+ * (2) No. of lines
+ *
+ *********************************************************************/
+void
+freeArrNZ( void ***ptr, long lines )
+{
+ if ( *ptr != (void **)NULL && lines > 0 ) {
+ for ( ; lines ; lines-- ) {
+ free( (*ptr)[lines-1] );
+ }
+ free( *ptr );
+ *ptr = ( void **)NULL ;
+ }
+}
+
+
+/*********************************************************************
+ * Function: freeArr( ptr, lines );
+ *
+ * Description: Frees an array.
+ * 'ptr' will be always freed !!!
+ *
+ * Parameters:
+ * Input : (1) Array pointer
+ * (2) No. of lines
+ *
+ *********************************************************************/
+void
+freeArr( void ***ptr, long lines )
+{
+ if ( *ptr != (void **)NULL ) {
+ if ( lines > 0 ) {
+ for ( ; lines ; lines-- ) {
+ free( (*ptr)[lines-1] );
+ }
+ }
+ free( *ptr );
+ *ptr = ( void **)NULL ;
+ }
+}
+
+
+/*********************************************************************
+ * Function: int findIndex( scan, number )
+ *
+ * Description: Compares if number == scan index .
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) number
+ * Returns:
+ * 0 : not found
+ * 1 : found
+ *
+ *********************************************************************/
+int
+findIndex( void *scan, void *number )
+{
+ return( ((SpecScan *)scan)->index == *(long *)number );
+}
+
+
+/*********************************************************************
+ * Function: int findFirst( scan, file_offset )
+ *
+ * Description: Compares if scan offset > file_offset
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) number
+ * Returns:
+ * 0 : not found
+ * 1 : found
+ *
+ *********************************************************************/
+int
+findFirst( void *scan, void *file_offset )
+{
+ return( ((SpecScan *)scan)->offset > *(long *)file_offset );
+}
+
+
+/*********************************************************************
+ * Function: int findNoAndOr( scan, number )
+ * ( Number
+ * Order )
+ *
+ * Description: Compares if number1 = scan number and
+ * number2 = scan order
+ * Parameters:
+ * Input: (1) SpecScan pointer
+ * (2) number[1]
+ * Returns:
+ * 0 : not found
+ * 1 : found
+ *
+ *********************************************************************/
+int
+findNoAndOr( void *scan, void *number )
+{
+
+ long *n = (long *)number;
+
+ return( ( ((SpecScan *)scan)->scan_no == *n++ ) && ( ((SpecScan *)scan)->order == *n ));
+}
+
+
+/*********************************************************************
+ * Function: ObjectList *findScanByIndex( list, index )
+ *
+ * Description: Looks for a scan .
+ *
+ * Parameters:
+ * Input: (1) List pointer
+ * (2) scan index
+ * Returns:
+ * ObjectList pointer if found ,
+ * NULL if not.
+ *
+ *********************************************************************/
+ObjectList *
+findScanByIndex( ListHeader *list, long index )
+{
+ return findInList( list, findIndex, (void *)&index );
+}
+
+
+/*********************************************************************
+ * Function: ObjectList findScanByNo( list, scan_no, order )
+ *
+ * Description: Looks for a scan .
+ *
+ * Parameters:
+ * Input: (1) List pointer
+ * (2) scan number
+ * (3) scan order
+ * Returns:
+ * ObjectList pointer if found ,
+ * NULL if not.
+ *
+ *********************************************************************/
+ObjectList *
+findScanByNo( ListHeader *list, long scan_no, long order )
+{
+ long value[2];
+
+ value[0] = scan_no;
+ value[1] = order;
+
+ return( findInList( (void *)list, findNoAndOr, (void *)value) );
+}
+
+
+
+/*********************************************************************
+ * Function: ObjectList *findFirstInFile( list, file_offset )
+ *
+ * Description: Looks for a scan .
+ *
+ * Parameters:
+ * Input: (1) List pointer
+ * (2) scan index
+ * Returns:
+ * ObjectList pointer if found ,
+ * NULL if not.
+ *
+ *********************************************************************/
+ObjectList *
+findFirstInFile( ListHeader *list, long file_offset )
+{
+ return findInList( list, findFirst, (void *)&file_offset );
+}
+
+
+/*********************************************************************
+ * Function: long mulstrtod( str, arr, error )
+ *
+ * Description: Converts string to data array.( double array )
+ *
+ * Parameters:
+ * Input : (1) String
+ *
+ * Output:
+ * (2) Data array
+ * (3) error number
+ * Returns:
+ * Number of values.
+ * ( -1 ) in case of errors.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+long
+mulstrtod( char *str, double **arr, int *error )
+{
+ int count,q,i=0;
+ double *ret;
+ char *str2;
+ static double tmpret[200];
+
+ *arr = (double *)NULL;
+
+ str2 = str;
+
+ while( (q = sscanf(str2, "%lf%n", &(tmpret[i]), &count)) > 0 ) {
+ i++;
+ str2 += count;
+ }
+ str2++;
+
+ if ( !i ) {
+ return( i );
+ }
+
+ ret = (double *)malloc( sizeof(double) * i );
+
+ if ( ret == (double *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ memcpy(ret, tmpret, i * sizeof(double) );
+
+ *arr = ret;
+ return( i );
+}
+
+void
+freeAllData(SpecFile *sf)
+{
+ if (sf->motor_pos != (double *)NULL) {
+ free(sf->motor_pos);
+ sf->motor_pos = (double *)NULL;
+ sf->no_motor_pos = -1;
+ }
+ if (sf->motor_names != (char **)NULL) {
+ freeArrNZ((void ***)&(sf->motor_names),sf->no_motor_names);
+ sf->motor_names = (char **)NULL;
+ sf->no_motor_names = -1;
+ }
+ if (sf->labels != (char **)NULL) {
+ freeArrNZ((void ***)&(sf->labels),sf->no_labels);
+ sf->labels = (char **)NULL;
+ sf->no_labels = -1;
+ }
+ if (sf->data_info != (long *)NULL) {
+ freeArrNZ((void ***)&(sf->data),sf->data_info[ROW]);
+ free(sf->data_info);
+ sf->data = (double **)NULL;
+ sf->data_info = (long *)NULL;
+ }
+}
+
+DllExport void
+SfShow (SpecFile *sf) {
+ printf("<Showing Info> - specfile: %s\n",sf->sfname);
+ printf(" - no_scans: %ld\n",sf->no_scans);
+ printf(" - current: %ld\n",((SpecScan*)sf->current->contents)->scan_no);
+ printf(" Cursor:\n");
+ printf(" - no_scans: %ld\n",sf->cursor.scanno);
+ printf(" - bytecnt: %ld\n",sf->cursor.bytecnt);
+}
+
+DllExport void
+SfShowScan (SpecFile *sf, long index) {
+ int error;
+ SpecScan *scan;
+
+ printf("<Showing Info> - specfile: %s / idx %ld\n",sf->sfname,index);
+
+ if (sfSetCurrent(sf,index,&error) == -1) {
+ printf("Cannot get scan index %ld\n",index);
+ }
+
+ scan = (SpecScan *) sf->current->contents;
+
+ printf(" - index: %ld\n",scan->index);
+ printf(" - scan_no: %ld\n",scan->scan_no);
+ printf(" - offset: %ld\n",scan->offset);
+ printf(" - data_offset: %ld\n",scan->data_offset);
+}
diff --git a/silx/io/specfile/src/sfwrite.c b/silx/io/specfile/src/sfwrite.c
new file mode 100644
index 0000000..4422ae0
--- /dev/null
+++ b/silx/io/specfile/src/sfwrite.c
@@ -0,0 +1,587 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfwrite.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions for scan output
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2003/09/12 13:20:35 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfwrite.c,v $
+ * Log: Revision 1.1 2003/09/12 13:20:35 rey
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:14 19:05:14 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+/*
+ * Declarations
+ */
+DllExport SpecFileOut *SfoInit ( SpecFile *sf, int *error );
+DllExport void SfoClose ( SpecFileOut *sfo );
+DllExport long SfoSelectAll ( SpecFileOut *sfo, int *error );
+DllExport long SfoSelectOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport long SfoSelect ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport long SfoSelectRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport long SfoRemoveOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport long SfoRemove ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport long SfoRemoveRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport long SfoRemoveAll ( SpecFileOut *sfo, int *error );
+DllExport long SfoWrite ( SpecFileOut *sfo, char *name,
+ int *error );
+DllExport long SfoGetList ( SpecFileOut *sfo, long **list,
+ int *error );
+
+/*
+ * Internal functions
+ */
+static int sfoWriteOne(SpecFileOut *sfo,int output, long index,int *error);
+
+
+/*********************************************************************
+ * Function: SpecFileOut *SfoInit( sf, error )
+ *
+ * Description: Initializes a SpecFileOut structure:
+ * - pointer to SpecFile
+ * - list of scans to be copied
+ * - size of this list
+ * - last written file header
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ *
+ * Output:
+ * (2) error number
+ * Returns:
+ * Pointer to the initialized SpecFileOut structure.
+ * NULL in case of an error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMOREY_ALLOC
+ *
+ * Remark: This function MUST be the FIRST called before
+ * any other WRITE function is called !
+ *
+ *********************************************************************/
+DllExport SpecFileOut *
+SfoInit( SpecFile *sf, int *error )
+{
+ SpecFileOut *sfo;
+
+ /*
+ * Alloc memory
+ */
+ sfo = (SpecFileOut *) malloc ( sizeof(SpecFileOut) );
+
+ if ( sfo == (SpecFileOut *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( (SpecFileOut *)NULL );
+ }
+
+ /*
+ * Initialize
+ */
+ sfo->sf = sf;
+ sfo->list = (long *)NULL;
+ sfo->list_size = 0;
+ sfo->file_header = -1;
+
+ return( sfo );
+}
+
+
+/*********************************************************************
+ * Function: long SfoGetList( sfo, list, error )
+ *
+ * Description: Makes a copy of the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ *
+ * Output: (2) Copy of the output list of spec scan indices.
+ * (3) error code
+ * Returns:
+ * Number of scan indices in the output list ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) in case of an error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMOREY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfoGetList( SpecFileOut *sfo, long **list, int *error )
+{
+ long i;
+
+ *list = (long *)NULL;
+
+ if ( sfo->list_size > 0 ) {
+ *list = (long *)malloc( sfo->list_size * sizeof(long) );
+ if ( *list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ for ( i=0 ; i < sfo->list_size ; i++ ) {
+ (*list)[i] = sfo->list[i];
+ }
+ } else *list = (long *)NULL;
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectOne( sfo, index, error )
+ *
+ * Description: Adds one scan index to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Scan index
+ * Output:
+ * (3) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectOne( SpecFileOut *sfo, long index, int *error )
+{
+ long i;
+
+ /*
+ * Check if index exists or if it's out of range.
+ */
+ if ( index > sfo->sf->no_scans || index < 1 ) {
+ return( sfo->list_size );
+ }
+
+ /*
+ * Alloc memory for the new index and add it to the list.
+ */
+ if ( sfo->list == (long *)NULL ) {
+ sfo->list = (long *)malloc( sizeof(long) );
+ if ( sfo->list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ sfo->list_size = 1;
+ } else {
+ /*
+ * Is the new index already in list ?
+ */
+ for ( i=0 ; i<sfo->list_size ; i++ )
+ if ( index == sfo->list[i] ) return( sfo->list_size );
+ sfo->list = realloc( sfo->list, ++(sfo->list_size) * sizeof(long) );
+ if ( sfo->list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ sfo->list_size = 0;
+ return( -1 );
+ }
+ }
+ sfo->list[sfo->list_size-1] = index;
+ printf("Adding scan %ld\n",index);
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelect( sfo, list, error )
+ *
+ * Description: Adds several scan indices to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) List scan indices (!The last element
+ * MUST be a '0' !)
+ * Output:
+ * (3) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoSelectOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoSelect( SpecFileOut *sfo, long *list, int *error )
+{
+ for ( ; *list != 0 ; list++ ) {
+ if ( SfoSelectOne( sfo, *list , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectRange( sfo, begin, end, error )
+ *
+ * Description: Adds scan indices between 'begin' and 'end'
+ * to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) First ...
+ * (3) Last index to be added
+ * Output:
+ * (4) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoSelectOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectRange( SpecFileOut *sfo, long begin, long end, int *error )
+{
+ long i;
+
+ if ( begin > end ) {
+ i=begin;
+ begin = end;
+ end = i;
+ }
+ if ( begin < 1 || end > sfo->sf->no_scans ) {
+ return( sfo->list_size );
+ }
+ for ( i=begin ; i<=end ; i++ ) {
+ if ( SfoSelectOne( sfo, i , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectAll( sfo, error )
+ *
+ * Description: Writes all scan indices in the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOutput pointer
+ * Output: (2) error number
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectAll( SpecFileOut *sfo, int *error )
+{
+ long i;
+
+ if ( sfo->sf->no_scans > 0 ) {
+ for ( i=1 ; i<=sfo->sf->no_scans ; i++ ) {
+ if ( SfoSelectOne( sfo, i , error ) < 0 ) return( -1 );
+ }
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveOne( sfo, index, error )
+ *
+ * Description: Removes one scan index from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Scan index to be removed
+ * Output:
+ * (3) error code
+ * Returns:
+ * Number of scans left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveOne( SpecFileOut *sfo, long index, int *error )
+{
+ long i;
+ int found = 0;
+
+ /*
+ * Look for scan index and delete.
+ */
+ for ( i=0 ; i < (sfo->list_size - found) ; i++ ) {
+ if ( sfo->list[i] == index ) found = 1;
+ if ( found ) sfo->list[i]=sfo->list[i+1];
+ }
+
+ /*
+ * Free unused memory
+ */
+ if ( found ) {
+ (sfo->list_size)--;
+ sfo->list = realloc( sfo->list, sfo->list_size * sizeof(long) );
+ if ( sfo->list == (long *)NULL && sfo->list_size != 0 ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemove( sfo, list, error )
+ *
+ * Description: Removes several scans indices from the
+ * SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) List of scan indices to be removed
+ * ( !!! The last element MUST be a '0' !!! )
+ * Output:
+ * (3) error code
+ * Returns:
+ * Number of scan indices left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoRemoveOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoRemove( SpecFileOut *sfo, long *list, int *error )
+{
+ for ( ; *list != 0 ; list++ ) {
+ if ( SfoRemoveOne( sfo, *list , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveRange( sfo, begin, end, error )
+ *
+ * Description: Removes scans indices from 'begin' to 'end'
+ * from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input :
+ * (1) SpecFileOut pointer
+ * (2) First ...
+ * (3) Last index to be removed
+ * Output:
+ * (4) error code
+ * Returns:
+ * Number of scan indices left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoRemoveOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveRange( SpecFileOut *sfo, long begin, long end, int *error )
+{
+ long i;
+
+ if ( begin > end ) {
+ i=begin;
+ begin = end;
+ end = i;
+ }
+ if ( begin < 1 || end > sfo->sf->no_scans ) {
+ return( sfo->list_size );
+ }
+ for ( i=begin ; i <= end ; i++ ) {
+ if ( SfoRemoveOne( sfo, i, error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveAll( sfo, error )
+ *
+ * Description: Removes all scans indices
+ * from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input :
+ * (1) SpecFileOut pointer
+ * Output:
+ * (2) error code
+ * Returns:
+ * ( 0 ) => OK
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveAll( SpecFileOut *sfo, int *error )
+{
+ free( sfo->list );
+ sfo->list = (long *)NULL;
+ sfo->list_size = 0;
+ sfo->file_header = -1;
+ return( 0 );
+}
+
+
+/*********************************************************************
+ * Function: int SfoWrite( sfo, name, error )
+ *
+ * Description: Writes (appends) SpecScans specified in the sfo->list
+ * in the file 'name'. Related file headers are copied
+ * too.
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Output file name
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of written scans,
+ * (-1 ) => Errors occured
+ * Possible errors:
+ * SF_ERR_FILE_WRITE | => cpyBlock()
+ * SF_ERR_FILE_READ
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_FILE_CLOSE
+ *
+ *********************************************************************/
+DllExport long
+SfoWrite( SpecFileOut *sfo, char *name, int *error )
+{
+ int output;
+ long i;
+
+ if ( sfo == (SpecFileOut *)NULL || sfo->list_size<1 ) return( 0 );
+
+ /*
+ * Open file
+ */
+ if ( (output = open(name, O_CREAT | O_RDWR | O_APPEND, SF_UMASK )) == (int)NULL ) {
+ *error = SF_ERR_FILE_OPEN;
+ return( -1 );
+ }
+
+ for ( i=0 ; i < sfo->list_size ; i++ )
+ sfoWriteOne(sfo,output,sfo->list[i],error);
+
+ if ( close( output ) ) {
+ *error = SF_ERR_FILE_CLOSE;
+ return( -1 );
+ }
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: int SfoClose( sfo )
+ *
+ * Description: Frees all memory used by
+ * SpecFileOut structure.
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ *
+ * Remark: This function should be called after all
+ * writing operations.
+ *
+ *********************************************************************/
+DllExport void
+SfoClose( SpecFileOut *sfo )
+{
+ /*
+ * Free memory.
+ */
+ free( sfo->list );
+ free( sfo );
+}
+
+
+static int
+sfoWriteOne(SpecFileOut *sfo,int output,long index,int *error)
+{
+ long file_header,size;
+ SpecFile *sf;
+
+ if ( sfSetCurrent(sfo->sf,index,error) == -1 ) {
+ *error = SF_ERR_SCAN_NOT_FOUND;
+ return(-1);
+ }
+
+ /*
+ * File header
+ */
+ sf = sfo->sf;
+
+ file_header = ((SpecScan *)sf->current->contents)->size;
+
+ if (file_header != -1 && file_header != sfo->file_header ) {
+ printf("Writing %ld bytes\n",sf->filebuffersize);
+ write(output, (void *) sf->filebuffer, sf->filebuffersize);
+ sfo->file_header = file_header;
+ }
+
+ /*
+ * write scan
+ */
+ size = ((SpecScan *)sf->current->contents)->size;
+
+ if ( write(output,(void *) sf->scanbuffer,size) == -1 ) {
+ *error = SF_ERR_FILE_WRITE;
+ return(-1);
+ }
+ return(0);
+}
diff --git a/silx/io/specfilewrapper.py b/silx/io/specfilewrapper.py
new file mode 100644
index 0000000..005e54e
--- /dev/null
+++ b/silx/io/specfilewrapper.py
@@ -0,0 +1,371 @@
+# coding: utf-8
+# /*#########################################################################
+# Copyright (C) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""This module provides a backward compatibility layer with the legacy
+specfile wrapper.
+
+If you are starting a new project, please consider using :mod:`silx.io.specfile`
+instead of this module.
+
+If you want to use this module for an existing project that used the old
+wrapper through PyMca, you can try replacing::
+
+ from PyMca5.PyMcaIO import specfilewrapper
+
+with::
+
+ from silx.io import specfilewrapper
+
+There might still be differences between this module and the old
+wrapper, due to differences in the underlying implementation.
+Any of these differences that break your code should be reported on
+https://github.com/silx-kit/silx/issues
+
+The documentation mentions only the methods and attributes that are different
+from the ones in :class:`silx.io.specfile.SpecFile` and
+:class:`silx.io.specfile.Scan`. You should refer to the documentation of these
+base classes for more information.
+"""
+from silx.io.specfile import SpecFile, Scan
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+
+
+def _format_number_list(number_list):
+ """Return string representation of a list of integers,
+ using ``,`` as a separator and ``:`` as a range separator.
+ """
+ ret = ""
+ first_in_range = number_list[0]
+ last_in_range = number_list[0]
+ previous = number_list[0]
+ for number in number_list[1:]:
+ if number - previous != 1:
+ # reached end of range
+ if last_in_range > first_in_range:
+ ret += "%d:%d," % (first_in_range, last_in_range)
+ # passed isolated number
+ else:
+ ret += "%d," % previous
+ # reinitialize range
+ first_in_range = number
+ last_in_range = number
+ else:
+ # still inside a continuous range
+ last_in_range = number
+
+ previous = number
+
+ # last number
+ if last_in_range > first_in_range:
+ ret += "%d:%d" % (first_in_range, last_in_range)
+ else:
+ ret += "%d" % previous
+
+ return ret
+
+
+class Specfile(SpecFile):
+ """
+ This class is a subclass of :class:`silx.io.specfile.SpecFile`.
+
+ It redefines following methods:
+
+ - :meth:`__getitem__`: returns a :class:`scandata` object instead of
+ a :class:`silx.io.specfile.Scan` object
+ - :meth:`list`: returns a string representation of a list instead of a
+ list of integers
+
+ Following methods are added:
+
+ - :meth:`select`
+ - :meth:`scanno`
+ - :meth:`allmotors`
+ - :meth:`epoch`
+ - :meth:`title`
+ """
+ def __init__(self, filename):
+ SpecFile.__init__(self, filename)
+
+ def __getitem__(self, key):
+ """Get scan by 0-based index
+
+ :param key: 0-based scan index
+ :type key: int
+
+ :return: Scan
+ :rtype: :class:`scandata`
+ """
+ if not isinstance(key, int):
+ raise TypeError("Scan index must be an integer")
+
+ scan_index = key
+ # allow negative index, like lists
+ if scan_index < 0:
+ scan_index += len(self)
+
+ if not 0 <= scan_index < len(self):
+ msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ raise IndexError(msg)
+
+ return scandata(self, scan_index)
+
+ def list(self):
+ """Return a string representation of a list of scan numbers.
+
+ The scans numbers are listed in the order in which they appear
+ in the file. Continuous ranges of scan numbers are represented
+ as ``first:last``.
+
+ For instance, let's assume our specfile contains following scans:
+ *1, 2, 3, 4, 5, 684, 685, 687, 688, 689, 700, 688, 688*.
+ This method will then return::
+
+ "1:5,684:685,687:689,700,688,688"
+ """
+ number_list = SpecFile.list(self)
+ return _format_number_list(number_list)
+
+ def select(self, key):
+ """Get scan by ``n.m`` key
+
+ :param key: ``"s.o"`` (scan number, scan order)
+ :type key: str
+ :return: Scan
+ :rtype: :class:`scandata`
+ """
+ msg = "Key must be a string 'N.M' with N being the scan"
+ msg += " number and M the order (eg '2.3')."
+
+ if not hasattr(key, "lower") or "." not in key:
+ raise TypeError(msg)
+
+ try:
+ (number, order) = map(int, key.split("."))
+ scan_index = self.index(number, order)
+ except (ValueError, IndexError):
+ # self.index can raise an index error
+ # int() can raise a value error
+ raise KeyError(msg + "\nValid keys: '" +
+ "', '".join(self.keys()) + "'")
+ except AttributeError:
+ # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ raise TypeError(msg)
+
+ if not 0 <= scan_index < len(self):
+ msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ raise IndexError(msg)
+
+ return scandata(self, scan_index)
+
+ def scanno(self):
+ """Return the number of scans in the SpecFile
+
+ This is an alias for :meth:`__len__`, for compatibility with the old
+ specfile wrapper API.
+ """
+ return len(self)
+
+ def allmotors(self, scan_index=0):
+ """
+ This is an alias for :meth:`motor_names`, for compatibility with
+ the old specfile wrapper API.
+ """
+ return self.motor_names(scan_index)
+
+ def epoch(self):
+ """:return: Epoch, from last word on file header line *#E*
+ :rtype: int
+ :raise: ValueError if *#E* line not found in header or last
+ word on *#E* cannot be converted to type *int*"""
+ fh = self.file_header()
+ for line in fh:
+ if line.startswith("#E "):
+ return int(line.split()[-1])
+ raise ValueError("No #E header found in specfile")
+
+ def title(self):
+ """:return: Title, from second field on *#C* header line (field are
+ strings separated by two spaces)
+ :rtype: str
+ :raise: ValueError if *#C* line not found in header or line is empty"""
+ fh = self.file_header()
+ for line in fh:
+ if line.startswith("#C "):
+ line1 = line.lstrip("#C ")
+ return line1.split(" ")[0]
+ raise ValueError("No #C header found in specfile")
+
+ # # these functions exist in the old API but don't seem to be
+ # # used, and are not easy to implement
+ # def show(self):
+ # raise NotImplementedError
+ #
+ # def user(self):
+ # raise NotImplementedError
+ #
+ # def update(self):
+ # raise NotImplementedError
+
+
+# PEP8 violation in class name is to respect old API
+class scandata(Scan): # noqa
+ """
+ This class is a subclass of :class:`silx.io.specfile.Scan`.
+
+ It redefines following methods/attributes:
+
+ - :meth:`data` becomes a method returning an array, instead of just
+ an array
+ - :meth:`mca`: becomes a method returning an array, instead of
+ a :class:`silx.io.specfile.MCA` object
+ - :meth:`header`: becomes a method returning a list of **scan**
+ header lines (or a list of a single header line, if a key is
+ specified), instead of just a list of all header lines
+
+ Following methods are added:
+
+ - :meth:`allmotors`
+ - :meth:`allmotorpos`
+ - :meth:`alllabels`
+ - :meth:`cols`
+ - :meth:`lines`
+ - :meth:`command`
+ - :meth:`date`
+ - :meth:`datacol`
+ - :meth:`dataline`
+ - :meth:`fileheader`
+ - :meth:`nbmca`
+ """
+ def __init__(self, specfile, scan_index):
+ Scan.__init__(self, specfile, scan_index)
+
+ def allmotors(self):
+ """Return a list of all motor names (identical to
+ :attr:`motor_names`).
+ """
+ return self.motor_names
+
+ def allmotorpos(self):
+ """Return a list of all motor positions (identical to
+ :attr:`motor_positions`).
+ """
+ return self.motor_positions
+
+ def alllabels(self):
+ """
+ Return a list of all labels (:attr:`labels`).
+ """
+ return self.labels
+
+ def cols(self):
+ """Return the number of data columns (number of detectors)"""
+ return super(scandata, self).data.shape[1]
+
+ def command(self):
+ """Return the command called for this scan (``#S`` header line)"""
+ return self._specfile.command(self._index)
+
+ def data(self):
+ """Return the data in this scan as a 2D numpy array.
+
+ The first index corresponds to the columns/detectors in the original
+ file, and the second index is the row index from the original file.
+ Indices are 0-based.
+
+ For instance, this is how you access the 18th data sample for the 3rd
+ detector (assuming ``sc`` is your scan object):
+
+ >>> scdata = sc.data()
+ >>> data_sample = scdata[2, 17]"""
+ return super(scandata, self).data
+
+ def datacol(self, col):
+ """Return a data column (all data for one detector)
+
+ :param col: column number (1-based index)"""
+ return super(scandata, self).data[col - 1, :]
+
+ def dataline(self, line):
+ """Return a data line (one sample for all detectors)
+
+ :param line: line number (1-based index)"""
+ return super(scandata, self).data[:, line - 1]
+
+ def date(self):
+ """Return the date from the scan header line ``#D``"""
+ return self._specfile.date(self._index)
+
+ def fileheader(self, key=''): # noqa
+ """Return a list of file header lines"""
+ # key is there for compatibility
+ return self.file_header
+
+ def header(self, key=""):
+ """Return a list of scan header lines if no key is specified.
+ If a valid key is specified, return a list of a single header line.
+
+ :param key: Header key (e.g. ``S, N, L, @CALIB``…)
+ If ``key`` is an empty string, return complete list of scan header
+ lines.
+ If ``key`` does not match any header line, return empty list.
+ :return: List of scan header lines
+ :rtype: list[str]
+ """
+ if key.strip() == "":
+ return self.scan_header
+ if self.record_exists_in_hdr(key):
+ prefix = "#" + key + " "
+ # there is no leading @ in self.mca_header_dict keys
+ key_mca_dict = key.lstrip("@") if key.startswith("@") else None
+ if key_mca_dict in self.mca_header_dict:
+ return [prefix + self.mca_header_dict[key_mca_dict]]
+ elif key in self.scan_header_dict:
+ return [prefix + self.scan_header_dict[key]]
+ elif key in self.file_header_dict:
+ return [prefix + self.file_header_dict[key]]
+ elif self.record_exists_in_hdr("@" + key):
+ # in case key is a mca header key without the @
+ if key in self.mca_header_dict:
+ prefix = "#@" + key + " "
+ return [prefix + self.mca_header_dict[key]]
+ return []
+
+ def lines(self):
+ """Return the number of data lines (number of data points per
+ detector)"""
+ return super(scandata, self).data.shape[0]
+
+ def mca(self, number):
+ """Return one MCA spectrum
+
+ :param number: MCA number (1-based index)
+ :rtype: 1D numpy array"""
+ # in the base class, mca is an object that can be indexed (but 0-based)
+ return super(scandata, self).mca[number - 1]
+
+ def nbmca(self):
+ """Return number of MCAs in this scan"""
+ return len(super(scandata, self).mca)
diff --git a/silx/io/spech5.py b/silx/io/spech5.py
new file mode 100644
index 0000000..58a6c6b
--- /dev/null
+++ b/silx/io/spech5.py
@@ -0,0 +1,1634 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""This module provides a h5py-like API to access SpecFile data.
+
+API description
+===============
+Specfile data structure exposed by this API:
+
+::
+
+ /
+ 1.1/
+ title = "…"
+ start_time = "…"
+ instrument/
+ specfile/
+ file_header = "…"
+ scan_header = "…"
+ positioners/
+ motor_name = value
+ …
+ mca_0/
+ data = …
+ calibration = …
+ channels = …
+ preset_time = …
+ elapsed_time = …
+ live_time = …
+
+ mca_1/
+ …
+ …
+ measurement/
+ colname0 = …
+ colname1 = …
+ …
+ mca_0/
+ data -> /1.1/instrument/mca_0/data
+ info -> /1.1/instrument/mca_0/
+ …
+ 2.1/
+ …
+
+``file_header`` and ``scan_header`` are the raw headers as they
+appear in the original file, as a string of lines separated by newline (``\\n``) characters.
+
+The title is the content of the ``#S`` scan header line without the leading
+``#S`` (e.g ``"1 ascan ss1vo -4.55687 -0.556875 40 0.2"``).
+
+The start time is converted to ISO8601 format (``"2016-02-23T22:49:05Z"``),
+if the original date format is standard.
+
+Numeric datasets are stored in *float32* format, except for scalar integers
+which are stored as *int64*.
+
+Motor positions (e.g. ``/1.1/instrument/positioners/motor_name``) can be
+1D numpy arrays if they are measured as scan data, or else scalars as defined
+on ``#P`` scan header lines. A simple test is done to check if the motor name
+is also a data column header defined in the ``#L`` scan header line.
+
+Scan data (e.g. ``/1.1/measurement/colname0``) is accessed by column,
+the dataset name ``colname0`` being the column label as defined in the ``#L``
+scan header line.
+
+If a ``/`` character is present in a column label or in a motor name in the
+original SPEC file, it will be substituted with a ``%`` character in the
+corresponding dataset name.
+
+MCA data is exposed as a 2D numpy array containing all spectra for a given
+analyser. The number of analysers is calculated as the number of MCA spectra
+per scan data line. Demultiplexing is then performed to assign the correct
+spectra to a given analyser.
+
+MCA calibration is an array of 3 scalars, from the ``#@CALIB`` header line.
+It is identical for all MCA analysers, as there can be only one
+``#@CALIB`` line per scan.
+
+MCA channels is an array containing all channel numbers. This information is
+computed from the ``#@CHANN`` scan header line (if present), or computed from
+the shape of the first spectrum in a scan (``[0, … len(first_spectrum] - 1]``).
+
+Accessing data
+==============
+
+Data and groups are accessed in :mod:`h5py` fashion::
+
+ from silx.io.spech5 import SpecH5
+
+ # Open a SpecFile
+ sfh5 = SpecH5("test.dat")
+
+ # using SpecH5 as a regular group to access scans
+ scan1group = sfh5["1.1"]
+ instrument_group = scan1group["instrument"]
+
+ # alternative: full path access
+ measurement_group = sfh5["/1.1/measurement"]
+
+ # accessing a scan data column by name as a 1D numpy array
+ data_array = measurement_group["Pslit HGap"]
+
+ # accessing all mca-spectra for one MCA device
+ mca_0_spectra = measurement_group["mca_0/data"]
+
+:class:`SpecH5` and :class:`SpecH5Group` provide a :meth:`SpecH5Group.keys` method::
+
+ >>> sfh5.keys()
+ ['96.1', '97.1', '98.1']
+ >>> sfh5['96.1'].keys()
+ ['title', 'start_time', 'instrument', 'measurement']
+
+They can also be treated as iterators:
+
+.. code-block:: python
+
+ for scan_group in SpecH5("test.dat"):
+ dataset_names = [item.name in scan_group["measurement"] if
+ isinstance(item, SpecH5Dataset)]
+ print("Found data columns in scan " + scan_group.name)
+ print(", ".join(dataset_names))
+
+You can test for existence of data or groups::
+
+ >>> "/1.1/measurement/Pslit HGap" in sfh5
+ True
+ >>> "positioners" in sfh5["/2.1/instrument"]
+ True
+ >>> "spam" in sfh5["1.1"]
+ False
+
+Strings are stored encoded as ``numpy.string_``, as recommended by
+`the h5py documentation <http://docs.h5py.org/en/latest/strings.html>`_.
+This ensures maximum compatibility with third party software libraries,
+when saving a :class:`SpecH5` to a HDF5 file using :mod:`silx.io.spectoh5`.
+
+The type ``numpy.string_`` is a byte-string format. The consequence of this
+is that you should decode strings before using them in **Python 3**::
+
+ >>> from silx.io.spech5 import SpecH5
+ >>> sfh5 = SpecH5("31oct98.dat")
+ >>> sfh5["/68.1/title"]
+ b'68 ascan tx3 -28.5 -24.5 20 0.5'
+ >>> sfh5["/68.1/title"].decode()
+ '68 ascan tx3 -28.5 -24.5 20 0.5'
+
+
+Classes
+=======
+
+- :class:`SpecH5`
+- :class:`SpecH5Group`
+- :class:`SpecH5Dataset`
+- :class:`SpecH5LinkToGroup`
+- :class:`SpecH5LinkToDataset`
+"""
+
+import logging
+import numpy
+import posixpath
+import re
+import sys
+
+from .specfile import SpecFile
+
+__authors__ = ["P. Knobel", "D. Naudet"]
+__license__ = "MIT"
+__date__ = "11/05/2017"
+
+logging.basicConfig()
+logger1 = logging.getLogger(__name__)
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+ logger1.debug("Module h5py optional.", exc_info=True)
+
+
+string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+
+# Static subitems: all groups and datasets that are present in any
+# scan (excludes list of scans, data columns, list of mca devices,
+# optional mca headers, optional sample group)
+static_items = {
+ "scan": [u"title", u"start_time", u"instrument",
+ u"measurement"],
+ "scan/instrument": [u"specfile", u"positioners"],
+ "scan/instrument/specfile": [u"file_header", u"scan_header"],
+ "scan/measurement/mca": [u"data", u"info"],
+ "scan/instrument/mca": [u"data", u"calibration", u"channels"],
+}
+
+# Patterns for group keys
+root_pattern = re.compile(r"/$")
+scan_pattern = re.compile(r"/[0-9]+\.[0-9]+/?$")
+instrument_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/?$")
+sample_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/?$")
+specfile_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/specfile/?$")
+positioners_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/positioners/?$")
+measurement_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/?$")
+measurement_mca_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_[0-9]+/?$")
+instrument_mca_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_[0-9]+/?$")
+
+
+# Link to group
+measurement_mca_info_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_([0-9]+)/info/?$")
+
+# Patterns for dataset keys
+header_pattern = re.compile(r"/[0-9]+\.[0-9]+/header$")
+title_pattern = re.compile(r"/[0-9]+\.[0-9]+/title$")
+start_time_pattern = re.compile(r"/[0-9]+\.[0-9]+/start_time$")
+file_header_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/specfile/file_header$")
+scan_header_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/specfile/scan_header$")
+positioners_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/positioners/([^/]+)$")
+measurement_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/([^/]+)$")
+instrument_mca_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_([0-9]+)/data$")
+instrument_mca_calib_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_([0-9]+)/calibration$")
+instrument_mca_chann_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_([0-9])+/channels$")
+instrument_mca_preset_t_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_[0-9]+/preset_time$")
+instrument_mca_elapsed_t_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_[0-9]+/elapsed_time$")
+instrument_mca_live_t_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_[0-9]+/live_time$")
+ub_matrix_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/ub_matrix$")
+unit_cell_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/unit_cell$")
+unit_cell_abc_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/unit_cell_abc$")
+unit_cell_alphabetagamma_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/unit_cell_alphabetagamma$")
+
+# Links to dataset
+measurement_mca_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_([0-9]+)/data$")
+# info/ + calibration, channel, preset_time, live_time, elapsed_time (not data)
+measurement_mca_info_dataset_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_([0-9]+)/info/([^d/][^/]+)$")
+# info/data
+measurement_mca_info_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_([0-9]+)/info/data$")
+
+
+def _bulk_match(string_, list_of_patterns):
+ """Check whether a string matches any regular expression pattern in a list
+ """
+ for pattern in list_of_patterns:
+ if pattern.match(string_):
+ return True
+ return False
+
+
+def is_group(name):
+ """Check if ``name`` matches a valid group name pattern in a
+ :class:`SpecH5`.
+
+ :param name: Full name of member
+ :type name: str
+
+ For example:
+
+ - ``is_group("/123.456/instrument/")`` returns ``True``.
+ - ``is_group("spam")`` returns ``False`` because :literal:`\"spam\"`
+ is not at all a valid group name.
+ - ``is_group("/1.2/instrument/positioners/xyz")`` returns ``False``
+ because this key would point to a motor position, which is a
+ dataset and not a group.
+ """
+ group_patterns = (
+ root_pattern, scan_pattern, instrument_pattern,
+ specfile_group_pattern, positioners_group_pattern,
+ measurement_group_pattern, measurement_mca_group_pattern,
+ instrument_mca_group_pattern, sample_pattern
+ )
+ return _bulk_match(name, group_patterns)
+
+
+def is_dataset(name):
+ """Check if ``name`` matches a valid dataset name pattern in a
+ :class:`SpecH5`.
+
+ :param name: Full name of member
+ :type name: str
+
+ For example:
+
+ - ``is_dataset("/1.2/instrument/positioners/xyz")`` returns ``True``
+ because this name could be the key to the dataset recording motor
+ positions for motor ``xyz`` in scan ``1.2``.
+ - ``is_dataset("/123.456/instrument/")`` returns ``False`` because
+ this name points to a group.
+ - ``is_dataset("spam")`` returns ``False`` because :literal:`\"spam\"`
+ is not at all a valid dataset name.
+ """
+ # Check groups first because /1.1/measurement/mca_0 could be interpreted
+ # as a data column with label "mca_0"
+ if measurement_mca_group_pattern.match(name):
+ return False
+
+ data_patterns = (
+ header_pattern, title_pattern, start_time_pattern,
+ file_header_data_pattern, scan_header_data_pattern,
+ positioners_data_pattern, measurement_data_pattern,
+ instrument_mca_data_pattern, instrument_mca_calib_pattern,
+ instrument_mca_chann_pattern,
+ instrument_mca_preset_t_pattern, instrument_mca_elapsed_t_pattern,
+ instrument_mca_live_t_pattern,
+ ub_matrix_pattern, unit_cell_pattern, unit_cell_abc_pattern, unit_cell_alphabetagamma_pattern
+ )
+ return _bulk_match(name, data_patterns)
+
+
+def is_link_to_group(name):
+ """Check if ``name`` is a valid link to a group in a :class:`SpecH5`.
+ Return ``True`` or ``False``
+
+ :param name: Full name of member
+ :type name: str
+ """
+ # so far we only have one type of link to a group
+ if measurement_mca_info_pattern.match(name):
+ return True
+ return False
+
+
+def is_link_to_dataset(name):
+ """Check if ``name`` is a valid link to a dataset in a :class:`SpecH5`.
+ Return ``True`` or ``False``
+
+ :param name: Full name of member
+ :type name: str
+ """
+ list_of_link_patterns = (
+ measurement_mca_data_pattern, measurement_mca_info_dataset_pattern,
+ measurement_mca_info_data_pattern
+ )
+ return _bulk_match(name, list_of_link_patterns)
+
+
+def _get_attrs_dict(name):
+ """Return attributes dictionary corresponding to the group or dataset
+ pointed to by name.
+
+ :param name: Full name/path to data or group
+ :return: attributes dictionary
+ """
+ # Associate group and dataset patterns to their attributes
+ pattern_attrs = {
+ root_pattern:
+ {"NX_class": "NXroot",
+ },
+ scan_pattern:
+ {"NX_class": "NXentry", },
+ title_pattern:
+ {},
+ start_time_pattern:
+ {},
+ instrument_pattern:
+ {"NX_class": "NXinstrument", },
+ specfile_group_pattern:
+ {"NX_class": "NXcollection", },
+ file_header_data_pattern:
+ {},
+ scan_header_data_pattern:
+ {},
+ positioners_group_pattern:
+ {"NX_class": "NXcollection", },
+ positioners_data_pattern:
+ {},
+ instrument_mca_group_pattern:
+ {"NX_class": "NXdetector", },
+ instrument_mca_data_pattern:
+ {"interpretation": "spectrum", },
+ instrument_mca_calib_pattern:
+ {},
+ instrument_mca_chann_pattern:
+ {},
+ instrument_mca_preset_t_pattern:
+ {},
+ instrument_mca_elapsed_t_pattern:
+ {},
+ instrument_mca_live_t_pattern:
+ {},
+ measurement_group_pattern:
+ {"NX_class": "NXcollection", },
+ measurement_data_pattern:
+ {},
+ measurement_mca_group_pattern:
+ {},
+ measurement_mca_data_pattern:
+ {"interpretation": "spectrum", },
+ measurement_mca_info_pattern:
+ {"NX_class": "NXdetector", },
+ measurement_mca_info_dataset_pattern:
+ {},
+ measurement_mca_info_data_pattern:
+ {"interpretation": "spectrum"},
+ sample_pattern:
+ {"NX_class": "NXsample", },
+ ub_matrix_pattern:
+ {"interpretation": "scalar"},
+ unit_cell_pattern:
+ {"interpretation": "scalar"},
+ unit_cell_abc_pattern:
+ {"interpretation": "scalar"},
+ unit_cell_alphabetagamma_pattern:
+ {"interpretation": "scalar"},
+ }
+
+ for pattern in pattern_attrs:
+ if pattern.match(name):
+ return pattern_attrs[pattern]
+
+ logger1.warning("%s not a known pattern, assigning empty dict to attrs",
+ name)
+ return {}
+
+
+def _get_scan_key_in_name(item_name):
+ """
+ :param item_name: Name of a group or dataset
+ :return: Scan identification key (e.g. ``"1.1"``)
+ :rtype: str on None
+ """
+ scan_match = re.match(r"/([0-9]+\.[0-9]+)", item_name)
+ if not scan_match:
+ return None
+ return scan_match.group(1)
+
+
+def _get_mca_index_in_name(item_name):
+ """
+ :param item_name: Name of a group or dataset
+ :return: MCA analyser index, ``None`` if item name does not reference
+ a mca dataset
+ :rtype: int or None
+ """
+ mca_match = re.match(r"/.*/mca_([0-9]+)[^0-9]*", item_name)
+ if not mca_match:
+ return None
+ return int(mca_match.group(1))
+
+
+def _get_motor_in_name(item_name):
+ """
+ :param item_name: Name of a group or dataset
+ :return: Motor name or ``None``
+ :rtype: str on None
+ """
+ motor_match = positioners_data_pattern.match(item_name)
+ if not motor_match:
+ return None
+ return motor_match.group(1)
+
+
+def _get_data_column_label_in_name(item_name):
+ """
+ :param item_name: Name of a group or dataset
+ :return: Data column label or ``None``
+ :rtype: str on None
+ """
+ # /1.1/measurement/mca_0 should not be interpreted as the label of a
+ # data column (let's hope no-one ever uses mca_0 as a label)
+ if measurement_mca_group_pattern.match(item_name):
+ return None
+ data_column_match = measurement_data_pattern.match(item_name)
+ if not data_column_match:
+ return None
+ return data_column_match.group(1)
+
+
+def _get_number_of_mca_analysers(scan):
+ """
+ :param SpecFile sf: :class:`SpecFile` instance
+ :param str scan_key: Scan identification key (e.g. ``1.1``)
+ """
+ number_of_MCA_spectra = len(scan.mca)
+ # Scan.data is transposed
+ number_of_data_lines = scan.data.shape[1]
+
+ if not number_of_data_lines == 0:
+ # Number of MCA spectra must be a multiple of number of data lines
+ assert number_of_MCA_spectra % number_of_data_lines == 0
+ return number_of_MCA_spectra // number_of_data_lines
+ elif number_of_MCA_spectra:
+ # Case of a scan without data lines, only MCA.
+ # Our only option is to assume that the number of analysers
+ # is the number of #@CHANN lines
+ return len(scan.mca.channels)
+ else:
+ return 0
+
+
+def _mca_analyser_in_scan(sf, scan_key, mca_analyser_index):
+ """
+ :param sf: :class:`SpecFile` instance
+ :param scan_key: Scan identification key (e.g. ``1.1``)
+ :param mca_analyser_index: 0-based index of MCA analyser
+ :return: ``True`` if MCA analyser exists in Scan, else ``False``
+ :raise: ``KeyError`` if scan_key not found in SpecFile
+ :raise: ``AssertionError`` if number of MCA spectra is not a multiple
+ of the number of data lines
+ """
+ if scan_key not in sf:
+ raise KeyError("Scan key %s " % scan_key +
+ "does not exist in SpecFile %s" % sf.filename)
+
+ number_of_analysers = _get_number_of_mca_analysers(sf[scan_key])
+
+ return 0 <= mca_analyser_index < number_of_analysers
+
+
+def _motor_in_scan(sf, scan_key, motor_name):
+ """
+ :param sf: :class:`SpecFile` instance
+ :param scan_key: Scan identification key (e.g. ``1.1``)
+ :param motor_name: Name of motor as defined in file header lines
+ :return: ``True`` if motor exists in scan, else ``False``
+ :raise: ``KeyError`` if scan_key not found in SpecFile
+ """
+ if scan_key not in sf:
+ raise KeyError("Scan key %s " % scan_key +
+ "does not exist in SpecFile %s" % sf.filename)
+ ret = motor_name in sf[scan_key].motor_names
+ if not ret and "%" in motor_name:
+ motor_name = motor_name.replace("%", "/")
+ ret = motor_name in sf[scan_key].motor_names
+ return ret
+
+
+def _column_label_in_scan(sf, scan_key, column_label):
+ """
+ :param sf: :class:`SpecFile` instance
+ :param scan_key: Scan identification key (e.g. ``1.1``)
+ :param column_label: Column label as defined in scan header
+ :return: ``True`` if data column label exists in scan, else ``False``
+ :raise: ``KeyError`` if scan_key not found in SpecFile
+ """
+ if scan_key not in sf:
+ raise KeyError("Scan key %s " % scan_key +
+ "does not exist in SpecFile %s" % sf.filename)
+ ret = column_label in sf[scan_key].labels
+ if not ret and "%" in column_label:
+ column_label = column_label.replace("%", "/")
+ ret = column_label in sf[scan_key].labels
+ return ret
+
+
+def _parse_ctime(ctime_lines, analyser_index=0):
+ """
+ :param ctime_lines: e.g ``@CTIME %f %f %f``, first word ``@CTIME`` optional
+ When multiple CTIME lines are present in a scan header, this argument
+ is a concatenation of them separated by a ``\n`` character.
+ :param analyser_index: MCA device/analyser index, when multiple devices
+ are in a scan.
+ :return: (preset_time, live_time, elapsed_time)
+ """
+ ctime_lines = ctime_lines.lstrip("@CTIME ")
+ ctimes_lines_list = ctime_lines.split("\n")
+ if len(ctimes_lines_list) == 1:
+ # single @CTIME line for all devices
+ ctime_line = ctimes_lines_list[0]
+ else:
+ ctime_line = ctimes_lines_list[analyser_index]
+ if not len(ctime_line.split()) == 3:
+ raise ValueError("Incorrect format for @CTIME header line " +
+ '(expected "@CTIME %f %f %f").')
+ return list(map(float, ctime_line.split()))
+
+
+def spec_date_to_iso8601(date, zone=None):
+ """Convert SpecFile date to Iso8601.
+
+ :param date: Date (see supported formats below)
+ :type date: str
+ :param zone: Time zone as it appears in a ISO8601 date
+
+ Supported formats:
+
+ * ``DDD MMM dd hh:mm:ss YYYY``
+ * ``DDD YYYY/MM/dd hh:mm:ss YYYY``
+
+ where `DDD` is the abbreviated weekday, `MMM` is the month abbreviated
+ name, `MM` is the month number (zero padded), `dd` is the weekday number
+ (zero padded) `YYYY` is the year, `hh` the hour (zero padded), `mm` the
+ minute (zero padded) and `ss` the second (zero padded).
+ All names are expected to be in english.
+
+ Examples::
+
+ >>> spec_date_to_iso8601("Thu Feb 11 09:54:35 2016")
+ '2016-02-11T09:54:35'
+
+ >>> spec_date_to_iso8601("Sat 2015/03/14 03:53:50")
+ '2015-03-14T03:53:50'
+ """
+ months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
+ 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+ days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+
+ days_rx = '(?P<day>' + '|'.join(days) + ')'
+ months_rx = '(?P<month>' + '|'.join(months) + ')'
+ year_rx = '(?P<year>\d{4})'
+ day_nb_rx = '(?P<day_nb>[0-3 ]\d)'
+ month_nb_rx = '(?P<month_nb>[0-1]\d)'
+ hh_rx = '(?P<hh>[0-2]\d)'
+ mm_rx = '(?P<mm>[0-5]\d)'
+ ss_rx = '(?P<ss>[0-5]\d)'
+ tz_rx = '(?P<tz>[+-]\d\d:\d\d){0,1}'
+
+ # date formats must have either month_nb (1..12) or month (Jan, Feb, ...)
+ re_tpls = ['{days} {months} {day_nb} {hh}:{mm}:{ss}{tz} {year}',
+ '{days} {year}/{month_nb}/{day_nb} {hh}:{mm}:{ss}{tz}']
+
+ grp_d = None
+
+ for rx in re_tpls:
+ full_rx = rx.format(days=days_rx,
+ months=months_rx,
+ year=year_rx,
+ day_nb=day_nb_rx,
+ month_nb=month_nb_rx,
+ hh=hh_rx,
+ mm=mm_rx,
+ ss=ss_rx,
+ tz=tz_rx)
+ m = re.match(full_rx, date)
+
+ if m:
+ grp_d = m.groupdict()
+ break
+
+ if not grp_d:
+ raise ValueError('Date format not recognized : {0}'.format(date))
+
+ year = grp_d['year']
+
+ month = grp_d.get('month_nb')
+
+ if not month:
+ month = '{0:02d}'.format(months.index(grp_d.get('month')) + 1)
+
+ day = grp_d['day_nb']
+
+ tz = grp_d['tz']
+ if not tz:
+ tz = zone
+
+ time = '{0}:{1}:{2}'.format(grp_d['hh'],
+ grp_d['mm'],
+ grp_d['ss'])
+
+ full_date = '{0}-{1}-{2}T{3}{4}'.format(year,
+ month,
+ day,
+ time,
+ tz if tz else '')
+ return full_date
+
+
+def _fixed_length_strings(strings, length=0):
+ """Return list of fixed length strings, left-justified and right-padded
+ with spaces.
+
+ :param strings: List of variable length strings
+ :param length: Length of strings in returned list, defaults to the maximum
+ length in the original list if set to 0.
+ :type length: int or None
+ """
+ if length == 0 and strings:
+ length = max(len(s) for s in strings)
+ return [s.ljust(length) for s in strings]
+
+
+class SpecH5Dataset(object):
+ """Emulate :class:`h5py.Dataset` for a SpecFile object.
+
+ A :class:`SpecH5Dataset` instance is basically a proxy for the numpy
+ array :attr:`value` attribute, with additional attributes for
+ compatibility with *h5py* datasets.
+
+ :param value: Actual dataset value
+ :param name: Dataset full name (posix path format, starting with ``/``)
+ :type name: str
+ :param file_: Parent :class:`SpecH5`
+ :param parent: Parent :class:`SpecH5Group` which contains this dataset
+ """
+ def __init__(self, value, name, file_, parent):
+ object.__init__(self)
+
+ self.value = None
+ """Actual dataset, can be a *numpy array*, a *numpy.string_*,
+ a *numpy.int_* or a *numpy.float32*
+
+ All operations applied to an instance of the class use this."""
+
+ # get proper value types, to inherit from numpy
+ # attributes (dtype, shape, size)
+ if isinstance(value, string_types):
+ # use bytes for maximum compatibility
+ # (see http://docs.h5py.org/en/latest/strings.html)
+ self.value = numpy.string_(value)
+ elif isinstance(value, float):
+ # use 32 bits for float scalars
+ self.value = numpy.float32(value)
+ elif isinstance(value, int):
+ self.value = numpy.int_(value)
+ else:
+ # Enforce numpy array
+ array = numpy.array(value)
+ data_kind = array.dtype.kind
+
+ if data_kind in ["S", "U"]:
+ self.value = numpy.asarray(array, dtype=numpy.string_)
+ elif data_kind in ["f"]:
+ self.value = numpy.asarray(array, dtype=numpy.float32)
+ else:
+ self.value = array
+
+ # numpy array attributes (more attributes handled in __getattribute__)
+ self.shape = self.value.shape
+ """Dataset shape, as a tuple with the length of each dimension
+ of the dataset."""
+
+ self.dtype = self.value.dtype
+ """Dataset dtype"""
+
+ self.size = self.value.size
+ """Dataset size (number of elements)"""
+
+ # h5py dataset specific attributes
+ self.name = name
+ """"Dataset name (posix path format, starting with ``/``)"""
+
+ self.parent = parent
+ """Parent :class:`SpecH5Group` object which contains this dataset"""
+
+ self.file = file_
+ """Parent :class:`SpecH5` object"""
+
+ self.attrs = _get_attrs_dict(name)
+ """Attributes dictionary"""
+
+ self.compression = None
+ """Compression attribute as provided by h5py.Dataset"""
+
+ self.compression_opts = None
+ """Compression options attribute as provided by h5py.Dataset"""
+
+ self.chunks = None
+
+ @property
+ def h5py_class(self):
+ """Return h5py class which is mimicked by this class:
+ :class:`h5py.dataset`.
+
+ Accessing this attribute if :mod:`h5py` is not installed causes
+ an ``ImportError`` to be raised
+ """
+ if h5py is None:
+ raise ImportError("Cannot return h5py.Dataset class, " +
+ "unable to import h5py module")
+ return h5py.Dataset
+
+ def __getattribute__(self, item):
+ if item in ["value", "name", "parent", "file", "attrs",
+ "shape", "dtype", "size", "h5py_class",
+ "chunks", "compression", "compression_opts",
+ "target"]:
+ return object.__getattribute__(self, item)
+
+ if hasattr(self.value, item):
+ return getattr(self.value, item)
+
+ raise AttributeError("SpecH5Dataset has no attribute %s" % item)
+
+ def __len__(self):
+ return len(self.value)
+
+ def __getitem__(self, item):
+ if not isinstance(self.value, numpy.ndarray):
+ if item == Ellipsis:
+ return numpy.array(self.value)
+ elif item == tuple():
+ return self.value
+ else:
+ raise ValueError("Scalar can only be reached with an ellipsis or an empty tuple")
+ return self.value.__getitem__(item)
+
+ def __getslice__(self, i, j):
+ # deprecated but still in use for python 2.7
+ return self.__getitem__(slice(i, j, None))
+
+ def __iter__(self):
+ return self.value.__iter__()
+
+ def __dir__(self):
+ attrs = set(dir(self.value) +
+ ["value", "name", "parent", "file",
+ "attrs", "shape", "dtype", "size",
+ "h5py_class", "chunks", "compression",
+ "compression_opts"])
+ return sorted(attrs)
+
+ # casting
+ def __repr__(self):
+ return '<SpecH5Dataset "%s": shape %s, type "%s">' % \
+ (self.name, self.shape, self.dtype.str)
+
+ def __float__(self):
+ return float(self.value)
+
+ def __int__(self):
+ return int(self.value)
+
+ def __str__(self):
+ basename = self.name.split("/")[-1]
+ return '<SPEC dataset "%s": shape %s, type "%s">' % \
+ (basename, self.shape, self.dtype.str)
+
+ def __bool__(self):
+ if self.value:
+ return True
+ return False
+
+ def __nonzero__(self):
+ # python 2
+ return self.__bool__()
+
+ def __array__(self, dtype=None):
+ if dtype is None:
+ return numpy.array(self.value)
+ else:
+ return numpy.array(self.value, dtype=dtype)
+
+ # comparisons
+ def __eq__(self, other):
+ if hasattr(other, "value"):
+ return self.value == other.value
+ else:
+ return self.value == other
+
+ def __ne__(self, other):
+ if hasattr(other, "value"):
+ return self.value != other.value
+ else:
+ return self.value != other
+
+ def __lt__(self, other):
+ if hasattr(other, "value"):
+ return self.value < other.value
+ else:
+ return self.value < other
+
+ def __le__(self, other):
+ if hasattr(other, "value"):
+ return self.value <= other.value
+ else:
+ return self.value <= other
+
+ def __gt__(self, other):
+ if hasattr(other, "value"):
+ return self.value > other.value
+ else:
+ return self.value > other
+
+ def __ge__(self, other):
+ if hasattr(other, "value"):
+ return self.value >= other.value
+ else:
+ return self.value >= other
+
+ # operations
+ def __add__(self, other):
+ return self.value + other
+
+ def __radd__(self, other):
+ return other + self.value
+
+ def __sub__(self, other):
+ return self.value - other
+
+ def __rsub__(self, other):
+ return other - self.value
+
+ def __mul__(self, other):
+ return self.value * other
+
+ def __rmul__(self, other):
+ return other * self.value
+
+ def __truediv__(self, other):
+ return self.value / other
+
+ def __rtruediv__(self, other):
+ return other / self.value
+
+ def __floordiv__(self, other):
+ return self.value // other
+
+ def __rfloordiv__(self, other):
+ return other // self.value
+
+ # unary operations
+ def __neg__(self):
+ return -self.value
+
+ def __abs__(self):
+ return abs(self.value)
+
+
+class SpecH5LinkToDataset(SpecH5Dataset):
+ """Special :class:`SpecH5Dataset` representing a link to a dataset. It
+ works like a regular dataset, but :meth:`SpecH5Group.visit`
+ and :meth:`SpecH5Group.visititems` methods will recognize that it is
+ a link and will ignore it.
+
+ A special attribute contains the name of the target dataset:
+ :attr:`target`
+ """
+ def __init__(self, value, name, file_, parent, target):
+ """
+ :param value: Actual dataset value
+ :param name: Dataset full name (posix path format, starting with ``/``)
+ :type name: str
+ :param file_: Parent :class:`SpecH5`
+ :param parent: Parent :class:`SpecH5Group` which contains this dataset
+ :param str target: Name of linked dataset
+ """
+ SpecH5Dataset.__init__(self, value, name, file_, parent)
+ self.target = target
+ """Name of the target dataset"""
+
+
+def _dataset_builder(name, specfileh5, parent_group):
+ """Retrieve dataset from :class:`SpecFile`, based on dataset name, as a
+ subclass of :class:`numpy.ndarray`.
+
+ :param name: Datatset full name (posix path format, starting with ``/``)
+ :type name: str
+ :param specfileh5: parent :class:`SpecH5` object
+ :type specfileh5: :class:`SpecH5`
+ :param parent_group: Parent :class:`SpecH5Group`
+
+ :return: Array with the requested data
+ :rtype: :class:`SpecH5Dataset`.
+ """
+ scan_key = _get_scan_key_in_name(name)
+ scan = specfileh5._sf[scan_key]
+
+ # get dataset in an array-like format (ndarray, str, list…)
+ array_like = None
+
+ if title_pattern.match(name):
+ array_like = scan.scan_header_dict["S"]
+
+ elif start_time_pattern.match(name):
+ if "D" in scan.scan_header_dict:
+ try:
+ array_like = spec_date_to_iso8601(scan.scan_header_dict["D"])
+ except (IndexError, ValueError):
+ logger1.warn("Could not parse date format in scan %s header." +
+ " Using original date not converted to ISO-8601",
+ scan_key)
+ array_like = scan.scan_header_dict["D"]
+ elif "D" in scan.file_header_dict:
+ logger1.warn("No #D line in scan %s header. " +
+ "Using file header for start_time.",
+ scan_key)
+ try:
+ array_like = spec_date_to_iso8601(scan.file_header_dict["D"])
+ except (IndexError, ValueError):
+ logger1.warn("Could not parse date format in scan %s header. " +
+ "Using original date not converted to ISO-8601",
+ scan_key)
+ array_like = scan.file_header_dict["D"]
+ else:
+ logger1.warn("No #D line in %s header. Setting date to empty string.",
+ scan_key)
+ array_like = ""
+
+ elif file_header_data_pattern.match(name):
+ # array_like = _fixed_length_strings(scan.file_header)
+ array_like = "\n".join(scan.file_header)
+
+ elif scan_header_data_pattern.match(name):
+ # array_like = _fixed_length_strings(scan.scan_header)
+ array_like = "\n".join(scan.scan_header)
+
+ elif positioners_data_pattern.match(name):
+ m = positioners_data_pattern.match(name)
+ motor_name = m.group(1)
+ if motor_name not in (scan.labels + scan.motor_names):
+ if "%" in motor_name:
+ motor_name = motor_name.replace("%", "/")
+ # if a motor is recorded as a data column, ignore its position in
+ # header and return the data column instead
+ if motor_name in scan.labels and scan.data.shape[0] > 0:
+ array_like = scan.data_column_by_name(motor_name)
+ else:
+ # may return float("inf") if #P line is missing from scan hdr
+ array_like = scan.motor_position_by_name(motor_name)
+
+ elif measurement_data_pattern.match(name):
+ m = measurement_data_pattern.match(name)
+ column_name = m.group(1)
+ if column_name not in scan.labels:
+ if "%" in column_name:
+ column_name = column_name.replace("%", "/")
+ array_like = scan.data_column_by_name(column_name)
+
+ elif instrument_mca_data_pattern.match(name):
+ m = instrument_mca_data_pattern.match(name)
+
+ analyser_index = int(m.group(1))
+ # retrieve 2D array of all MCA spectra from one analyser
+ array_like = _demultiplex_mca(scan, analyser_index)
+
+ elif instrument_mca_calib_pattern.match(name):
+ m = instrument_mca_calib_pattern.match(name)
+ analyser_index = int(m.group(1))
+ if len(scan.mca.channels) == 1:
+ # single @CALIB line applying to multiple devices
+ analyser_index = 0
+ array_like = scan.mca.calibration[analyser_index]
+
+ elif instrument_mca_chann_pattern.match(name):
+ m = instrument_mca_chann_pattern.match(name)
+ analyser_index = int(m.group(1))
+ if len(scan.mca.channels) == 1:
+ # single @CHANN line applying to multiple devices
+ analyser_index = 0
+ array_like = scan.mca.channels[analyser_index]
+
+ elif ub_matrix_pattern.match(name):
+ if not "G3" in scan.scan_header_dict:
+ raise KeyError("No UB matrix in a scan without a #G3 header line")
+ array_like = numpy.array(
+ list(map(float, scan.scan_header_dict["G3"].split()))).reshape((1, 3, 3))
+ elif unit_cell_pattern.match(name):
+ if not "G1" in scan.scan_header_dict:
+ raise KeyError(
+ "No unit_cell matrix in a scan without a #G1 header line")
+ array_like = numpy.array(
+ list(map(float, scan.scan_header_dict["G1"].split()))[0:6]).reshape((1, 6))
+ elif unit_cell_abc_pattern.match(name):
+ if not "G1" in scan.scan_header_dict:
+ raise KeyError(
+ "No unit_cell matrix in a scan without a #G1 header line")
+ array_like = numpy.array(
+ list(map(float, scan.scan_header_dict["G1"].split()))[0:3]).reshape((3,))
+ elif unit_cell_alphabetagamma_pattern.match(name):
+ if not "G1" in scan.scan_header_dict:
+ raise KeyError(
+ "No unit_cell matrix in a scan without a #G1 header line")
+ array_like = numpy.array(
+ list(map(float, scan.scan_header_dict["G1"].split()))[3:6]).reshape((3,))
+ elif "CTIME" in scan.mca_header_dict and "mca_" in name:
+ m = re.compile(r"/.*/mca_([0-9]+)/.*").match(name)
+ analyser_index = int(m.group(1))
+
+ ctime_line = scan.mca_header_dict['CTIME']
+ (preset_time, live_time, elapsed_time) = _parse_ctime(ctime_line, analyser_index)
+ if instrument_mca_preset_t_pattern.match(name):
+ array_like = preset_time
+ elif instrument_mca_live_t_pattern.match(name):
+ array_like = live_time
+ elif instrument_mca_elapsed_t_pattern.match(name):
+ array_like = elapsed_time
+
+ if array_like is None:
+ raise KeyError("Name " + name + " does not match any known dataset.")
+
+ return SpecH5Dataset(array_like, name,
+ file_=specfileh5, parent=parent_group)
+
+
+def _link_to_dataset_builder(name, specfileh5, parent_group):
+ """Same as :func:`_dataset_builder`, but returns a
+ :class:`SpecH5LinkToDataset`
+
+ :param name: Datatset full name (posix path format, starting with ``/``)
+ :type name: str
+ :param specfileh5: parent :class:`SpecH5` object
+ :type specfileh5: :class:`SpecH5`
+ :param parent_group: Parent :class:`SpecH5Group`
+
+ :return: Array with the requested data
+ :rtype: :class:`SpecH5LinkToDataset`.
+ """
+ scan_key = _get_scan_key_in_name(name)
+ scan = specfileh5._sf[scan_key]
+
+ # get dataset in an array-like format (ndarray, str, list…)
+ array_like = None
+
+ # /1.1/measurement/mca_0/data -> /1.1/instrument/mca_0/data
+ if measurement_mca_data_pattern.match(name):
+ m = measurement_mca_data_pattern.match(name)
+ analyser_index = int(m.group(1))
+ array_like = _demultiplex_mca(scan, analyser_index)
+
+ # /1.1/measurement/mca_0/info/X -> /1.1/instrument/mca_0/X
+ # X: calibration, channels, preset_time, live_time, elapsed_time
+ elif measurement_mca_info_dataset_pattern.match(name):
+ m = measurement_mca_info_dataset_pattern.match(name)
+ analyser_index = int(m.group(1))
+ mca_hdr_type = m.group(2)
+
+ if mca_hdr_type == "calibration":
+ if len(scan.mca.calibration) == 1:
+ # single @CALIB line for multiple devices
+ analyser_index = 0
+ array_like = scan.mca.calibration[analyser_index]
+
+ elif mca_hdr_type == "channels":
+ if len(scan.mca.channels) == 1:
+ # single @CHANN line for multiple devices
+ analyser_index = 0
+ array_like = scan.mca.channels[analyser_index]
+
+ elif "CTIME" in scan.mca_header_dict:
+ ctime_line = scan.mca_header_dict['CTIME']
+ (preset_time, live_time, elapsed_time) = _parse_ctime(ctime_line,
+ analyser_index)
+ if mca_hdr_type == "preset_time":
+ array_like = preset_time
+ elif mca_hdr_type == "live_time":
+ array_like = live_time
+ elif mca_hdr_type == "elapsed_time":
+ array_like = elapsed_time
+
+ # /1.1/measurement/mca_0/info/data -> /1.1/instrument/mca_0/data
+ elif measurement_mca_info_data_pattern.match(name):
+ m = measurement_mca_info_data_pattern.match(name)
+ analyser_index = int(m.group(1))
+ array_like = _demultiplex_mca(scan, analyser_index)
+
+ if array_like is None:
+ raise KeyError("Name " + name + " does not match any known dataset.")
+
+ target = name.replace("measurement", "instrument")
+ target = target.replace("info/", "")
+
+ return SpecH5LinkToDataset(array_like, name,
+ file_=specfileh5, parent=parent_group,
+ target=target)
+
+
+def _demultiplex_mca(scan, analyser_index):
+ """Return MCA data for a single analyser.
+
+ Each MCA spectrum is a 1D array. For each analyser, there is one
+ spectrum recorded per scan data line. When there are more than a single
+ MCA analyser in a scan, the data will be multiplexed. For instance if
+ there are 3 analysers, the consecutive spectra for the first analyser must
+ be accessed as ``mca[0], mca[3], mca[6]…``.
+
+ :param scan: :class:`Scan` instance containing the MCA data
+ :param analyser_index: 0-based index referencing the analyser
+ :type analyser_index: int
+ :return: 2D numpy array containing all spectra for one analyser
+ """
+ number_of_analysers = _get_number_of_mca_analysers(scan)
+
+ number_of_MCA_spectra = len(scan.mca)
+
+ list_of_1D_arrays = []
+ for i in range(analyser_index,
+ number_of_MCA_spectra,
+ number_of_analysers):
+ list_of_1D_arrays.append(scan.mca[i])
+ # convert list to 2D array
+ return numpy.array(list_of_1D_arrays)
+
+
+class SpecH5Group(object):
+ """Emulate :class:`h5py.Group` for a SpecFile object
+
+ :param name: Group full name (posix path format, starting with ``/``)
+ :type name: str
+ :param specfileh5: parent :class:`SpecH5` instance
+
+ """
+ def __init__(self, name, specfileh5):
+ self.name = name
+ """Full name/path of group"""
+
+ self.file = specfileh5
+ """Parent SpecH5 object"""
+
+ self.attrs = _get_attrs_dict(name)
+ """Attributes dictionary"""
+
+ if name != "/":
+ if name not in specfileh5:
+ raise KeyError("File %s does not contain group %s" %
+ (specfileh5, name))
+ scan_key = _get_scan_key_in_name(name)
+ self._scan = self.file._sf[scan_key]
+
+ @property
+ def h5py_class(self):
+ """Return h5py class which is mimicked by this class:
+ :class:`h5py.Group`.
+
+ Accessing this attribute if :mod:`h5py` is not installed causes
+ an ``ImportError`` to be raised
+ """
+ if h5py is None:
+ raise ImportError("Cannot return h5py.Group class, " +
+ "unable to import h5py module")
+ return h5py.Group
+
+ @property
+ def parent(self):
+ """Parent group (group that contains this group)"""
+ if not self.name.strip("/"):
+ return None
+
+ parent_name = posixpath.dirname(self.name.rstrip("/"))
+ return SpecH5Group(parent_name, self.file)
+
+ def __contains__(self, key):
+ """
+ :param key: Path to child element (e.g. ``"mca_0/info"``) or full name
+ of group or dataset (e.g. ``"/2.1/instrument/positioners"``)
+ :return: True if key refers to a valid member of this group,
+ else False
+ """
+ # Absolute path to an item outside this group
+ if key.startswith("/"):
+ if not key.startswith(self.name):
+ return False
+ # Make sure key is an absolute path by prepending this group's name
+ else:
+ key = self.name.rstrip("/") + "/" + key
+
+ # key not matching any known pattern
+ if not is_group(key) and not is_dataset(key) and\
+ not is_link_to_group(key) and not is_link_to_dataset(key):
+ return False
+
+ # nonexistent scan in specfile
+ scan_key = _get_scan_key_in_name(key)
+ if scan_key not in self.file._sf:
+ return False
+
+ # nonexistent MCA analyser in scan
+ mca_analyser_index = _get_mca_index_in_name(key)
+ if mca_analyser_index is not None:
+ if not _mca_analyser_in_scan(self.file._sf,
+ scan_key,
+ mca_analyser_index):
+ return False
+
+ # nonexistent motor name
+ motor_name = _get_motor_in_name(key)
+ if motor_name is not None:
+ if not _motor_in_scan(self.file._sf,
+ scan_key,
+ motor_name):
+ return False
+
+ # nonexistent data column
+ column_label = _get_data_column_label_in_name(key)
+ if column_label is not None:
+ if not _column_label_in_scan(self.file._sf,
+ scan_key,
+ column_label):
+ return False
+
+ if key.endswith("preset_time") or\
+ key.endswith("elapsed_time") or\
+ key.endswith("live_time"):
+ return "CTIME" in self.file._sf[scan_key].mca_header_dict
+
+ if sample_pattern.match(key):
+ return ("G3" in self.file._sf[scan_key].scan_header_dict or
+ "G1" in self.file._sf[scan_key].scan_header_dict)
+
+ if key.endswith("sample/ub_matrix"):
+ return "G3" in self.file._sf[scan_key].scan_header_dict
+
+ if key.endswith("sample/unit_cell"):
+ return "G1" in self.file._sf[scan_key].scan_header_dict
+
+ if key.endswith("sample/unit_cell_abc"):
+ return "G1" in self.file._sf[scan_key].scan_header_dict
+
+
+ if key.endswith("sample/unit_cell_alphabetagamma"):
+ return "G1" in self.file._sf[scan_key].scan_header_dict
+
+ # header, title, start_time, existing scan/mca/motor/measurement
+ return True
+
+ def __eq__(self, other):
+ return (isinstance(other, SpecH5Group) and
+ self.name == other.name and
+ self.file.filename == other.file.filename and
+ self.keys() == other.keys())
+
+ def get(self, name, default=None, getclass=False, getlink=False):
+ """Retrieve an item by name, or a default value if name does not
+ point to an existing item.
+
+ :param name str: name of the item
+ :param default: Default value returned if the name is not found
+ :param bool getclass: if *True*, the returned object is the class of
+ the item, instead of the item instance.
+ :param bool getlink: Not implemented. This method always returns
+ an instance of the original class of the requested item (or
+ just the class, if *getclass* is *True*)
+ :return: The requested item, or its class if *getclass* is *True*,
+ or the specified *default* value if the group does not contain
+ an item with the requested name.
+ """
+ if name not in self:
+ return default
+
+ if getlink and getclass:
+ pass
+
+ if getclass:
+ return self[name].h5py_class
+
+ return self[name]
+
+ def __getitem__(self, key):
+ """Return a :class:`SpecH5Group` or a :class:`SpecH5Dataset`
+ if ``key`` is a valid name of a group or dataset.
+
+ ``key`` can be a member of ``self.keys()``, i.e. an immediate child of
+ the group, or a path reaching into subgroups (e.g.
+ ``"instrument/positioners"``)
+
+ In the special case were this group is the root group, ``key`` can
+ start with a ``/`` character.
+
+ :param key: Name of member
+ :type key: str
+ :raise: KeyError if ``key`` is not a known member of this group.
+ """
+ # accept numbers for scan indices
+ if isinstance(key, int):
+ number = self.file._sf.number(key)
+ order = self.file._sf.order(key)
+ full_key = "/%d.%d" % (number, order)
+ # Relative path starting from this group (e.g "mca_0/info")
+ elif not key.startswith("/"):
+ full_key = self.name.rstrip("/") + "/" + key
+ # Absolute path called from the root group or from a parent group
+ elif key.startswith(self.name):
+ full_key = key
+ # Absolute path to an element called from a non-parent group
+ else:
+ raise KeyError(key + " is not a child of " + self.__repr__())
+
+ if is_group(full_key):
+ return SpecH5Group(full_key, self.file)
+ elif is_dataset(full_key):
+ return _dataset_builder(full_key, self.file, self)
+ elif is_link_to_group(full_key):
+ link_target = full_key.replace("measurement", "instrument").rstrip("/")[:-4]
+ return SpecH5LinkToGroup(full_key, self.file, link_target)
+ elif is_link_to_dataset(full_key):
+ return _link_to_dataset_builder(full_key, self.file, self)
+ else:
+ raise KeyError("unrecognized group or dataset: " + full_key)
+
+ def __iter__(self):
+ for key in self.keys():
+ yield key
+
+ def items(self):
+ for key in self.keys():
+ yield key, self[key]
+
+ def __len__(self):
+ """Return number of members, subgroups and datasets, attached to this
+ group.
+ """
+ return len(self.keys())
+
+ def __repr__(self):
+ return '<SpecH5Group "%s" (%d members)>' % (self.name, len(self))
+
+ def keys(self):
+ """:return: List of all names of members attached to this group
+ """
+ # keys in hdf5 are unicode
+ if self.name == "/":
+ return self.file.keys()
+
+ if scan_pattern.match(self.name):
+ ret = static_items["scan"]
+ if "G1" in self._scan.scan_header_dict or "G3" in self._scan.scan_header_dict:
+ return ret + [u"sample"]
+ return ret
+
+ if positioners_group_pattern.match(self.name):
+ motor_names = self._scan.motor_names
+ return [name.replace("/", "%") for name in motor_names]
+
+ if specfile_group_pattern.match(self.name):
+ return static_items["scan/instrument/specfile"]
+
+ if measurement_mca_group_pattern.match(self.name):
+ return static_items["scan/measurement/mca"]
+
+ if instrument_mca_group_pattern.match(self.name):
+ ret = static_items["scan/instrument/mca"]
+ if "CTIME" in self._scan.mca_header_dict:
+ return ret + [u"preset_time", u"elapsed_time", u"live_time"]
+ return ret
+
+ if sample_pattern.match(self.name):
+ ret = []
+ if "G1" in self._scan.scan_header_dict:
+ ret.append(u"unit_cell")
+ ret.append(u"unit_cell_abc")
+ ret.append(u"unit_cell_alphabetagamma")
+ if "G3" in self._scan.scan_header_dict:
+ ret.append(u"ub_matrix")
+ return ret
+
+ number_of_MCA_spectra = len(self._scan.mca)
+ number_of_data_lines = self._scan.data.shape[1]
+
+ if not number_of_data_lines == 0:
+ # Number of MCA spectra must be a multiple of number of data lines
+ assert number_of_MCA_spectra % number_of_data_lines == 0
+ number_of_MCA_analysers = number_of_MCA_spectra // number_of_data_lines
+ elif number_of_MCA_spectra:
+ # Case of a scan without data lines, only MCA.
+ # Our only option is to assume that the number of analysers
+ # is the number of #@CHANN lines
+ number_of_MCA_analysers = len(self._scan.mca.channels)
+ else:
+ number_of_MCA_analysers = 0
+
+ mca_list = ["mca_%d" % i for i in range(number_of_MCA_analysers)]
+
+ if measurement_group_pattern.match(self.name):
+ scan_labels = self._scan.labels
+ return [label.replace("/", "%") for label in scan_labels] + mca_list
+
+ if instrument_pattern.match(self.name):
+ return static_items["scan/instrument"] + mca_list
+
+ def visit(self, func, follow_links=False):
+ """Recursively visit all names in this group and subgroups.
+
+ :param func: Callable (function, method or callable object)
+ :type func: function
+
+ You supply a callable (function, method or callable object); it
+ will be called exactly once for each link in this group and every
+ group below it. Your callable must conform to the signature:
+
+ ``func(<member name>) => <None or return value>``
+
+ Returning ``None`` continues iteration, returning anything else stops
+ and immediately returns that value from the visit method. No
+ particular order of iteration within groups is guaranteed.
+
+ Example:
+
+ .. code-block:: python
+
+ # Get a list of all contents (groups and datasets) in a SpecFile
+ mylist = []
+ f = File('foo.dat')
+ f.visit(mylist.append)
+ """
+ for member_name in self.keys():
+ member = self[member_name]
+ ret = None
+ if (not is_link_to_dataset(member.name) and
+ not is_link_to_group(member.name)) or follow_links:
+ ret = func(member.name)
+ if ret is not None:
+ return ret
+ # recurse into subgroups
+ if isinstance(member, SpecH5Group):
+ if not isinstance(member, SpecH5LinkToGroup) or follow_links:
+ self[member_name].visit(func, follow_links)
+
+ def visititems(self, func, follow_links=False):
+ """Recursively visit names and objects in this group.
+
+ :param func: Callable (function, method or callable object)
+ :type func: function
+
+ You supply a callable (function, method or callable object); it
+ will be called exactly once for each
+ member in this group and every group below it. Your callable must
+ conform to the signature:
+
+ ``func(<member name>, <object>) => <None or return value>``
+
+ Returning ``None`` continues iteration, returning anything else stops
+ and immediately returns that value from the visit method. No
+ particular order of iteration within groups is guaranteed.
+
+ Example:
+
+ .. code-block:: python
+
+ # Get a list of all datasets in a specific scan
+ mylist = []
+ def func(name, obj):
+ if isinstance(obj, SpecH5Dataset):
+ mylist.append(name)
+
+ f = File('foo.dat')
+ f["1.1"].visititems(func)
+ """
+ for member_name in self.keys():
+ member = self[member_name]
+ ret = None
+ if (not is_link_to_dataset(member.name) and
+ not is_link_to_group(member.name)) or follow_links:
+ ret = func(member.name, member)
+ if ret is not None:
+ return ret
+ # recurse into subgroups
+ if isinstance(self[member_name], SpecH5Group):
+ if not isinstance(self[member_name], SpecH5LinkToGroup) or follow_links:
+ self[member_name].visititems(func, follow_links)
+
+
+class SpecH5LinkToGroup(SpecH5Group):
+ """Special :class:`SpecH5Group` representing a link to a group.
+
+ It works like a regular group but :meth:`SpecH5Group.visit`
+ and :meth:`SpecH5Group.visititems` methods will recognize it as a
+ link and will ignore it.
+
+ An additional attribute indicates the name of the target group:
+ :attr:`target`
+ """
+ def __init__(self, name, specfileh5, target):
+ SpecH5Group.__init__(self, name, specfileh5)
+ self.target = target
+ """Name of the target group."""
+
+ def keys(self):
+ """:return: List of all names of members attached to the target group
+ """
+ # we only have a single type of link to a group:
+ # /1.1/measurement/mca_0/info/ -> /1.1/instrument/mca_0/
+ if measurement_mca_info_pattern.match(self.name):
+ # link_target = self.name.replace("measurement", "instrument").rstrip("/")[:-4]
+ # return SpecH5Group(link_target, self.file).keys()
+ return SpecH5Group(self.target, self.file).keys()
+ else:
+ raise NameError("Unknown link to SpecH5Group: "
+ "%s -> %s" % (self.name, self.target))
+
+
+class SpecH5(SpecH5Group):
+ """Special :class:`SpecH5Group` representing the root of a SpecFile.
+
+ :param filename: Path to SpecFile in filesystem
+ :type filename: str
+
+ In addition to all generic :class:`SpecH5Group` attributes, this class
+ also keeps a reference to the original :class:`SpecFile` object and
+ has a :attr:`filename` attribute.
+
+ Its immediate children are scans, but it also gives access to any group
+ or dataset in the entire SpecFile tree by specifying the full path.
+ """
+ def __init__(self, filename):
+ self.filename = filename
+ self.attrs = _get_attrs_dict("/")
+ self._sf = SpecFile(filename)
+
+ SpecH5Group.__init__(self, name="/", specfileh5=self)
+ if len(self) == 0:
+ # SpecFile library do not raise exception for non specfiles
+ raise IOError("Empty specfile. Not a valid spec format.")
+
+ def keys(self):
+ """
+ :return: List of all scan keys in this SpecFile
+ (e.g. ``["1.1", "2.1"…]``)
+ """
+ return self._sf.keys()
+
+ def __enter__(self):
+ """Context manager enter"""
+ return self
+
+ def __exit__(self, type, value, tb): # pylint: disable=W0622
+ """Context manager exit"""
+ self.close()
+
+ def close(self):
+ """Close the object, and free up associated resources.
+
+ After calling this method, attempts to use the object may fail.
+ """
+ self._sf = None
+
+ def __repr__(self):
+ return '<SpecH5 "%s" (%d members)>' % (self.filename, len(self))
+
+ def __eq__(self, other):
+ return (isinstance(other, SpecH5) and
+ self.filename == other.filename and
+ self.keys() == other.keys())
+
+ @property
+ def h5py_class(self):
+ """h5py class which is mimicked by this class"""
+ if h5py is None:
+ raise ImportError("Cannot return h5py.File class, " +
+ "unable to import h5py module")
+ return h5py.File
diff --git a/silx/io/spectoh5.py b/silx/io/spectoh5.py
new file mode 100644
index 0000000..53988f2
--- /dev/null
+++ b/silx/io/spectoh5.py
@@ -0,0 +1,304 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""This module provides functions to convert a SpecFile into a HDF5 file.
+
+Read the documentation of :mod:`silx.io.spech5` for information on the
+structure of the output HDF5 files.
+
+Strings are written to the HDF5 datasets as fixed-length ASCII (NumPy *S* type).
+This is done in order to produce files that have maximum compatibility with
+other HDF5 libraries, as recommended in the
+`h5py documentation <http://docs.h5py.org/en/latest/strings.html#how-to-store-text-strings>`_.
+
+If you read the files back with *h5py* in Python 3, you will recover strings
+as bytes, which you should decode to transform them into python strings::
+
+ >>> import h5py
+ >>> f = h5py.File("myfile.h5")
+ >>> f["/1.1/instrument/specfile/scan_header"][0]
+ b'#S 94 ascan del -0.5 0.5 20 1'
+ >>> f["/1.1/instrument/specfile/scan_header"][0].decode()
+ '#S 94 ascan del -0.5 0.5 20 1'
+
+Arrays of strings, such as file and scan headers, are stored as fixed-length
+strings. The length of all strings in an array is equal to the length of the
+longest string. Shorter strings are right-padded with blank spaces.
+
+.. note:: This module has a dependency on the `h5py <http://www.h5py.org/>`_
+ library, which is not a mandatory dependency for `silx`. You might need
+ to install it if you don't already have it.
+"""
+
+import numpy
+import logging
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import h5py
+except ImportError as e:
+ _logger.error("Module " + __name__ + " requires h5py")
+ raise e
+
+from .spech5 import SpecH5, SpecH5Group, SpecH5Dataset, \
+ SpecH5LinkToGroup, SpecH5LinkToDataset
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "07/02/2017"
+
+
+def _create_link(h5f, link_name, target_name,
+ link_type="hard", overwrite_data=False):
+ """Create a link in a HDF5 file
+
+ If member with name ``link_name`` already exists, delete it first or
+ ignore link depending on global param ``overwrite_data``.
+
+ :param h5f: :class:`h5py.File` object
+ :param link_name: Link path
+ :param target_name: Handle for target group or dataset
+ :param str link_type: "hard" (default) or "soft"
+ :param bool overwrite_data: If True, delete existing member (group,
+ dataset or link) with the same name. Default is False.
+ """
+ if link_name not in h5f:
+ _logger.debug("Creating link " + link_name + " -> " + target_name)
+ elif overwrite_data:
+ _logger.warn("Overwriting " + link_name + " with link to" +
+ target_name)
+ del h5f[link_name]
+ else:
+ _logger.warn(link_name + " already exist. Can't create link to " +
+ target_name)
+ return None
+
+ if link_type == "hard":
+ h5f[link_name] = h5f[target_name]
+ elif link_type == "soft":
+ h5f[link_name] = h5py.SoftLink(target_name)
+ else:
+ raise ValueError("link_type must be 'hard' or 'soft'")
+
+
+class SpecToHdf5Writer(object):
+ """Converter class to write a Spec file to a HDF5 file."""
+ def __init__(self,
+ h5path='/',
+ overwrite_data=False,
+ link_type="hard",
+ create_dataset_args=None):
+ """
+
+ :param h5path: Target path where the scan groups will be written
+ in the output HDF5 file.
+ :param bool overwrite_data:
+ See documentation of :func:`write_spec_to_h5`
+ :param str link_type: ``"hard"`` (default) or ``"soft"``
+ :param dict create_dataset_args: Dictionary of args you want to pass to
+ ``h5py.File.create_dataset``.
+ See documentation of :func:`write_spec_to_h5`
+ """
+ self.h5path = h5path
+
+ self._h5f = None
+ """SpecH5 object, assigned in :meth:`write`"""
+
+ if create_dataset_args is None:
+ create_dataset_args = {}
+ self.create_dataset_args = create_dataset_args
+
+ self.overwrite_data = overwrite_data # boolean
+
+ self.link_type = link_type
+ """'soft' or 'hard' """
+
+ self._links = []
+ """List of *(link_path, target_path)* tuples."""
+
+ def _filter_links(self):
+ """Remove all links that are part of the subtree whose
+ root is a link to a group."""
+ filtered_links = []
+ for i, link in enumerate(self._links):
+ link_is_valid = True
+ link_path, target_path = link
+ other_links = self._links[:i] + self._links[i+1:]
+ for link_path2, target_path2 in other_links:
+ if link_path.startswith(link_path2):
+ # parent group is a link to a group
+ link_is_valid = False
+ break
+ if link_is_valid:
+ filtered_links.append(link)
+ self._links = filtered_links
+
+ def write(self, sfh5, h5f):
+ """Do the conversion from :attr:`sfh5` (Spec file) to *h5f* (HDF5)
+
+ All the parameters needed for the conversion have been initialized
+ in the constructor.
+
+ :param sfh5: :class:`SpecH5` object
+ :param h5f: :class:`h5py.File` instance
+ """
+ # Recurse through all groups and datasets to add them to the HDF5
+ sfh5 = sfh5
+ self._h5f = h5f
+ sfh5.visititems(self.append_spec_member_to_h5, follow_links=True)
+
+ # Handle the attributes of the root group
+ root_grp = h5f[self.h5path]
+ for key in sfh5.attrs:
+ if self.overwrite_data or key not in root_grp.attrs:
+ root_grp.attrs.create(key,
+ numpy.string_(sfh5.attrs[key]))
+
+ # Handle links at the end, when their targets are created
+ self._filter_links()
+ for link_name, target_name in self._links:
+ _create_link(self._h5f, link_name, target_name,
+ link_type=self.link_type,
+ overwrite_data=self.overwrite_data)
+
+ def append_spec_member_to_h5(self, spec_h5_name, obj):
+ """Add one group or one dataset to :attr:`h5f`"""
+ h5_name = self.h5path + spec_h5_name.lstrip("/")
+
+ if isinstance(obj, SpecH5LinkToGroup) or\
+ isinstance(obj, SpecH5LinkToDataset):
+ # links to be created after all groups and datasets
+ h5_target = self.h5path + obj.target.lstrip("/")
+ self._links.append((h5_name, h5_target))
+
+ elif isinstance(obj, SpecH5Dataset):
+ _logger.debug("Saving dataset: " + h5_name)
+
+ member_initially_exists = h5_name in self._h5f
+
+ if self.overwrite_data and member_initially_exists:
+ _logger.warn("Overwriting dataset: " + h5_name)
+ del self._h5f[h5_name]
+
+ if self.overwrite_data or not member_initially_exists:
+ # fancy arguments don't apply to scalars (shape==())
+ if obj.shape == ():
+ ds = self._h5f.create_dataset(h5_name, data=obj.value)
+ else:
+ ds = self._h5f.create_dataset(h5_name, data=obj.value,
+ **self.create_dataset_args)
+
+ # add HDF5 attributes
+ for key in obj.attrs:
+ if self.overwrite_data or key not in ds.attrs:
+ ds.attrs.create(key, numpy.string_(obj.attrs[key]))
+
+ if not self.overwrite_data and member_initially_exists:
+ _logger.warn("Ignoring existing dataset: " + h5_name)
+
+ elif isinstance(obj, SpecH5Group):
+ if h5_name not in self._h5f:
+ _logger.debug("Creating group: " + h5_name)
+ grp = self._h5f.create_group(h5_name)
+ else:
+ grp = self._h5f[h5_name]
+
+ # add HDF5 attributes
+ for key in obj.attrs:
+ if self.overwrite_data or key not in grp.attrs:
+ grp.attrs.create(key, numpy.string_(obj.attrs[key]))
+
+
+def write_spec_to_h5(specfile, h5file, h5path='/',
+ mode="a", overwrite_data=False,
+ link_type="hard", create_dataset_args=None):
+ """Write content of a SpecFile in a HDF5 file.
+
+ :param specfile: Path of input SpecFile or :class:`SpecH5` object
+ :param h5file: Path of output HDF5 file or HDF5 file handle
+ (`h5py.File` object)
+ :param h5path: Target path in HDF5 file in which scan groups are created.
+ Default is root (``"/"``)
+ :param mode: Can be ``"r+"`` (read/write, file must exist),
+ ``"w"`` (write, existing file is lost), ``"w-"`` (write, fail
+ if exists) or ``"a"`` (read/write if exists, create otherwise).
+ This parameter is ignored if ``h5file`` is a file handle.
+ :param overwrite_data: If ``True``, existing groups and datasets can be
+ overwritten, if ``False`` they are skipped. This parameter is only
+ relevant if ``file_mode`` is ``"r+"`` or ``"a"``.
+ :param link_type: ``"hard"`` (default) or ``"soft"``
+ :param create_dataset_args: Dictionary of args you want to pass to
+ ``h5py.File.create_dataset``. This allows you to specify filters and
+ compression parameters. Don't specify ``name`` and ``data``.
+ These arguments don't apply to scalar datasets.
+
+ The structure of the spec data in an HDF5 file is described in the
+ documentation of :mod:`silx.io.spech5`.
+ """
+ if not isinstance(specfile, SpecH5):
+ sfh5 = SpecH5(specfile)
+ else:
+ sfh5 = specfile
+
+ if not h5path.endswith("/"):
+ h5path += "/"
+
+ writer = SpecToHdf5Writer(h5path=h5path,
+ overwrite_data=overwrite_data,
+ link_type=link_type,
+ create_dataset_args=create_dataset_args)
+
+ if not isinstance(h5file, h5py.File):
+ # If h5file is a file path, open and close it
+ with h5py.File(h5file, mode) as h5f:
+ writer.write(sfh5, h5f)
+ else:
+ writer.write(sfh5, h5file)
+
+
+def convert(specfile, h5file, mode="w-",
+ create_dataset_args=None):
+ """Convert a SpecFile into an HDF5 file, write scans into the root (``/``)
+ group.
+
+ :param specfile: Path of input SpecFile or :class:`SpecH5` object
+ :param h5file: Path of output HDF5 file, or h5py.File object
+ :param mode: Can be ``"w"`` (write, existing file is
+ lost), ``"w-"`` (write, fail if exists). This is ignored
+ if ``h5file`` is a file handle.
+ :param create_dataset_args: Dictionary of args you want to pass to
+ ``h5py.File.create_dataset``. This allows you to specify filters and
+ compression parameters. Don't specify ``name`` and ``data``.
+
+ This is a convenience shortcut to call::
+
+ write_spec_to_h5(specfile, h5file, h5path='/',
+ mode="w-", link_type="hard")
+ """
+ if mode not in ["w", "w-"]:
+ raise IOError("File mode must be 'w' or 'w-'. Use write_spec_to_h5" +
+ " to append Spec data to an existing HDF5 file.")
+ write_spec_to_h5(specfile, h5file, h5path='/', mode=mode,
+ create_dataset_args=create_dataset_args)
diff --git a/silx/io/test/__init__.py b/silx/io/test/__init__.py
new file mode 100644
index 0000000..72bd8f9
--- /dev/null
+++ b/silx/io/test/__init__.py
@@ -0,0 +1,53 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "31/08/2016"
+
+import unittest
+
+from .test_specfile import suite as test_specfile_suite
+from .test_specfilewrapper import suite as test_specfilewrapper_suite
+from .test_dictdump import suite as test_dictdump_suite
+from .test_spech5 import suite as test_spech5_suite
+from .test_spectoh5 import suite as test_spectoh5_suite
+from .test_octaveh5 import suite as test_octaveh5_suite
+from .test_fabioh5 import suite as test_fabioh5_suite
+from .test_utils import suite as test_utils_suite
+from .test_nxdata import suite as test_nxdata_suite
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(test_dictdump_suite())
+ test_suite.addTest(test_specfile_suite())
+ test_suite.addTest(test_specfilewrapper_suite())
+ test_suite.addTest(test_spech5_suite())
+ test_suite.addTest(test_spectoh5_suite())
+ test_suite.addTest(test_octaveh5_suite())
+ test_suite.addTest(test_utils_suite())
+ test_suite.addTest(test_fabioh5_suite())
+ test_suite.addTest(test_nxdata_suite())
+ return test_suite
diff --git a/silx/io/test/test_dictdump.py b/silx/io/test/test_dictdump.py
new file mode 100644
index 0000000..15d5fdc
--- /dev/null
+++ b/silx/io/test/test_dictdump.py
@@ -0,0 +1,249 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""Tests for dicttoh5 module"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "10/02/2017"
+
+from collections import OrderedDict
+import numpy
+import os
+import tempfile
+import unittest
+
+try:
+ import h5py
+ h5py_missing = False
+except ImportError:
+ h5py_missing = True
+
+from collections import defaultdict
+
+from ..configdict import ConfigDict
+from ..dictdump import dicttoh5, dicttojson, dicttoini, dump
+from ..dictdump import h5todict, load
+
+
+def tree():
+ """Tree data structure as a recursive nested dictionary"""
+ return defaultdict(tree)
+
+
+city_attrs = tree()
+city_attrs["Europe"]["France"]["Grenoble"]["area"] = "18.44 km2"
+city_attrs["Europe"]["France"]["Grenoble"]["inhabitants"] = 160215
+city_attrs["Europe"]["France"]["Grenoble"]["coordinates"] = [45.1830, 5.7196]
+city_attrs["Europe"]["France"]["Tourcoing"]["area"]
+
+
+@unittest.skipIf(h5py_missing, "Could not import h5py")
+class TestDictToH5(unittest.TestCase):
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+ self.h5_fname = os.path.join(self.tempdir, "cityattrs.h5")
+
+ def tearDown(self):
+ os.unlink(self.h5_fname)
+ os.rmdir(self.tempdir)
+
+ def testH5CityAttrs(self):
+ filters = {'shuffle': True,
+ 'fletcher32': True}
+ dicttoh5(city_attrs, self.h5_fname, h5path='/city attributes',
+ mode="w", create_dataset_args=filters)
+
+ h5f = h5py.File(self.h5_fname)
+
+ self.assertIn("Tourcoing/area", h5f["/city attributes/Europe/France"])
+ ds = h5f["/city attributes/Europe/France/Grenoble/inhabitants"]
+ self.assertEqual(ds[...], 160215)
+
+ # filters only apply to datasets that are not scalars (shape != () )
+ ds = h5f["/city attributes/Europe/France/Grenoble/coordinates"]
+ #self.assertEqual(ds.compression, "gzip")
+ self.assertTrue(ds.fletcher32)
+ self.assertTrue(ds.shuffle)
+
+ h5f.close()
+
+ ddict = load(self.h5_fname, fmat="hdf5")
+ self.assertAlmostEqual(
+ min(ddict["city attributes"]["Europe"]["France"]["Grenoble"]["coordinates"]),
+ 5.7196)
+
+
+@unittest.skipIf(h5py_missing, "Could not import h5py")
+class TestH5ToDict(unittest.TestCase):
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+ self.h5_fname = os.path.join(self.tempdir, "cityattrs.h5")
+ dicttoh5(city_attrs, self.h5_fname)
+
+ def tearDown(self):
+ os.unlink(self.h5_fname)
+ os.rmdir(self.tempdir)
+
+ def testExcludeNames(self):
+ ddict = h5todict(self.h5_fname, path="/Europe/France",
+ exclude_names=["ourcoing", "inhab", "toto"])
+ self.assertNotIn("Tourcoing", ddict)
+ self.assertIn("Grenoble", ddict)
+
+ self.assertNotIn("inhabitants", ddict["Grenoble"])
+ self.assertIn("coordinates", ddict["Grenoble"])
+ self.assertIn("area", ddict["Grenoble"])
+
+
+class TestDictToJson(unittest.TestCase):
+ def setUp(self):
+ self.dir_path = tempfile.mkdtemp()
+ self.json_fname = os.path.join(self.dir_path, "cityattrs.json")
+
+ def tearDown(self):
+ os.unlink(self.json_fname)
+ os.rmdir(self.dir_path)
+
+ def testJsonCityAttrs(self):
+ self.json_fname = os.path.join(self.dir_path, "cityattrs.json")
+ dicttojson(city_attrs, self.json_fname, indent=3)
+
+ with open(self.json_fname, "r") as f:
+ json_content = f.read()
+ self.assertIn('"inhabitants": 160215', json_content)
+
+
+class TestDictToIni(unittest.TestCase):
+ def setUp(self):
+ self.dir_path = tempfile.mkdtemp()
+ self.ini_fname = os.path.join(self.dir_path, "test.ini")
+
+ def tearDown(self):
+ os.unlink(self.ini_fname)
+ os.rmdir(self.dir_path)
+
+ def testConfigDictIO(self):
+ """Ensure values and types of data is preserved when dictionary is
+ written to file and read back."""
+ testdict = {
+ 'simple_types': {
+ 'float': 1.0,
+ 'int': 1,
+ 'percent string': '5 % is too much',
+ 'backslash string': 'i can use \\',
+ 'empty_string': '',
+ 'nonestring': 'None',
+ 'nonetype': None,
+ 'interpstring': 'interpolation: %(percent string)s',
+ },
+ 'containers': {
+ 'list': [-1, 'string', 3.0, False, None],
+ 'array': numpy.array([1.0, 2.0, 3.0]),
+ 'dict': {
+ 'key1': 'Hello World',
+ 'key2': 2.0,
+ }
+ }
+ }
+
+ dump(testdict, self.ini_fname)
+
+ #read the data back
+ readdict = load(self.ini_fname)
+
+ testdictkeys = list(testdict.keys())
+ readkeys = list(readdict.keys())
+
+ self.assertTrue(len(readkeys) == len(testdictkeys),
+ "Number of read keys not equal")
+
+ self.assertEqual(readdict['simple_types']["interpstring"],
+ "interpolation: 5 % is too much")
+
+ testdict['simple_types']["interpstring"] = "interpolation: 5 % is too much"
+
+ for key in testdict["simple_types"]:
+ original = testdict['simple_types'][key]
+ read = readdict['simple_types'][key]
+ self.assertEqual(read, original,
+ "Read <%s> instead of <%s>" % (read, original))
+
+ for key in testdict["containers"]:
+ original = testdict["containers"][key]
+ read = readdict["containers"][key]
+ if key == 'array':
+ self.assertEqual(read.all(), original.all(),
+ "Read <%s> instead of <%s>" % (read, original))
+ else:
+ self.assertEqual(read, original,
+ "Read <%s> instead of <%s>" % (read, original))
+
+ def testConfigDictOrder(self):
+ """Ensure order is preserved when dictionary is
+ written to file and read back."""
+ test_dict = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
+ # sort by key
+ test_ordered_dict1 = OrderedDict(sorted(test_dict.items(),
+ key=lambda t: t[0]))
+ # sort by value
+ test_ordered_dict2 = OrderedDict(sorted(test_dict.items(),
+ key=lambda t: t[1]))
+ # add the two ordered dict as sections of a third ordered dict
+ test_ordered_dict3 = OrderedDict()
+ test_ordered_dict3["section1"] = test_ordered_dict1
+ test_ordered_dict3["section2"] = test_ordered_dict2
+
+ # write to ini and read back as a ConfigDict (inherits OrderedDict)
+ dump(test_ordered_dict3,
+ self.ini_fname, fmat="ini")
+ read_instance = ConfigDict()
+ read_instance.read(self.ini_fname)
+
+ # loop through original and read-back dictionaries,
+ # test identical order for key/value pairs
+ for orig_key, section in zip(test_ordered_dict3.keys(),
+ read_instance.keys()):
+ self.assertEqual(orig_key, section)
+ for orig_key2, read_key in zip(test_ordered_dict3[section].keys(),
+ read_instance[section].keys()):
+ self.assertEqual(orig_key2, read_key)
+ self.assertEqual(test_ordered_dict3[section][orig_key2],
+ read_instance[section][read_key])
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestDictToIni))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestDictToH5))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestDictToJson))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestH5ToDict))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_fabioh5.py b/silx/io/test/test_fabioh5.py
new file mode 100644
index 0000000..c1f4a43
--- /dev/null
+++ b/silx/io/test/test_fabioh5.py
@@ -0,0 +1,236 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""Tests for fabioh5 wrapper"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "11/04/2017"
+
+import logging
+import numpy
+import unittest
+
+_logger = logging.getLogger(__name__)
+
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+if fabio is not None and h5py is not None:
+ from .. import fabioh5
+
+
+class TestFabioH5(unittest.TestCase):
+
+ def setUp(self):
+ if fabio is None:
+ self.skipTest("fabio is needed")
+ if h5py is None:
+ self.skipTest("h5py is needed")
+
+ header = {
+ "integer": "-100",
+ "float": "1.0",
+ "string": "hi!",
+ "list_integer": "100 50 0",
+ "list_float": "1.0 2.0 3.5",
+ "string_looks_like_list": "2000 hi!",
+ }
+ data = numpy.array([[10, 11], [12, 13], [14, 15]], dtype=numpy.int64)
+ self.fabio_image = fabio.numpyimage.NumpyImage(data, header)
+ self.h5_image = fabioh5.File(fabio_image=self.fabio_image)
+
+ def test_main_groups(self):
+ self.assertEquals(self.h5_image.h5py_class, h5py.File)
+ self.assertEquals(self.h5_image["/"].h5py_class, h5py.File)
+ self.assertEquals(self.h5_image["/scan_0"].h5py_class, h5py.Group)
+ self.assertEquals(self.h5_image["/scan_0/instrument"].h5py_class, h5py.Group)
+ self.assertEquals(self.h5_image["/scan_0/measurement"].h5py_class, h5py.Group)
+
+ def test_wrong_path_syntax(self):
+ # result tested with a default h5py file
+ self.assertRaises(ValueError, lambda: self.h5_image[""])
+
+ def test_wrong_root_name(self):
+ # result tested with a default h5py file
+ self.assertRaises(KeyError, lambda: self.h5_image["/foo"])
+
+ def test_wrong_root_path(self):
+ # result tested with a default h5py file
+ self.assertRaises(KeyError, lambda: self.h5_image["/foo/foo"])
+
+ def test_wrong_name(self):
+ # result tested with a default h5py file
+ self.assertRaises(KeyError, lambda: self.h5_image["foo"])
+
+ def test_wrong_path(self):
+ # result tested with a default h5py file
+ self.assertRaises(KeyError, lambda: self.h5_image["foo/foo"])
+
+ def test_frames(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/data"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertTrue(isinstance(dataset[()], numpy.ndarray))
+ self.assertEquals(dataset.dtype.kind, "i")
+ self.assertEquals(dataset.shape, (1, 3, 2))
+ self.assertEquals(dataset.attrs["interpretation"], "image")
+
+ def test_metadata_int(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/integer"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset[()], -100)
+ self.assertEquals(dataset.dtype.kind, "i")
+ self.assertEquals(dataset.shape, (1,))
+
+ def test_metadata_float(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/float"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset[()], 1.0)
+ self.assertEquals(dataset.dtype.kind, "f")
+ self.assertEquals(dataset.shape, (1,))
+
+ def test_metadata_string(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/string"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset[()], numpy.string_("hi!"))
+ self.assertEquals(dataset.dtype.type, numpy.string_)
+ self.assertEquals(dataset.shape, (1,))
+
+ def test_metadata_list_integer(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/list_integer"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset.dtype.kind, "u")
+ self.assertEquals(dataset.shape, (1, 3))
+ self.assertEquals(dataset[0, 0], 100)
+ self.assertEquals(dataset[0, 1], 50)
+
+ def test_metadata_list_float(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/list_float"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset.dtype.kind, "f")
+ self.assertEquals(dataset.shape, (1, 3))
+ self.assertEquals(dataset[0, 0], 1.0)
+ self.assertEquals(dataset[0, 1], 2.0)
+
+ def test_metadata_list_looks_like_list(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/string_looks_like_list"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset[()], numpy.string_("2000 hi!"))
+ self.assertEquals(dataset.dtype.type, numpy.string_)
+ self.assertEquals(dataset.shape, (1,))
+
+ def test_float_32(self):
+ float_list = [u'1.2', u'1.3', u'1.4']
+ data = numpy.array([[0, 0], [0, 0]], dtype=numpy.int8)
+ fabio_image = None
+ for float_item in float_list:
+ header = {"float_item": float_item}
+ if fabio_image is None:
+ fabio_image = fabio.edfimage.EdfImage(data=data, header=header)
+ else:
+ fabio_image.appendFrame(data=data, header=header)
+ h5_image = fabioh5.File(fabio_image=fabio_image)
+ data = h5_image["/scan_0/instrument/detector_0/others/float_item"]
+ # There is no equality between items
+ self.assertEqual(len(data), len(set(data)))
+ # At worst a float32
+ self.assertIn(data.dtype.char, ['d', 'f'])
+ self.assertLessEqual(data.dtype.itemsize, 32 / 8)
+
+ def test_float_64(self):
+ float_list = [
+ u'1469117129.082226',
+ u'1469117136.684986', u'1469117144.312749', u'1469117151.892507',
+ u'1469117159.474265', u'1469117167.100027', u'1469117174.815799',
+ u'1469117182.437561', u'1469117190.094326', u'1469117197.721089']
+ data = numpy.array([[0, 0], [0, 0]], dtype=numpy.int8)
+ fabio_image = None
+ for float_item in float_list:
+ header = {"time_of_day": float_item}
+ if fabio_image is None:
+ fabio_image = fabio.edfimage.EdfImage(data=data, header=header)
+ else:
+ fabio_image.appendFrame(data=data, header=header)
+ h5_image = fabioh5.File(fabio_image=fabio_image)
+ data = h5_image["/scan_0/instrument/detector_0/others/time_of_day"]
+ # There is no equality between items
+ self.assertEqual(len(data), len(set(data)))
+ # At least a float64
+ self.assertIn(data.dtype.char, ['d', 'f'])
+ self.assertGreaterEqual(data.dtype.itemsize, 64 / 8)
+
+ def test_ub_matrix(self):
+ """Data from mediapix.edf"""
+ header = {}
+ header["UB_mne"] = 'UB0 UB1 UB2 UB3 UB4 UB5 UB6 UB7 UB8'
+ header["UB_pos"] = '1.99593e-16 2.73682e-16 -1.54 -1.08894 1.08894 1.6083e-16 1.08894 1.08894 9.28619e-17'
+ header["sample_mne"] = 'U0 U1 U2 U3 U4 U5'
+ header["sample_pos"] = '4.08 4.08 4.08 90 90 90'
+ data = numpy.array([[0, 0], [0, 0]], dtype=numpy.int8)
+ fabio_image = fabio.edfimage.EdfImage(data=data, header=header)
+ h5_image = fabioh5.File(fabio_image=fabio_image)
+ sample = h5_image["/scan_0/sample"]
+ self.assertIsNotNone(sample)
+ self.assertEquals(sample.attrs["NXclass"], "NXsample")
+
+ d = sample['unit_cell_abc']
+ expected = numpy.array([4.08, 4.08, 4.08])
+ self.assertIsNotNone(d)
+ self.assertEquals(d.shape, (3, ))
+ self.assertIn(d.dtype.char, ['d', 'f'])
+ numpy.testing.assert_array_almost_equal(d[...], expected)
+
+ d = sample['unit_cell_alphabetagamma']
+ expected = numpy.array([90.0, 90.0, 90.0])
+ self.assertIsNotNone(d)
+ self.assertEquals(d.shape, (3, ))
+ self.assertIn(d.dtype.char, ['d', 'f'])
+ numpy.testing.assert_array_almost_equal(d[...], expected)
+
+ d = sample['ub_matrix']
+ expected = numpy.array([[[1.99593e-16, 2.73682e-16, -1.54],
+ [-1.08894, 1.08894, 1.6083e-16],
+ [1.08894, 1.08894, 9.28619e-17]]])
+ self.assertIsNotNone(d)
+ self.assertEquals(d.shape, (1, 3, 3))
+ self.assertIn(d.dtype.char, ['d', 'f'])
+ numpy.testing.assert_array_almost_equal(d[...], expected)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestFabioH5))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_nxdata.py b/silx/io/test/test_nxdata.py
new file mode 100644
index 0000000..caa8c1e
--- /dev/null
+++ b/silx/io/test/test_nxdata.py
@@ -0,0 +1,305 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""Tests for NXdata parsing"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "27/09/2016"
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+import numpy
+import tempfile
+import unittest
+from .. import nxdata
+
+
+@unittest.skipIf(h5py is None, "silx.io.nxdata tests depend on h5py")
+class TestNXdata(unittest.TestCase):
+ def setUp(self):
+ tmp = tempfile.NamedTemporaryFile(prefix="nxdata_examples_", suffix=".h5", delete=True)
+ tmp.file.close()
+ self.h5fname = tmp.name
+ self.h5f = h5py.File(tmp.name, "w")
+
+ # SCALARS
+ g0d = self.h5f.create_group("scalars")
+
+ g0d0 = g0d.create_group("0D_scalar")
+ g0d0.attrs["NX_class"] = "NXdata"
+ g0d0.attrs["signal"] = "scalar"
+ g0d0.create_dataset("scalar", data=10)
+
+ g0d1 = g0d.create_group("2D_scalars")
+ g0d1.attrs["NX_class"] = "NXdata"
+ g0d1.attrs["signal"] = "scalars"
+ ds = g0d1.create_dataset("scalars", data=numpy.arange(3 * 10).reshape((3, 10)))
+ ds.attrs["interpretation"] = "scalar"
+
+ g0d1 = g0d.create_group("4D_scalars")
+ g0d1.attrs["NX_class"] = "NXdata"
+ g0d1.attrs["signal"] = "scalars"
+ ds = g0d1.create_dataset("scalars", data=numpy.arange(2 * 2 * 3 * 10).reshape((2, 2, 3, 10)))
+ ds.attrs["interpretation"] = "scalar"
+
+ # SPECTRA
+ g1d = self.h5f.create_group("spectra")
+
+ g1d0 = g1d.create_group("1D_spectrum")
+ g1d0.attrs["NX_class"] = "NXdata"
+ g1d0.attrs["signal"] = "count"
+ g1d0.attrs["axes"] = "energy_calib"
+ g1d0.attrs["uncertainties"] = b"energy_errors",
+ g1d0.create_dataset("count", data=numpy.arange(10))
+ g1d0.create_dataset("energy_calib", data=(10, 5)) # 10 * idx + 5
+ g1d0.create_dataset("energy_errors", data=3.14 * numpy.random.rand(10))
+
+ g1d1 = g1d.create_group("2D_spectra")
+ g1d1.attrs["NX_class"] = "NXdata"
+ g1d1.attrs["signal"] = "counts"
+ ds = g1d1.create_dataset("counts", data=numpy.arange(3 * 10).reshape((3, 10)))
+ ds.attrs["interpretation"] = "spectrum"
+
+ g1d2 = g1d.create_group("4D_spectra")
+ g1d2.attrs["NX_class"] = "NXdata"
+ g1d2.attrs["signal"] = "counts"
+ g1d2.attrs["axes"] = b"energy",
+ ds = g1d2.create_dataset("counts", data=numpy.arange(2 * 2 * 3 * 10).reshape((2, 2, 3, 10)))
+ ds.attrs["interpretation"] = "spectrum"
+ ds = g1d2.create_dataset("errors", data=4.5 * numpy.random.rand(2, 2, 3, 10))
+ ds = g1d2.create_dataset("energy", data=5 + 10 * numpy.arange(15),
+ shuffle=True, compression="gzip")
+ ds.attrs["long_name"] = "Calibrated energy"
+ ds.attrs["first_good"] = 3
+ ds.attrs["last_good"] = 12
+ g1d2.create_dataset("energy_errors", data=10 * numpy.random.rand(15))
+
+ # IMAGES
+ g2d = self.h5f.create_group("images")
+
+ g2d0 = g2d.create_group("2D_regular_image")
+ g2d0.attrs["NX_class"] = "NXdata"
+ g2d0.attrs["signal"] = "image"
+ g2d0.attrs["axes"] = b"rows_calib", b"columns_coordinates"
+ g2d0.create_dataset("image", data=numpy.arange(4 * 6).reshape((4, 6)))
+ ds = g2d0.create_dataset("rows_calib", data=(10, 5))
+ ds.attrs["long_name"] = "Calibrated Y"
+ g2d0.create_dataset("columns_coordinates", data=0.5 + 0.02 * numpy.arange(6))
+
+ g2d1 = g2d.create_group("2D_irregular_data")
+ g2d1.attrs["NX_class"] = "NXdata"
+ g2d1.attrs["signal"] = "data"
+ g2d1.attrs["axes"] = b"rows_coordinates", b"columns_coordinates"
+ g2d1.create_dataset("data", data=numpy.arange(64 * 128).reshape((64, 128)))
+ g2d1.create_dataset("rows_coordinates", data=numpy.arange(64) + numpy.random.rand(64))
+ g2d1.create_dataset("columns_coordinates", data=numpy.arange(128) + 2.5 * numpy.random.rand(128))
+
+ g2d2 = g2d.create_group("3D_images")
+ g2d2.attrs["NX_class"] = "NXdata"
+ g2d2.attrs["signal"] = "images"
+ ds = g2d2.create_dataset("images", data=numpy.arange(2 * 4 * 6).reshape((2, 4, 6)))
+ ds.attrs["interpretation"] = "image"
+
+ g2d3 = g2d.create_group("5D_images")
+ g2d3.attrs["NX_class"] = "NXdata"
+ g2d3.attrs["signal"] = "images"
+ g2d3.attrs["axes"] = b"rows_coordinates", b"columns_coordinates"
+ ds = g2d3.create_dataset("images", data=numpy.arange(2 * 2 * 2 * 4 * 6).reshape((2, 2, 2, 4, 6)))
+ ds.attrs["interpretation"] = "image"
+ g2d3.create_dataset("rows_coordinates", data=5 + 10 * numpy.arange(4))
+ g2d3.create_dataset("columns_coordinates", data=0.5 + 0.02 * numpy.arange(6))
+
+ # SCATTER
+ g = self.h5f.create_group("scatters")
+
+ gd0 = g.create_group("x_y_scatter")
+ gd0.attrs["NX_class"] = "NXdata"
+ gd0.attrs["signal"] = "y"
+ gd0.attrs["axes"] = b"x",
+ gd0.create_dataset("y", data=numpy.random.rand(128) - 0.5)
+ gd0.create_dataset("x", data=2 * numpy.random.rand(128))
+ gd0.create_dataset("x_errors", data=0.05 * numpy.random.rand(128))
+ gd0.create_dataset("errors", data=0.05 * numpy.random.rand(128))
+
+ gd1 = g.create_group("x_y_value_scatter")
+ gd1.attrs["NX_class"] = "NXdata"
+ gd1.attrs["signal"] = "values"
+ gd1.attrs["axes"] = b"x", b"y"
+ gd1.create_dataset("values", data=3.14 * numpy.random.rand(128))
+ gd1.create_dataset("y", data=numpy.random.rand(128))
+ gd1.create_dataset("y_errors", data=0.02 * numpy.random.rand(128))
+ gd1.create_dataset("x", data=numpy.random.rand(128))
+ gd1.create_dataset("x_errors", data=0.02 * numpy.random.rand(128))
+
+ def tearDown(self):
+ self.h5f.close()
+
+ def testValidity(self):
+ for group in self.h5f:
+ for subgroup in self.h5f[group]:
+ self.assertTrue(
+ nxdata.is_valid_nxdata(self.h5f[group][subgroup]),
+ "%s/%s not found to be a valid NXdata group" % (group, subgroup))
+
+ def testScalars(self):
+ nxd = nxdata.NXdata(self.h5f["scalars/0D_scalar"])
+ self.assertTrue(nxd.signal_is_0d)
+ self.assertEqual(nxd.signal[()], 10)
+ self.assertEqual(nxd.axes_names, [])
+ self.assertEqual(nxd.axes_dataset_names, [])
+ self.assertEqual(nxd.axes, [])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["scalars/2D_scalars"])
+ self.assertTrue(nxd.signal_is_2d)
+ self.assertEqual(nxd.signal[1, 2], 12)
+ self.assertEqual(nxd.axes_names, [None, None])
+ self.assertEqual(nxd.axes_dataset_names, [None, None])
+ self.assertEqual(nxd.axes, [None, None])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "scalar")
+
+ nxd = nxdata.NXdata(self.h5f["scalars/4D_scalars"])
+ self.assertFalse(nxd.signal_is_0d or nxd.signal_is_1d or
+ nxd.signal_is_2d or nxd.signal_is_3d)
+ self.assertEqual(nxd.signal[1, 0, 1, 4], 74)
+ self.assertEqual(nxd.axes_names, [None, None, None, None])
+ self.assertEqual(nxd.axes_dataset_names, [None, None, None, None])
+ self.assertEqual(nxd.axes, [None, None, None, None])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "scalar")
+
+ def testSpectra(self):
+ nxd = nxdata.NXdata(self.h5f["spectra/1D_spectrum"])
+ self.assertTrue(nxd.signal_is_1d)
+ self.assertTrue(numpy.array_equal(numpy.array(nxd.signal),
+ numpy.arange(10)))
+ self.assertEqual(nxd.axes_names, ["energy_calib"])
+ self.assertEqual(nxd.axes_dataset_names, ["energy_calib"])
+ self.assertEqual(nxd.axes[0][0], 10)
+ self.assertEqual(nxd.axes[0][1], 5)
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["spectra/2D_spectra"])
+ self.assertTrue(nxd.signal_is_2d)
+ self.assertEqual(nxd.axes_names, [None, None])
+ self.assertEqual(nxd.axes_dataset_names, [None, None])
+ self.assertEqual(nxd.axes, [None, None])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "spectrum")
+
+ nxd = nxdata.NXdata(self.h5f["spectra/4D_spectra"])
+ self.assertFalse(nxd.signal_is_0d or nxd.signal_is_1d or
+ nxd.signal_is_2d or nxd.signal_is_3d)
+ self.assertEqual(nxd.axes_names,
+ [None, None, None, "Calibrated energy"])
+ self.assertEqual(nxd.axes_dataset_names,
+ [None, None, None, "energy"])
+ self.assertEqual(nxd.axes[:3], [None, None, None])
+ self.assertEqual(nxd.axes[3].shape, (10, )) # dataset shape (15, ) sliced [3:12]
+ self.assertIsNotNone(nxd.errors)
+ self.assertEqual(nxd.errors.shape, (2, 2, 3, 10))
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "spectrum")
+
+ def testImages(self):
+ nxd = nxdata.NXdata(self.h5f["images/2D_regular_image"])
+ self.assertTrue(nxd.signal_is_2d)
+ self.assertEqual(nxd.axes_names, ["Calibrated Y", "columns_coordinates"])
+ self.assertEqual(list(nxd.axes_dataset_names),
+ ["rows_calib", "columns_coordinates"])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["images/2D_irregular_data"])
+ self.assertTrue(nxd.signal_is_2d)
+
+ self.assertEqual(nxd.axes_dataset_names, nxd.axes_names)
+ self.assertEqual(list(nxd.axes_dataset_names),
+ ["rows_coordinates", "columns_coordinates"])
+ self.assertEqual(len(nxd.axes), 2)
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["images/5D_images"])
+ self.assertFalse(nxd.signal_is_0d or nxd.signal_is_1d or
+ nxd.signal_is_2d or nxd.signal_is_3d)
+ self.assertEqual(nxd.axes_names,
+ [None, None, None, 'rows_coordinates', 'columns_coordinates'])
+ self.assertEqual(nxd.axes_dataset_names,
+ [None, None, None, 'rows_coordinates', 'columns_coordinates'])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "image")
+
+ def testScatters(self):
+ nxd = nxdata.NXdata(self.h5f["scatters/x_y_scatter"])
+ self.assertTrue(nxd.signal_is_1d)
+ self.assertEqual(nxd.axes_names, ["x"])
+ self.assertEqual(nxd.axes_dataset_names,
+ ["x"])
+ self.assertIsNotNone(nxd.errors)
+ self.assertEqual(nxd.get_axis_errors("x").shape,
+ (128, ))
+ self.assertTrue(nxd.is_scatter)
+ self.assertFalse(nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["scatters/x_y_value_scatter"])
+ self.assertFalse(nxd.signal_is_1d)
+ self.assertTrue(nxd.axes_dataset_names,
+ nxd.axes_names)
+ self.assertEqual(nxd.axes_dataset_names,
+ ["x", "y"])
+ self.assertEqual(nxd.get_axis_errors("x").shape,
+ (128, ))
+ self.assertEqual(nxd.get_axis_errors("y").shape,
+ (128, ))
+ self.assertEqual(len(nxd.axes), 2)
+ self.assertIsNone(nxd.errors)
+ self.assertTrue(nxd.is_scatter)
+ self.assertTrue(nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestNXdata))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_octaveh5.py b/silx/io/test/test_octaveh5.py
new file mode 100644
index 0000000..2e65820
--- /dev/null
+++ b/silx/io/test/test_octaveh5.py
@@ -0,0 +1,165 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""
+Tests for the octaveh5 module
+"""
+
+__authors__ = ["C. Nemoz", "H. Payno"]
+__license__ = "MIT"
+__date__ = "12/07/2016"
+
+import unittest
+import os
+import tempfile
+
+try:
+ from ..octaveh5 import Octaveh5
+except ImportError:
+ Octaveh5 = None
+
+
+@unittest.skipIf(Octaveh5 is None, "Could not import h5py")
+class TestOctaveH5(unittest.TestCase):
+ @staticmethod
+ def _get_struct_FT():
+ return {
+ 'NO_CHECK': 0.0, 'SHOWSLICE': 1.0, 'DOTOMO': 1.0, 'DATABASE': 0.0, 'ANGLE_OFFSET': 0.0,
+ 'VOLSELECTION_REMEMBER': 0.0, 'NUM_PART': 4.0, 'VOLOUTFILE': 0.0, 'RINGSCORRECTION': 0.0,
+ 'DO_TEST_SLICE': 1.0, 'ZEROOFFMASK': 1.0, 'VERSION': 'fastomo3 version 2.0',
+ 'CORRECT_SPIKES_THRESHOLD': 0.040000000000000001, 'SHOWPROJ': 0.0, 'HALF_ACQ': 0.0,
+ 'ANGLE_OFFSET_VALUE': 0.0, 'FIXEDSLICE': 'middle', 'VOLSELECT': 'total' }
+ @staticmethod
+ def _get_struct_PYHSTEXE():
+ return {
+ 'EXE': 'PyHST2_2015d', 'VERBOSE': 0.0, 'OFFV': 'PyHST2_2015d', 'TOMO': 0.0,
+ 'VERBOSE_FILE': 'pyhst_out.txt', 'DIR': '/usr/bin/', 'OFFN': 'pyhst2'}
+
+ @staticmethod
+ def _get_struct_FTAXIS():
+ return {
+ 'POSITION_VALUE': 12345.0, 'COR_ERROR': 0.0, 'FILESDURINGSCAN': 0.0, 'PLOTFIGURE': 1.0,
+ 'DIM1': 0.0, 'OVERSAMPLING': 5.0, 'TO_THE_CENTER': 1.0, 'POSITION': 'fixed',
+ 'COR_POSITION': 0.0, 'HA': 0.0 }
+
+ @staticmethod
+ def _get_struct_PAGANIN():
+ return {
+ 'MKEEP_MASK': 0.0, 'UNSHARP_SIGMA': 0.80000000000000004, 'DILATE': 2.0, 'UNSHARP_COEFF': 3.0,
+ 'MEDIANR': 4.0, 'DB': 500.0, 'MKEEP_ABS': 0.0, 'MODE': 0.0, 'THRESHOLD': 0.5,
+ 'MKEEP_BONE': 0.0, 'DB2': 100.0, 'MKEEP_CORR': 0.0, 'MKEEP_SOFT': 0.0 }
+
+ @staticmethod
+ def _get_struct_BEAMGEO():
+ return {'DIST': 55.0, 'SY': 0.0, 'SX': 0.0, 'TYPE': 'p'}
+
+
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+ self.test_3_6_fname = os.path.join(self.tempdir, "silx_tmp_t00_octaveTest_3_6.h5")
+ self.test_3_8_fname = os.path.join(self.tempdir, "silx_tmp_t00_octaveTest_3_8.h5")
+
+ def tearDown(self):
+ if os.path.isfile(self.test_3_6_fname):
+ os.unlink(self.test_3_6_fname)
+ if os.path.isfile(self.test_3_8_fname):
+ os.unlink(self.test_3_8_fname)
+
+ def testWritedIsReaded(self):
+ """
+ Simple test to write and reaf the structure compatible with the octave h5 using structure.
+ This test is for # test for octave version > 3.8
+ """
+ writer = Octaveh5()
+
+ writer.open(self.test_3_8_fname, 'a')
+ # step 1 writing the file
+ writer.write('FT', self._get_struct_FT())
+ writer.write('PYHSTEXE', self._get_struct_PYHSTEXE())
+ writer.write('FTAXIS', self._get_struct_FTAXIS())
+ writer.write('PAGANIN', self._get_struct_PAGANIN())
+ writer.write('BEAMGEO', self._get_struct_BEAMGEO())
+ writer.close()
+
+ # step 2 reading the file
+ reader = Octaveh5().open(self.test_3_8_fname)
+ # 2.1 check FT
+ data_readed = reader.get('FT')
+ self.assertEqual(data_readed, self._get_struct_FT() )
+ # 2.2 check PYHSTEXE
+ data_readed = reader.get('PYHSTEXE')
+ self.assertEqual(data_readed, self._get_struct_PYHSTEXE() )
+ # 2.3 check FTAXIS
+ data_readed = reader.get('FTAXIS')
+ self.assertEqual(data_readed, self._get_struct_FTAXIS() )
+ # 2.4 check PAGANIN
+ data_readed = reader.get('PAGANIN')
+ self.assertEqual(data_readed, self._get_struct_PAGANIN() )
+ # 2.5 check BEAMGEO
+ data_readed = reader.get('BEAMGEO')
+ self.assertEqual(data_readed, self._get_struct_BEAMGEO() )
+ reader.close()
+
+ def testWritedIsReadedOldOctaveVersion(self):
+ """The same test as testWritedIsReaded but for octave version < 3.8
+ """
+ # test for octave version < 3.8
+ writer = Octaveh5(3.6)
+
+ writer.open(self.test_3_6_fname, 'a')
+
+ # step 1 writing the file
+ writer.write('FT', self._get_struct_FT())
+ writer.write('PYHSTEXE', self._get_struct_PYHSTEXE())
+ writer.write('FTAXIS', self._get_struct_FTAXIS())
+ writer.write('PAGANIN', self._get_struct_PAGANIN())
+ writer.write('BEAMGEO', self._get_struct_BEAMGEO())
+ writer.close()
+
+ # step 2 reading the file
+ reader = Octaveh5(3.6).open(self.test_3_6_fname)
+ # 2.1 check FT
+ data_readed = reader.get('FT')
+ self.assertEqual(data_readed, self._get_struct_FT() )
+ # 2.2 check PYHSTEXE
+ data_readed = reader.get('PYHSTEXE')
+ self.assertEqual(data_readed, self._get_struct_PYHSTEXE() )
+ # 2.3 check FTAXIS
+ data_readed = reader.get('FTAXIS')
+ self.assertEqual(data_readed, self._get_struct_FTAXIS() )
+ # 2.4 check PAGANIN
+ data_readed = reader.get('PAGANIN')
+ self.assertEqual(data_readed, self._get_struct_PAGANIN() )
+ # 2.5 check BEAMGEO
+ data_readed = reader.get('BEAMGEO')
+ self.assertEqual(data_readed, self._get_struct_BEAMGEO() )
+ reader.close()
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestOctaveH5))
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_specfile.py b/silx/io/test/test_specfile.py
new file mode 100644
index 0000000..884cb04
--- /dev/null
+++ b/silx/io/test/test_specfile.py
@@ -0,0 +1,431 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""Tests for specfile wrapper"""
+
+__authors__ = ["P. Knobel", "V.A. Sole"]
+__license__ = "MIT"
+__date__ = "24/04/2017"
+
+import gc
+import locale
+import logging
+import numpy
+import os
+import sys
+import tempfile
+import unittest
+
+logging.basicConfig()
+logger1 = logging.getLogger(__name__)
+
+from ..specfile import SpecFile, Scan
+from .. import specfile
+
+sftext = """#F /tmp/sf.dat
+#E 1455180875
+#D Thu Feb 11 09:54:35 2016
+#C imaging User = opid17
+#U00 user comment first line
+#U01 This is a dummy file to test SpecFile parsing
+#U02
+#U03 last line
+
+#O0 Pslit HGap MRTSlit UP MRTSlit DOWN
+#O1 Sslit1 VOff Sslit1 HOff Sslit1 VGap
+#o0 pshg mrtu mrtd
+#o2 ss1vo ss1ho ss1vg
+
+#J0 Seconds IA ion.mono Current
+#J1 xbpmc2 idgap1 Inorm
+
+#S 1 ascan ss1vo -4.55687 -0.556875 40 0.2
+#D Thu Feb 11 09:55:20 2016
+#T 0.2 (Seconds)
+#G0 0
+#G1 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
+#G3 0 0 0 0 0 0 0 0 0
+#G4 0
+#Q
+#P0 180.005 -0.66875 0.87125
+#P1 14.74255 16.197579 12.238283
+#UMI0 Current AutoM Shutter
+#UMI1 192.51 OFF FE open
+#UMI2 Refill in 39883 sec, Fill Mode: uniform multibunch / Message: Feb 11 08:00 Delivery:Next Refill at 21:00;
+#N 4
+#L first column second column 3rd_col
+-1.23 5.89 8
+8.478100E+01 5 1.56
+3.14 2.73 -3.14
+1.2 2.3 3.4
+
+#S 25 ascan c3th 1.33245 1.52245 40 0.15
+#D Thu Feb 11 10:00:31 2016
+#P0 80.005 -1.66875 1.87125
+#P1 4.74255 6.197579 2.238283
+#N 5
+#L column0 column1 col2 col3
+0.0 0.1 0.2 0.3
+1.0 1.1 1.2 1.3
+2.0 2.1 2.2 2.3
+3.0 3.1 3.2 3.3
+
+#S 26 yyyyyy
+#D Thu Feb 11 09:55:20 2016
+#P0 80.005 -1.66875 1.87125
+#P1 4.74255 6.197579 2.238283
+#N 4
+#L first column second column 3rd_col
+#C Sat Oct 31 15:51:47 1998. Scan aborted after 0 points.
+
+#F /tmp/sf.dat
+#E 1455180876
+#D Thu Feb 11 09:54:36 2016
+
+#S 1 aaaaaa
+#U first duplicate line
+#U second duplicate line
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+3 4
+@A 3.1 4 5
+5 6
+@A 6 7.7 8
+"""
+
+
+loc = locale.getlocale(locale.LC_NUMERIC)
+try:
+ locale.setlocale(locale.LC_NUMERIC, 'de_DE.utf8')
+except locale.Error:
+ try_DE = False
+else:
+ try_DE = True
+ locale.setlocale(locale.LC_NUMERIC, loc)
+
+
+class TestSpecFile(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname1 = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ fd2, cls.fname2 = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd2, sftext[370:923])
+ else:
+ os.write(fd2, bytes(sftext[370:923], 'ascii'))
+ os.close(fd2)
+
+ fd3, cls.fname3 = tempfile.mkstemp(text=False)
+ txt = sftext[371:923]
+ if sys.version < '3.0':
+ os.write(fd3, txt)
+ else:
+ os.write(fd3, bytes(txt, 'ascii'))
+ os.close(fd3)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname1)
+ os.unlink(cls.fname2)
+ os.unlink(cls.fname3)
+
+ def setUp(self):
+ self.sf = SpecFile(self.fname1)
+ self.scan1 = self.sf[0]
+ self.scan1_2 = self.sf["1.2"]
+ self.scan25 = self.sf["25.1"]
+ self.empty_scan = self.sf["26.1"]
+
+ self.sf_no_fhdr = SpecFile(self.fname2)
+ self.scan1_no_fhdr = self.sf_no_fhdr[0]
+
+ self.sf_no_fhdr_crash = SpecFile(self.fname3)
+ self.scan1_no_fhdr_crash = self.sf_no_fhdr_crash[0]
+
+ def tearDown(self):
+ del self.sf
+ del self.sf_no_fhdr
+ del self.scan1
+ del self.scan1_2
+ del self.scan25
+ del self.scan1_no_fhdr
+ del self.sf_no_fhdr_crash
+ del self.scan1_no_fhdr_crash
+ del self.empty_scan
+ gc.collect()
+
+ def test_open(self):
+ self.assertIsInstance(self.sf, SpecFile)
+ with self.assertRaises(specfile.SfErrFileOpen):
+ sf2 = SpecFile("doesnt_exist.dat")
+
+ # test filename types unicode and bytes
+ if sys.version_info[0] < 3:
+ try:
+ SpecFile(self.fname1)
+ except TypeError:
+ self.fail("failed to handle filename as python2 str")
+ try:
+ SpecFile(unicode(self.fname1))
+ except TypeError:
+ self.fail("failed to handle filename as python2 unicode")
+ else:
+ try:
+ SpecFile(self.fname1)
+ except TypeError:
+ self.fail("failed to handle filename as python3 str")
+ try:
+ SpecFile(bytes(self.fname1, 'utf-8'))
+ except TypeError:
+ self.fail("failed to handle filename as python3 bytes")
+
+ def test_number_of_scans(self):
+ self.assertEqual(4, len(self.sf))
+
+ def test_list_of_scan_indices(self):
+ self.assertEqual(self.sf.list(),
+ [1, 25, 26, 1])
+ self.assertEqual(self.sf.keys(),
+ ["1.1", "25.1", "26.1", "1.2"])
+
+ def test_index_number_order(self):
+ self.assertEqual(self.sf.index(1, 2), 3) #sf["1.2"]==sf[3]
+ self.assertEqual(self.sf.number(1), 25) #sf[1]==sf["25"]
+ self.assertEqual(self.sf.order(3), 2) #sf[3]==sf["1.2"]
+ with self.assertRaises(specfile.SfErrScanNotFound):
+ self.sf.index(3, 2)
+ with self.assertRaises(specfile.SfErrScanNotFound):
+ self.sf.index(99)
+
+ def test_getitem(self):
+ self.assertIsInstance(self.sf[2], Scan)
+ self.assertIsInstance(self.sf["1.2"], Scan)
+ # int out of range
+ with self.assertRaisesRegexp(IndexError, 'Scan index must be in ran'):
+ self.sf[107]
+ # float indexing not allowed
+ with self.assertRaisesRegexp(TypeError, 'The scan identification k'):
+ self.sf[1.2]
+ # non existant scan with "N.M" indexing
+ with self.assertRaises(KeyError):
+ self.sf["3.2"]
+
+ def test_specfile_iterator(self):
+ i=0
+ for scan in self.sf:
+ if i == 1:
+ self.assertEqual(scan.motor_positions,
+ self.sf[1].motor_positions)
+ i += 1
+ # number of returned scans
+ self.assertEqual(i, len(self.sf))
+
+ def test_scan_index(self):
+ self.assertEqual(self.scan1.index, 0)
+ self.assertEqual(self.scan1_2.index, 3)
+ self.assertEqual(self.scan25.index, 1)
+
+ def test_scan_headers(self):
+ self.assertEqual(self.scan25.scan_header_dict['S'],
+ "25 ascan c3th 1.33245 1.52245 40 0.15")
+ self.assertEqual(self.scan1.header[17], '#G0 0')
+ self.assertEqual(len(self.scan1.header), 29)
+ # parsing headers with long keys
+ self.assertEqual(self.scan1.scan_header_dict['UMI0'],
+ 'Current AutoM Shutter')
+ # parsing empty headers
+ self.assertEqual(self.scan1.scan_header_dict['Q'], '')
+ # duplicate headers: concatenated (with newline)
+ self.assertEqual(self.scan1_2.scan_header_dict["U"],
+ "first duplicate line\nsecond duplicate line")
+
+ def test_file_headers(self):
+ self.assertEqual(self.scan1.header[1],
+ '#E 1455180875')
+ self.assertEqual(self.scan1.file_header_dict['F'],
+ '/tmp/sf.dat')
+
+ def test_multiple_file_headers(self):
+ """Scan 1.2 is after the second file header, with a different
+ Epoch"""
+ self.assertEqual(self.scan1_2.header[1],
+ '#E 1455180876')
+
+ def test_scan_labels(self):
+ self.assertEqual(self.scan1.labels,
+ ['first column', 'second column', '3rd_col'])
+
+ def test_data(self):
+ # data_line() and data_col() take 1-based indices as arg
+ self.assertAlmostEqual(self.scan1.data_line(1)[2],
+ 1.56)
+ # tests for data transposition between original file and .data attr
+ self.assertAlmostEqual(self.scan1.data[2, 0],
+ 8)
+ self.assertEqual(self.scan1.data.shape, (3, 4))
+ self.assertAlmostEqual(numpy.sum(self.scan1.data), 113.631)
+
+ def test_data_column_by_name(self):
+ self.assertAlmostEqual(self.scan25.data_column_by_name("col2")[1],
+ 1.2)
+ # Scan.data is transposed after readinq, so column is the first index
+ self.assertAlmostEqual(numpy.sum(self.scan25.data_column_by_name("col2")),
+ numpy.sum(self.scan25.data[2, :]))
+ with self.assertRaises(specfile.SfErrColNotFound):
+ self.scan25.data_column_by_name("ygfxgfyxg")
+
+ def test_motors(self):
+ self.assertEqual(len(self.scan1.motor_names), 6)
+ self.assertEqual(len(self.scan1.motor_positions), 6)
+ self.assertAlmostEqual(sum(self.scan1.motor_positions),
+ 223.385912)
+ self.assertEqual(self.scan1.motor_names[1], 'MRTSlit UP')
+ self.assertAlmostEqual(
+ self.scan25.motor_position_by_name('MRTSlit UP'),
+ -1.66875)
+
+ def test_absence_of_file_header(self):
+ """We expect Scan.file_header to be an empty list in the absence
+ of a file header.
+ """
+ self.assertEqual(len(self.scan1_no_fhdr.motor_names), 0)
+ # motor positions can still be read in the scan header
+ # even in the absence of motor names
+ self.assertAlmostEqual(sum(self.scan1_no_fhdr.motor_positions),
+ 223.385912)
+ self.assertEqual(len(self.scan1_no_fhdr.header), 15)
+ self.assertEqual(len(self.scan1_no_fhdr.scan_header), 15)
+ self.assertEqual(len(self.scan1_no_fhdr.file_header), 0)
+
+ def test_crash_absence_of_file_header(self):
+ """Test no crash in absence of file header and no leading newline
+ character
+ """
+ self.assertEqual(len(self.scan1_no_fhdr_crash.motor_names), 0)
+ # motor positions can still be read in the scan header
+ # even in the absence of motor names
+ self.assertAlmostEqual(sum(self.scan1_no_fhdr_crash.motor_positions),
+ 223.385912)
+ self.assertEqual(len(self.scan1_no_fhdr_crash.scan_header), 15)
+ self.assertEqual(len(self.scan1_no_fhdr_crash.file_header), 0)
+
+ def test_mca(self):
+ self.assertEqual(len(self.scan1.mca), 0)
+ self.assertEqual(len(self.scan1_2.mca), 3)
+ self.assertEqual(self.scan1_2.mca[1][2], 5)
+ self.assertEqual(sum(self.scan1_2.mca[2]), 21.7)
+
+ # Negative indexing
+ self.assertEqual(sum(self.scan1_2.mca[len(self.scan1_2.mca)-1]),
+ sum(self.scan1_2.mca[-1]))
+
+ # Test iterator
+ line_count, total_sum = (0, 0)
+ for mca_line in self.scan1_2.mca:
+ line_count += 1
+ total_sum += sum(mca_line)
+ self.assertEqual(line_count, 3)
+ self.assertAlmostEqual(total_sum, 36.8)
+
+ def test_mca_header(self):
+ self.assertEqual(self.scan1.mca_header_dict, {})
+ self.assertEqual(len(self.scan1_2.mca_header_dict), 4)
+ self.assertEqual(self.scan1_2.mca_header_dict["CALIB"], "1 2 3")
+ self.assertEqual(self.scan1_2.mca.calibration,
+ [[1., 2., 3.]])
+ # default calib in the absence of #@CALIB
+ self.assertEqual(self.scan25.mca.calibration,
+ [[0., 1., 0.]])
+ self.assertEqual(self.scan1_2.mca.channels,
+ [[0, 1, 2]])
+ # absence of #@CHANN and spectra
+ self.assertEqual(self.scan25.mca.channels,
+ [])
+
+ def test_empty_scan(self):
+ """Test reading a scan with no data points"""
+ self.assertEqual(len(self.empty_scan.labels),
+ 3)
+ col1 = self.empty_scan.data_column_by_name("second column")
+ self.assertEqual(col1.shape, (0, ))
+
+
+class TestSFLocale(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+ locale.setlocale(locale.LC_NUMERIC, loc) # restore saved locale
+ gc.collect()
+
+ def crunch_data(self):
+ self.sf3 = SpecFile(self.fname)
+ self.assertAlmostEqual(self.sf3[0].data_line(1)[2],
+ 1.56)
+ del self.sf3
+
+ @unittest.skipIf(not try_DE, "de_DE.utf8 locale not installed")
+ def test_locale_de_DE(self):
+ locale.setlocale(locale.LC_NUMERIC, 'de_DE.utf8')
+ self.crunch_data()
+
+ def test_locale_user(self):
+ locale.setlocale(locale.LC_NUMERIC, '') # use user's preferred locale
+ self.crunch_data()
+
+ def test_locale_C(self):
+ locale.setlocale(locale.LC_NUMERIC, 'C') # use default (C) locale
+ self.crunch_data()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecFile))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSFLocale))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_specfilewrapper.py b/silx/io/test/test_specfilewrapper.py
new file mode 100644
index 0000000..e9e1a24
--- /dev/null
+++ b/silx/io/test/test_specfilewrapper.py
@@ -0,0 +1,220 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""Tests for old specfile wrapper"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/07/2016"
+
+import gc
+import locale
+import logging
+import numpy
+import os
+import sys
+import tempfile
+import unittest
+
+logging.basicConfig()
+logger1 = logging.getLogger(__name__)
+
+from ..specfilewrapper import Specfile
+
+sftext = """#F /tmp/sf.dat
+#E 1455180875
+#D Thu Feb 11 09:54:35 2016
+#C imaging User = opid17
+#U00 user comment first line
+#U01 This is a dummy file to test SpecFile parsing
+#U02
+#U03 last line
+
+#O0 Pslit HGap MRTSlit UP MRTSlit DOWN
+#O1 Sslit1 VOff Sslit1 HOff Sslit1 VGap
+#o0 pshg mrtu mrtd
+#o2 ss1vo ss1ho ss1vg
+
+#J0 Seconds IA ion.mono Current
+#J1 xbpmc2 idgap1 Inorm
+
+#S 1 ascan ss1vo -4.55687 -0.556875 40 0.2
+#D Thu Feb 11 09:55:20 2016
+#T 0.2 (Seconds)
+#G0 0
+#G1 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
+#G3 0 0 0 0 0 0 0 0 0
+#G4 0
+#Q
+#P0 180.005 -0.66875 0.87125
+#P1 14.74255 16.197579 12.238283
+#UMI0 Current AutoM Shutter
+#UMI1 192.51 OFF FE open
+#UMI2 Refill in 39883 sec, Fill Mode: uniform multibunch / Message: Feb 11 08:00 Delivery:Next Refill at 21:00;
+#N 4
+#L first column second column 3rd_col
+-1.23 5.89 8
+8.478100E+01 5 1.56
+3.14 2.73 -3.14
+1.2 2.3 3.4
+
+#S 25 ascan c3th 1.33245 1.52245 40 0.15
+#D Thu Feb 11 10:00:31 2016
+#P0 80.005 -1.66875 1.87125
+#P1 4.74255 6.197579 2.238283
+#N 5
+#L column0 column1 col2 col3
+0.0 0.1 0.2 0.3
+1.0 1.1 1.2 1.3
+2.0 2.1 2.2 2.3
+3.0 3.1 3.2 3.3
+
+#F /tmp/sf.dat
+#E 1455180876
+#D Thu Feb 11 09:54:36 2016
+
+#S 1 aaaaaa
+#U first duplicate line
+#U second duplicate line
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+3 4
+@A 3.1 4 5
+5 6
+@A 6 7.7 8
+"""
+
+
+class TestSpecfilewrapper(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname1 = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ fd2, cls.fname2 = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd2, sftext[370:-97])
+ else:
+ os.write(fd2, bytes(sftext[370:-97], 'ascii'))
+ os.close(fd2)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname1)
+ os.unlink(cls.fname2)
+
+ def setUp(self):
+ self.sf = Specfile(self.fname1)
+ self.scan1 = self.sf[0]
+ self.scan1_2 = self.sf.select("1.2")
+ self.scan25 = self.sf.select("25.1")
+
+ def tearDown(self):
+ del self.sf
+ del self.scan1
+ del self.scan1_2
+ del self.scan25
+ gc.collect()
+
+ def test_number_of_scans(self):
+ self.assertEqual(3, len(self.sf))
+
+ def test_list_of_scan_indices(self):
+ self.assertEqual(self.sf.list(),
+ '1,25,1')
+ self.assertEqual(self.sf.keys(),
+ ["1.1", "25.1", "1.2"])
+
+ def test_scan_headers(self):
+ self.assertEqual(self.scan25.header('S'),
+ ["#S 25 ascan c3th 1.33245 1.52245 40 0.15"])
+ self.assertEqual(self.scan1.header("G0"), ['#G0 0'])
+ # parsing headers with long keys
+ # parsing empty headers
+ self.assertEqual(self.scan1.header('Q'), ['#Q '])
+
+ def test_file_headers(self):
+ self.assertEqual(self.scan1.header("E"),
+ ['#E 1455180875'])
+ self.assertEqual(self.sf.title(),
+ "imaging")
+ self.assertEqual(self.sf.epoch(),
+ 1455180875)
+ self.assertEqual(self.sf.allmotors(),
+ ["Pslit HGap", "MRTSlit UP", "MRTSlit DOWN",
+ "Sslit1 VOff", "Sslit1 HOff", "Sslit1 VGap"])
+
+ def test_scan_labels(self):
+ self.assertEqual(self.scan1.alllabels(),
+ ['first column', 'second column', '3rd_col'])
+
+ def test_data(self):
+ self.assertAlmostEqual(self.scan1.dataline(3)[2],
+ -3.14)
+ self.assertAlmostEqual(self.scan1.datacol(1)[2],
+ 3.14)
+ # tests for data transposition between original file and .data attr
+ self.assertAlmostEqual(self.scan1.data()[2, 0],
+ 8)
+ self.assertEqual(self.scan1.data().shape, (3, 4))
+ self.assertAlmostEqual(numpy.sum(self.scan1.data()), 113.631)
+
+ def test_date(self):
+ self.assertEqual(self.scan1.date(),
+ "Thu Feb 11 09:55:20 2016")
+
+ def test_motors(self):
+ self.assertEqual(len(self.sf.allmotors()), 6)
+ self.assertEqual(len(self.scan1.allmotorpos()), 6)
+ self.assertAlmostEqual(sum(self.scan1.allmotorpos()),
+ 223.385912)
+ self.assertEqual(self.sf.allmotors()[1], 'MRTSlit UP')
+
+ def test_mca(self):
+ self.assertEqual(self.scan1_2.mca(2)[2], 5)
+ self.assertEqual(sum(self.scan1_2.mca(3)), 21.7)
+
+ def test_mca_header(self):
+ self.assertEqual(self.scan1_2.header("CALIB"),
+ ["#@CALIB 1 2 3"])
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecfilewrapper))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_spech5.py b/silx/io/test/test_spech5.py
new file mode 100644
index 0000000..ac250ab
--- /dev/null
+++ b/silx/io/test/test_spech5.py
@@ -0,0 +1,820 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""Tests for spech5"""
+import gc
+from numpy import array_equal
+import os
+import sys
+import tempfile
+import unittest
+import datetime
+from functools import partial
+
+from ..spech5 import (SpecH5, SpecH5Group,
+ SpecH5Dataset, spec_date_to_iso8601)
+from .. import specfile
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "11/05/2017"
+
+sftext = """#F /tmp/sf.dat
+#E 1455180875
+#D Thu Feb 11 09:54:35 2016
+#C imaging User = opid17
+#O0 Pslit HGap MRTSlit UP MRTSlit DOWN
+#O1 Sslit1 VOff Sslit1 HOff Sslit1 VGap
+#o0 pshg mrtu mrtd
+#o2 ss1vo ss1ho ss1vg
+
+#J0 Seconds IA ion.mono Current
+#J1 xbpmc2 idgap1 Inorm
+
+#S 1 ascan ss1vo -4.55687 -0.556875 40 0.2
+#D Thu Feb 11 09:55:20 2016
+#T 0.2 (Seconds)
+#P0 180.005 -0.66875 0.87125
+#P1 14.74255 16.197579 12.238283
+#N 4
+#L MRTSlit UP second column 3rd_col
+-1.23 5.89 8
+8.478100E+01 5 1.56
+3.14 2.73 -3.14
+1.2 2.3 3.4
+
+#S 25 ascan c3th 1.33245 1.52245 40 0.15
+#D Sat 2015/03/14 03:53:50
+#P0 80.005 -1.66875 1.87125
+#P1 4.74255 6.197579 2.238283
+#N 5
+#L column0 column1 col2 col3
+0.0 0.1 0.2 0.3
+1.0 1.1 1.2 1.3
+2.0 2.1 2.2 2.3
+3.0 3.1 3.2 3.3
+
+#S 1 aaaaaa
+#D Thu Feb 11 10:00:32 2016
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+@A 10 9 8
+@A 1 1 1.1
+3 4
+@A 3.1 4 5
+@A 7 6 5
+@A 1 1 1
+5 6
+@A 6 7.7 8
+@A 4 3 2
+@A 1 1 1
+
+#S 1000 bbbbb
+#G1 3.25 3.25 5.207 90 90 120 2.232368448 2.232368448 1.206680489 90 90 60 1 1 2 -1 2 2 26.132 7.41 -88.96 1.11 1.000012861 15.19 26.06 67.355 -88.96 1.11 1.000012861 15.11 0.723353 0.723353
+#G3 0.0106337923671 0.027529133 1.206191273 -1.43467075 0.7633438883 0.02401568018 -1.709143587 -2.097621783 0.02456954971
+#L a b
+1 2
+
+"""
+
+
+class TestSpecDate(unittest.TestCase):
+ """
+ Test of the spec_date_to_iso8601 function.
+ """
+ # TODO : time zone tests
+ # TODO : error cases
+
+ @classmethod
+ def setUpClass(cls):
+ import locale
+ # FYI : not threadsafe
+ cls.locale_saved = locale.setlocale(locale.LC_TIME)
+ locale.setlocale(locale.LC_TIME, 'C')
+
+ @classmethod
+ def tearDownClass(cls):
+ import locale
+ # FYI : not threadsafe
+ locale.setlocale(locale.LC_TIME, cls.locale_saved)
+
+ def setUp(self):
+ # covering all week days
+ self.n_days = range(1, 10)
+ # covering all months
+ self.n_months = range(1, 13)
+
+ self.n_years = [1999, 2016, 2020]
+ self.n_seconds = [0, 5, 26, 59]
+ self.n_minutes = [0, 9, 42, 59]
+ self.n_hours = [0, 2, 17, 23]
+
+ self.formats = ['%a %b %d %H:%M:%S %Y', '%a %Y/%m/%d %H:%M:%S']
+
+ self.check_date_formats = partial(self.__check_date_formats,
+ year=self.n_years[0],
+ month=self.n_months[0],
+ day=self.n_days[0],
+ hour=self.n_hours[0],
+ minute=self.n_minutes[0],
+ second=self.n_seconds[0],
+ msg=None)
+
+ def __check_date_formats(self,
+ year,
+ month,
+ day,
+ hour,
+ minute,
+ second,
+ msg=None):
+ dt = datetime.datetime(year, month, day, hour, minute, second)
+ expected_date = dt.isoformat()
+
+ for i_fmt, fmt in enumerate(self.formats):
+ spec_date = dt.strftime(fmt)
+ iso_date = spec_date_to_iso8601(spec_date)
+ self.assertEqual(iso_date,
+ expected_date,
+ msg='Testing {0}. format={1}. '
+ 'Expected "{2}", got "{3} ({4})" (dt={5}).'
+ ''.format(msg,
+ i_fmt,
+ expected_date,
+ iso_date,
+ spec_date,
+ dt))
+
+ def testYearsNominal(self):
+ for year in self.n_years:
+ self.check_date_formats(year=year, msg='year')
+
+ def testMonthsNominal(self):
+ for month in self.n_months:
+ self.check_date_formats(month=month, msg='month')
+
+ def testDaysNominal(self):
+ for day in self.n_days:
+ self.check_date_formats(day=day, msg='day')
+
+ def testHoursNominal(self):
+ for hour in self.n_hours:
+ self.check_date_formats(hour=hour, msg='hour')
+
+ def testMinutesNominal(self):
+ for minute in self.n_minutes:
+ self.check_date_formats(minute=minute, msg='minute')
+
+ def testSecondsNominal(self):
+ for second in self.n_seconds:
+ self.check_date_formats(second=second, msg='second')
+
+
+class TestSpecH5(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp()
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+
+ def setUp(self):
+ self.sfh5 = SpecH5(self.fname)
+
+ def tearDown(self):
+ # fix Win32 permission error when deleting temp file
+ del self.sfh5
+ gc.collect()
+
+ def testContainsFile(self):
+ self.assertIn("/1.2/measurement", self.sfh5)
+ self.assertIn("/25.1", self.sfh5)
+ self.assertIn("25.1", self.sfh5)
+ self.assertNotIn("25.2", self.sfh5)
+ # measurement is a child of a scan, full path would be required to
+ # access from root level
+ self.assertNotIn("measurement", self.sfh5)
+ # Groups may or may not have a trailing /
+ self.assertIn("/1.2/measurement/mca_1/", self.sfh5)
+ self.assertIn("/1.2/measurement/mca_1", self.sfh5)
+ # Datasets can't have a trailing /
+ self.assertNotIn("/1.2/measurement/mca_0/info/calibration/ ", self.sfh5)
+ # No mca_8
+ self.assertNotIn("/1.2/measurement/mca_8/info/calibration", self.sfh5)
+ # Link
+ self.assertIn("/1.2/measurement/mca_0/info/calibration", self.sfh5)
+
+ def testContainsGroup(self):
+ self.assertIn("measurement", self.sfh5["/1.2/"])
+ self.assertIn("measurement", self.sfh5["/1.2"])
+ self.assertIn("25.1", self.sfh5["/"])
+ self.assertNotIn("25.2", self.sfh5["/"])
+ self.assertIn("instrument/positioners/Sslit1 HOff", self.sfh5["/1.1"])
+ # illegal trailing "/" after dataset name
+ self.assertNotIn("instrument/positioners/Sslit1 HOff/",
+ self.sfh5["/1.1"])
+ # full path to element in group (OK)
+ self.assertIn("/1.1/instrument/positioners/Sslit1 HOff",
+ self.sfh5["/1.1/instrument"])
+ # full path to element outside group (illegal)
+ self.assertNotIn("/1.1/instrument/positioners/Sslit1 HOff",
+ self.sfh5["/1.1/measurement"])
+
+ def testDataColumn(self):
+ self.assertAlmostEqual(sum(self.sfh5["/1.2/measurement/duo"]),
+ 12.0)
+ self.assertAlmostEqual(
+ sum(self.sfh5["1.1"]["measurement"]["MRTSlit UP"]),
+ 87.891, places=4)
+
+ def testDate(self):
+ # start time is in Iso8601 format
+ self.assertEqual(self.sfh5["/1.1/start_time"],
+ b"2016-02-11T09:55:20")
+ self.assertEqual(self.sfh5["25.1/start_time"],
+ b"2015-03-14T03:53:50")
+
+ def testDatasetInstanceAttr(self):
+ """The SpecH5Dataset objects must implement some dummy attributes
+ to improve compatibility with widgets dealing with h5py datasets."""
+ self.assertIsNone(self.sfh5["/1.1/start_time"].compression)
+ self.assertIsNone(self.sfh5["1.1"]["measurement"]["MRTSlit UP"].chunks)
+
+ # error message must be explicit
+ with self.assertRaisesRegexp(
+ AttributeError,
+ "SpecH5Dataset has no attribute tOTo"):
+ dummy = self.sfh5["/1.1/start_time"].tOTo
+
+ def testGet(self):
+ """Test :meth:`SpecH5Group.get`"""
+ # default value of param *default* is None
+ self.assertIsNone(self.sfh5.get("toto"))
+ self.assertEqual(self.sfh5["25.1"].get("toto", default=-3),
+ -3)
+
+ self.assertEqual(self.sfh5.get("/1.1/start_time", default=-3),
+ b"2016-02-11T09:55:20")
+
+ def testGetClass(self):
+ """Test :meth:`SpecH5Group.get`"""
+ if h5py is None:
+ self.skipTest("h5py is not available")
+ self.assertIs(self.sfh5["1.1"].get("start_time", getclass=True),
+ h5py.Dataset)
+ self.assertIs(self.sfh5["1.1"].get("instrument", getclass=True),
+ h5py.Group)
+
+ # spech5 does not define external link, so there is no way
+ # a group can *get* a SpecH5 class
+
+ def testGetItemGroup(self):
+ group = self.sfh5["25.1"]["instrument"]
+ self.assertEqual(group["positioners"].keys(),
+ ["Pslit HGap", "MRTSlit UP", "MRTSlit DOWN",
+ "Sslit1 VOff", "Sslit1 HOff", "Sslit1 VGap"])
+ with self.assertRaises(KeyError):
+ group["Holy Grail"]
+
+ def testGetitemSpecH5(self):
+ self.assertEqual(self.sfh5["/1.2/instrument/positioners"],
+ self.sfh5["1.2"]["instrument"]["positioners"])
+
+ @unittest.skipIf(h5py is None, "test requires h5py (not installed)")
+ def testH5pyClass(self):
+ """Test :attr:`h5py_class` returns the corresponding h5py class
+ (h5py.File, h5py.Group, h5py.Dataset)"""
+ a_file = self.sfh5
+ self.assertIs(a_file.h5py_class,
+ h5py.File)
+
+ a_group = self.sfh5["/1.2/measurement"]
+ self.assertIs(a_group.h5py_class,
+ h5py.Group)
+
+ a_dataset = self.sfh5["/1.1/instrument/positioners/Sslit1 HOff"]
+ self.assertIs(a_dataset.h5py_class,
+ h5py.Dataset)
+
+ def testHeader(self):
+ file_header = self.sfh5["/1.2/instrument/specfile/file_header"]
+ scan_header = self.sfh5["/1.2/instrument/specfile/scan_header"]
+ # convert ndarray(dtype=numpy.string_) to str
+ if sys.version < '3.0':
+ file_header = str(file_header[()])
+ scan_header = str(scan_header[()])
+ else:
+ file_header = str(file_header.astype(str))
+ scan_header = str(scan_header.astype(str))
+
+ # File header has 10 lines
+ self.assertEqual(len(file_header.split("\n")), 10)
+ # 1.2 has 9 scan & mca header lines
+ self.assertEqual(len(scan_header.split("\n")), 9)
+
+ # line 4 of file header
+ self.assertEqual(
+ file_header.split("\n")[3],
+ "#C imaging User = opid17")
+ # line 4 of scan header
+ scan_header = self.sfh5["25.1/instrument/specfile/scan_header"]
+ if sys.version < '3.0':
+ scan_header = str(scan_header[()])
+ else:
+ scan_header = str(scan_header[()].astype(str))
+
+ self.assertEqual(
+ scan_header.split("\n")[3],
+ "#P1 4.74255 6.197579 2.238283")
+
+ def testLinks(self):
+ self.assertTrue(
+ array_equal(self.sfh5["/1.2/measurement/mca_0/data"],
+ self.sfh5["/1.2/instrument/mca_0/data"])
+ )
+ self.assertTrue(
+ array_equal(self.sfh5["/1.2/measurement/mca_0/info/data"],
+ self.sfh5["/1.2/instrument/mca_0/data"])
+ )
+ self.assertTrue(
+ array_equal(self.sfh5["/1.2/measurement/mca_0/info/channels"],
+ self.sfh5["/1.2/instrument/mca_0/channels"])
+ )
+ self.assertEqual(self.sfh5["/1.2/measurement/mca_0/info/"].keys(),
+ self.sfh5["/1.2/instrument/mca_0/"].keys())
+
+ self.assertEqual(self.sfh5["/1.2/measurement/mca_0/info/preset_time"],
+ self.sfh5["/1.2/instrument/mca_0/preset_time"])
+ self.assertEqual(self.sfh5["/1.2/measurement/mca_0/info/live_time"],
+ self.sfh5["/1.2/instrument/mca_0/live_time"])
+ self.assertEqual(self.sfh5["/1.2/measurement/mca_0/info/elapsed_time"],
+ self.sfh5["/1.2/instrument/mca_0/elapsed_time"])
+
+ def testListScanIndices(self):
+ self.assertEqual(self.sfh5.keys(),
+ ["1.1", "25.1", "1.2", "1000.1"])
+ self.assertEqual(self.sfh5["1.2"].attrs,
+ {"NX_class": "NXentry", })
+
+ def testMcaAbsent(self):
+ def access_absent_mca():
+ """This must raise a KeyError, because scan 1.1 has no MCA"""
+ return self.sfh5["/1.1/measurement/mca_0/"]
+ self.assertRaises(KeyError, access_absent_mca)
+
+ def testMcaCalib(self):
+ mca0_calib = self.sfh5["/1.2/measurement/mca_0/info/calibration"]
+ mca1_calib = self.sfh5["/1.2/measurement/mca_1/info/calibration"]
+ self.assertEqual(mca0_calib.tolist(),
+ [1, 2, 3])
+ # calibration is unique in this scan and applies to all analysers
+ self.assertEqual(mca0_calib.tolist(),
+ mca1_calib.tolist())
+
+ def testMcaChannels(self):
+ mca0_chann = self.sfh5["/1.2/measurement/mca_0/info/channels"]
+ mca1_chann = self.sfh5["/1.2/measurement/mca_1/info/channels"]
+ self.assertEqual(mca0_chann.tolist(),
+ [0, 1, 2])
+ self.assertEqual(mca0_chann.tolist(),
+ mca1_chann.tolist())
+
+ def testMcaCtime(self):
+ """Tests for #@CTIME mca header"""
+ datasets = ["preset_time", "live_time", "elapsed_time"]
+ for ds in datasets:
+ self.assertNotIn("/1.1/instrument/mca_0/" + ds, self.sfh5)
+ self.assertIn("/1.2/instrument/mca_0/" + ds, self.sfh5)
+
+ mca0_preset_time = self.sfh5["/1.2/instrument/mca_0/preset_time"]
+ mca1_preset_time = self.sfh5["/1.2/instrument/mca_1/preset_time"]
+ self.assertLess(mca0_preset_time - 123.4,
+ 10**-5)
+ # ctime is unique in a this scan and applies to all analysers
+ self.assertEqual(mca0_preset_time,
+ mca1_preset_time)
+
+ mca0_live_time = self.sfh5["/1.2/instrument/mca_0/live_time"]
+ mca1_live_time = self.sfh5["/1.2/instrument/mca_1/live_time"]
+ self.assertLess(mca0_live_time - 234.5,
+ 10**-5)
+ self.assertEqual(mca0_live_time,
+ mca1_live_time)
+
+ mca0_elapsed_time = self.sfh5["/1.2/instrument/mca_0/elapsed_time"]
+ mca1_elapsed_time = self.sfh5["/1.2/instrument/mca_1/elapsed_time"]
+ self.assertLess(mca0_elapsed_time - 345.6,
+ 10**-5)
+ self.assertEqual(mca0_elapsed_time,
+ mca1_elapsed_time)
+
+ def testMcaData(self):
+ # sum 1st MCA in scan 1.2 over rows
+ mca_0_data = self.sfh5["/1.2/measurement/mca_0/data"]
+ for summed_row, expected in zip(mca_0_data.sum(axis=1).tolist(),
+ [3.0, 12.1, 21.7]):
+ self.assertAlmostEqual(summed_row, expected, places=4)
+
+ # sum 3rd MCA in scan 1.2 along both axis
+ mca_2_data = self.sfh5["1.2"]["measurement"]["mca_2"]["data"]
+ self.assertAlmostEqual(sum(sum(mca_2_data)), 9.1, places=5)
+ # attrs
+ self.assertEqual(mca_0_data.attrs, {"interpretation": "spectrum"})
+
+ def testMotorPosition(self):
+ positioners_group = self.sfh5["/1.1/instrument/positioners"]
+ # MRTSlit DOWN position is defined in #P0 san header line
+ self.assertAlmostEqual(float(positioners_group["MRTSlit DOWN"]),
+ 0.87125)
+ # MRTSlit UP position is defined in first data column
+ for a, b in zip(positioners_group["MRTSlit UP"].tolist(),
+ [-1.23, 8.478100E+01, 3.14, 1.2]):
+ self.assertAlmostEqual(float(a), b, places=4)
+
+ def testNumberMcaAnalysers(self):
+ """Scan 1.2 has 2 data columns + 3 mca spectra per data line."""
+ self.assertEqual(len(self.sfh5["1.2"]["measurement"]), 5)
+
+ def testTitle(self):
+ self.assertEqual(self.sfh5["/25.1/title"],
+ b"25 ascan c3th 1.33245 1.52245 40 0.15")
+
+ # visit and visititems ignore links
+ def testVisit(self):
+ name_list = []
+ self.sfh5.visit(name_list.append)
+ self.assertIn('/1.2/instrument/positioners/Pslit HGap', name_list)
+ self.assertIn("/1.2/instrument/specfile/scan_header", name_list)
+ self.assertEqual(len(name_list), 100) #, "actual name list: %s" % "\n".join(name_list))
+
+ def testVisitItems(self):
+ dataset_name_list = []
+
+ def func(name, obj):
+ if isinstance(obj, SpecH5Dataset):
+ dataset_name_list.append(name)
+
+ self.sfh5.visititems(func)
+ self.assertIn('/1.2/instrument/positioners/Pslit HGap', dataset_name_list)
+ self.assertEqual(len(dataset_name_list), 73)
+
+ def testNotSpecH5(self):
+ fd, fname = tempfile.mkstemp()
+ os.write(fd, b"Not a spec file!")
+ os.close(fd)
+ self.assertRaises(specfile.SfErrFileOpen, SpecH5, fname)
+ os.unlink(fname)
+
+ def testSample(self):
+ self.assertNotIn("sample", self.sfh5["/1.1"])
+ self.assertIn("sample", self.sfh5["/1000.1"])
+ self.assertIn("ub_matrix", self.sfh5["/1000.1/sample"])
+ self.assertIn("unit_cell", self.sfh5["/1000.1/sample"])
+ self.assertIn("unit_cell_abc", self.sfh5["/1000.1/sample"])
+ self.assertIn("unit_cell_alphabetagamma", self.sfh5["/1000.1/sample"])
+
+
+sftext_multi_mca_headers = """
+#S 1 aaaaaa
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+#@MCA %16C
+#@CHANN 3 1 3 1
+#@CALIB 5.5 6.6 7.7
+#@CTIME 10 11 12
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+@A 10 9 8
+3 4
+@A 3.1 4 5
+@A 7 6 5
+5 6
+@A 6 7.7 8
+@A 4 3 2
+
+"""
+
+
+class TestSpecH5MultiMca(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext_multi_mca_headers)
+ else:
+ os.write(fd, bytes(sftext_multi_mca_headers, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+
+ def setUp(self):
+ self.sfh5 = SpecH5(self.fname)
+
+ def tearDown(self):
+ # fix Win32 permission error when deleting temp file
+ del self.sfh5
+ gc.collect()
+
+ def testMcaCalib(self):
+ mca0_calib = self.sfh5["/1.1/measurement/mca_0/info/calibration"]
+ mca1_calib = self.sfh5["/1.1/measurement/mca_1/info/calibration"]
+ self.assertEqual(mca0_calib.tolist(),
+ [1, 2, 3])
+ self.assertAlmostEqual(sum(mca1_calib.tolist()),
+ sum([5.5, 6.6, 7.7]),
+ places=5)
+
+ def testMcaChannels(self):
+ mca0_chann = self.sfh5["/1.1/measurement/mca_0/info/channels"]
+ mca1_chann = self.sfh5["/1.1/measurement/mca_1/info/channels"]
+ self.assertEqual(mca0_chann.tolist(),
+ [0., 1., 2.])
+ # @CHANN is unique in this scan and applies to all analysers
+ self.assertEqual(mca1_chann.tolist(),
+ [1., 2., 3.])
+
+ def testMcaCtime(self):
+ """Tests for #@CTIME mca header"""
+ mca0_preset_time = self.sfh5["/1.1/instrument/mca_0/preset_time"]
+ mca1_preset_time = self.sfh5["/1.1/instrument/mca_1/preset_time"]
+ self.assertLess(mca0_preset_time - 123.4,
+ 10**-5)
+ self.assertLess(mca1_preset_time - 10,
+ 10**-5)
+
+ mca0_live_time = self.sfh5["/1.1/instrument/mca_0/live_time"]
+ mca1_live_time = self.sfh5["/1.1/instrument/mca_1/live_time"]
+ self.assertLess(mca0_live_time - 234.5,
+ 10**-5)
+ self.assertLess(mca1_live_time - 11,
+ 10**-5)
+
+ mca0_elapsed_time = self.sfh5["/1.1/instrument/mca_0/elapsed_time"]
+ mca1_elapsed_time = self.sfh5["/1.1/instrument/mca_1/elapsed_time"]
+ self.assertLess(mca0_elapsed_time - 345.6,
+ 10**-5)
+ self.assertLess(mca1_elapsed_time - 12,
+ 10**-5)
+
+
+sftext_no_cols = r"""#F C:/DATA\test.mca
+#D Thu Jul 7 08:40:19 2016
+
+#S 1 31oct98.dat 22.1 If4
+#D Thu Jul 7 08:40:19 2016
+#C no data cols, one mca analyser, single spectrum
+#@MCA %16C
+#@CHANN 151 29 29 1
+#@CALIB 0 2 0
+@A 789 784 788 814 847 862 880 904 925 955 987 1015 1031 1070 1111 1139 \
+1203 1236 1290 1392 1492 1558 1688 1813 1977 2119 2346 2699 3121 3542 4102 4970 \
+6071 7611 10426 16188 28266 40348 50539 55555 56162 54162 47102 35718 24588 17034 12994 11444 \
+11808 13461 15687 18885 23827 31578 41999 49556 58084 59415 59456 55698 44525 28219 17680 12881 \
+9518 7415 6155 5246 4646 3978 3612 3299 3020 2761 2670 2472 2500 2310 2286 2106 \
+1989 1890 1782 1655 1421 1293 1135 990 879 757 672 618 532 488 445 424 \
+414 373 351 325 307 284 270 247 228 213 199 187 183 176 164 156 \
+153 140 142 130 118 118 103 101 97 86 90 86 87 81 75 82 \
+80 76 77 75 76 77 62 69 74 60 65 68 65 58 63 64 \
+63 59 60 56 57 60 55
+
+#S 2 31oct98.dat 22.1 If4
+#D Thu Jul 7 08:40:19 2016
+#C no data cols, one mca analyser, multiple spectra
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+@A 0 1 2
+@A 10 9 8
+@A 1 1 1.1
+@A 3.1 4 5
+@A 7 6 5
+@A 1 1 1
+@A 6 7.7 8
+@A 4 3 2
+@A 1 1 1
+
+#S 3 31oct98.dat 22.1 If4
+#D Thu Jul 7 08:40:19 2016
+#C no data cols, 3 mca analysers, multiple spectra
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+#@MCADEV 2
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+#@MCADEV 3
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+@A 0 1 2
+@A 10 9 8
+@A 1 1 1.1
+@A 3.1 4 5
+@A 7 6 5
+@A 1 1 1
+@A 6 7.7 8
+@A 4 3 2
+@A 1 1 1
+"""
+
+
+class TestSpecH5NoDataCols(unittest.TestCase):
+ """Test reading SPEC files with only MCA data"""
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp()
+ if sys.version < '3.0':
+ os.write(fd, sftext_no_cols)
+ else:
+ os.write(fd, bytes(sftext_no_cols, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+
+ def setUp(self):
+ self.sfh5 = SpecH5(self.fname)
+
+ def tearDown(self):
+ # fix Win32 permission error when deleting temp file
+ del self.sfh5
+ gc.collect()
+
+ def testScan1(self):
+ # 1.1: single analyser, single spectrum, 151 channels
+ self.assertIn("mca_0",
+ self.sfh5["1.1/instrument/"])
+ self.assertEqual(self.sfh5["1.1/instrument/mca_0/data"].shape,
+ (1, 151))
+ self.assertNotIn("mca_1",
+ self.sfh5["1.1/instrument/"])
+
+ def testScan2(self):
+ # 2.1: single analyser, 9 spectra, 3 channels
+ self.assertIn("mca_0",
+ self.sfh5["2.1/instrument/"])
+ self.assertEqual(self.sfh5["2.1/instrument/mca_0/data"].shape,
+ (9, 3))
+ self.assertNotIn("mca_1",
+ self.sfh5["2.1/instrument/"])
+
+ def testScan3(self):
+ # 3.1: 3 analysers, 3 spectra/analyser, 3 channels
+ for i in range(3):
+ self.assertIn("mca_%d" % i,
+ self.sfh5["3.1/instrument/"])
+ self.assertEqual(
+ self.sfh5["3.1/instrument/mca_%d/data" % i].shape,
+ (3, 3))
+
+ self.assertNotIn("mca_3",
+ self.sfh5["3.1/instrument/"])
+
+
+sf_text_slash = r"""#F /data/id09/archive/logspecfiles/laue/2016/scan_231_laue_16-11-29.dat
+#D Sat Dec 10 22:20:59 2016
+#O0 Pslit/HGap MRTSlit%UP
+
+#S 1 laue_16-11-29.log 231.1 PD3/A
+#D Sat Dec 10 22:20:59 2016
+#P0 180.005 -0.66875
+#N 2
+#L GONY/mm PD3%A
+-2.015 5.250424e-05
+-2.01 5.30798e-05
+-2.005 5.281903e-05
+-2 5.220436e-05
+"""
+
+
+class TestSpecH5SlashInLabels(unittest.TestCase):
+ """Test reading SPEC files with labels containing a / character
+
+ The / character must be substituted with a %
+ """
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp()
+ if sys.version < '3.0':
+ os.write(fd, sf_text_slash)
+ else:
+ os.write(fd, bytes(sf_text_slash, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+
+ def setUp(self):
+ self.sfh5 = SpecH5(self.fname)
+
+ def tearDown(self):
+ # fix Win32 permission error when deleting temp file
+ del self.sfh5
+ gc.collect()
+
+ def testLabels(self):
+ """Ensure `/` is substituted with `%` and
+ ensure legitimate `%` in names are still working"""
+ self.assertEqual(self.sfh5["1.1/measurement/"].keys(),
+ ["GONY%mm", "PD3%A"])
+
+ # substituted "%"
+ self.assertIn("GONY%mm",
+ self.sfh5["1.1/measurement/"])
+ self.assertNotIn("GONY/mm",
+ self.sfh5["1.1/measurement/"])
+ self.assertAlmostEqual(self.sfh5["1.1/measurement/GONY%mm"][0],
+ -2.015, places=4)
+ # legitimate "%"
+ self.assertIn("PD3%A",
+ self.sfh5["1.1/measurement/"])
+
+ def testMotors(self):
+ """Ensure `/` is substituted with `%` and
+ ensure legitimate `%` in names are still working"""
+ self.assertEqual(self.sfh5["1.1/instrument/positioners"].keys(),
+ ["Pslit%HGap", "MRTSlit%UP"])
+ # substituted "%"
+ self.assertIn("Pslit%HGap",
+ self.sfh5["1.1/instrument/positioners"])
+ self.assertNotIn("Pslit/HGap",
+ self.sfh5["1.1/instrument/positioners"])
+ self.assertAlmostEqual(
+ self.sfh5["1.1/instrument/positioners/Pslit%HGap"],
+ 180.005, places=4)
+ # legitimate "%"
+ self.assertIn("MRTSlit%UP",
+ self.sfh5["1.1/instrument/positioners"])
+
+
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecH5))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecDate))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecH5MultiMca))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecH5NoDataCols))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecH5SlashInLabels))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_spectoh5.py b/silx/io/test/test_spectoh5.py
new file mode 100644
index 0000000..f42f8a8
--- /dev/null
+++ b/silx/io/test/test_spectoh5.py
@@ -0,0 +1,197 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""Tests for SpecFile to HDF5 converter"""
+
+import gc
+from numpy import array_equal, string_
+import os
+import sys
+import tempfile
+import unittest
+
+try:
+ import h5py
+except ImportError:
+ h5py_missing = True
+else:
+ h5py_missing = False
+ from ..spech5 import SpecH5
+ from ..spectoh5 import convert, write_spec_to_h5
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/10/2016"
+
+
+sftext = """#F /tmp/sf.dat
+#E 1455180875
+#D Thu Feb 11 09:54:35 2016
+#C imaging User = opid17
+#O0 Pslit HGap MRTSlit UP MRTSlit DOWN
+#O1 Sslit1 VOff Sslit1 HOff Sslit1 VGap
+#o0 pshg mrtu mrtd
+#o2 ss1vo ss1ho ss1vg
+
+#J0 Seconds IA ion.mono Current
+#J1 xbpmc2 idgap1 Inorm
+
+#S 1 ascan ss1vo -4.55687 -0.556875 40 0.2
+#D Thu Feb 11 09:55:20 2016
+#T 0.2 (Seconds)
+#P0 180.005 -0.66875 0.87125
+#P1 14.74255 16.197579 12.238283
+#N 4
+#L MRTSlit UP second column 3rd_col
+-1.23 5.89 8
+8.478100E+01 5 1.56
+3.14 2.73 -3.14
+1.2 2.3 3.4
+
+#S 1 aaaaaa
+#D Thu Feb 11 10:00:32 2016
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+@A 10 9 8
+3 4
+@A 3.1 4 5
+@A 7 6 5
+5 6
+@A 6 7.7 8
+@A 4 3 2
+"""
+
+
+@unittest.skipIf(h5py_missing, "Could not import h5py")
+class TestConvertSpecHDF5(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.spec_fname = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ fd, cls.h5_fname = tempfile.mkstemp(text=False)
+ # Close and delete (we just need the name)
+ os.close(fd)
+ os.unlink(cls.h5_fname)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.spec_fname)
+
+ def setUp(self):
+ convert(self.spec_fname, self.h5_fname)
+
+ self.sfh5 = SpecH5(self.spec_fname)
+ self.h5f = h5py.File(self.h5_fname)
+
+ def tearDown(self):
+ del self.sfh5
+ self.h5f.close()
+ del self.h5f
+ os.unlink(self.h5_fname)
+ gc.collect()
+
+ def testAppendToHDF5(self):
+ write_spec_to_h5(self.sfh5, self.h5f,
+ h5path="/foo/bar/spam")
+ self.assertTrue(
+ array_equal(self.h5f["/1.2/measurement/mca_1/data"],
+ self.h5f["/foo/bar/spam/1.2/measurement/mca_1/data"])
+ )
+
+ def testTitle(self):
+ """Test the value of a dataset"""
+ title12 = self.h5f["/1.2/title"].value
+ if sys.version > '3.0':
+ title12 = title12.decode()
+ self.assertEqual(title12,
+ "1 aaaaaa")
+
+ def testAttrs(self):
+ # Test root group (file) attributes
+ self.assertEqual(self.h5f.attrs["NX_class"],
+ string_("NXroot"))
+ # Test dataset attributes
+ ds = self.h5f["/1.2/instrument/mca_1/data"]
+ self.assertTrue("interpretation" in ds.attrs)
+ self.assertEqual(list(ds.attrs.values()),
+ [string_("spectrum")])
+ # Test group attributes
+ grp = self.h5f["1.1"]
+ self.assertEqual(grp.attrs["NX_class"],
+ string_("NXentry"))
+ self.assertEqual(len(list(grp.attrs.keys())),
+ 1)
+
+ def testHdf5HasSameMembers(self):
+ spec_member_list = []
+
+ def append_spec_members(name):
+ spec_member_list.append(name)
+ self.sfh5.visit(append_spec_members)
+
+ hdf5_member_list = []
+
+ def append_hdf5_members(name):
+ hdf5_member_list.append(name)
+ self.h5f.visit(append_hdf5_members)
+
+ # 1. For some reason, h5py visit method doesn't include the leading
+ # "/" character when it passes the member name to the function,
+ # even though an explicit the .name attribute of a member will
+ # have a leading "/"
+ spec_member_list = [m.lstrip("/") for m in spec_member_list]
+
+ self.assertEqual(set(hdf5_member_list),
+ set(spec_member_list))
+
+ def testLinks(self):
+ self.assertTrue(
+ array_equal(self.sfh5["/1.2/measurement/mca_0/data"],
+ self.h5f["/1.2/measurement/mca_0/data"])
+ )
+ self.assertTrue(
+ array_equal(self.h5f["/1.2/instrument/mca_1/channels"],
+ self.h5f["/1.2/measurement/mca_1/info/channels"])
+ )
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestConvertSpecHDF5))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_utils.py b/silx/io/test/test_utils.py
new file mode 100644
index 0000000..15d0005
--- /dev/null
+++ b/silx/io/test/test_utils.py
@@ -0,0 +1,510 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+"""Tests for utils module"""
+
+
+import numpy
+import os
+import re
+import shutil
+import tempfile
+import unittest
+
+from .. import utils
+
+try:
+ import h5py
+except ImportError:
+ h5py_missing = True
+else:
+ h5py_missing = False
+ from ..utils import h5ls
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "11/01/2017"
+
+
+expected_spec1 = r"""#F .*
+#D .*
+
+#S 1 Ordinate1
+#D .*
+#N 2
+#L Abscissa Ordinate1
+1 4\.00
+2 5\.00
+3 6\.00
+"""
+
+expected_spec2 = expected_spec1 + """
+#S 2 Ordinate2
+#D .*
+#N 2
+#L Abscissa Ordinate2
+1 7\.00
+2 8\.00
+3 9\.00
+"""
+expected_csv = r"""Abscissa;Ordinate1;Ordinate2
+1;4\.00;7\.00e\+00
+2;5\.00;8\.00e\+00
+3;6\.00;9\.00e\+00
+"""
+
+expected_csv2 = r"""x;y0;y1
+1;4\.00;7\.00e\+00
+2;5\.00;8\.00e\+00
+3;6\.00;9\.00e\+00
+"""
+
+
+class TestSave(unittest.TestCase):
+ """Test saving curves as SpecFile:
+ """
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+ self.spec_fname = os.path.join(self.tempdir, "savespec.dat")
+ self.csv_fname = os.path.join(self.tempdir, "savecsv.csv")
+ self.npy_fname = os.path.join(self.tempdir, "savenpy.npy")
+
+ self.x = [1, 2, 3]
+ self.xlab = "Abscissa"
+ self.y = [[4, 5, 6], [7, 8, 9]]
+ self.ylabs = ["Ordinate1", "Ordinate2"]
+
+ def tearDown(self):
+ if os.path.isfile(self.spec_fname):
+ os.unlink(self.spec_fname)
+ if os.path.isfile(self.csv_fname):
+ os.unlink(self.csv_fname)
+ if os.path.isfile(self.npy_fname):
+ os.unlink(self.npy_fname)
+ shutil.rmtree(self.tempdir)
+
+ def test_save_csv(self):
+ utils.save1D(self.csv_fname, self.x, self.y,
+ xlabel=self.xlab, ylabels=self.ylabs,
+ filetype="csv", fmt=["%d", "%.2f", "%.2e"],
+ csvdelim=";", autoheader=True)
+
+ csvf = open(self.csv_fname)
+ actual_csv = csvf.read()
+ csvf.close()
+
+ self.assertRegexpMatches(actual_csv, expected_csv)
+
+ def test_save_npy(self):
+ """npy file is saved with numpy.save after building a numpy array
+ and converting it to a named record array"""
+ npyf = open(self.npy_fname, "wb")
+ utils.save1D(npyf, self.x, self.y,
+ xlabel=self.xlab, ylabels=self.ylabs)
+ npyf.close()
+
+ npy_recarray = numpy.load(self.npy_fname)
+
+ self.assertEqual(npy_recarray.shape, (3,))
+ self.assertTrue(
+ numpy.array_equal(
+ npy_recarray['Ordinate1'],
+ numpy.array((4, 5, 6))))
+
+ def test_savespec_filename(self):
+ """Save SpecFile using savespec()"""
+ utils.savespec(self.spec_fname, self.x, self.y[0], xlabel=self.xlab,
+ ylabel=self.ylabs[0], fmt=["%d", "%.2f"], close_file=True,
+ scan_number=1)
+
+ specf = open(self.spec_fname)
+ actual_spec = specf.read()
+ specf.close()
+
+ self.assertRegexpMatches(actual_spec, expected_spec1)
+
+ def test_savespec_file_handle(self):
+ """Save SpecFile using savespec(), passing a file handle"""
+ # first savespec: open, write file header, save y[0] as scan 1,
+ # return file handle
+ specf = utils.savespec(self.spec_fname, self.x, self.y[0], xlabel=self.xlab,
+ ylabel=self.ylabs[0], fmt=["%d", "%.2f"],
+ close_file=False)
+
+ # second savespec: save y[1] as scan 2, close file
+ utils.savespec(specf, self.x, self.y[1], xlabel=self.xlab,
+ ylabel=self.ylabs[1], fmt=["%d", "%.2f"],
+ write_file_header=False, close_file=True,
+ scan_number=2)
+
+ specf = open(self.spec_fname)
+ actual_spec = specf.read()
+ specf.close()
+
+ self.assertRegexpMatches(actual_spec, expected_spec2)
+
+ def test_save_spec(self):
+ """Save SpecFile using save()"""
+ utils.save1D(self.spec_fname, self.x, self.y, xlabel=self.xlab,
+ ylabels=self.ylabs, filetype="spec", fmt=["%d", "%.2f"])
+
+ specf = open(self.spec_fname)
+ actual_spec = specf.read()
+ specf.close()
+ self.assertRegexpMatches(actual_spec, expected_spec2)
+
+ def test_save_csv_no_labels(self):
+ """Save csv using save(), with autoheader=True but
+ xlabel=None and ylabels=None
+ This is a non-regression test for bug #223"""
+ self.tempdir = tempfile.mkdtemp()
+ self.spec_fname = os.path.join(self.tempdir, "savespec.dat")
+ self.csv_fname = os.path.join(self.tempdir, "savecsv.csv")
+ self.npy_fname = os.path.join(self.tempdir, "savenpy.npy")
+
+ self.x = [1, 2, 3]
+ self.xlab = "Abscissa"
+ self.y = [[4, 5, 6], [7, 8, 9]]
+ self.ylabs = ["Ordinate1", "Ordinate2"]
+ utils.save1D(self.csv_fname, self.x, self.y,
+ autoheader=True, fmt=["%d", "%.2f", "%.2e"])
+
+ csvf = open(self.csv_fname)
+ actual_csv = csvf.read()
+ csvf.close()
+ self.assertRegexpMatches(actual_csv, expected_csv2)
+
+
+def assert_match_any_string_in_list(test, pattern, list_of_strings):
+ for string_ in list_of_strings:
+ if re.match(pattern, string_):
+ return True
+ return False
+
+
+@unittest.skipIf(h5py_missing, "Could not import h5py")
+class TestH5Ls(unittest.TestCase):
+ """Test displaying the following HDF5 file structure:
+
+ +foo
+ +bar
+ <HDF5 dataset "spam": shape (2, 2), type "<i8">
+ <HDF5 dataset "tmp": shape (3,), type "<i8">
+ <HDF5 dataset "data": shape (1,), type "<f8">
+
+ """
+ def assertMatchAnyStringInList(self, pattern, list_of_strings):
+ for string_ in list_of_strings:
+ if re.match(pattern, string_):
+ return None
+ raise AssertionError("regex pattern %s does not match any" % pattern +
+ " string in list " + str(list_of_strings))
+
+ def testHdf5(self):
+ fd, self.h5_fname = tempfile.mkstemp(text=False)
+ # Close and delete (we just want the name)
+ os.close(fd)
+ os.unlink(self.h5_fname)
+ self.h5f = h5py.File(self.h5_fname, "w")
+ self.h5f["/foo/bar/tmp"] = [1, 2, 3]
+ self.h5f["/foo/bar/spam"] = [[1, 2], [3, 4]]
+ self.h5f["/foo/data"] = [3.14]
+ self.h5f.close()
+
+ rep = h5ls(self.h5_fname)
+ lines = rep.split("\n")
+
+ self.assertIn("+foo", lines)
+ self.assertIn("\t+bar", lines)
+
+ self.assertMatchAnyStringInList(
+ r'\t\t<HDF5 dataset "tmp": shape \(3,\), type "<i[48]">',
+ lines)
+ self.assertMatchAnyStringInList(
+ r'\t\t<HDF5 dataset "spam": shape \(2, 2\), type "<i[48]">',
+ lines)
+ self.assertMatchAnyStringInList(
+ r'\t<HDF5 dataset "data": shape \(1,\), type "<f[48]">',
+ lines)
+
+ os.unlink(self.h5_fname)
+
+ # Following test case disabled d/t errors on AppVeyor:
+ # os.unlink(spec_fname)
+ # PermissionError: [WinError 32] The process cannot access the file because
+ # it is being used by another process: 'C:\\...\\savespec.dat'
+
+ # def testSpec(self):
+ # tempdir = tempfile.mkdtemp()
+ # spec_fname = os.path.join(tempdir, "savespec.dat")
+ #
+ # x = [1, 2, 3]
+ # xlab = "Abscissa"
+ # y = [[4, 5, 6], [7, 8, 9]]
+ # ylabs = ["Ordinate1", "Ordinate2"]
+ # utils.save1D(spec_fname, x, y, xlabel=xlab,
+ # ylabels=ylabs, filetype="spec",
+ # fmt=["%d", "%.2f"])
+ #
+ # rep = h5ls(spec_fname)
+ # lines = rep.split("\n")
+ # self.assertIn("+1.1", lines)
+ # self.assertIn("\t+instrument", lines)
+ #
+ # self.assertMatchAnyStringInList(
+ # r'\t\t\t<SPEC dataset "file_header": shape \(\), type "|S60">',
+ # lines)
+ # self.assertMatchAnyStringInList(
+ # r'\t\t<SPEC dataset "Ordinate1": shape \(3L?,\), type "<f4">',
+ # lines)
+ #
+ # os.unlink(spec_fname)
+ # shutil.rmtree(tempdir)
+
+
+class TestOpen(unittest.TestCase):
+ """Test `silx.io.utils.open` function."""
+
+ def testH5(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+ g = h5.create_group("arrays")
+ g.create_dataset("scalar", data=10)
+ h5.close()
+
+ # load it
+ f = utils.open(tmp.name)
+ self.assertIsNotNone(f)
+ self.assertIsInstance(f, h5py.File)
+ f.close()
+
+ def testH5With(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+ g = h5.create_group("arrays")
+ g.create_dataset("scalar", data=10)
+ h5.close()
+
+ # load it
+ with utils.open(tmp.name) as f:
+ self.assertIsNotNone(f)
+ self.assertIsInstance(f, h5py.File)
+
+ def testSpec(self):
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(mode="w+t", suffix=".dat", delete=True)
+ tmp.file.close()
+ utils.savespec(tmp.name, [1], [1.1], xlabel="x", ylabel="y",
+ fmt=["%d", "%.2f"], close_file=True, scan_number=1)
+
+ # load it
+ f = utils.open(tmp.name)
+ self.assertIsNotNone(f)
+ self.assertEquals(f.h5py_class, h5py.File)
+ f.close()
+
+ def testSpecWith(self):
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(mode="w+t", suffix=".dat", delete=True)
+ tmp.file.close()
+ utils.savespec(tmp.name, [1], [1.1], xlabel="x", ylabel="y",
+ fmt=["%d", "%.2f"], close_file=True, scan_number=1)
+
+ # load it
+ with utils.open(tmp.name) as f:
+ self.assertIsNotNone(f)
+ self.assertEquals(f.h5py_class, h5py.File)
+
+ def testEdf(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+ if fabio is None:
+ self.skipTest("Fabio is missing")
+
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(suffix=".edf", delete=True)
+ tmp.file.close()
+ header = fabio.fabioimage.OrderedDict()
+ header["integer"] = "10"
+ data = numpy.array([[10, 50], [50, 10]])
+ fabiofile = fabio.edfimage.EdfImage(data, header)
+ fabiofile.write(tmp.name)
+
+ # load it
+ f = utils.open(tmp.name)
+ self.assertIsNotNone(f)
+ self.assertEquals(f.h5py_class, h5py.File)
+ f.close()
+
+ def testEdfWith(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+ if fabio is None:
+ self.skipTest("Fabio is missing")
+
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(suffix=".edf", delete=True)
+ tmp.file.close()
+ header = fabio.fabioimage.OrderedDict()
+ header["integer"] = "10"
+ data = numpy.array([[10, 50], [50, 10]])
+ fabiofile = fabio.edfimage.EdfImage(data, header)
+ fabiofile.write(tmp.name)
+
+ # load it
+ with utils.open(tmp.name) as f:
+ self.assertIsNotNone(f)
+ self.assertEquals(f.h5py_class, h5py.File)
+
+ def testUnsupported(self):
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(mode="w+t", suffix=".txt", delete=True)
+ tmp.write("Kikoo")
+ tmp.close()
+
+ # load it
+ self.assertRaises(IOError, utils.open, tmp.name)
+
+ def testNotExists(self):
+ # load it
+ self.assertRaises(IOError, utils.open, "#$.")
+
+
+class TestNodes(unittest.TestCase):
+ """Test `silx.io.utils.is_` functions."""
+ def test_real_h5py_objects(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ name = tempfile.mktemp(suffix=".h5")
+ try:
+ with h5py.File(name, "w") as h5file:
+ h5group = h5file.create_group("arrays")
+ h5dataset = h5group.create_dataset("scalar", data=10)
+
+ self.assertTrue(utils.is_file(h5file))
+ self.assertTrue(utils.is_group(h5file))
+ self.assertFalse(utils.is_dataset(h5file))
+
+ self.assertFalse(utils.is_file(h5group))
+ self.assertTrue(utils.is_group(h5group))
+ self.assertFalse(utils.is_dataset(h5group))
+
+ self.assertFalse(utils.is_file(h5dataset))
+ self.assertFalse(utils.is_group(h5dataset))
+ self.assertTrue(utils.is_dataset(h5dataset))
+ finally:
+ os.unlink(name)
+
+ def test_h5py_like_file(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ self.h5py_class = h5py.File
+ obj = Foo()
+ self.assertTrue(utils.is_file(obj))
+ self.assertTrue(utils.is_group(obj))
+ self.assertFalse(utils.is_dataset(obj))
+
+ def test_h5py_like_group(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ self.h5py_class = h5py.Group
+ obj = Foo()
+ self.assertFalse(utils.is_file(obj))
+ self.assertTrue(utils.is_group(obj))
+ self.assertFalse(utils.is_dataset(obj))
+
+ def test_h5py_like_dataset(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ self.h5py_class = h5py.Dataset
+ obj = Foo()
+ self.assertFalse(utils.is_file(obj))
+ self.assertFalse(utils.is_group(obj))
+ self.assertTrue(utils.is_dataset(obj))
+
+ def test_bad(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ pass
+ obj = Foo()
+ self.assertFalse(utils.is_file(obj))
+ self.assertFalse(utils.is_group(obj))
+ self.assertFalse(utils.is_dataset(obj))
+
+ def test_bad_api(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ self.h5py_class = int
+ obj = Foo()
+ self.assertFalse(utils.is_file(obj))
+ self.assertFalse(utils.is_group(obj))
+ self.assertFalse(utils.is_dataset(obj))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSave))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestH5Ls))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestOpen))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestNodes))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/utils.py b/silx/io/utils.py
new file mode 100644
index 0000000..2ab4496
--- /dev/null
+++ b/silx/io/utils.py
@@ -0,0 +1,500 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ############################################################################*/
+""" I/O utility functions"""
+
+import numpy
+import os.path
+import sys
+import time
+import logging
+from silx.utils.decorators import deprecated
+
+try:
+ import h5py
+except ImportError as e:
+ h5py_missing = True
+ h5py_import_error = e
+else:
+ h5py_missing = False
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "13/12/2016"
+
+
+logger = logging.getLogger(__name__)
+
+string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+
+builtin_open = open
+
+
+def save1D(fname, x, y, xlabel=None, ylabels=None, filetype=None,
+ fmt="%.7g", csvdelim=";", newline="\n", header="",
+ footer="", comments="#", autoheader=False):
+ """Saves any number of curves to various formats: `Specfile`, `CSV`,
+ `txt` or `npy`. All curves must have the same number of points and share
+ the same ``x`` values.
+
+ :param fname: Output file path, or file handle open in write mode.
+ If ``fname`` is a path, file is opened in ``w`` mode. Existing file
+ with a same name will be overwritten.
+ :param x: 1D-Array (or list) of abscissa values.
+ :param y: 2D-array (or list of lists) of ordinates values. First index
+ is the curve index, second index is the sample index. The length
+ of the second dimension (number of samples) must be equal to
+ ``len(x)``. ``y`` can be a 1D-array in case there is only one curve
+ to be saved.
+ :param filetype: Filetype: ``"spec", "csv", "txt", "ndarray"``.
+ If ``None``, filetype is detected from file name extension
+ (``.dat, .csv, .txt, .npy``).
+ :param xlabel: Abscissa label
+ :param ylabels: List of `y` labels
+ :param fmt: Format string for data. You can specify a short format
+ string that defines a single format for both ``x`` and ``y`` values,
+ or a list of two different format strings (e.g. ``["%d", "%.7g"]``).
+ Default is ``"%.7g"``.
+ This parameter does not apply to the `npy` format.
+ :param csvdelim: String or character separating columns in `txt` and
+ `CSV` formats. The user is responsible for ensuring that this
+ delimiter is not used in data labels when writing a `CSV` file.
+ :param newline: String or character separating lines/records in `txt`
+ format (default is line break character ``\\n``).
+ :param header: String that will be written at the beginning of the file in
+ `txt` format.
+ :param footer: String that will be written at the end of the file in `txt`
+ format.
+ :param comments: String that will be prepended to the ``header`` and
+ ``footer`` strings, to mark them as comments. Default: ``#``.
+ :param autoheader: In `CSV` or `txt`, ``True`` causes the first header
+ line to be written as a standard CSV header line with column labels
+ separated by the specified CSV delimiter.
+
+ When saving to Specfile format, each curve is saved as a separate scan
+ with two data columns (``x`` and ``y``).
+
+ `CSV` and `txt` formats are similar, except that the `txt` format allows
+ user defined header and footer text blocks, whereas the `CSV` format has
+ only a single header line with columns labels separated by field
+ delimiters and no footer. The `txt` format also allows defining a record
+ separator different from a line break.
+
+ The `npy` format is written with ``numpy.save`` and can be read back with
+ ``numpy.load``. If ``xlabel`` and ``ylabels`` are undefined, data is saved
+ as a regular 2D ``numpy.ndarray`` (contatenation of ``x`` and ``y``). If
+ both ``xlabel`` and ``ylabels`` are defined, the data is saved as a
+ ``numpy.recarray`` after being transposed and having labels assigned to
+ columns.
+ """
+
+ available_formats = ["spec", "csv", "txt", "ndarray"]
+
+ if filetype is None:
+ exttypes = {".dat": "spec",
+ ".csv": "csv",
+ ".txt": "txt",
+ ".npy": "ndarray"}
+ outfname = (fname if not hasattr(fname, "name") else
+ fname.name)
+ fileext = os.path.splitext(outfname)[1]
+ if fileext in exttypes:
+ filetype = exttypes[fileext]
+ else:
+ raise IOError("File type unspecified and could not be " +
+ "inferred from file extension (not in " +
+ "txt, dat, csv, npy)")
+ else:
+ filetype = filetype.lower()
+
+ if filetype not in available_formats:
+ raise IOError("File type %s is not supported" % (filetype))
+
+ # default column headers
+ if xlabel is None:
+ xlabel = "x"
+ if ylabels is None:
+ if len(numpy.array(y).shape) > 1:
+ ylabels = ["y%d" % i for i in range(len(y))]
+ else:
+ ylabels = ["y"]
+ elif isinstance(ylabels, (list, tuple)):
+ # if ylabels is provided as a list, every element must
+ # be a string
+ ylabels = [ylabels[i] if ylabels[i] is not None else "y%d" % i
+ for i in range(len(ylabels))]
+
+ if filetype.lower() == "spec":
+ y_array = numpy.asarray(y)
+
+ # make sure y_array is a 2D array even for a single curve
+ if len(y_array.shape) == 1:
+ y_array.shape = (1, y_array.shape[0])
+ elif len(y_array.shape) > 2 or len(y_array.shape) < 1:
+ raise IndexError("y must be a 1D or 2D array")
+
+ # First curve
+ specf = savespec(fname, x, y_array[0], xlabel, ylabels[0], fmt=fmt,
+ scan_number=1, mode="w", write_file_header=True,
+ close_file=False)
+ # Other curves
+ for i in range(1, y_array.shape[0]):
+ specf = savespec(specf, x, y_array[i], xlabel, ylabels[i],
+ fmt=fmt, scan_number=i + 1, mode="w",
+ write_file_header=False, close_file=False)
+ # close file if we created it
+ if not hasattr(fname, "write"):
+ specf.close()
+
+ else:
+ autoheader_line = xlabel + csvdelim + csvdelim.join(ylabels)
+ if xlabel is not None and ylabels is not None and filetype == "csv":
+ # csv format: optional single header line with labels, no footer
+ if autoheader:
+ header = autoheader_line + newline
+ else:
+ header = ""
+ comments = ""
+ footer = ""
+ newline = "\n"
+ elif filetype == "txt" and autoheader:
+ # Comments string is added at the beginning of header string in
+ # savetxt(). We add another one after the first header line and
+ # before the rest of the header.
+ if header:
+ header = autoheader_line + newline + comments + header
+ else:
+ header = autoheader_line + newline
+
+ # Concatenate x and y in a single 2D array
+ X = numpy.vstack((x, y))
+
+ if filetype.lower() in ["csv", "txt"]:
+ X = X.transpose()
+ savetxt(fname, X, fmt=fmt, delimiter=csvdelim,
+ newline=newline, header=header, footer=footer,
+ comments=comments)
+
+ elif filetype.lower() == "ndarray":
+ if xlabel is not None and ylabels is not None:
+ labels = [xlabel] + ylabels
+
+ # .transpose is needed here because recarray labels
+ # apply to columns
+ X = numpy.core.records.fromrecords(X.transpose(),
+ names=labels)
+ numpy.save(fname, X)
+
+
+# Replace with numpy.savetxt when dropping support of numpy < 1.7.0
+def savetxt(fname, X, fmt="%.7g", delimiter=";", newline="\n",
+ header="", footer="", comments="#"):
+ """``numpy.savetxt`` backport of header and footer arguments from
+ numpy=1.7.0.
+
+ See ``numpy.savetxt`` help:
+ http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.savetxt.html
+ """
+ if not hasattr(fname, "name"):
+ ffile = builtin_open(fname, 'wb')
+ else:
+ ffile = fname
+
+ if header:
+ if sys.version_info[0] >= 3:
+ header = header.encode("utf-8")
+ ffile.write(header)
+
+ numpy.savetxt(ffile, X, fmt, delimiter, newline)
+
+ if footer:
+ footer = (comments + footer.replace(newline, newline + comments) +
+ newline)
+ if sys.version_info[0] >= 3:
+ footer = footer.encode("utf-8")
+ ffile.write(footer)
+
+ if not hasattr(fname, "name"):
+ ffile.close()
+
+
+def savespec(specfile, x, y, xlabel="X", ylabel="Y", fmt="%.7g",
+ scan_number=1, mode="w", write_file_header=True,
+ close_file=False):
+ """Saves one curve to a SpecFile.
+
+ The curve is saved as a scan with two data columns. To save multiple
+ curves to a single SpecFile, call this function for each curve by
+ providing the same file handle each time.
+
+ :param specfile: Output SpecFile name, or file handle open in write
+ or append mode. If a file name is provided, a new file is open in
+ write mode (existing file with the same name will be lost)
+ :param x: 1D-Array (or list) of abscissa values
+ :param y: 1D-array (or list) of ordinates values
+ :param xlabel: Abscissa label (default ``"X"``)
+ :param ylabel: Ordinate label
+ :param fmt: Format string for data. You can specify a short format
+ string that defines a single format for both ``x`` and ``y`` values,
+ or a list of two different format strings (e.g. ``["%d", "%.7g"]``).
+ Default is ``"%.7g"``.
+ :param scan_number: Scan number (default 1).
+ :param mode: Mode for opening file: ``w`` (default), ``a``, ``r+``,
+ ``w+``, ``a+``. This parameter is only relevant if ``specfile`` is a
+ path.
+ :param write_file_header: If ``True``, write a file header before writing
+ the scan (``#F`` and ``#D`` line).
+ :param close_file: If ``True``, close the file after saving curve.
+ :return: ``None`` if ``close_file`` is ``True``, else return the file
+ handle.
+ """
+ # Make sure we use binary mode for write
+ # (issue with windows: write() replaces \n with os.linesep in text mode)
+ if "b" not in mode:
+ first_letter = mode[0]
+ assert first_letter in "rwa"
+ mode = mode.replace(first_letter, first_letter + "b")
+
+ x_array = numpy.asarray(x)
+ y_array = numpy.asarray(y)
+
+ if y_array.shape[0] != x_array.shape[0]:
+ raise IndexError("X and Y columns must have the same length")
+
+ if isinstance(fmt, string_types) and fmt.count("%") == 1:
+ full_fmt_string = fmt + " " + fmt + "\n"
+ elif isinstance(fmt, (list, tuple)) and len(fmt) == 2:
+ full_fmt_string = " ".join(fmt) + "\n"
+ else:
+ raise ValueError("fmt must be a single format string or a list of " +
+ "two format strings")
+
+ if not hasattr(specfile, "write"):
+ f = builtin_open(specfile, mode)
+ else:
+ f = specfile
+
+ output = ""
+
+ current_date = "#D %s\n" % (time.ctime(time.time()))
+
+ if write_file_header:
+ output += "#F %s\n" % f.name
+ output += current_date
+ output += "\n"
+
+ output += "#S %d %s\n" % (scan_number, ylabel)
+ output += current_date
+ output += "#N 2\n"
+ output += "#L %s %s\n" % (xlabel, ylabel)
+ for i in range(y_array.shape[0]):
+ output += full_fmt_string % (x_array[i], y_array[i])
+ output += "\n"
+
+ f.write(output.encode())
+
+ if close_file:
+ f.close()
+ return None
+ return f
+
+
+def h5ls(h5group, lvl=0):
+ """Return a simple string representation of a HDF5 tree structure.
+
+ :param h5group: Any :class:`h5py.Group` or :class:`h5py.File` instance,
+ or a HDF5 file name
+ :param lvl: Number of tabulations added to the group. ``lvl`` is
+ incremented as we recursively process sub-groups.
+ :return: String representation of an HDF5 tree structure
+
+
+ Group names and dataset representation are printed preceded by a number of
+ tabulations corresponding to their depth in the tree structure.
+ Datasets are represented as :class:`h5py.Dataset` objects.
+
+ Example::
+
+ >>> print(h5ls("Downloads/sample.h5"))
+ +fields
+ +fieldB
+ <HDF5 dataset "z": shape (256, 256), type "<f4">
+ +fieldE
+ <HDF5 dataset "x": shape (256, 256), type "<f4">
+ <HDF5 dataset "y": shape (256, 256), type "<f4">
+
+ .. note:: This function requires `h5py <http://www.h5py.org/>`_ to be
+ installed.
+ """
+ if h5py_missing:
+ logger.error("h5ls requires h5py")
+ raise h5py_import_error
+
+ h5repr = ''
+ if is_group(h5group):
+ h5f = h5group
+ elif isinstance(h5group, string_types):
+ h5f = open(h5group) # silx.io.open
+ else:
+ raise TypeError("h5group must be a hdf5-like group object or a file name.")
+
+ for key in h5f.keys():
+ # group
+ if hasattr(h5f[key], 'keys'):
+ h5repr += '\t' * lvl + '+' + key
+ h5repr += '\n'
+ h5repr += h5ls(h5f[key], lvl + 1)
+ # dataset
+ else:
+ h5repr += '\t' * lvl
+ h5repr += str(h5f[key])
+ h5repr += '\n'
+
+ if isinstance(h5group, string_types):
+ h5f.close()
+
+ return h5repr
+
+
+def open(filename): # pylint:disable=redefined-builtin
+ """
+ Load a file as an `h5py.File`-like object.
+
+ Format supported:
+ - h5 files, if `h5py` module is installed
+ - Spec files if `SpecFile` module is installed
+ - a set of raster image formats (tiff, edf...) if `fabio` is installed
+
+ :param str filename: A filename
+ :raises: IOError if the file can't be loaded as an h5py.File like object
+ :rtype: h5py.File
+ """
+ if not os.path.isfile(filename):
+ raise IOError("Filename '%s' must be a file path" % filename)
+
+ if not h5py_missing:
+ if h5py.is_hdf5(filename):
+ return h5py.File(filename)
+
+ try:
+ from . import fabioh5
+ return fabioh5.File(filename)
+ except ImportError:
+ logger.debug("fabioh5 can't be loaded.", exc_info=True)
+ except Exception:
+ logger.debug("File '%s' can't be read as fabio file.", filename, exc_info=True)
+
+ try:
+ from . import spech5
+ return spech5.SpecH5(filename)
+ except ImportError:
+ logger.debug("spech5 can't be loaded.", exc_info=True)
+ except IOError:
+ logger.debug("File '%s' can't be read as spec file.", filename, exc_info=True)
+
+ raise IOError("File '%s' can't be read as HDF5" % filename)
+
+
+@deprecated
+def load(filename):
+ """
+ Load a file as an `h5py.File`-like object.
+
+ Format supported:
+ - h5 files, if `h5py` module is installed
+ - Spec files if `SpecFile` module is installed
+
+ .. deprecated:: 0.4
+ Use :meth:`open`, or :meth:`silx.io.open`. Will be removed in
+ Silx 0.5.
+
+ :param str filename: A filename
+ :raises: IOError if the file can't be loaded as an h5py.File like object
+ :rtype: h5py.File
+ """
+ return open(filename)
+
+
+def get_h5py_class(obj):
+ """Returns the h5py class from an object.
+
+ If it is an h5py object or an h5py-like object, an h5py class is returned.
+ If the object is not an h5py-like object, None is returned.
+
+ :param obj: An object
+ :return: An h5py object
+ """
+ if hasattr(obj, "h5py_class"):
+ return obj.h5py_class
+ elif isinstance(obj, (h5py.File, h5py.Group, h5py.Dataset)):
+ return obj.__class__
+ else:
+ return None
+
+
+def is_file(obj):
+ """
+ True is the object is an h5py.File-like object.
+
+ :param obj: An object
+ """
+ class_ = get_h5py_class(obj)
+ if class_ is None:
+ return False
+ return issubclass(class_, h5py.File)
+
+
+def is_group(obj):
+ """
+ True is the object is an h5py.Group-like object.
+
+ :param obj: An object
+ """
+ class_ = get_h5py_class(obj)
+ if class_ is None:
+ return False
+ return issubclass(class_, h5py.Group)
+
+
+def is_dataset(obj):
+ """
+ True is the object is an h5py.Dataset-like object.
+
+ :param obj: An object
+ """
+ class_ = get_h5py_class(obj)
+ if class_ is None:
+ return False
+ return issubclass(class_, h5py.Dataset)
+
+
+if h5py_missing:
+ def raise_h5py_missing(obj):
+ logger.error("get_h5py_class/is_file/is_group/is_dataset requires h5py")
+ raise h5py_import_error
+
+ get_h5py_class = raise_h5py_missing
+ is_file = raise_h5py_missing
+ is_group = raise_h5py_missing
+ is_dataset = raise_h5py_missing