diff --git a/.bumpversion.cfg b/.bumpversion.cfg index e251e52b..82670a06 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,6 +1,7 @@ [bumpversion] -current_version = 1.4.0 +current_version = 1.3.1 commit = True tag = True [bumpversion:file:pygac/version.py] + diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml deleted file mode 100644 index d73a100d..00000000 --- a/.github/workflows/ci.yaml +++ /dev/null @@ -1,49 +0,0 @@ -name: CI - -on: [push, pull_request] - -jobs: - test: - runs-on: ${{ matrix.os }} - continue-on-error: ${{ matrix.experimental }} - strategy: - fail-fast: true - matrix: - os: ["ubuntu-latest"] - python-version: ["3.7", "3.8"] - experimental: [false] - - env: - PYTHON_VERSION: ${{ matrix.python-version }} - OS: ${{ matrix.os }} - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - PYGAC_CONFIG_FILE: etc/pygac.cfg.template - - steps: - - name: Checkout source - uses: actions/checkout@v2 - - - name: Setup Conda Environment - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - python-version: ${{ matrix.python-version }} - environment-file: continuous_integration/environment.yaml - activate-environment: test-environment - - - name: Install pygac - shell: bash -l {0} - run: | - pip install --no-deps -e . - - - name: Run unit tests - shell: bash -l {0} - run: | - coverage run --source=pygac setup.py test - coverage xml - - - name: Upload unittest coverage - uses: codecov/codecov-action@v1 - with: - file: ./coverage.xml - env_vars: OS,PYTHON_VERSION diff --git a/.stickler.yml b/.stickler.yml index e5e6fe74..4a6f4e14 100644 --- a/.stickler.yml +++ b/.stickler.yml @@ -1,7 +1,6 @@ linters: flake8: fixer: true - python: 3 - config: setup.cfg + max-line-length: 120 fixers: enable: true diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..1e035c52 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: python +python: + - "2.7_with_system_site_packages" + - "3.7" +# command to install dependencies, e.g. +install: + - pip install -r requirements.txt + - pip install . + - pip install coveralls +# command to run tests, e.g. python setup.py test +env: PYGAC_CONFIG_FILE=etc/pygac.cfg.template +script: coverage run --source=pygac setup.py test +before_install: + - sudo apt-get install -qq python-numpy python-h5py python-scipy libhdf5-serial-dev +after_success: coveralls +deploy: + provider: pypi + user: adybbroe + password: + secure: FznD38SHxuj1RoFXUqLstF//O3+pypF84hCOHO8A3Poa+ygh7X4a+9aimCeiuY9d+5tbE0ZlyG7LMcCOFA3JCvH7lUChmQbbn3pcFvJdJzzYQgxYNfvCL9YtjRF/n648bVdpN265hm07rmOe7DHbysw4q8hMlxtUH87MYctRg90= + on: + tags: true + repo: pytroll/pygac + branch: master diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bfc11c1..32761845 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,33 +1,3 @@ -## Version 1.4.0 (2020/08/06) - -### Issues Closed - -* [Issue 66](https://github.com/pytroll/pygac/issues/66) - Typos in calibration coefficients ([PR 67](https://github.com/pytroll/pygac/pull/67)) -* [Issue 62](https://github.com/pytroll/pygac/issues/62) - Computation of Earth scene radiance ([PR 58](https://github.com/pytroll/pygac/pull/58)) -* [Issue 60](https://github.com/pytroll/pygac/issues/60) - Improve readability of quality indicators bit unpacking ([PR 72](https://github.com/pytroll/pygac/pull/72)) -* [Issue 57](https://github.com/pytroll/pygac/issues/57) - channel 4 BT to radiance conversion ([PR 67](https://github.com/pytroll/pygac/pull/67)) -* [Issue 54](https://github.com/pytroll/pygac/issues/54) - Function check_file_version should not be part of pygac-run ([PR 55](https://github.com/pytroll/pygac/pull/55)) -* [Issue 47](https://github.com/pytroll/pygac/issues/47) - Fix reading of renamed files - -In this release 6 issues were closed. - -### Pull Requests Merged - -#### Bugs fixed - -* [PR 73](https://github.com/pytroll/pygac/pull/73) - Fix azimuth encoding -* [PR 67](https://github.com/pytroll/pygac/pull/67) - Correct coefficients ([66](https://github.com/pytroll/pygac/issues/66), [57](https://github.com/pytroll/pygac/issues/57)) - -#### Features added - -* [PR 72](https://github.com/pytroll/pygac/pull/72) - Quality indicators ([60](https://github.com/pytroll/pygac/issues/60)) -* [PR 71](https://github.com/pytroll/pygac/pull/71) - Expose new metadata -* [PR 70](https://github.com/pytroll/pygac/pull/70) - Remove config dependency from reader class -* [PR 58](https://github.com/pytroll/pygac/pull/58) - export coefficients to json file ([62](https://github.com/pytroll/pygac/issues/62)) -* [PR 55](https://github.com/pytroll/pygac/pull/55) - Refactor gac-run ([54](https://github.com/pytroll/pygac/issues/54)) - -In this release 7 pull requests were closed. - ## Version v1.3.1 (2020/02/07) ### Issues Closed diff --git a/README.md b/README.md index 4f1aafa9..37edd75f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ pygac ===== -[![Build](https://github.com/pytroll/pygac/actions/workflows/ci.yaml/badge.svg)](https://github.com/pytroll/pygac/actions/workflows/ci.yaml) -[![Coverage](https://codecov.io/gh/pytroll/pygac/branch/main/graph/badge.svg?token=DQMgf2LxuM)](https://codecov.io/gh/pytroll/pygac) +[![Build Status](https://travis-ci.org/adybbroe/pygac.png?branch=feature-clock)](https://travis-ci.org/pytroll/pygac) +[![Coverage Status](https://coveralls.io/repos/adybbroe/pygac/badge.png?branch=feature-clock)](https://coveralls.io/r/pytroll/pygac?branch=develop) A python package to read, calibrate and navigate NOAA and Metop AVHRR GAC and LAC data. diff --git a/RELEASING.md b/RELEASING.md index 372cfca3..4a218844 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,6 +1,6 @@ # Releasing Pygac -1. checkout main branch +1. checkout master 2. pull from repo 3. run the unittests 4. run `loghub`. Replace and with proper diff --git a/bin/pygac-convert-patmosx-coefficients b/bin/pygac-convert-patmosx-coefficients deleted file mode 100755 index aef0d044..00000000 --- a/bin/pygac-convert-patmosx-coefficients +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/env python - -# Author(s): - -# Carlos Horn - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program 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 General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -"""Convert PATMOS-x calibration file tarballs to PyGAC calibration json format. - -The official tarballs are available on the PATMOS-x webpage "https://cimss.ssec.wisc.edu/patmosx/avhrr_cal.html". -""" - -import argparse -import pathlib -import datetime as dt -import tarfile -import re -import json -import logging -from scipy.optimize import bisect - -class PatmosxReader: - """Read PATMOS-x coefficient files tarballs.""" - # regular expression with named capturing groups to read an entire patmosx file - regex = re.compile( - r'\s*(?P\w+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+),?\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'(?:[a-z]+[^\n]*\n)?' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)\s*(?P[eE0-9\.-]+)[^\n]*\n' - r'(?:\s*(?P[eE0-9\.-]+),\s*(?P[eE0-9\.-]+),\s*(?P[eE0-9\.-]+),\s*(?P[eE0-9\.-]+)[^\n]*\n)?' - r'(?:\s*(?P[eE0-9\.-]+),\s*(?P[eE0-9\.-]+),\s*(?P[eE0-9\.-]+),\s*(?P[eE0-9\.-]+)[^\n]*\n)?' - r'(?:\![^v][^\n]*\n)*' - r'(?:\!(?Pv\w+))?' - ) - - def __init__(self, tarball): - self.tarball = tarball - self.coeffs = [] - with tarfile.open(tarball) as archive: - for tarinfo in archive: - if tarinfo.isfile(): - # open satellite specific coefficient file - filename = tarinfo.name - fileobj = archive.extractfile(filename) - content = fileobj.read().decode() - match = self.regex.match(content) - sat_coeffs = {key: self.parse_types(value) for key, value in match.groupdict().items()} - self.coeffs.append(sat_coeffs) - - def __iter__(self): - yield from self.coeffs # noqa - - @staticmethod - def parse_types(value): - """parse the types of coefficients""" - try: - try: - _value = int(value) - except ValueError: - _value = float(value) - except ValueError: - _value = value - except TypeError: - _value = None - return _value - - -class Translator: - """Translate PATMOS-x coefficients to PyGAC format.""" - sat_names = {"m01": "metopb", "m02": "metopa", "n05": "tirosn", "m03": "metopc"} - sat_names.update({"n{0:02d}".format(i): "noaa{0}".format(i) for i in range(6,20)}) - description = { - "visible": { - "channels": ['1', '2', '3a'], - "coefficients": { - 'dark_count': "instrument counts under dark conditions []", - "gain_switch": "dual-gain switch count, set to 'null' for single-gain instruments []", - "s0": "single-gain calibration slope at launch date [%]", - "s1": "linear single-gain calibration slope parameter [% years^{-1}]", - "s2": "quadratic single-gain calibration slope parameter [% years^{-2}]", - "date_of_launch": "timestamp of launch date [UTC]" - }, - "method": 'Heidinger, A.K., W.C. Straka III, C.C. Molling, J.T. Sullivan, and X. Wu, 2010: Deriving an inter-sensor consistent calibration for the AVHRR solar reflectance data record. International Journal of Remote Sensing, 31:6493-6517' - }, - "thermal": { - "channels": ['3b', '4', '5'], - "coefficients": { - 'centroid_wavenumber': "centroid wavenumber [cm^{-1}]", - "b0": "constant non-linear radiance correction coefficient [mW m^{-2} sr cm^{-1}]", - "b1": "linear non-linear radiance correction coefficient []", - "b2": "quadratic non-linear radiance correction coefficient [(mW^{-1} m^2 sr^{-1} cm)]", - "space_radiance": "radiance of space [mW m^{-2} sr cm^{-1}]", - "to_eff_blackbody_intercept": "thermal channel temperature to effective blackbody temperature intercept [K]", - "to_eff_blackbody_slope": "thermal channel temperature to effective blackbody temperature slope []", - "d0": "constant thermometer counts to temperature conversion coefficient [K]", - "d1": "linear thermometer counts to temperature conversion coefficient [K]", - "d2": "quadratic thermometer counts to temperature conversion coefficient [K]", - "d3": "cubic thermometer counts to temperature conversion coefficient [K]", - "d4": "quartic thermometer counts to temperature conversion coefficient [K]" - }, - "method": "Goodrum, G., Kidwell, K.B. and W. Winston, 2000: NOAA KLM User's Guide. U.S. Department of Commerce, National Oceanic and Atmospheric Administration, National Environmental Satellite, Data and Information Service; Walton, C. C., J. T. Sullivan, C. R. N. Rao, and M. P. Weinreb, 1998: Corrections for detector nonlinearities and calibration inconsistencies of the infrared channels of the Advanced Very High Resolution Radiometer. J. Geophys. Res., 103, 3323-3337; Trishchenko, A.P., 2002: Removing Unwanted Fluctuations in the AVHRR Thermal Calibration Data Using Robust Techniques. Journal of Atmospheric and Oceanic Technology, 19:1939-1954" - } - } - - def __init__(self, patmosx_coeffs): - self.coeffs = {"description": self.description} - for patmosx_sat_coeffs in patmosx_coeffs: - sat_name = self.sat_names[patmosx_sat_coeffs["sat_name"]] - pygac_sat_coeffs = self.convert(patmosx_sat_coeffs) - self.coeffs[sat_name] = pygac_sat_coeffs - - @classmethod - def convert(cls, patmosx_sat_coeffs): - pygac_sat_coeffs = {} - # visible calibration - for ch in ("1", "2", "3a"): - s0l = patmosx_sat_coeffs['ch{0}_low_gain_S0'.format(ch)] - s0h = patmosx_sat_coeffs['ch{0}_high_gain_S0'.format(ch)] - if s0l == s0h: - gain_switch = None - s0 = s0l - else: - gain_switch = patmosx_sat_coeffs['ch{0}_gain_switches_count'.format(ch)] - s0 = cls.find_s0(s0l, s0h, ch) - pygac_sat_coeffs["channel_{0}".format(ch)] = { - "dark_count": float(patmosx_sat_coeffs['ch{0}_dark_count'.format(ch)]), - "gain_switch": gain_switch, - "s0": s0, - "s1": patmosx_sat_coeffs['ch{0}_high_gain_S1'.format(ch)], - "s2": patmosx_sat_coeffs['ch{0}_high_gain_S2'.format(ch)] - } - date_of_launch = cls.float2date(patmosx_sat_coeffs['date_of_launch']) - pygac_sat_coeffs['date_of_launch'] = date_of_launch.strftime("%Y-%m-%dT%H:%M:%S.%fZ") - # thermal channels - for ch in ("3b", "4", "5"): - pygac_sat_coeffs["channel_{0}".format(ch)] = { - "b0": patmosx_sat_coeffs['ch{0}_b0'.format(ch)], - "b1": patmosx_sat_coeffs['ch{0}_b1'.format(ch)], - "b2": patmosx_sat_coeffs['ch{0}_b2'.format(ch)], - "centroid_wavenumber": patmosx_sat_coeffs['nu_{0}'.format(ch)], - "space_radiance": patmosx_sat_coeffs['ch{0}_Ns'.format(ch)], - "to_eff_blackbody_intercept": (-patmosx_sat_coeffs['a1_{0}'.format(ch)] - / patmosx_sat_coeffs['a2_{0}'.format(ch)]), - "to_eff_blackbody_slope": 1/patmosx_sat_coeffs['a2_{0}'.format(ch)] - } - for t in range(1, 5): - pygac_sat_coeffs["thermometer_{0}".format(t)] = { - "d{0}".format(d): float(patmosx_sat_coeffs["PRT{0}_{1}".format(t, d)]) - for d in range(5) - } - return pygac_sat_coeffs - - @staticmethod - def find_s0(s0_low, s0_high, ch): - """Find the single-gain calibration slope at launch date. - - Arguments - s0_low - low gain calibration slope at launch date - s0_high - high gain calibration slope at launch date - ch - channel name ("1", "2", "3a") - - Note: - In case of a single-gain instrument, s0_low is equal to s0_high. - """ - if s0_low == s0_high: - # single gain case - return s0_low - if ch == '3a': - g_low, g_high = 0.25, 1.75 - else: - g_low, g_high = 0.5, 1.5 - - # Note: the PATMOS-x coefficients are rounded to three decimals. - def diff(s0): return s0_low - round(s0*g_low, 3) + s0_high - round(s0*g_high, 3) - - s0_l = s0_low / g_low - s0_h = s0_high / g_high - if diff(s0_l) == 0: - s0 = s0_l - elif diff(s0_h) == 0: - s0 = s0_h - else: - s0 = bisect(diff, s0_l, s0_h) - return s0 - - @staticmethod - def float2date(date_float): - """Convert date float to date. - - Argument - date_float (float) - date as year - - Return - date (datetime.datetime) - date - - Note - This is the reverse function of date2float. - """ - year = int(date_float) - days_in_year = (dt.datetime(year+1, 1, 1) - dt.datetime(year, 1, 1)).days - seconds = date_float*days_in_year*24*3600 - year*days_in_year*24*3600 - diff = dt.timedelta(seconds=seconds) - date = dt.datetime(year, 1, 1) + diff - return date - - def save(self, filepath): - """Save coefficients as PyGAC json file.""" - with open(filepath, mode='w') as json_file: - json.dump(self.coeffs, json_file, indent=4, sort_keys=True) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('tarball', type=str, help='path to PATMOS-x coefficients tarball') - parser.add_argument('-o', '--output', type=str, metavar="JSON", - help='path to PyGAC json file, defaults to tarball path with suffix ".json"') - parser.add_argument('-v', '--verbose', action='store_true', help='explain what is being done') - args = parser.parse_args() - if args.verbose: - loglevel = logging.INFO - else: - loglevel = logging.WARNING - logging.basicConfig(level=loglevel, format='[%(asctime)s] %(message)s') - tarball = pathlib.Path(args.tarball) - logging.info('Read PATMOS-x tarball "%s".', tarball) - patmosx_coeffs = PatmosxReader(tarball) - logging.info('Translate PATMOS-x coefficients to PyGAC format.') - pygac_coeffs = Translator(patmosx_coeffs) - output = args.output or tarball.with_suffix(".json") - logging.info('Write PyGAC calibration json file "%s".', output) - pygac_coeffs.save(output) - logging.info('Done!') diff --git a/continuous_integration/environment.yaml b/continuous_integration/environment.yaml deleted file mode 100644 index a34f4d4f..00000000 --- a/continuous_integration/environment.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: test-environment -channels: - - conda-forge -dependencies: - - numpy - - scipy - - bottleneck - - python-dateutil - - hdf5 - - h5py - - pytest - - pytest-cov - - pip - - pip: - - docutils - - pyorbital - - python-geotiepoints - - trollimage - - pyspectral - - pyorbital diff --git a/doc/source/usage.rst b/doc/source/usage.rst index 4aa25329..7d3fea49 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -32,4 +32,4 @@ will be processed. In Satpy ~~~~~~~~ It is also possible to use pygac as a library in Satpy, see this `example notebook -`_. +`_. diff --git a/pygac/_filter.c b/pygac/_filter.c new file mode 100644 index 00000000..3729730a --- /dev/null +++ b/pygac/_filter.c @@ -0,0 +1,6630 @@ +/* Generated by Cython 0.24 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [] + } +} +END: Cython Metadata */ + +#define PY_SSIZE_T_CLEAN +#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_24" +#include +#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 !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000 + #define CYTHON_USE_PYLONG_INTERNALS 1 +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #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 +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef 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) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) +#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])) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#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) +#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)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#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 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#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 +#if PY_VERSION_HEX >= 0x030500B1 +#define __Pyx_PyAsyncMethodsStruct PyAsyncMethods +#define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) +#elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 +typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; +} __Pyx_PyAsyncMethodsStruct; +#define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) +#else +#define __Pyx_PyType_AsAsync(obj) NULL +#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 +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) + +#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 + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif + + +#define __PYX_ERR(f_index, lineno, Ln_error) \ +{ \ + __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \ +} + +#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 + +#define __PYX_HAVE__pygac___filter +#define __PYX_HAVE_API__pygac___filter +#include "string.h" +#include "stdio.h" +#include "stdlib.h" +#include "numpy/arrayobject.h" +#include "numpy/ufuncobject.h" +#ifdef _OPENMP +#include +#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 +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +typedef struct {PyObject **p; const 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_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#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))) ) +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) && defined (_M_X64) + #define __Pyx_sst_abs(value) _abs64(value) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +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_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(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_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(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 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(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*) "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 PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + +/* None.proto */ +#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 + #else + #include + #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[] = { + "pygac/_filter.pyx", + "__init__.pxd", + "type.pxd", +}; +/* BufferFormatStructs.proto */ +#define IS_UNSIGNED(type) (((type) -1) > 0) +struct __Pyx_StructField_; +#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) +typedef struct { + const char* name; + struct __Pyx_StructField_* fields; + size_t size; + size_t arraysize[8]; + int ndim; + char typegroup; + char is_unsigned; + int flags; +} __Pyx_TypeInfo; +typedef struct __Pyx_StructField_ { + __Pyx_TypeInfo* type; + const char* name; + size_t offset; +} __Pyx_StructField; +typedef struct { + __Pyx_StructField* field; + size_t parent_offset; +} __Pyx_BufFmt_StackElem; +typedef struct { + __Pyx_StructField root; + __Pyx_BufFmt_StackElem* head; + size_t fmt_offset; + size_t new_count, enc_count; + size_t struct_alignment; + int is_complex; + char enc_type; + char new_packmode; + char enc_packmode; + char is_valid_array; +} __Pyx_BufFmt_Context; + + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":725 + * # 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":726 + * + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":727 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":728 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":732 + * #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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":733 + * + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":734 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":735 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":739 + * #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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":740 + * + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":749 + * # 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":750 + * # 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":751 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":753 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":754 + * + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulonglong_t + * + */ +typedef npy_ulonglong __pyx_t_5numpy_ulong_t; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":755 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":757 + * ctypedef npy_ulonglong ulonglong_t + * + * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< + * ctypedef npy_uintp uintp_t + * + */ +typedef npy_intp __pyx_t_5numpy_intp_t; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":758 + * + * ctypedef npy_intp intp_t + * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< + * + * ctypedef npy_double float_t + */ +typedef npy_uintp __pyx_t_5numpy_uintp_t; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":760 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":761 + * + * ctypedef npy_double float_t + * ctypedef npy_double double_t # <<<<<<<<<<<<<< + * ctypedef npy_longdouble longdouble_t + * + */ +typedef npy_double __pyx_t_5numpy_double_t; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":762 + * 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; + +/* "pygac/_filter.pyx":5 + * + * DTYPE = np.double + * ctypedef np.double_t DTYPE_T # <<<<<<<<<<<<<< + * + * def _mean_filter(np.ndarray[DTYPE_T, ndim=2] data, int box_size, + */ +typedef __pyx_t_5numpy_double_t __pyx_t_5pygac_7_filter_DTYPE_T; +/* None.proto */ +#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 + +/* None.proto */ +#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 ---*/ + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":764 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":765 + * + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< + * ctypedef npy_clongdouble clongdouble_t + * + */ +typedef npy_cdouble __pyx_t_5numpy_cdouble_t; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":766 + * 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; + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":768 + * ctypedef npy_clongdouble clongdouble_t + * + * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew1(a): + */ +typedef npy_cdouble __pyx_t_5numpy_complex_t; + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#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) + +/* PyObjectGetAttrStr.proto */ +#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 + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* RaiseArgTupleInvalid.proto */ +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); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* ArgTypeTest.proto */ +static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, + const char *name, int exact); + +/* BufferFormatCheck.proto */ +static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, + __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type); // PROTO + +/* GetModuleGlobalName.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); + +/* PyObjectCall.proto */ +#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 + +/* ExtTypeTest.proto */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); + +/* None.proto */ +static CYTHON_INLINE long __Pyx_div_long(long, long); + +/* BufferIndexError.proto */ +static void __Pyx_RaiseBufferIndexError(int axis); + +#define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1) +/* PyThreadStateGet.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = PyThreadState_GET(); +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* DictGetItem.proto */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +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 + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* RaiseNoneIterError.proto */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __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); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* BufferStructDeclare.proto */ +typedef struct { + Py_ssize_t shape, strides, suboffsets; +} __Pyx_Buf_DimInfo; +typedef struct { + size_t refcount; + Py_buffer pybuffer; +} __Pyx_Buffer; +typedef struct { + __Pyx_Buffer *rcbuffer; + char *data; + __Pyx_Buf_DimInfo diminfo[8]; +} __Pyx_LocalBuf_ND; + +#if PY_MAJOR_VERSION < 3 + static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); + static void __Pyx_ReleaseBuffer(Py_buffer *view); +#else + #define __Pyx_GetBuffer PyObject_GetBuffer + #define __Pyx_ReleaseBuffer PyBuffer_Release +#endif + + +/* None.proto */ +static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0}; +static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1}; + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* None.proto */ +#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(__cplusplus) && CYTHON_CCOMPLEX && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #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 + +/* None.proto */ +static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); + +/* None.proto */ +#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 + +/* None.proto */ +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + +/* None.proto */ +#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 + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* PyIdentifierFromString.proto */ +#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 + +/* ModuleImport.proto */ +static PyObject *__Pyx_ImportModule(const char *name); + +/* TypeImport.proto */ +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'cpython.buffer' */ + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'cpython' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from 'cpython.ref' */ + +/* 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 'pygac._filter' */ +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5pygac_7_filter_DTYPE_T = { "DTYPE_T", NULL, sizeof(__pyx_t_5pygac_7_filter_DTYPE_T), { 0 }, 0, 'R', 0, 0 }; +#define __Pyx_MODULE_NAME "pygac._filter" +int __pyx_module_is_main_pygac___filter = 0; + +/* Implementation of 'pygac._filter' */ +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_ValueError; +static PyObject *__pyx_builtin_RuntimeError; +static const char __pyx_k_np[] = "np"; +static const char __pyx_k_col[] = "col"; +static const char __pyx_k_row[] = "row"; +static const char __pyx_k_bcol[] = "bcol"; +static const char __pyx_k_brow[] = "brow"; +static const char __pyx_k_data[] = "data"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_ones[] = "ones"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_DTYPE[] = "DTYPE"; +static const char __pyx_k_dtype[] = "dtype"; +static const char __pyx_k_ncols[] = "ncols"; +static const char __pyx_k_nrows[] = "nrows"; +static const char __pyx_k_numpy[] = "numpy"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_double[] = "double"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_radius[] = "radius"; +static const char __pyx_k_box_size[] = "box_size"; +static const char __pyx_k_filtered[] = "filtered"; +static const char __pyx_k_num_valid[] = "num_valid"; +static const char __pyx_k_sum_valid[] = "sum_valid"; +static const char __pyx_k_ValueError[] = "ValueError"; +static const char __pyx_k_fill_value[] = "fill_value"; +static const char __pyx_k_mean_filter[] = "_mean_filter"; +static const char __pyx_k_RuntimeError[] = "RuntimeError"; +static const char __pyx_k_pygac__filter[] = "pygac._filter"; +static const char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; +static const char __pyx_k_home_sfinkens_code_pygac_pygac[] = "/home/sfinkens/code/pygac/pygac/_filter.pyx"; +static const char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; +static const char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; +static const char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; +static const char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous"; +static const char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; +static PyObject *__pyx_n_s_DTYPE; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; +static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; +static PyObject *__pyx_n_s_RuntimeError; +static PyObject *__pyx_n_s_ValueError; +static PyObject *__pyx_n_s_bcol; +static PyObject *__pyx_n_s_box_size; +static PyObject *__pyx_n_s_brow; +static PyObject *__pyx_n_s_col; +static PyObject *__pyx_n_s_data; +static PyObject *__pyx_n_s_double; +static PyObject *__pyx_n_s_dtype; +static PyObject *__pyx_n_s_fill_value; +static PyObject *__pyx_n_s_filtered; +static PyObject *__pyx_kp_s_home_sfinkens_code_pygac_pygac; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_mean_filter; +static PyObject *__pyx_n_s_ncols; +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_np; +static PyObject *__pyx_n_s_nrows; +static PyObject *__pyx_n_s_num_valid; +static PyObject *__pyx_n_s_numpy; +static PyObject *__pyx_n_s_ones; +static PyObject *__pyx_n_s_pygac__filter; +static PyObject *__pyx_n_s_radius; +static PyObject *__pyx_n_s_range; +static PyObject *__pyx_n_s_row; +static PyObject *__pyx_n_s_sum_valid; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; +static PyObject *__pyx_pf_5pygac_7_filter__mean_filter(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_data, int __pyx_v_box_size, __pyx_t_5pygac_7_filter_DTYPE_T __pyx_v_fill_value); /* 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_tuple_; +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__7; +static PyObject *__pyx_codeobj__8; + +/* "pygac/_filter.pyx":7 + * ctypedef np.double_t DTYPE_T + * + * def _mean_filter(np.ndarray[DTYPE_T, ndim=2] data, int box_size, # <<<<<<<<<<<<<< + * DTYPE_T fill_value): + * """Filter a 2D array using an arithmetic mean kernel. + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_5pygac_7_filter_1_mean_filter(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_5pygac_7_filter__mean_filter[] = "Filter a 2D array using an arithmetic mean kernel.\n\n Compute the arithmetic mean of the valid elements within a box of size\n (boxsize x boxsize) around each pixel. Fill values are not taken into\n account.\n\n Args:\n data (np.ndarray): 2D array to be filtered. Masked arrays are not\n supported, invalid data must be filled with fill_value.\n box_size (int): Specifies the box_size. Must be odd.\n fill_value: Value indicating missing data.\n\n Returns:\n np.ndarray: The filtered array\n "; +static PyMethodDef __pyx_mdef_5pygac_7_filter_1_mean_filter = {"_mean_filter", (PyCFunction)__pyx_pw_5pygac_7_filter_1_mean_filter, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5pygac_7_filter__mean_filter}; +static PyObject *__pyx_pw_5pygac_7_filter_1_mean_filter(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_data = 0; + int __pyx_v_box_size; + __pyx_t_5pygac_7_filter_DTYPE_T __pyx_v_fill_value; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_mean_filter (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_box_size,&__pyx_n_s_fill_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_data)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_box_size)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_mean_filter", 1, 3, 3, 1); __PYX_ERR(0, 7, __pyx_L3_error) + } + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fill_value)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_mean_filter", 1, 3, 3, 2); __PYX_ERR(0, 7, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_mean_filter") < 0)) __PYX_ERR(0, 7, __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_data = ((PyArrayObject *)values[0]); + __pyx_v_box_size = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_box_size == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 7, __pyx_L3_error) + __pyx_v_fill_value = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_fill_value == (npy_double)-1) && PyErr_Occurred())) __PYX_ERR(0, 8, __pyx_L3_error) + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_mean_filter", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 7, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("pygac._filter._mean_filter", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_data), __pyx_ptype_5numpy_ndarray, 1, "data", 0))) __PYX_ERR(0, 7, __pyx_L1_error) + __pyx_r = __pyx_pf_5pygac_7_filter__mean_filter(__pyx_self, __pyx_v_data, __pyx_v_box_size, __pyx_v_fill_value); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_5pygac_7_filter__mean_filter(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_data, int __pyx_v_box_size, __pyx_t_5pygac_7_filter_DTYPE_T __pyx_v_fill_value) { + int __pyx_v_nrows; + int __pyx_v_ncols; + int __pyx_v_row; + int __pyx_v_col; + int __pyx_v_brow; + int __pyx_v_bcol; + int __pyx_v_num_valid; + __pyx_t_5pygac_7_filter_DTYPE_T __pyx_v_sum_valid; + PyArrayObject *__pyx_v_filtered = 0; + int __pyx_v_radius; + __Pyx_LocalBuf_ND __pyx_pybuffernd_data; + __Pyx_Buffer __pyx_pybuffer_data; + __Pyx_LocalBuf_ND __pyx_pybuffernd_filtered; + __Pyx_Buffer __pyx_pybuffer_filtered; + 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; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyArrayObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + int __pyx_t_10; + int __pyx_t_11; + int __pyx_t_12; + long __pyx_t_13; + long __pyx_t_14; + long __pyx_t_15; + int __pyx_t_16; + long __pyx_t_17; + long __pyx_t_18; + Py_ssize_t __pyx_t_19; + Py_ssize_t __pyx_t_20; + int __pyx_t_21; + Py_ssize_t __pyx_t_22; + Py_ssize_t __pyx_t_23; + Py_ssize_t __pyx_t_24; + Py_ssize_t __pyx_t_25; + __Pyx_RefNannySetupContext("_mean_filter", 0); + __pyx_pybuffer_filtered.pybuffer.buf = NULL; + __pyx_pybuffer_filtered.refcount = 0; + __pyx_pybuffernd_filtered.data = NULL; + __pyx_pybuffernd_filtered.rcbuffer = &__pyx_pybuffer_filtered; + __pyx_pybuffer_data.pybuffer.buf = NULL; + __pyx_pybuffer_data.refcount = 0; + __pyx_pybuffernd_data.data = NULL; + __pyx_pybuffernd_data.rcbuffer = &__pyx_pybuffer_data; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_data.rcbuffer->pybuffer, (PyObject*)__pyx_v_data, &__Pyx_TypeInfo_nn___pyx_t_5pygac_7_filter_DTYPE_T, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 7, __pyx_L1_error) + } + __pyx_pybuffernd_data.diminfo[0].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_data.diminfo[0].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_data.diminfo[1].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_data.diminfo[1].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[1]; + + /* "pygac/_filter.pyx":24 + * np.ndarray: The filtered array + * """ + * assert data.dtype == DTYPE # <<<<<<<<<<<<<< + * + * cdef int nrows = data.shape[0] + */ + #ifndef CYTHON_WITHOUT_ASSERTIONS + if (unlikely(!Py_OptimizeFlag)) { + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_data), __pyx_n_s_dtype); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __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_ERR(0, 24, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_4)) { + PyErr_SetNone(PyExc_AssertionError); + __PYX_ERR(0, 24, __pyx_L1_error) + } + } + #endif + + /* "pygac/_filter.pyx":26 + * assert data.dtype == DTYPE + * + * cdef int nrows = data.shape[0] # <<<<<<<<<<<<<< + * cdef int ncols = data.shape[1] + * cdef int row, col, brow, bcol, num_valid + */ + __pyx_v_nrows = (__pyx_v_data->dimensions[0]); + + /* "pygac/_filter.pyx":27 + * + * cdef int nrows = data.shape[0] + * cdef int ncols = data.shape[1] # <<<<<<<<<<<<<< + * cdef int row, col, brow, bcol, num_valid + * cdef DTYPE_T sum_valid + */ + __pyx_v_ncols = (__pyx_v_data->dimensions[1]); + + /* "pygac/_filter.pyx":30 + * cdef int row, col, brow, bcol, num_valid + * cdef DTYPE_T sum_valid + * cdef np.ndarray[DTYPE_T, ndim=2] filtered = fill_value*np.ones( # <<<<<<<<<<<<<< + * (nrows, ncols), dtype=DTYPE) + * cdef int radius = box_size//2 + */ + __pyx_t_3 = PyFloat_FromDouble(__pyx_v_fill_value); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ones); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "pygac/_filter.pyx":31 + * cdef DTYPE_T sum_valid + * cdef np.ndarray[DTYPE_T, ndim=2] filtered = fill_value*np.ones( + * (nrows, ncols), dtype=DTYPE) # <<<<<<<<<<<<<< + * cdef int radius = box_size//2 + * + */ + __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_nrows); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_ncols); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5); + __pyx_t_2 = 0; + __pyx_t_5 = 0; + + /* "pygac/_filter.pyx":30 + * cdef int row, col, brow, bcol, num_valid + * cdef DTYPE_T sum_valid + * cdef np.ndarray[DTYPE_T, ndim=2] filtered = fill_value*np.ones( # <<<<<<<<<<<<<< + * (nrows, ncols), dtype=DTYPE) + * cdef int radius = box_size//2 + */ + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6); + __pyx_t_6 = 0; + + /* "pygac/_filter.pyx":31 + * cdef DTYPE_T sum_valid + * cdef np.ndarray[DTYPE_T, ndim=2] filtered = fill_value*np.ones( + * (nrows, ncols), dtype=DTYPE) # <<<<<<<<<<<<<< + * cdef int radius = box_size//2 + * + */ + __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_DTYPE); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_2) < 0) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "pygac/_filter.pyx":30 + * cdef int row, col, brow, bcol, num_valid + * cdef DTYPE_T sum_valid + * cdef np.ndarray[DTYPE_T, ndim=2] filtered = fill_value*np.ones( # <<<<<<<<<<<<<< + * (nrows, ncols), dtype=DTYPE) + * cdef int radius = box_size//2 + */ + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 30, __pyx_L1_error) + __pyx_t_7 = ((PyArrayObject *)__pyx_t_6); + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_filtered.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5pygac_7_filter_DTYPE_T, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) { + __pyx_v_filtered = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_filtered.rcbuffer->pybuffer.buf = NULL; + __PYX_ERR(0, 30, __pyx_L1_error) + } else {__pyx_pybuffernd_filtered.diminfo[0].strides = __pyx_pybuffernd_filtered.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_filtered.diminfo[0].shape = __pyx_pybuffernd_filtered.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_filtered.diminfo[1].strides = __pyx_pybuffernd_filtered.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_filtered.diminfo[1].shape = __pyx_pybuffernd_filtered.rcbuffer->pybuffer.shape[1]; + } + } + __pyx_t_7 = 0; + __pyx_v_filtered = ((PyArrayObject *)__pyx_t_6); + __pyx_t_6 = 0; + + /* "pygac/_filter.pyx":32 + * cdef np.ndarray[DTYPE_T, ndim=2] filtered = fill_value*np.ones( + * (nrows, ncols), dtype=DTYPE) + * cdef int radius = box_size//2 # <<<<<<<<<<<<<< + * + * for row in range(nrows): + */ + __pyx_v_radius = __Pyx_div_long(__pyx_v_box_size, 2); + + /* "pygac/_filter.pyx":34 + * cdef int radius = box_size//2 + * + * for row in range(nrows): # <<<<<<<<<<<<<< + * for col in range(ncols): + * # Reset values + */ + __pyx_t_8 = __pyx_v_nrows; + for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { + __pyx_v_row = __pyx_t_9; + + /* "pygac/_filter.pyx":35 + * + * for row in range(nrows): + * for col in range(ncols): # <<<<<<<<<<<<<< + * # Reset values + * sum_valid = 0. + */ + __pyx_t_10 = __pyx_v_ncols; + for (__pyx_t_11 = 0; __pyx_t_11 < __pyx_t_10; __pyx_t_11+=1) { + __pyx_v_col = __pyx_t_11; + + /* "pygac/_filter.pyx":37 + * for col in range(ncols): + * # Reset values + * sum_valid = 0. # <<<<<<<<<<<<<< + * num_valid = 0 + * + */ + __pyx_v_sum_valid = 0.; + + /* "pygac/_filter.pyx":38 + * # Reset values + * sum_valid = 0. + * num_valid = 0 # <<<<<<<<<<<<<< + * + * # Compute box mean + */ + __pyx_v_num_valid = 0; + + /* "pygac/_filter.pyx":42 + * # Compute box mean + * for brow in range(max(row-radius, 0), + * min(row+radius+1, nrows)): # <<<<<<<<<<<<<< + * for bcol in range(max(col-radius, 0), + * min(col+radius+1, ncols)): + */ + __pyx_t_12 = __pyx_v_nrows; + __pyx_t_13 = ((__pyx_v_row + __pyx_v_radius) + 1); + if (((__pyx_t_12 < __pyx_t_13) != 0)) { + __pyx_t_14 = __pyx_t_12; + } else { + __pyx_t_14 = __pyx_t_13; + } + __pyx_t_13 = __pyx_t_14; + + /* "pygac/_filter.pyx":41 + * + * # Compute box mean + * for brow in range(max(row-radius, 0), # <<<<<<<<<<<<<< + * min(row+radius+1, nrows)): + * for bcol in range(max(col-radius, 0), + */ + __pyx_t_14 = 0; + __pyx_t_12 = (__pyx_v_row - __pyx_v_radius); + if (((__pyx_t_14 > __pyx_t_12) != 0)) { + __pyx_t_15 = __pyx_t_14; + } else { + __pyx_t_15 = __pyx_t_12; + } + for (__pyx_t_12 = __pyx_t_15; __pyx_t_12 < __pyx_t_13; __pyx_t_12+=1) { + __pyx_v_brow = __pyx_t_12; + + /* "pygac/_filter.pyx":44 + * min(row+radius+1, nrows)): + * for bcol in range(max(col-radius, 0), + * min(col+radius+1, ncols)): # <<<<<<<<<<<<<< + * if data[brow, bcol] != fill_value: + * sum_valid += data[brow, bcol] + */ + __pyx_t_16 = __pyx_v_ncols; + __pyx_t_14 = ((__pyx_v_col + __pyx_v_radius) + 1); + if (((__pyx_t_16 < __pyx_t_14) != 0)) { + __pyx_t_17 = __pyx_t_16; + } else { + __pyx_t_17 = __pyx_t_14; + } + __pyx_t_14 = __pyx_t_17; + + /* "pygac/_filter.pyx":43 + * for brow in range(max(row-radius, 0), + * min(row+radius+1, nrows)): + * for bcol in range(max(col-radius, 0), # <<<<<<<<<<<<<< + * min(col+radius+1, ncols)): + * if data[brow, bcol] != fill_value: + */ + __pyx_t_17 = 0; + __pyx_t_16 = (__pyx_v_col - __pyx_v_radius); + if (((__pyx_t_17 > __pyx_t_16) != 0)) { + __pyx_t_18 = __pyx_t_17; + } else { + __pyx_t_18 = __pyx_t_16; + } + for (__pyx_t_16 = __pyx_t_18; __pyx_t_16 < __pyx_t_14; __pyx_t_16+=1) { + __pyx_v_bcol = __pyx_t_16; + + /* "pygac/_filter.pyx":45 + * for bcol in range(max(col-radius, 0), + * min(col+radius+1, ncols)): + * if data[brow, bcol] != fill_value: # <<<<<<<<<<<<<< + * sum_valid += data[brow, bcol] + * num_valid += 1 + */ + __pyx_t_19 = __pyx_v_brow; + __pyx_t_20 = __pyx_v_bcol; + __pyx_t_21 = -1; + if (__pyx_t_19 < 0) { + __pyx_t_19 += __pyx_pybuffernd_data.diminfo[0].shape; + if (unlikely(__pyx_t_19 < 0)) __pyx_t_21 = 0; + } else if (unlikely(__pyx_t_19 >= __pyx_pybuffernd_data.diminfo[0].shape)) __pyx_t_21 = 0; + if (__pyx_t_20 < 0) { + __pyx_t_20 += __pyx_pybuffernd_data.diminfo[1].shape; + if (unlikely(__pyx_t_20 < 0)) __pyx_t_21 = 1; + } else if (unlikely(__pyx_t_20 >= __pyx_pybuffernd_data.diminfo[1].shape)) __pyx_t_21 = 1; + if (unlikely(__pyx_t_21 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_21); + __PYX_ERR(0, 45, __pyx_L1_error) + } + __pyx_t_4 = (((*__Pyx_BufPtrStrided2d(__pyx_t_5pygac_7_filter_DTYPE_T *, __pyx_pybuffernd_data.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_data.diminfo[0].strides, __pyx_t_20, __pyx_pybuffernd_data.diminfo[1].strides)) != __pyx_v_fill_value) != 0); + if (__pyx_t_4) { + + /* "pygac/_filter.pyx":46 + * min(col+radius+1, ncols)): + * if data[brow, bcol] != fill_value: + * sum_valid += data[brow, bcol] # <<<<<<<<<<<<<< + * num_valid += 1 + * if num_valid > 0: + */ + __pyx_t_22 = __pyx_v_brow; + __pyx_t_23 = __pyx_v_bcol; + __pyx_t_21 = -1; + if (__pyx_t_22 < 0) { + __pyx_t_22 += __pyx_pybuffernd_data.diminfo[0].shape; + if (unlikely(__pyx_t_22 < 0)) __pyx_t_21 = 0; + } else if (unlikely(__pyx_t_22 >= __pyx_pybuffernd_data.diminfo[0].shape)) __pyx_t_21 = 0; + if (__pyx_t_23 < 0) { + __pyx_t_23 += __pyx_pybuffernd_data.diminfo[1].shape; + if (unlikely(__pyx_t_23 < 0)) __pyx_t_21 = 1; + } else if (unlikely(__pyx_t_23 >= __pyx_pybuffernd_data.diminfo[1].shape)) __pyx_t_21 = 1; + if (unlikely(__pyx_t_21 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_21); + __PYX_ERR(0, 46, __pyx_L1_error) + } + __pyx_v_sum_valid = (__pyx_v_sum_valid + (*__Pyx_BufPtrStrided2d(__pyx_t_5pygac_7_filter_DTYPE_T *, __pyx_pybuffernd_data.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_data.diminfo[0].strides, __pyx_t_23, __pyx_pybuffernd_data.diminfo[1].strides))); + + /* "pygac/_filter.pyx":47 + * if data[brow, bcol] != fill_value: + * sum_valid += data[brow, bcol] + * num_valid += 1 # <<<<<<<<<<<<<< + * if num_valid > 0: + * filtered[row, col] = sum_valid/float(num_valid) + */ + __pyx_v_num_valid = (__pyx_v_num_valid + 1); + + /* "pygac/_filter.pyx":45 + * for bcol in range(max(col-radius, 0), + * min(col+radius+1, ncols)): + * if data[brow, bcol] != fill_value: # <<<<<<<<<<<<<< + * sum_valid += data[brow, bcol] + * num_valid += 1 + */ + } + } + } + + /* "pygac/_filter.pyx":48 + * sum_valid += data[brow, bcol] + * num_valid += 1 + * if num_valid > 0: # <<<<<<<<<<<<<< + * filtered[row, col] = sum_valid/float(num_valid) + * + */ + __pyx_t_4 = ((__pyx_v_num_valid > 0) != 0); + if (__pyx_t_4) { + + /* "pygac/_filter.pyx":49 + * num_valid += 1 + * if num_valid > 0: + * filtered[row, col] = sum_valid/float(num_valid) # <<<<<<<<<<<<<< + * + * return filtered + */ + if (unlikely(((double)__pyx_v_num_valid) == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 49, __pyx_L1_error) + } + __pyx_t_24 = __pyx_v_row; + __pyx_t_25 = __pyx_v_col; + __pyx_t_12 = -1; + if (__pyx_t_24 < 0) { + __pyx_t_24 += __pyx_pybuffernd_filtered.diminfo[0].shape; + if (unlikely(__pyx_t_24 < 0)) __pyx_t_12 = 0; + } else if (unlikely(__pyx_t_24 >= __pyx_pybuffernd_filtered.diminfo[0].shape)) __pyx_t_12 = 0; + if (__pyx_t_25 < 0) { + __pyx_t_25 += __pyx_pybuffernd_filtered.diminfo[1].shape; + if (unlikely(__pyx_t_25 < 0)) __pyx_t_12 = 1; + } else if (unlikely(__pyx_t_25 >= __pyx_pybuffernd_filtered.diminfo[1].shape)) __pyx_t_12 = 1; + if (unlikely(__pyx_t_12 != -1)) { + __Pyx_RaiseBufferIndexError(__pyx_t_12); + __PYX_ERR(0, 49, __pyx_L1_error) + } + *__Pyx_BufPtrStrided2d(__pyx_t_5pygac_7_filter_DTYPE_T *, __pyx_pybuffernd_filtered.rcbuffer->pybuffer.buf, __pyx_t_24, __pyx_pybuffernd_filtered.diminfo[0].strides, __pyx_t_25, __pyx_pybuffernd_filtered.diminfo[1].strides) = (__pyx_v_sum_valid / ((double)__pyx_v_num_valid)); + + /* "pygac/_filter.pyx":48 + * sum_valid += data[brow, bcol] + * num_valid += 1 + * if num_valid > 0: # <<<<<<<<<<<<<< + * filtered[row, col] = sum_valid/float(num_valid) + * + */ + } + } + } + + /* "pygac/_filter.pyx":51 + * filtered[row, col] = sum_valid/float(num_valid) + * + * return filtered # <<<<<<<<<<<<<< + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_filtered)); + __pyx_r = ((PyObject *)__pyx_v_filtered); + goto __pyx_L0; + + /* "pygac/_filter.pyx":7 + * ctypedef np.double_t DTYPE_T + * + * def _mean_filter(np.ndarray[DTYPE_T, ndim=2] data, int box_size, # <<<<<<<<<<<<<< + * DTYPE_T fill_value): + * """Filter a 2D array using an arithmetic mean kernel. + */ + + /* 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_5); + __Pyx_XDECREF(__pyx_t_6); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_data.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_filtered.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("pygac._filter._mean_filter", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_data.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_filtered.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XDECREF((PyObject *)__pyx_v_filtered); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":197 + * # 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; + __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); + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":203 + * # 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; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":206 + * + * cdef int copy_shape, i, ndim + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + */ + __pyx_v_endian_detector = 1; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":207 + * cdef int copy_shape, i, ndim + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * + * ndim = PyArray_NDIM(self) + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":209 + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211 + * 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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":212 + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * copy_shape = 1 # <<<<<<<<<<<<<< + * else: + * copy_shape = 0 + */ + __pyx_v_copy_shape = 1; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":211 + * ndim = PyArray_NDIM(self) + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * copy_shape = 1 + * else: + */ + goto __pyx_L4; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":214 + * copy_shape = 1 + * else: + * copy_shape = 0 # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + */ + /*else*/ { + __pyx_v_copy_shape = 0; + } + __pyx_L4:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":216 + * 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; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":217 + * + * 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:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":216 + * 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") + */ + if (__pyx_t_1) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218 + * 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_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 218, __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_ERR(1, 218, __pyx_L1_error) + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":216 + * 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") + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":220 + * 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; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":221 + * + * 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:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":220 + * 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") + */ + if (__pyx_t_1) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222 + * 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__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 222, __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_ERR(1, 222, __pyx_L1_error) + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":220 + * 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") + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":224 + * 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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":225 + * + * 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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226 + * 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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":229 + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + * info.strides = stdlib.malloc(sizeof(Py_ssize_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))); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":230 + * # This is allocated as one block, strides first. + * info.strides = stdlib.malloc(sizeof(Py_ssize_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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":231 + * info.strides = stdlib.malloc(sizeof(Py_ssize_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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":232 + * 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]); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":233 + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< + * else: + * info.strides = PyArray_STRIDES(self) + */ + (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":226 + * 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. + */ + goto __pyx_L11; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":235 + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + */ + /*else*/ { + __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":236 + * else: + * info.strides = PyArray_STRIDES(self) + * info.shape = 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:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":237 + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL # <<<<<<<<<<<<<< + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) + */ + __pyx_v_info->suboffsets = NULL; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":238 + * info.shape = 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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":239 + * 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)); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":242 + * + * cdef int t + * cdef char* f = NULL # <<<<<<<<<<<<<< + * cdef dtype descr = self.descr + * cdef int offset + */ + __pyx_v_f = NULL; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":243 + * cdef int t + * cdef char* f = NULL + * cdef dtype descr = self.descr # <<<<<<<<<<<<<< + * 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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":246 + * cdef int offset + * + * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<< + * + * if not hasfields and not copy_shape: + */ + __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248 + * 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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":250 + * 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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":248 + * cdef bint hasfields = PyDataType_HASFIELDS(descr) + * + * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< + * # do not call releasebuffer + * info.obj = None + */ + goto __pyx_L14; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":253 + * else: + * # need to call releasebuffer + * info.obj = self # <<<<<<<<<<<<<< + * + * if not hasfields: + */ + /*else*/ { + __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:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255 + * 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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":256 + * + * 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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257 + * 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:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":258 + * 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:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257 + * 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") + */ + if (__pyx_t_1) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259 + * 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__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 259, __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_ERR(1, 259, __pyx_L1_error) + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":257 + * 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") + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":260 + * (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" + */ + switch (__pyx_v_t) { + case NPY_BYTE: + __pyx_v_f = ((char *)"b"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":261 + * 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 = ((char *)"B"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":262 + * 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 = ((char *)"h"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":263 + * 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 = ((char *)"H"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":264 + * 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 = ((char *)"i"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":265 + * 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 = ((char *)"I"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":266 + * 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 = ((char *)"l"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":267 + * 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 = ((char *)"L"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":268 + * 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 = ((char *)"q"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":269 + * 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 = ((char *)"Q"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":270 + * 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 = ((char *)"f"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":271 + * 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 = ((char *)"d"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":272 + * 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 = ((char *)"g"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":273 + * 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 = ((char *)"Zf"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":274 + * 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 = ((char *)"Zd"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":275 + * 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 = ((char *)"Zg"); + break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":276 + * 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 = ((char *)"O"); + break; + default: + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":278 + * 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_ERR(1, 278, __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_ERR(1, 278, __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_ERR(1, 278, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 0, __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_ERR(1, 278, __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_ERR(1, 278, __pyx_L1_error) + break; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":279 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f # <<<<<<<<<<<<<< + * return + * else: + */ + __pyx_v_info->format = __pyx_v_f; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":280 + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f + * return # <<<<<<<<<<<<<< + * else: + * info.format = stdlib.malloc(_buffer_format_string_len) + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":255 + * info.obj = self + * + * if not hasfields: # <<<<<<<<<<<<<< + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":282 + * return + * else: + * info.format = stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + */ + /*else*/ { + __pyx_v_info->format = ((char *)malloc(0xFF)); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":283 + * else: + * info.format = 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]) = '^'; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":284 + * info.format = 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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":285 + * 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 + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) __PYX_ERR(1, 285, __pyx_L1_error) + __pyx_v_f = __pyx_t_7; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":288 + * 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'; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":197 + * # 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; +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290 + * 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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291 + * + * 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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":292 + * 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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":291 + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< + * stdlib.free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":293 + * 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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":294 + * 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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":293 + * 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 + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":290 + * 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(); +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":770 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, 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; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":771 + * + * cdef inline object PyArray_MultiIterNew1(a): + * return PyArray_MultiIterNew(1, 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_ERR(1, 771, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":770 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, 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; +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":773 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, 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; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":774 + * + * cdef inline object PyArray_MultiIterNew2(a, b): + * return PyArray_MultiIterNew(2, a, 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_ERR(1, 774, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":773 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, 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; +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":776 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, 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; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":777 + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + * return PyArray_MultiIterNew(3, a, b, 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_ERR(1, 777, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":776 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, 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; +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":779 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, 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; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":780 + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + * return PyArray_MultiIterNew(4, a, b, c, 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_ERR(1, 780, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":779 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, 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; +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":782 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, 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; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":783 + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + * return PyArray_MultiIterNew(5, a, b, c, d, 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_ERR(1, 783, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":782 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, 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; +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":785 + * return PyArray_MultiIterNew(5, a, b, c, d, 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; + __Pyx_RefNannySetupContext("_util_dtypestring", 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":790 + * + * cdef dtype child + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * cdef tuple fields + */ + __pyx_v_endian_detector = 1; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":791 + * cdef dtype child + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * cdef tuple fields + * + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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_ERR(1, 794, __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_ERR(1, 794, __pyx_L1_error) + #else + __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 794, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":795 + * + * for childname in descr.names: + * fields = descr.fields[childname] # <<<<<<<<<<<<<< + * child, new_offset = fields + * + */ + if (unlikely(__pyx_v_descr->fields == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 795, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 795, __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_ERR(1, 795, __pyx_L1_error) + __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":796 + * for childname in descr.names: + * fields = descr.fields[childname] + * child, new_offset = fields # <<<<<<<<<<<<<< + * + * if (end - f) - (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_ERR(1, 796, __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_ERR(1, 796, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 796, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 796, __pyx_L1_error) + } + if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) __PYX_ERR(1, 796, __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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798 + * child, new_offset = fields + * + * if (end - f) - (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_ERR(1, 798, __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_ERR(1, 798, __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_ERR(1, 798, __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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799 + * + * if (end - f) - (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__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 799, __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_ERR(1, 799, __pyx_L1_error) + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":798 + * child, new_offset = fields + * + * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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") + */ + if (__pyx_t_6) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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__5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 803, __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_ERR(1, 803, __pyx_L1_error) + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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") + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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_ERR(1, 813, __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_ERR(1, 813, __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_ERR(1, 813, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (!__pyx_t_6) break; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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]) = 0x78; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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); + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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_ERR(1, 821, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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__6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 823, __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_ERR(1, 823, __pyx_L1_error) + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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.") + * + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 826, __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_ERR(1, 826, __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_ERR(1, 826, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 98; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 827, __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_ERR(1, 827, __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_ERR(1, 827, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 66; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 828, __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_ERR(1, 828, __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_ERR(1, 828, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x68; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 829, __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_ERR(1, 829, __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_ERR(1, 829, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 72; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 830, __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_ERR(1, 830, __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_ERR(1, 830, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x69; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 831, __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_ERR(1, 831, __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_ERR(1, 831, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 73; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 832, __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_ERR(1, 832, __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_ERR(1, 832, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x6C; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 833, __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_ERR(1, 833, __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_ERR(1, 833, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 76; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 834, __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_ERR(1, 834, __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_ERR(1, 834, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x71; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 835, __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_ERR(1, 835, __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_ERR(1, 835, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 81; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 836, __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_ERR(1, 836, __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_ERR(1, 836, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x66; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 837, __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_ERR(1, 837, __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_ERR(1, 837, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x64; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 838, __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_ERR(1, 838, __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_ERR(1, 838, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x67; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 839, __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_ERR(1, 839, __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_ERR(1, 839, __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]) = 0x66; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 840, __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_ERR(1, 840, __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_ERR(1, 840, __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]) = 0x64; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 841, __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_ERR(1, 841, __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_ERR(1, 841, __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]) = 0x67; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 842, __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_ERR(1, 842, __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_ERR(1, 842, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 79; + goto __pyx_L15; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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: + */ + /*else*/ { + __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 844, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 844, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_4, 0, __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_ERR(1, 844, __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_ERR(1, 844, __pyx_L1_error) + } + __pyx_L15:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":820 + * offset[0] += child.itemsize + * + * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< + * t = child.type_num + * if end - f < 5: + */ + goto __pyx_L13; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 + * + */ + /*else*/ { + __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_ERR(1, 849, __pyx_L1_error) + __pyx_v_f = __pyx_t_9; + } + __pyx_L13:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":785 + * return PyArray_MultiIterNew(5, a, b, c, d, 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; +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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: + */ + goto __pyx_L3; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":971 + * baseptr = NULL + * else: + * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<< + * baseptr = base + * Py_XDECREF(arr.base) + */ + /*else*/ { + Py_INCREF(__pyx_v_base); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":972 + * else: + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base # <<<<<<<<<<<<<< + * Py_XDECREF(arr.base) + * arr.base = baseptr + */ + __pyx_v_baseptr = ((PyObject *)__pyx_v_base); + } + __pyx_L3:; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":973 + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base + * Py_XDECREF(arr.base) # <<<<<<<<<<<<<< + * arr.base = baseptr + * + */ + Py_XDECREF(__pyx_v_arr->base); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":974 + * baseptr = base + * Py_XDECREF(arr.base) + * arr.base = baseptr # <<<<<<<<<<<<<< + * + * cdef inline object get_array_base(ndarray arr): + */ + __pyx_v_arr->base = __pyx_v_baseptr; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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(); +} + +/* "../../../../data/sfinkens/usr/lib64/python2.7/site-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); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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) { + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":978 + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: + * return None # <<<<<<<<<<<<<< + * else: + * return arr.base + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_None); + __pyx_r = Py_None; + goto __pyx_L0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":977 + * + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: # <<<<<<<<<<<<<< + * return None + * else: + */ + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":980 + * return None + * else: + * return arr.base # <<<<<<<<<<<<<< + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_arr->base)); + __pyx_r = ((PyObject *)__pyx_v_arr->base); + goto __pyx_L0; + } + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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 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 + "_filter", + 0, /* 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_n_s_DTYPE, __pyx_k_DTYPE, sizeof(__pyx_k_DTYPE), 0, 0, 1, 1}, + {&__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_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_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_n_s_bcol, __pyx_k_bcol, sizeof(__pyx_k_bcol), 0, 0, 1, 1}, + {&__pyx_n_s_box_size, __pyx_k_box_size, sizeof(__pyx_k_box_size), 0, 0, 1, 1}, + {&__pyx_n_s_brow, __pyx_k_brow, sizeof(__pyx_k_brow), 0, 0, 1, 1}, + {&__pyx_n_s_col, __pyx_k_col, sizeof(__pyx_k_col), 0, 0, 1, 1}, + {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 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_fill_value, __pyx_k_fill_value, sizeof(__pyx_k_fill_value), 0, 0, 1, 1}, + {&__pyx_n_s_filtered, __pyx_k_filtered, sizeof(__pyx_k_filtered), 0, 0, 1, 1}, + {&__pyx_kp_s_home_sfinkens_code_pygac_pygac, __pyx_k_home_sfinkens_code_pygac_pygac, sizeof(__pyx_k_home_sfinkens_code_pygac_pygac), 0, 0, 1, 0}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_mean_filter, __pyx_k_mean_filter, sizeof(__pyx_k_mean_filter), 0, 0, 1, 1}, + {&__pyx_n_s_ncols, __pyx_k_ncols, sizeof(__pyx_k_ncols), 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_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, + {&__pyx_n_s_nrows, __pyx_k_nrows, sizeof(__pyx_k_nrows), 0, 0, 1, 1}, + {&__pyx_n_s_num_valid, __pyx_k_num_valid, sizeof(__pyx_k_num_valid), 0, 0, 1, 1}, + {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, + {&__pyx_n_s_ones, __pyx_k_ones, sizeof(__pyx_k_ones), 0, 0, 1, 1}, + {&__pyx_n_s_pygac__filter, __pyx_k_pygac__filter, sizeof(__pyx_k_pygac__filter), 0, 0, 1, 1}, + {&__pyx_n_s_radius, __pyx_k_radius, sizeof(__pyx_k_radius), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_row, __pyx_k_row, sizeof(__pyx_k_row), 0, 0, 1, 1}, + {&__pyx_n_s_sum_valid, __pyx_k_sum_valid, sizeof(__pyx_k_sum_valid), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 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}, + {0, 0, 0, 0, 0, 0, 0} +}; +static int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 34, __pyx_L1_error) + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 218, __pyx_L1_error) + __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(1, 799, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":218 + * 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_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 218, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":222 + * 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__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 222, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":259 + * 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__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 259, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__3); + __Pyx_GIVEREF(__pyx_tuple__3); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd":799 + * + * if (end - f) - (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__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 799, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 803, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 823, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + + /* "pygac/_filter.pyx":7 + * ctypedef np.double_t DTYPE_T + * + * def _mean_filter(np.ndarray[DTYPE_T, ndim=2] data, int box_size, # <<<<<<<<<<<<<< + * DTYPE_T fill_value): + * """Filter a 2D array using an arithmetic mean kernel. + */ + __pyx_tuple__7 = PyTuple_Pack(13, __pyx_n_s_data, __pyx_n_s_box_size, __pyx_n_s_fill_value, __pyx_n_s_nrows, __pyx_n_s_ncols, __pyx_n_s_row, __pyx_n_s_col, __pyx_n_s_brow, __pyx_n_s_bcol, __pyx_n_s_num_valid, __pyx_n_s_sum_valid, __pyx_n_s_filtered, __pyx_n_s_radius); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(3, 0, 13, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__7, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_sfinkens_code_pygac_pygac, __pyx_n_s_mean_filter, 7, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) __PYX_ERR(0, 7, __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_ERR(0, 1, __pyx_L1_error); + return 0; + __pyx_L1_error:; + return -1; +} + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC init_filter(void); /*proto*/ +PyMODINIT_FUNC init_filter(void) +#else +PyMODINIT_FUNC PyInit__filter(void); /*proto*/ +PyMODINIT_FUNC PyInit__filter(void) +#endif +{ + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + __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__filter(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __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("_filter", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_COMPILING_IN_PYPY + Py_INCREF(__pyx_b); + #endif + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __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_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_pygac___filter) { + if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "pygac._filter")) { + if (unlikely(PyDict_SetItemString(modules, "pygac._filter", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global init code ---*/ + /*--- Variable export code ---*/ + /*--- Function export code ---*/ + /*--- Type init code ---*/ + /*--- 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_ERR(2, 9, __pyx_L1_error) + __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) __PYX_ERR(1, 155, __pyx_L1_error) + __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) __PYX_ERR(1, 168, __pyx_L1_error) + __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) __PYX_ERR(1, 172, __pyx_L1_error) + __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) __PYX_ERR(1, 181, __pyx_L1_error) + __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) __PYX_ERR(1, 861, __pyx_L1_error) + /*--- Variable import code ---*/ + /*--- Function import code ---*/ + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "pygac/_filter.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "pygac/_filter.pyx":4 + * cimport numpy as np + * + * DTYPE = np.double # <<<<<<<<<<<<<< + * ctypedef np.double_t DTYPE_T + * + */ + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_double); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (PyDict_SetItem(__pyx_d, __pyx_n_s_DTYPE, __pyx_t_2) < 0) __PYX_ERR(0, 4, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "pygac/_filter.pyx":7 + * ctypedef np.double_t DTYPE_T + * + * def _mean_filter(np.ndarray[DTYPE_T, ndim=2] data, int box_size, # <<<<<<<<<<<<<< + * DTYPE_T fill_value): + * """Filter a 2D array using an arithmetic mean kernel. + */ + __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_5pygac_7_filter_1_mean_filter, NULL, __pyx_n_s_pygac__filter); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_mean_filter, __pyx_t_2) < 0) __PYX_ERR(0, 7, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "pygac/_filter.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * + */ + __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "../../../../data/sfinkens/usr/lib64/python2.7/site-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); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init pygac._filter", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_DECREF(__pyx_m); __pyx_m = 0; + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init pygac._filter"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if PY_MAJOR_VERSION < 3 + return; + #else + return __pyx_m; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#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 + +/* GetBuiltinName */ +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; +} + +/* RaiseArgTupleInvalid */ +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); +} + +/* RaiseDoubleKeywords */ +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 +} + +/* ParseKeywords */ +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; +} + +/* ArgTypeTest */ +static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) { + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", + name, type->tp_name, Py_TYPE(obj)->tp_name); +} +static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, + const char *name, int exact) +{ + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (none_allowed && obj == Py_None) return 1; + else if (exact) { + if (likely(Py_TYPE(obj) == type)) return 1; + #if PY_MAJOR_VERSION == 2 + else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(PyObject_TypeCheck(obj, type))) return 1; + } + __Pyx_RaiseArgumentTypeInvalid(name, obj, type); + return 0; +} + +/* BufferFormatCheck */ +static CYTHON_INLINE int __Pyx_IsLittleEndian(void) { + unsigned int n = 1; + return *(unsigned char*)(&n) != 0; +} +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->new_packmode = '@'; + ctx->enc_packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + ctx->is_valid_array = 0; + ctx->struct_alignment = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } +} +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t < '9') { + count *= 10; + count += *t++ - '0'; + } + } + *ts = t; + return count; +} +static int __Pyx_BufFmt_ExpectNumber(const char **ts) { + int number = __Pyx_BufFmt_ParseNumber(ts); + if (number == -1) + PyErr_Format(PyExc_ValueError,\ + "Does not understand character buffer dtype format string ('%c')", **ts); + return number; +} +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + PyErr_Format(PyExc_ValueError, + "Unexpected format string character: '%c'", ch); +} +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case 'c': return "'char'"; + case 'b': return "'signed char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); + case 'T': return "a struct"; + case 'O': return "Python object"; + case 'P': return "a pointer"; + case 's': case 'p': return "a string"; + case 0: return "end"; + default: return "unparseable format string"; + } +} +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; + } + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +/* These are for computing the padding at the end of the struct to align + on the first member of the struct. This will probably the same as above, + but we don't have any guarantees. + */ +typedef struct { short x; char c; } __Pyx_pad_short; +typedef struct { int x; char c; } __Pyx_pad_int; +typedef struct { long x; char c; } __Pyx_pad_long; +typedef struct { float x; char c; } __Pyx_pad_float; +typedef struct { double x; char c; } __Pyx_pad_double; +typedef struct { long double x; char c; } __Pyx_pad_longdouble; +typedef struct { void *x; char c; } __Pyx_pad_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); + case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); + case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': + return 'H'; + case 'b': case 'h': case 'i': + case 'l': case 'q': case 's': case 'p': + return 'I'; + case 'B': case 'H': case 'I': case 'L': case 'Q': + return 'U'; + case 'f': case 'd': case 'g': + return (is_complex ? 'C' : 'R'); + case 'O': + return 'O'; + case 'P': + return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; + } else { + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } +} +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset, arraysize = 1; + if (ctx->enc_type == 0) return 0; + if (ctx->head->field->type->arraysize[0]) { + int i, ndim = 0; + if (ctx->enc_type == 's' || ctx->enc_type == 'p') { + ctx->is_valid_array = ctx->head->field->type->ndim == 1; + ndim = 1; + if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %zu", + ctx->head->field->type->arraysize[0], ctx->enc_count); + return -1; + } + } + if (!ctx->is_valid_array) { + PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", + ctx->head->field->type->ndim, ndim); + return -1; + } + for (i = 0; i < ctx->head->field->type->ndim; i++) { + arraysize *= ctx->head->field->type->arraysize[i]; + } + ctx->is_valid_array = 0; + ctx->enc_count = 1; + } + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->enc_packmode == '@') { + size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + size_t align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + if (ctx->struct_alignment == 0) + ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, + ctx->is_complex); + } + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + if ((type->typegroup == 'H' || group == 'H') && type->size == size) { + } else { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + } + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", + (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); + return -1; + } + ctx->fmt_offset += size; + if (arraysize) + ctx->fmt_offset += (arraysize - 1) * size; + --ctx->enc_count; + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + break; + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } + } + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; +} +static CYTHON_INLINE PyObject * +__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) +{ + const char *ts = *tsp; + int i = 0, number; + int ndim = ctx->head->field->type->ndim; +; + ++ts; + if (ctx->new_count != 1) { + PyErr_SetString(PyExc_ValueError, + "Cannot handle repeated arrays in format string"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + while (*ts && *ts != ')') { + switch (*ts) { + case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; + default: break; + } + number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) + return PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %d", + ctx->head->field->type->arraysize[i], number); + if (*ts != ',' && *ts != ')') + return PyErr_Format(PyExc_ValueError, + "Expected a comma in format string, got '%c'", *ts); + if (*ts == ',') ts++; + i++; + } + if (i != ndim) + return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", + ctx->head->field->type->ndim, i); + if (!*ts) { + PyErr_SetString(PyExc_ValueError, + "Unexpected end of format string, expected ')'"); + return NULL; + } + ctx->is_valid_array = 1; + ctx->new_count = 1; + *tsp = ++ts; + return Py_None; +} +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case '\r': + case '\n': + ++ts; + break; + case '<': + if (!__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + ctx->new_packmode = *ts++; + break; + case 'T': + { + const char* ts_after_sub; + size_t i, struct_count = ctx->new_count; + size_t struct_alignment = ctx->struct_alignment; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + ctx->enc_count = 0; + ctx->struct_alignment = 0; + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + if (struct_alignment) ctx->struct_alignment = struct_alignment; + } + break; + case '}': + { + size_t alignment = ctx->struct_alignment; + ++ts; + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + if (alignment && ctx->fmt_offset % alignment) { + ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); + } + } + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->enc_packmode = ctx->new_packmode; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } + case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': case 'p': + if (ctx->enc_type == *ts && got_Z == ctx->is_complex && + ctx->enc_packmode == ctx->new_packmode) { + ctx->enc_count += ctx->new_count; + ctx->new_count = 1; + got_Z = 0; + ++ts; + break; + } + case 's': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_packmode = ctx->new_packmode; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + case ':': + ++ts; + while(*ts != ':') ++ts; + ++ts; + break; + case '(': + if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; + break; + default: + { + int number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + ctx->new_count = (size_t)number; + } + } + } +} +static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; +} +static CYTHON_INLINE int __Pyx_GetBufferAndValidate( + Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, + int nd, int cast, __Pyx_BufFmt_StackElem* stack) +{ + if (obj == Py_None || obj == NULL) { + __Pyx_ZeroBuffer(buf); + return 0; + } + buf->buf = NULL; + if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail; + if (buf->ndim != nd) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if ((unsigned)buf->itemsize != dtype->size) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_ZeroBuffer(buf); + return -1; +} +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { + if (info->buf == NULL) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); +} + +/* GetModuleGlobalName */ + 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; +} + +/* PyObjectCall */ + #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 + +/* ExtTypeTest */ + 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; +} + +/* None */ + static CYTHON_INLINE long __Pyx_div_long(long a, long b) { + long q = a / b; + long r = a - q*b; + q -= ((r != 0) & ((r ^ b) < 0)); + return q; +} + +/* BufferIndexError */ + static void __Pyx_RaiseBufferIndexError(int axis) { + PyErr_Format(PyExc_IndexError, + "Out of bounds on buffer access (axis %d)", axis); +} + +/* PyErrFetchRestore */ + #if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + 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); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* RaiseException */ + #if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + 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_PyThreadState_assign + __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) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + 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 + +/* RaiseTooManyValuesToUnpack */ + 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); +} + +/* RaiseNeedMoreValuesToUnpack */ + 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"); +} + +/* RaiseNoneIterError */ + static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +/* Import */ + 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; +} + +/* CodeObjectCache */ + 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 - start) / 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); +} + +/* AddTraceback */ + #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); +} + +#if PY_MAJOR_VERSION < 3 +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); + if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags); + PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); + return -1; +} +static void __Pyx_ReleaseBuffer(Py_buffer *view) { + PyObject *obj = view->obj; + if (!obj) return; + if (PyObject_CheckBuffer(obj)) { + PyBuffer_Release(view); + return; + } + if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; } + Py_DECREF(obj); + view->obj = NULL; +} +#endif + + + /* CIntFromPyVerify */ + #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + 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 (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) -1, const_zero = (int) 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 PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_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); + } +} + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) -1, const_zero = (long) 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 PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_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); + } +} + +/* None */ + #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 + +/* None */ + #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 + +/* None */ + #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 + +/* None */ + #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 + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) { + const enum NPY_TYPES neg_one = (enum NPY_TYPES) -1, const_zero = (enum NPY_TYPES) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(enum NPY_TYPES) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); + } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); + } + } else { + if (sizeof(enum NPY_TYPES) <= sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES), + little, !is_unsigned); + } +} + +/* CIntFromPy */ + static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) -1, const_zero = (int) 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_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_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_IntOrLong(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_IntOrLong(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; +} + +/* CIntFromPy */ + static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) -1, const_zero = (long) 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_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_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_IntOrLong(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_IntOrLong(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; +} + +/* CheckBinaryVersion */ + 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; +} + +/* ModuleImport */ + #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 + +/* TypeImport */ + #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. Expected %zd, got %zd", + module_name, class_name, basicsize, size); + 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. Expected %zd, got %zd", + module_name, class_name, basicsize, size); + goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(py_module); + Py_XDECREF(result); + return NULL; +} +#endif + +/* InitStrings */ + 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 CYTHON_COMPILING_IN_CPYTHON && (__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) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + 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_IntOrLong(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 __Pyx_NewRef(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))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(x); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #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/pygac/_filter.pyx b/pygac/_filter.pyx new file mode 100644 index 00000000..f626dd18 --- /dev/null +++ b/pygac/_filter.pyx @@ -0,0 +1,51 @@ +import numpy as np +cimport numpy as np + +DTYPE = np.double +ctypedef np.double_t DTYPE_T + +def _mean_filter(np.ndarray[DTYPE_T, ndim=2] data, int box_size, + DTYPE_T fill_value): + """Filter a 2D array using an arithmetic mean kernel. + + Compute the arithmetic mean of the valid elements within a box of size + (boxsize x boxsize) around each pixel. Fill values are not taken into + account. + + Args: + data (np.ndarray): 2D array to be filtered. Masked arrays are not + supported, invalid data must be filled with fill_value. + box_size (int): Specifies the box_size. Must be odd. + fill_value: Value indicating missing data. + + Returns: + np.ndarray: The filtered array + """ + assert data.dtype == DTYPE + + cdef int nrows = data.shape[0] + cdef int ncols = data.shape[1] + cdef int row, col, brow, bcol, num_valid + cdef DTYPE_T sum_valid + cdef np.ndarray[DTYPE_T, ndim=2] filtered = fill_value*np.ones( + (nrows, ncols), dtype=DTYPE) + cdef int radius = box_size//2 + + for row in range(nrows): + for col in range(ncols): + # Reset values + sum_valid = 0. + num_valid = 0 + + # Compute box mean + for brow in range(max(row-radius, 0), + min(row+radius+1, nrows)): + for bcol in range(max(col-radius, 0), + min(col+radius+1, ncols)): + if data[brow, bcol] != fill_value: + sum_valid += data[brow, bcol] + num_valid += 1 + if num_valid > 0: + filtered[row, col] = sum_valid/float(num_valid) + + return filtered diff --git a/pygac/calibration.py b/pygac/calibration.py index 5755b97f..1d1d18b2 100644 --- a/pygac/calibration.py +++ b/pygac/calibration.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- # Copyright (c) 2014-2015, 2019 Pytroll Developers @@ -6,7 +7,6 @@ # Martin Raspaud # Abhay Devasthale -# Carlos Horn # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -24,412 +24,480 @@ """Calibration coefficients and generic calibration functions """ from __future__ import division -from enum import Enum -import sys -import logging import numpy as np -import json -import hashlib -import warnings -import datetime as dt -from collections import namedtuple -from pkg_resources import resource_filename +coeffs = { + 'metopb': {'ah': np.array([0.166, 0.183, 0.201]), + 'al': np.array([0.055, 0.061, 0.029]), + 'bh': np.array([2.019, 1.476, 1.748]), + 'bl': np.array([2.019, 1.476, 1.748]), + 'ch': np.array([-0.201, -0.137, -0.033]), + 'cl': np.array([-0.201, -0.137, -0.033]), + 'c_dark': np.array([39.70, 40.00, 40.30]), + 'c_s': np.array([501.12, 500.82, 501.32]), + 'l_date': 2012.77, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.6194, 0.050919, 1.471E-06, 0.0, 0.0], + [276.6511, 0.050892, 1.489E-06, 0.0, 0.0], + [276.6597, 0.050845, 1.521E-06, 0.0, 0.0], + [276.3685, 0.050992, 1.482E-06, 0.0, 0.0]]), + 'n_s': np.array([0.0, -4.98, -3.40]), + 'c_wn': np.array([2664.3384, 933.71521, 839.72764]), + 'a': np.array([1.7711318, 0.51860807, 0.40059787]), + 'b': np.array([1.0 / 1.0029931, + 1.0 / 1.0013778, + 1.0 / 1.0011702]), + 'b0': np.array([0.0, 5.44, 3.84]), + 'b1': np.array([1 - 0.0, 1 - 0.10152, 1 - 0.06249]), + 'b2': np.array([0.0, 0.00046964, 0.00025239]), + }, + 'metopa': {'ah': np.array([0.169, 0.199, 0.213]), + 'al': np.array([0.056, 0.066, 0.030]), + 'bh': np.array([0.609, 0.980, -0.016]), + 'bl': np.array([0.609, 0.980, -0.016]), + 'ch': np.array([-0.029, -0.016, -0.033]), + 'cl': np.array([-0.029, -0.016, -0.033]), + 'c_dark': np.array([40.43, 39.75, 41.8]), + 'c_s': np.array([501.0, 500.0, 502.0]), + 'l_date': 2006.7995, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.6194, 0.050919, 1.471E-06, 0.0, 0.0], + [276.6511, 0.050892, 1.489E-06, 0.0, 0.0], + [276.6597, 0.050845, 1.521E-06, 0.0, 0.0], + [276.3685, 0.050992, 1.482E-06, 0.0, 0.0]]), + 'n_s': np.array([0.0, -4.98, -3.40]), + 'c_wn': np.array([2687.0392, 927.27630, 837.80762]), + 'a': np.array([2.0653147, 0.56503332, 0.38472766]), + 'b': np.array([1.0 / 1.0034418, + 1.0 / 1.0015090, + 1.0 / 1.0011264]), + 'b0': np.array([0.0, 5.44, 3.84]), + 'b1': np.array([1 - 0.0, 1 - 0.10152, 1 - 0.06249]), + 'b2': np.array([0.0, 0.00046964, 0.00025239]), + }, + 'tirosn': {'ah': np.array([0.115, 0.133, 0.1]), + 'al': np.array([0.115, 0.133, 0.1]), + 'bh': np.array([5.110, 0.717, 0.0]), + 'bl': np.array([5.110, 0.717, 0.0]), + 'ch': np.array([0.0, 0.0, 0.0]), + 'cl': np.array([0.0, 0.0, 0.0]), + 'c_dark': np.array([39.44, 39.40, 37.51]), + 'l_date': 1978.783, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [277.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0]]), + 'n_s': np.array([-0.0039, -8.130, -8.130]), + 'c_wn': np.array([2655.7409, 913.0537, 913.0537]), + 'a': np.array([1.6485446, 0.53135445, 0.53135445]), + 'b': np.array([1.0 / 1.0020894, + 1.0 / 1.0014343, + 1.0 / 1.0014343]), + 'b1': np.array([1.0 - 0.015, 1.0 - 0.131942, 1.0 - 0.131942]), + 'b2': np.array([0.011, 0.000673193, 0.000673193]), + 'b0': np.array([0.00195, 6.13, 6.13]), + }, + 'noaa6': {'ah': np.array([0.133, 0.128, 0.10]), + 'al': np.array([0.133, 0.128, 0.10]), + 'bh': np.array([0.900, 0.699, 0.0]), + 'bl': np.array([0.900, 0.699, 0.0]), + 'ch': np.array([0.0, 0.0, 0.0]), + 'cl': np.array([0.0, 0.0, 0.0]), + 'c_dark': np.array([39.44, 39.40, 37.51]), + 'l_date': 1979.490, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [277.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0]]), + 'n_s': np.array([0.0, -3.26, -3.26]), + 'c_wn': np.array([2671.5433, 913.46088, 913.46088]), + 'a': np.array([1.76671100, 0.50395970, 0.50395970]), + 'b': np.array([1.0 / 1.0024428, + 1.0 / 1.0013592, + 1.0 / 1.0013592]), + 'b1': np.array([1.0, 1.0 - 0.03964, 1.0 - 0.03964]), + 'b2': np.array([0.0, 0.00016925, 0.00016925]), + 'b0': np.array([0.0, 2.24, 2.24]), + }, + 'noaa7': {'ah': np.array([0.115, 0.127, 0.10]), + 'al': np.array([0.115, 0.127, 0.10]), + 'bh': np.array([3.792, 2.685, 0.0]), + 'bl': np.array([3.972, 2.685, 0.0]), + 'ch': np.array([-0.269, -0.101, 0.0]), + 'cl': np.array([-0.269, -0.101, 0.0]), + 'c_dark': np.array([36.0, 37.0, 39.0]), + 'l_date': 1981.4764, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [277.099, 5.048E-2, 2.823E-6, 0, 0], + [276.734, 5.069E-2, 2.493E-6, 0, 0], + [276.876, 5.148E-2, 1.040E-6, 0, 0], + [276.160, 5.128E-2, 1.414E-6, 0, 0]]), + 'n_s': np.array([0.0, -5.16, -4.28]), + 'c_wn': np.array([2684.5233, 928.23757, 841.52137]), + 'a': np.array([1.94882690, 0.52807997, 0.40557027]), + 'b': np.array([1.0 / 1.0029260, + 1.0 / 1.0014039, + 1.0 / 1.0011789]), + 'b1': np.array([1.0, 0.89783, 0.93683]), + 'b2': np.array([0.0, 0.0004819, 0.0002425]), + 'b0': np.array([0.0, 5.25, 3.93]), + }, + 'noaa8': {'ah': np.array([0.119, 0.136, 0.10]), + 'al': np.array([0.119, 0.136, 0.10]), + 'bh': np.array([6.065, 7.248, 0.0]), + 'bl': np.array([6.065, 7.248, 0.0]), + 'ch': np.array([0.0, 0.0, 0.0]), + 'cl': np.array([0.0, 0.0, 0.0]), + 'c_dark': np.array([39.44, 39.40, 37.51]), + 'l_date': 1983.241, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0]]), + 'n_s': np.array([0.0, -3.26, -3.26]), + 'c_wn': np.array([2651.3776, 915.30330, 915.30330]), + 'a': np.array([1.76641050, 0.50017997, 0.50017997]), + 'b': np.array([1.0 / 1.0024260, + 1.0 / 1.0013460, + 1.0 / 1.0013460]), + 'b1': np.array([1.0, 1.0 - 0.03964, 1.0 - 0.03964]), + 'b2': np.array([0.0, 0.00016925, 0.00016925]), + 'b0': np.array([0.0, 2.24, 2.24]), + }, + 'noaa9': {'ah': np.array([0.108, 0.122, 0.10]), + 'al': np.array([0.108, 0.122, 0.10]), + 'bh': np.array([4.255, 0.310, 0.0]), + 'bl': np.array([4.255, 0.310, 0.0]), + 'ch': np.array([0.640, 0.642, 0.0]), + 'cl': np.array([0.640, 0.642, 0.0]), + 'c_dark': np.array([38.0, 40.0, 38.0]), + 'l_date': 1984.9480, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [277.018000, 0.051280, 0.0, 0, 0], + [276.750000, 0.051280, 0.0, 0, 0], + [276.862000, 0.051280, 0.0, 0, 0], + [276.546000, 0.051280, 0.0, 0, 0]]), + + 'n_s': np.array([0.0, -5.530, -3.06]), + 'c_wn': np.array([2690.0451, 930.50230, 845.75000]), + 'a': np.array([1.8832662, 0.5115335, 0.3882150]), + 'b': np.array([1.0 / 1.0028978, + 1.0 / 1.0013570, + 1.0 / 1.0011210]), + 'b1': np.array([1.0, 0.88643, 0.95311]), + 'b2': np.array([0.0, 0.0006033, 0.0002198]), + 'b0': np.array([0.0, 5.24, 2.42]), + }, + 'noaa10': {'ah': np.array([0.111, 0.137, 0.10]), + 'al': np.array([0.111, 0.137, 0.10]), + 'bh': np.array([6.087, 0.119, 0.0]), + 'bl': np.array([6.087, 0.119, 0.0]), + 'ch': np.array([-1.039, 0.123, 0.0]), + 'cl': np.array([-1.039, 0.123, 0.0]), + 'c_dark': np.array([39.44, 39.40, 37.51]), + 'l_date': 1986.712, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0], + [276.659, 0.051275, 1.363e-06, 0, 0]]), + 'n_s': np.array([0.0, -7.27, -7.29]), + 'c_wn': np.array([2672.6164, 910.49626, 910.49626]), + 'a': np.array([1.7986926, 0.45707063, 0.45707063]), + 'b': np.array([1.0 / 1.0026326, + 1.0 / 1.0012272, + 1.0 / 1.0012272]), + 'b1': np.array([1.0, 1.0 - 0.1157, 1.0 - 0.1157]), + 'b2': np.array([0.0, 0.0005885, 0.0005882]), + 'b0': np.array([0.0, 5.76, 5.76]), + }, + 'noaa11': {'ah': np.array([0.110, 0.118, 0.0]), + 'al': np.array([0.110, 0.118, 0.0]), + 'bh': np.array([0.632, -0.037, 0.0]), + 'bl': np.array([0.632, -0.037, 0.0]), + 'ch': np.array([-0.044, 0.072, 0.0]), + 'cl': np.array([-0.044, 0.072, 0.0]), + 'c_dark': np.array([40.0, 40.0, 40.0]), + 'l_date': 1988.7310, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0]]), + 'n_s': np.array([0.0, -8.055, -3.51]), + 'c_wn': np.array([2680.05, 927.462, 840.746]), + 'a': np.array([1.738973, 0.321199, 0.048652]), + 'b': np.array([1.0 / 1.003354, + 1.0 / 1.001213, + 1.0 / 1.000664]), + 'b1': np.array([1.0, 0.84120, 0.94598]), + 'b2': np.array([0.0, 0.0008739, 0.0002504]), + 'b0': np.array([0.0, 7.21, 2.92]), + }, + 'noaa12': {'ah': np.array([0.121, 0.148, 0.10]), + 'al': np.array([0.121, 0.148, 0.10]), + 'bh': np.array([2.032, 1.323, 0.0]), + 'bl': np.array([2.032, 1.323, 0.0]), + 'ch': np.array([-0.032, -0.008, 0.0]), + 'cl': np.array([-0.032, -0.008, 0.0]), + 'c_dark': np.array([41.0, 40.0, 40.0]), + 'l_date': 1991.3669, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0]]), + 'n_s': np.array([0.0, -5.510, -2.51]), + 'c_wn': np.array([2651.7708, 922.36261, 838.02678]), + 'a': np.array([1.90527390, 0.63404209, 0.41086587]), + 'b': np.array([1.0 / 1.0030100, + 1.0 / 1.0017076, + 1.0 / 1.0012010]), + 'b1': np.array([1.0, 0.88929, 0.96299]), + 'b2': np.array([0.0, 0.0005968, 0.0001775]), + 'b0': np.array([0.0, 5.11, 1.91]), + }, + 'noaa14': {'ah': np.array([0.121, 0.152, 0.10]), + 'al': np.array([0.121, 0.152, 0.10]), + 'bh': np.array([3.555, 0.254, 0.0]), + 'bl': np.array([3.555, 0.254, 0.0]), + 'ch': np.array([-0.339, 0.201, 0.0]), + 'cl': np.array([-0.339, 0.201, 0.0]), + 'c_dark': np.array([41.0, 41.0, 39.0]), + 'l_date': 1994.9966, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0], + [276.597, 0.051275, 1.363e-06, 0, 0]]), + 'n_s': np.array([0.0069, -4.05, -2.29]), + 'c_wn': np.array([2654.25, 928.349, 833.040]), + 'a': np.array([1.885330, 0.308384, 0.022171]), + 'b': np.array([1.0 / 1.003839, 1.0 / 1.001443, 1.0 / 1.000538]), + 'b1': np.array([1.00359, 0.92378, 0.96194]), + 'b2': np.array([0.0, 0.0003822, 0.0001742]), + 'b0': np.array([-0.0031, 3.72, 2.00]), + }, + 'noaa15': {'ah': np.array([0.179, 0.206, 0.175]), + 'al': np.array([0.060, 0.069, 0.025]), + 'bh': np.array([-0.069, 0.339, 0.0]), + 'bl': np.array([-0.069, 0.339, 0.0]), + 'ch': np.array([0.002, -0.010, 0.0]), + 'cl': np.array([0.002, -0.010, 0.0]), + 'c_dark': np.array([39.0, 40.0, 39.0]), + 'c_s': np.array([500.0, 500.0, 500.0]), + 'l_date': 1998.3641, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.60157, 0.051045, 1.36328E-06, 0.0, 0.0], + [276.62531, 0.050909, 1.47266E-06, 0.0, 0.0], + [276.67413, 0.050907, 1.47656E-06, 0.0, 0.0], + [276.59258, 0.050966, 1.47656E-06, 0.0, 0.0]]), + 'n_s': np.array([0.0, -4.50, -3.61]), + 'c_wn': np.array([2695.9743, 925.4075, 839.8979]), + 'a': np.array([1.624481, 0.338243, 0.304856]), + 'b': np.array([1.0 / 1.001989, + 1.0 / 1.001283, + 1.0 / 1.000977]), + 'b0': np.array([0.0, 4.76, 3.83]), + 'b1': np.array([1 - 0.0, 1 - 0.0932, 1 - 0.0659]), + 'b2': np.array([0.0, 0.0004524, 0.0002811]), + }, + 'noaa16': {'ah': np.array([0.165, 0.179, 0.187]), + 'al': np.array([0.055, 0.060, 0.027]), + 'bh': np.array([0.839, 0.786, 0.290]), + 'bl': np.array([0.839, 0.786, 0.290]), + 'ch': np.array([-0.051, -0.031, -0.294]), + 'cl': np.array([-0.051, -0.031, -0.294]), + 'c_dark': np.array([39.3, 38.9, 38.4]), + 'c_s': np.array([498.96, 500.17, 499.43]), + 'l_date': 2000.7228, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.355, 5.562E-02, -1.590E-05, + 2.486E-08, -1.199E-11], + [276.142, 5.605E-02, -1.707E-05, + 2.595E-08, -1.224E-11], + [275.996, 5.486E-02, -1.223E-05, + 1.862E-08, -0.853E-11], + [276.132, 5.494E-02, -1.344E-05, + 2.112E-08, -1.001E-11]]), + 'n_s': np.array([0.0, -2.467, -2.009]), + 'c_wn': np.array([2681.2540, 922.34790, 834.61814]), + 'a': np.array([1.6774586, 0.55636216, 0.41430789]), + 'b': np.array([1.0 / 1.0017316, + 1.0 / 1.0014921, + 1.0 / 1.0012166]), + 'b0': np.array([0.0, 2.96, 2.25]), + 'b1': np.array([1 - 0.0, 1 - 0.05411, 1 - 0.03665]), + 'b2': np.array([0.0, 0.00024532, 0.00014854]), + }, + 'noaa17': {'ah': np.array([0.172, 0.210, 0.209]), + 'al': np.array([0.057, 0.070, 0.030]), + 'bh': np.array([1.007, 1.474, 2.787]), + 'bl': np.array([1.007, 1.474, 2.787]), + 'ch': np.array([-0.044, -0.118, -0.292]), + 'cl': np.array([-0.044, -0.118, -0.292]), + 'c_dark': np.array([39.99, 39.09, 42.09]), + 'c_s': np.array([501.12, 500.73, 501.37]), + 'l_date': 2002.47912, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.628, 0.05098, 1.371E-06, 0.0, 0.0], + [276.538, 0.05098, 1.371E-06, 0.0, 0.0], + [276.761, 0.05097, 1.369E-06, 0.0, 0.0], + [276.660, 0.05100, 1.348E-06, 0.0, 0.0]]), + 'n_s': np.array([0.0, -8.55, -3.97]), + 'c_wn': np.array([2669.1414, 928.29959, 840.20289]), + 'a': np.array([1.70002941, 0.56634758, 0.37264803]), + 'b': np.array([1.0 / 1.0026724, + 1.0 / 1.0015205, + 1.0 / 1.0010841]), + 'b0': np.array([0.0, 8.22, 4.31]), + 'b1': np.array([1 - 0.0, 1 - 0.15795, 1 - 0.07318]), + 'b2': np.array([0.0, 0.00075579, 0.00030976]), + }, + 'noaa18': {'ah': np.array([0.171, 0.192, 0.175]), + 'al': np.array([0.057, 0.064, 0.025]), + 'bh': np.array([0.603, 0.632, 0.0]), + 'bl': np.array([0.603, 0.632, 0.0]), + 'ch': np.array([0.0, 0.045, 0.0]), + 'cl': np.array([0.0, 0.045, 0.0]), + 'c_dark': np.array([39.44, 39.40, 37.51]), + 'c_s': np.array([500.54, 500.40, 500.56]), + 'l_date': 2005.3833, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.601, 0.05090, 1.657E-06, 0.0, 0.0], + [276.683, 0.05101, 1.482E-06, 0.0, 0.0], + [276.565, 0.05117, 1.313E-06, 0.0, 0.0], + [276.615, 0.05103, 1.484E-06, 0.0, 0.0]]), + 'n_s': np.array([0.0, -5.53, -2.22]), + 'c_wn': np.array([2660.6468, 928.73452, 834.08306]), + 'a': np.array([1.7222650, 0.54696239, 0.39938376]), + 'b': np.array([1.0 / 1.0028633, + 1.0 / 1.0014581, + 1.0 / 1.0011724]), + 'b0': np.array([0.0, 5.82, 2.67]), + 'b1': np.array([1 - 0.0, 1 - 0.11069, 1 - 0.04360]), + 'b2': np.array([0.0, 0.00052337, 0.00017715]), + }, + 'noaa19': {'ah': np.array([0.162, 0.183, 0.175]), + 'al': np.array([0.054, 0.061, 0.025]), + 'bh': np.array([0.626, 0.950, 0.0]), + 'bl': np.array([0.626, 0.950, 0.0]), + 'ch': np.array([-0.044, -0.039, 0.0]), + 'cl': np.array([-0.044, -0.039, 0.0]), + 'c_dark': np.array([38.8, 39.00, 39.4]), + 'c_s': np.array([496.43, 500.37, 496.11]), + 'l_date': 2009.096, + 'd': np.array([[0, 0, 0, 0, 0], # reset prt + [276.6067, 0.051111, 1.405783e-06, 0, 0], + [276.6119, 0.051090, 1.496037e-06, 0, 0], + [276.6311, 0.051033, 1.496990e-06, 0, 0], + [276.6268, 0.051058, 1.493110e-06, 0, 0]]), + 'n_s': np.array([0.0, -5.49, -3.39]), + 'c_wn': np.array([2670.2425, 927.92374, 831.28619]), + 'a': np.array([1.6863857, 0.39419031, 0.26364620]), + 'b': np.array([1.0 / 1.0025955, + 1.0 / 1.0013299, + 1.0 / 1.0009546]), + 'b0': np.array([0.0, 5.70, 3.58]), + 'b1': np.array([1 - 0.0, 1 - 0.11187, 1 - 0.05991]), + 'b2': np.array([0.0, 0.00054668, 0.00024985])}} + +"""Source Patmos-X Coeffs: Version Tag 'y2017r1_sbaf' +https://cimss.ssec.wisc.edu/patmosx/avhrr_cal.html""" -LOG = logging.getLogger(__name__) +class Calibrator(object): -class CoeffStatus(Enum): - """Indicates the status of calibration coefficients.""" - NOMINAL = 'nominal' - PROVISIONAL = 'provisional' - EXPERIMENTAL = 'experimental' + def __init__(self, spacecraft): + self.ah = None + self.al = None + self.bh = None + self.bl = None + self.ch = None + self.cl = None + self.c_s = None + self.c_dark = None + self.l_date = None + self.d = None + self.n_s = None + self.c_wn = None + self.a = None + self.b = None + self.b0 = None + self.b1 = None + self.b2 = None + self.__dict__.update(coeffs[spacecraft]) + + +def calibrate_solar(counts, chan, year, jday, spacecraft, corr=1): + """Do the solar calibration and return reflectance (between 0 and 100).""" + cal = Calibrator(spacecraft) + + t = (year + jday / 365.0) - cal.l_date + stl = (cal.al[chan] * (100.0 + cal.bl[chan] * t + + cal.cl[chan] * t * t)) / 100.0 + sth = (cal.ah[chan] * (100.0 + cal.bh[chan] * t + + cal.ch[chan] * t * t)) / 100.0 + if cal.c_s is not None: + refl = np.where(counts <= cal.c_s[chan], + (counts - cal.c_dark[chan]) * stl * corr, + ((cal.c_s[chan] - cal.c_dark[chan]) * stl + + (counts - cal.c_s[chan]) * sth) * corr) + else: + refl = (counts - cal.c_dark[chan]) * stl * corr + # Mask negative reflectances + refl[refl < 0] = np.nan + + return refl + + +def calibrate_thermal(counts, prt, ict, space, line_numbers, channel, spacecraft): + """Do the thermal calibration and return brightness temperatures (K).""" + cal = Calibrator(spacecraft) -class Calibrator(object): - """Factory class to create namedtuples holding the calibration coefficients. - - Attributes: - fields: coefficient names - Calibrator: namedtuple constructor - default_coeffs: dictonary containing default values for all spacecrafts - """ - version_hashs = { - '963af9b66268475ed500ad7b37da33c5': { - 'name': 'PATMOS-x, v2017r1', - 'status': CoeffStatus.NOMINAL - }, - '87ae8f270e63d17178b0e764c5869f4f': { - 'name': 'PATMOS-x, v2017r1, with provisional coefficients for MetOp-C', - 'status': CoeffStatus.PROVISIONAL - } - } - fields = [ - "dark_count", "gain_switch", "s0", "s1", "s2", "b", # "b0", "b1", "b2", - "centroid_wavenumber", "space_radiance", "to_eff_blackbody_intercept", - "to_eff_blackbody_slope", "date_of_launch", "d", "spacecraft", "version" - ] - - Calibrator = namedtuple('Calibrator', fields) - default_coeffs = None - default_file = None - default_version = None - - def __new__(cls, spacecraft, custom_coeffs=None, coeffs_file=None): - """Creates a namedtuple for calibration coefficients of a given spacecraft - - Args: - spacecraft (str): spacecraft name in pygac convention - custom_coeffs (dict): custom coefficients (optional) - coeffs_file (str): path to coefficents file (optional) - - Returns: - calibrator (namedtuple): calibration coefficients - - Note: - The coefficients in coeffs_file serve as default values if no custom_coeffs - are given. If omitted, Calibrator uses the PyGAC internal defaults. - """ - if cls.default_coeffs is None or cls.default_file != coeffs_file: - cls.default_file = coeffs_file - cls.default_coeffs, cls.default_version = cls.read_coeffs(coeffs_file) - if custom_coeffs: - LOG.info('Using following custom coefficients "%s".', custom_coeffs) - customs = custom_coeffs or {} - defaults = cls.default_coeffs[spacecraft] - coeffs = defaults.copy() - coeffs.update(customs) - - # transpose the coefficient order from channel - coeff to coeff - channel - # and store as arrays for vectorized calls of calibration functions - arraycoeffs = dict.fromkeys(cls.fields) - # visible channels - for key in ("dark_count", "gain_switch", "s0", "s1", "s2"): - arraycoeffs[key] = np.array([ - coeffs[channel][key] - for channel in ('channel_1', 'channel_2', 'channel_3a') - ], dtype=float) - # thermal channels - for key in ("centroid_wavenumber", "space_radiance", - "to_eff_blackbody_intercept", "to_eff_blackbody_slope"): - arraycoeffs[key] = np.array([ - coeffs[channel][key] - for channel in ('channel_3b', 'channel_4', 'channel_5') - ], dtype=float) - arraycoeffs["b"] = np.array([ - [ - coeffs[channel][key] - for key in ("b0", "b1", "b2") - ] - for channel in ('channel_3b', 'channel_4', 'channel_5') - ], dtype=float) - # thermometers - # Note, that "thermometer_0" does not exists, and is filled with zeros to - # account for the PRT reset every fifth scanline - arraycoeffs["d"] = np.array([ - [ - coeffs.get("thermometer_{0}".format(t), {}).get("d{0}".format(d), 0.0) - for t in range(5) - ] - for d in range(5) - ], dtype=float) - # parse date of launch - date_of_launch_str = coeffs["date_of_launch"].replace('Z', '+00:00') - if sys.version_info < (3, 7): - # Note that here any time information is lost - import dateutil.parser - date_of_launch = dateutil.parser.parse(date_of_launch_str) - else: - # datetime.fromisoformat() was introduced in Python-3.7 - date_of_launch = dt.datetime.fromisoformat( - date_of_launch_str).astimezone(dt.timezone.utc) - # remove time zone information (easier to handle in calculations) - arraycoeffs["date_of_launch"] = date_of_launch.replace(tzinfo=None) - arraycoeffs["spacecraft"] = spacecraft - arraycoeffs["version"] = cls.default_version - if custom_coeffs: - arraycoeffs["version"] = None - # create namedtuple - calibrator = cls.Calibrator(**arraycoeffs) - return calibrator - - @classmethod - def read_coeffs(cls, coeffs_file): - """Read calibration coefficients for all satellites from file. - Argument - coeffs_file (str): path to coefficients file - Returns - coeffs (dict): dictionary containing coefficients for all satellites - version (str): version of the coefficients (None if unknown) - """ - if coeffs_file: - LOG.info('Read calibration coefficients from "%s"', coeffs_file) - else: - LOG.debug("Read PyGAC internal calibration coefficients.") - coeffs_file = resource_filename('pygac', 'data/calibration.json') - with open(coeffs_file, mode='rb') as json_file: - content = json_file.read() - coeffs = json.loads(content) - version = cls._get_coeffs_version(content) - return coeffs, version - - @classmethod - def _get_coeffs_version(cls, coeff_file_content): - """Determine coefficient version.""" - md5_hash = hashlib.md5(coeff_file_content) - digest = md5_hash.hexdigest() - version_dict = cls.version_hashs.get( - digest, - {'name': None, 'status': None} - ) - version = version_dict['name'] - status = version_dict['status'] - if version is None: - warning = "Unknown calibration coefficients version!" - warnings.warn(warning, RuntimeWarning) - LOG.warning(warning) - else: - LOG.info('Identified calibration coefficients version "%s".', - version) - if status != CoeffStatus.NOMINAL: - warning = 'Using {} calibration coefficients'.format(status) - warnings.warn(warning, RuntimeWarning) - LOG.warning(warning) - return version - - @staticmethod - def date2float(date, decimals=5): - """Convert date to year float. - - Argument - date (datetime.datetime) - date - decimals (int or None) - rounding precision if None, do not round (default=5) - - Return - date_float (float) - date as year - - Note - rounding to the 5th decimal reproduces the original float values from patmos-x - - Example: - date2float('2000-07-02') == 2000.5 - because the 2nd of July was the middle day of the leap year 2000 - """ - year = date.year - days_in_year = (dt.datetime(year+1, 1, 1) - dt.datetime(year, 1, 1)).days - diff = date - dt.datetime(year, 1, 1) - seconds = diff.total_seconds() - date_float = date.year + seconds/(days_in_year*24*3600) - if decimals is not None: - date_float = round(date_float, decimals) - return date_float - - -def calibrate_solar(counts, chan, year, jday, cal, corr=1): - """Do the solar calibration and return scaled radiance. - - Arguments: - counts (array) - raw counts for the given channels (options 1, 2[, 3A if available & active]) - chan (array) - pygac internal channel index array - year (int) - year - jday (int) - day of year - cal (namedtuple) - spacecraft specific calibration coefficients, see Calibrator - - Optional: - corr (float) - depricated - reflectance correction multiplier (default = 1) - - Returns: - r_cal (array) - scaled radiance - - Note: - This function and documentation follows the time-dependent solar calibration as described in: - Heidinger, A.K., W.C. Straka III, C.C. Molling, J.T. Sullivan, and X. Wu, (2010). - "Deriving an inter-sensor consistent calibration for the AVHRR solar reflectance data record.", - International Journal of Remote Sensing, 31:6493 - 6517. - """ - # Step 1. Obtain the calibration slope using equation (6) in Heidinger et al 2010 - # S(t) = S_0*(100 + S_1*t + S_2*t^2) / 100, - # where t is the time since launch expressed as years, S(t) is the calibration slope - # and S_0, S_1 and S_2 are the coefficients of the quadratic fit. - # See also section "Fitting of Calibration Slope Equations" in PATMOS-x documentation - # (CDRP-ATBD-0184 Rev. 2 03/29/2018 page 19) - - # Note that the this implementation does not take leap years into account! - # Using datetime objects would include it automatically - # sensing_date = dt.strptime('{0}.{1}'.format(year, jday), '%Y.%j') - # delta = sensing_date - cal.date_of_launch - # t = delta.total_seconds() / 31557600 # divided by seconds of a Julian year - l_date = Calibrator.date2float(cal.date_of_launch) - t = (year + jday / 365.0) - l_date - - # Note: splitting the calibration slope is needed to reproduce old results and may disappear in future, - # because actually there is only one set of slope parameters defined for single-gain counts - # as described in Heidinger et al. 2010. See Step 2 for more information. - # Note that in case of a single-gain instrument, all gain_switch parameters are set to NaN. - if np.isnan(cal.gain_switch).all(): - glow = ghigh = np.ones(3) - else: - glow = np.array([0.5, 0.5, 0.25]) - ghigh = np.array([1.5, 1.5, 1.75]) - # especially the rounding to three digits is crutial to exectly reproduce the original PATMOS-x values. - al, bl, cl = np.round(glow*cal.s0, 3), cal.s1, cal.s2 - ah, bh, ch = np.round(ghigh*cal.s0, 3), cal.s1, cal.s2 - - # apply slope equation for low and high gain coefficients - stl = (al[chan] * (100.0 + bl[chan] * t + cl[chan] * t * t)) / 100.0 - sth = (ah[chan] * (100.0 + bh[chan] * t + ch[chan] * t * t)) / 100.0 - - # Step 2. Calculate the scaled radiance using equation (1) in Heidinger et al 2010 - # R_cal = S*(C-D), - # where R_cal is the value generated from the calibration and is referred to as a - # scaled radiance, S is the calibration slope, C the measured count and D the dark count. - # This equation is only valid for single-gain instruments. Starting with the AVHRR/3 series - # (from NOAA-15 onwards), the channel-1, 2 and 3a require a dual-gain calibration. - # The conversion for channel-1 and 2 is given in the appendix, equation (A1) and (A2). - # In general, these equations can be written as - # C(C_dg) = D + G_low*(C_dg-D), if C_dg <= B_dg - # C(C_dg) = C(B_dg) + G_high*(C_dg-B_dg), otherwise - # where C_dg is the measured dual-gain counts, B_dg is the dual-gain switch and G_low/high - # are the gain factors for the low and high count region. - # Quote from the book "Remote Sensing Time Series: Revealing Land Surface Dynamics": - # > Another change in design of the AVHRR/3 instrument was the introduction of a dual-gain feature - # > for the reflective channels 1, 2 and 3A. In order to improve the radiometric resolution of the - # > instrument for low reflectance targets, the dynamic range of the instrument was divided equally - # > in two ranges, i.e. nominally from 0 to 500 counts and from 500 to 1,000 counts. For channels 1 - # > and 2 half of the available Digital Number (DN) range is assigned to the low albedo range from - # > 0 to 25% with the other half to the high albedo range from 26 to 100%. This allows for an increase - # > in the radiometric resolution for dark targets. For channel 3A, the split between low and high - # > albedo range is set at 12.5% albedo (Rao and Sullivan 2001). - # The gain factors are given by the ratio of the fraction of albedo range to the fraction of count range - # for the given count region. From the information given by the book quote, we get - # G_low = 25% / 50% = 0.5 for channel-1 and 2 - # G_low = 12.5% / 50% = 0.25 for channel-3a - # G_high = (100% - 25%) / (100% - 50%) = 1.5 for channel-1 and 2 - # G_high = (100% - 12.5%) / (100% - 50%) = 1.75 for channel-3a - # Inserting the converted dual-gain counts into equation (1) yields the scaled radiance equation, which - # is a continuous piecewise linear function of two line segments. - # R_cal - # ^ * R_cal = S*G_low*(C_dg-D), if C_dg <= B_dg - # | * R_cal = S*G_low*(B_dg-D) + S*G_high*(C_dg-B_dg), otherwise - # | * - # R_cal(B_dg)|--------* - # | * | - # 0 +--*-------------> C_dg - # * D B_dg - # Note, that in the former implementation, there was a distinction beteen low and high gain slopes - # given by S_low/high = S*G_low/high. which only affects S0 in equation (6) in Heidinger et al 2010. - # Furthermore, the implementation allows for an additional correction factor corr which defaults to 1. (depricated) - d = cal.dark_count[chan] - b_dg = cal.gain_switch[chan] - # Note that in case of a single-gain instrument, all gain_switch parameters are set to NaN. - if not np.isnan(cal.gain_switch).all(): - r_cal = np.where( - counts <= b_dg, - (counts - d)*stl, - (b_dg - d)*stl + (counts - b_dg)*sth - ) - else: - r_cal = stl*(counts - d) - # apply depricated correction - if corr != 1: - warnings.warn( - "Using the 'corr' argument is depricated in favor of making the units" - " of the function result clear. Please make any unit conversion outside this function.", - DeprecationWarning - ) - r_cal *= corr - - # Mask negative scaled radiances - r_cal[r_cal < 0] = np.nan - - return r_cal - - -def calibrate_thermal(counts, prt, ict, space, line_numbers, channel, cal): - """Do the thermal calibration and return brightness temperatures (K). - - Arguments: - counts (array) - counts for the given channel (options: 3B (if active), 4, 5) - prt (array) - counts of the Platinum Resistance Thermometers (PRT) - ict (array) - counts of the In-orbit Calibration Targets (ICT) - space (array) - counts of cold space - line_numbers (array) - line number index - channel (array) - pygac internal channel index array - cal (namedtuple) - spacecraft specific calibration coefficients, see Calibrator - - Note: - This function and documentation follows steps 1 to 4 from the KLM User's Guide - (Robel, J. (2009). NOAA KLM user's guide with NOAA-N,-P supplement. NOAA KLM Users - Guide - August 2014 Revision) section 7.1.2.4 "Steps to Calibrate the AVHRR Thermal Channels", - and the smoothing approach by Trishchenko (2002). - The correction method for the non-linear response of the Mercury-Cadmium-Telluride detectors used - for channels 4 and 5 is based on Walton et al. (1998) - """ - # Shift channel index by three to obtain thermal channels [3b, 4, 5]. chan = channel - 3 lines, columns = counts.shape[:2] - # Step 1. The temperature of the internal blackbody target is measured by four platinum resistance - # thermometers (PRT)s. In each scanline, data words 18, 19 and 20 in the HRPT minor frame format contain - # three readings from one of the four PRTs. (See Section 4.1.3) A different PRT is sampled each scanline; - # every fifth scanline all three PRT values are set equal to 0 to indicate that a set of four PRTs has - # just been sampled. The count value CPRT of each PRT is converted to temperature TPRT by the formula - # T_PRT = d0 + d1*C_PRT + d2*C_PRT^2 + d3*C_PRT^3 + d4*C_PRT^4 (7.1.2.4-1) - # The coefficients d0, d1, d2, d3 and d4 vary slightly for each PRT. Values for the coefficients are - # found in Appendix D, in Table D.1-8 for NOAA-15 (coefficients d3 and d4 are 0 for NOAA-15), - # Table D.2-9 for NOAA-16, Table D.3-3 for NOAA-17 and Table D.4-3 for NOAA-18. To - # calculate the internal blackbody temperature TBB, NESDIS uses the simple average - # T_BB = (T_PRT1 + T_PRT2 + T_PRT3 + T_PRT4)/4 (7.1.2.4-2) - - # Find the corresponding PRT values for a given line number - # Note that the prt values are the average value of the three readings from one of the four - # PRTs. See reader.get_telemetry implementations. - prt_threshold = 50 # empirically found and set by Abhay Devasthale offset = 0 for i, prt_val in enumerate(prt): - # According to the KLM Guide the fill value between PRT measurments is 0, but we search - # for the first measurment gap using the threshold. Is this on purpose? - if prt_val < prt_threshold: + if prt_val < 50: offset = i break - # get the PRT index, iprt equals to 0 corresponds to the measurement gaps iprt = (line_numbers - line_numbers[0] + 5 - offset) % 5 - # fill measured values below threshold by interpolation - ifix = np.where(np.logical_and(iprt == 1, prt < prt_threshold)) + ifix = np.where(np.logical_and(iprt == 1, prt < 50)) if len(ifix[0]): - inofix = np.where(np.logical_and(iprt == 1, prt > prt_threshold)) + inofix = np.where(np.logical_and(iprt == 1, prt > 50)) prt[ifix] = np.interp(ifix[0], inofix[0], prt[inofix]) - ifix = np.where(np.logical_and(iprt == 2, prt < prt_threshold)) + ifix = np.where(np.logical_and(iprt == 2, prt < 50)) if len(ifix[0]): - inofix = np.where(np.logical_and(iprt == 2, prt > prt_threshold)) + inofix = np.where(np.logical_and(iprt == 2, prt > 50)) prt[ifix] = np.interp(ifix[0], inofix[0], prt[inofix]) - ifix = np.where(np.logical_and(iprt == 3, prt < prt_threshold)) + ifix = np.where(np.logical_and(iprt == 3, prt < 50)) if len(ifix[0]): - inofix = np.where(np.logical_and(iprt == 3, prt > prt_threshold)) + inofix = np.where(np.logical_and(iprt == 3, prt > 50)) prt[ifix] = np.interp(ifix[0], inofix[0], prt[inofix]) - ifix = np.where(np.logical_and(iprt == 4, prt < prt_threshold)) + ifix = np.where(np.logical_and(iprt == 4, prt < 50)) if len(ifix[0]): - inofix = np.where(np.logical_and(iprt == 4, prt > prt_threshold)) + inofix = np.where(np.logical_and(iprt == 4, prt > 50)) prt[ifix] = np.interp(ifix[0], inofix[0], prt[inofix]) - # calculate PRT temperature using equation (7.1.2.4-1) KLM Guide - # Tprt = d0 + d1*Cprt + d2*Cprt^2 + d3*Cprt^3 + d4*Cprt^4 - # Note: First dimension of cal.d are the five coefficient indicees - tprt = np.polynomial.polynomial.polyval(prt, cal.d[:, iprt], tensor=False) - - # Note: the KLM Guide proposes to calculate the mean temperature using equation (7.1.2.4-2). - # PyGAC follows the smoothing approach by Trishchenko (2002), i.e. - # filling the zeros that mark a complete set of thermometer measurements - # by interpolation, and then using a weighting function (so far only equal - # weighting) to convolve the temperatures to calculate a moving average of a given window size. - # The same averaging technique is applied for ICTs and Space counts. + tprt = (cal.d[iprt, 0] + prt * + (cal.d[iprt, 1] + prt * + (cal.d[iprt, 2] + prt * + (cal.d[iprt, 3] + prt * + (cal.d[iprt, 4]))))) + zeros = iprt == 0 nonzeros = np.logical_not(zeros) @@ -437,17 +505,14 @@ def calibrate_thermal(counts, prt, ict, space, line_numbers, channel, cal): (nonzeros).nonzero()[0], tprt[nonzeros]) - # Thresholds to flag missing/wrong data for interpolation - ict_threshold = 100 - space_threshold = 100 if channel == 3: - zeros = ict < ict_threshold + zeros = ict < 100 nonzeros = np.logical_not(zeros) ict[zeros] = np.interp((zeros).nonzero()[0], (nonzeros).nonzero()[0], ict[nonzeros]) - zeros = space < space_threshold + zeros = space < 100 nonzeros = np.logical_not(zeros) space[zeros] = np.interp((zeros).nonzero()[0], @@ -456,7 +521,7 @@ def calibrate_thermal(counts, prt, ict, space, line_numbers, channel, cal): # convolving and smoothing PRT, ICT and SPACE values if lines > 51: - wlength = 51 # empirically found and set by Abhay Devasthale + wlength = 51 else: wlength = 3 @@ -471,78 +536,30 @@ def calibrate_thermal(counts, prt, ict, space, line_numbers, channel, cal): space_convolved[0:(wlength - 1) // 2] = space_convolved[(wlength - 1) // 2] tprt_convolved[-(wlength - 1) // 2:] = tprt_convolved[-((wlength + 1) // 2)] ict_convolved[-(wlength - 1) // 2:] = ict_convolved[-((wlength + 1) // 2)] - space_convolved[-(wlength - 1) // 2:] = space_convolved[-((wlength + 1) // 2)] + space_convolved[-(wlength - 1) // 2:] = \ + space_convolved[-((wlength + 1) // 2)] new_tprt = np.transpose(np.tile(tprt_convolved, (columns, 1))) new_ict = np.transpose(np.tile(ict_convolved, (columns, 1))) new_space = np.transpose(np.tile(space_convolved, (columns, 1))) - # Step 2. The radiance NBB sensed in each thermal AVHRR channel from the internal blackbody - # at temperature TBB is the weighted mean of the Planck function over the spectral response of the - # channel. [...]. Each thermal channel has one equation, which uses a centroid wavenumber labmda_c and an - # "effective" blackbody temperature TBB*. The two steps are: - # TsBB = A + B*TBB (7.1.2.4-3) - # NBB = c1*nu_e^3/(exp(c2*nu_e/TsBB) - 1) (7.1.2.4-3) - # where the constants of the Planck function are defined as c1 = 2*h*c^2, c2 = h*c/k_B. - # constatns - c1 = 1.1910427e-5 # mW/m^2/sr/cm^{-4} - c2 = 1.4387752 # cm K - # coefficients - A = cal.to_eff_blackbody_intercept[chan] - B = cal.to_eff_blackbody_slope[chan] - nu_c = cal.centroid_wavenumber[chan] - nS = cal.space_radiance[chan] - b = cal.b[chan, 0:3] # the second index are the three polynomial coefficients - # variables + # calibrating thermal channel + tBB = new_tprt - cS = new_space - cE = counts.astype(float) - cBB = new_ict - - tsBB = A + B*tBB - nBB_num = c1 * nu_c**3 - nBB = nBB_num / (np.exp((c2 * nu_c) / tsBB) - 1.0) - - # Step 3. Output from the two in-orbit calibration targets is used to compute a linear estimate of - # the Earth scene radiance NE. Each scanline, the AVHRR views the internal blackbody target and - # outputs 10 count values for each of the three thermal channel detectors; these are found in words - # 23 to 52 in the HRPT data stream. When the AVHRR views cold space, 10 counts from each of - # the five channel sensors are output and placed into words 52 to 102. (Table 4.1.3-1 describes - # how these data are multiplexed.) Count values for each channel are averaged together to smooth - # our random noise; often counts from five consecutive scanlines are averaged because it takes five - # lines to obtain a set of all four PRT measurements. The average blackbody count CBB and the - # average space count CS, together with blackbody radiance NBB and space radiance NS, explained - # in the next paragraph, are used to compute the linear radiance estimate NLIN, - # NLIN = NS + (NBB - NS)*(CS - CE)/(CS - CBB) (7.1.2.4-5) - # where CE is the AVHRR count output when it views one of the reference Earth targets. - # While the detector in channel 3B has a linear response, the Mercury-Cadmium-Telluride detectors used - # for channels 4 and 5 have a nonlinear response to incoming radiance. Pre-launch laboratory measurements show that: - # a. scene radiance is a slightly nonlinear (quadratic) function of AVHRR output count, - # b. the nonlinearity depends on the AVHRR operating temperature. - # It is assumed that the nonlinear response will persist in orbit. For the NOAA KLM series of - # satellites, NESDIS uses a radiance-based nonlinear correction method. In this method, the linear - # radiance estimate is first computed using a non-zero radiance of space, the NS term in Equation - # 7.1.2.4-5. Then, the linear radiance value is input into a quadratic equation to generate the - # nonlinear radiance correction NCOR: - # NCOR = b0 + b1*NLIN + b2*NLIN^2 (7.1.2.4-6) - # Finally, the Earth scene radiance is obtained by adding NCOR to NLIN - # NE = NLIN + NCOR - - # Note: For channel 3B, the non-linear correction coefficients are set to zero to use the same equation. - Nlin = nS + (nBB - nS)*(cS - cE)/(cS - cBB) - Ncor = np.polynomial.polynomial.polyval(Nlin, b[0:3], tensor=False) - Ne = Nlin + Ncor - - # Step 4. Data users often convert the computed Earth scene radiance value NE into an equivalent - # blackbody temperature TE. This temperature is defined by simple inverting the steps used to - # calculate the radiance NE sensed by an AVHRR channel from an emitting blackbody at a - # temperature TE. The two-step process is: - # TsE = c2*nu_c / ln(1 + (c1*nu_c^3/NE)) (7.1.2.4-8) - # TE = (TsE - A)/B (7.1.2.4-9) - tsE = c2*nu_c / np.log(1.0 + nBB_num / Ne) - bt = (tsE - A) / B - - # Why do we do this on channel 3b? + tsBB = cal.a[chan] + cal.b[chan] * tBB + nBB_num = (1.1910427 * 0.000010) * cal.c_wn[chan] ** 3 + nBB = nBB_num / (np.exp((1.4387752 * cal.c_wn[chan]) / tsBB) - 1.0) + + Nlin = (cal.n_s[chan] + + (((nBB - cal.n_s[chan]) + * (new_space - counts.astype(float))) + / (new_space - new_ict))) + Ncor = cal.b0[chan] + Nlin * (cal.b1[chan] + cal.b2[chan] * Nlin) + Ne = Ncor + tsE = ((1.4387752 * cal.c_wn[chan]) + / np.log(1.0 + nBB_num / Ne)) + bt = (tsE - cal.a[chan]) / cal.b[chan] + if chan == 0: bt = np.where((counts - new_space) >= 0, 0.0, bt) diff --git a/pygac/configuration.py b/pygac/configuration.py index 9ca301e2..986fcedc 100644 --- a/pygac/configuration.py +++ b/pygac/configuration.py @@ -39,7 +39,7 @@ class FileNotFoundError(OSError): LOG = logging.getLogger(__name__) -class Configuration(configparser.ConfigParser, object): +class Configuration(configparser.ConfigParser): """Configuration container for pygac.""" config_file = '' @@ -66,21 +66,6 @@ def read(self, config_file): raise self.config_file = config_file - def get(self, *args, **kwargs): - """python 2 compatibility for fallback attribute""" - if sys.version_info.major < 3: - if 'fallback' in kwargs: - fallback = kwargs.pop('fallback') - else: - fallback = None - try: - value = super(Configuration, self).get(*args, **kwargs) - except (configparser.NoSectionError, configparser.NoOptionError): - value = fallback - else: - value = super().get(*args, **kwargs) - return value - _config = Configuration() diff --git a/pygac/correct_tsm_issue.py b/pygac/correct_tsm_issue.py index f940125f..1faabb6b 100644 --- a/pygac/correct_tsm_issue.py +++ b/pygac/correct_tsm_issue.py @@ -24,8 +24,8 @@ them with fill values.""" import numpy as np -import bottleneck as bn import datetime +from ._filter import _mean_filter TSM_AFFECTED_INTERVALS_POD = { 3: [(datetime.datetime(2001, 10, 19, 4, 50), datetime.datetime(2001, 10, 19, 13, 38)), @@ -376,47 +376,61 @@ } -def _rolling_window(array, size): - """Create an array view of rolling windows. +def mean_filter(data, fill_value, box_size): + """Filter a 2D array using an arithmetic mean kernel. + + Compute the arithmetic mean of the valid elements within a box of size + (boxsize x boxsize) around each pixel. Masked elements are not taken into + account. Args: - array (np.ndarray): 2D array - size (tuple): window size + data (numpy.ma.core.MaskedArray): 2D array to be filtered + box_size (int): Specifies the boxsize. Must be odd. + fill_value: Value to fill masked elements with. Must be outside the + valid range of the data. Returns: - windows (np.ndarray): 4D array of rolling windows the first dimensions - are the window location on the 2D array, the last two dimensions - are the location inside the window. + numpy.ma.core.MaskedArray: The filtered array. """ - shape = ((array.shape[0] - size[0] + 1, array.shape[1] - size[1] + 1,) - + size) - strides = array.strides + array.strides - return np.lib.stride_tricks.as_strided(array, shape=shape, strides=strides) + if not box_size % 2 == 1: + raise ValueError('Box size must be odd.') + + # Replace masked elements with fill_value + filled = np.where(np.isnan(data), fill_value, data) + + # Convert data to double (this is what _mean_filter() is expecting) and + # apply mean filter + filtered = _mean_filter(data=filled.astype('f8'), box_size=box_size, + fill_value=fill_value) + # Re-mask fill values + return np.where(filtered == fill_value, np.nan, filtered) -def std_filter(data, box_size): + +def std_filter(data, box_size, fill_value): """Filter a 2D array using a standard deviation kernel. + Compute the standard deviation of the valid elements within a box of size + (box_size x box_size) around each pixel. Masked values are not taken into + account. Since + + std = sqrt( mean(data^2) - mean(data)^2 ) + + we can use mean_filter() to compute the standard deviation. + Args: - data (np.ndarray): 2D array to be filtered + data (np.ma.core.MaskedArray): 2D array to be filtered box_size (int): Specifies the boxsize. Must be odd. + fill_value: Value indicating invalid/missing data Returns: - np.ndarray: The filtered array + np.ma.core.MaskedArray: The filtered array """ - size = (box_size, box_size) - border = box_size // 2 - # need to surround the data with NaNs to calculate values at the boundary - padded_data = np.pad( - data, (border, border), - mode='constant', - constant_values=np.nan - ) - windows = _rolling_window(padded_data, size) - n3, n2, n1, n0 = windows.shape - # flatten the windows for bottleneck function call - windows = windows.reshape((n3, n2, n1*n0)) - return bn.nanstd(windows, axis=2) + mean_squared = np.square(mean_filter(data, box_size=box_size, + fill_value=fill_value)) + squared_mean = mean_filter(np.square(data), box_size=box_size, + fill_value=fill_value) + return np.sqrt(squared_mean - mean_squared) def get_tsm_idx(ch1, ch2, ch4, ch5): @@ -429,11 +443,9 @@ def get_tsm_idx(ch1, ch2, ch4, ch5): # standard deviation of abs_d12 and rel_d45 box_size = 3 - std_d12 = std_filter(abs_d12, box_size) - std_d45 = std_filter(rel_d45, box_size) - # replace NaNs to avoid "RuntimeWarning: invalid value encountered in greater" - std_d12 = np.nan_to_num(std_d12, copy=False) - std_d45 = np.nan_to_num(std_d45, copy=False) + fill_value = -9999.0 + std_d12 = std_filter(abs_d12, box_size, fill_value) + std_d45 = std_filter(rel_d45, box_size, fill_value) # using ch1, ch2, ch4, ch5 in combination # all channels seems to be affected throughout the whole orbit, diff --git a/pygac/data/calibration.json b/pygac/data/calibration.json deleted file mode 100644 index 24e902c2..00000000 --- a/pygac/data/calibration.json +++ /dev/null @@ -1,1386 +0,0 @@ -{ - "description": { - "thermal": { - "channels": [ - "3b", - "4", - "5" - ], - "coefficients": { - "b0": "constant non-linear radiance correction coefficient [mW m^{-2} sr cm^{-1}]", - "b1": "linear non-linear radiance correction coefficient []", - "b2": "quadratic non-linear radiance correction coefficient [(mW^{-1} m^2 sr^{-1} cm)]", - "centroid_wavenumber": "centroid wavenumber [cm^{-1}]", - "d0": "constant thermometer counts to temperature conversion coefficient [K]", - "d1": "linear thermometer counts to temperature conversion coefficient [K]", - "d2": "quadratic thermometer counts to temperature conversion coefficient [K]", - "d3": "cubic thermometer counts to temperature conversion coefficient [K]", - "d4": "quartic thermometer counts to temperature conversion coefficient [K]", - "space_radiance": "radiance of space [mW m^{-2} sr cm^{-1}]", - "to_eff_blackbody_intercept": "thermal channel temperature to effective blackbody temperature intercept [K]", - "to_eff_blackbody_slope": "thermal channel temperature to effective blackbody temperature slope []" - }, - "method": "Goodrum, G., Kidwell, K.B. and W. Winston, 2000: NOAA KLM User's Guide. U.S. Department of Commerce, National Oceanic and Atmospheric Administration, National Environmental Satellite, Data and Information Service; Walton, C. C., J. T. Sullivan, C. R. N. Rao, and M. P. Weinreb, 1998: Corrections for detector nonlinearities and calibration inconsistencies of the infrared channels of the Advanced Very High Resolution Radiometer. J. Geophys. Res., 103, 3323-3337; Trishchenko, A.P., 2002: Removing Unwanted Fluctuations in the AVHRR Thermal Calibration Data Using Robust Techniques. Journal of Atmospheric and Oceanic Technology, 19:1939-1954" - }, - "visible": { - "channels": [ - "1", - "2", - "3a" - ], - "coefficients": { - "dark_count": "instrument counts under dark conditions []", - "date_of_launch": "timestamp of launch date [UTC]", - "gain_switch": "dual-gain switch count, set to 'null' for single-gain instruments []", - "s0": "single-gain calibration slope at launch date [%]", - "s1": "linear single-gain calibration slope parameter [% years^{-1}]", - "s2": "quadratic single-gain calibration slope parameter [% years^{-2}]" - }, - "method": "Heidinger, A.K., W.C. Straka III, C.C. Molling, J.T. Sullivan, and X. Wu, 2010: Deriving an inter-sensor consistent calibration for the AVHRR solar reflectance data record. International Journal of Remote Sensing, 31:6493-6517" - } - }, - "metopa": { - "channel_1": { - "dark_count": 40.43, - "gain_switch": 501.0, - "s0": 0.11266666666666668, - "s1": 0.609, - "s2": -0.029 - }, - "channel_2": { - "dark_count": 39.75, - "gain_switch": 500.0, - "s0": 0.13266666666666668, - "s1": 0.98, - "s2": -0.016 - }, - "channel_3a": { - "dark_count": 41.8, - "gain_switch": 502.0, - "s0": 0.1217142857142857, - "s1": 1.224, - "s2": -0.033 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2687.0392, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 2.0582306816399316, - "to_eff_blackbody_slope": 0.9965700053555672 - }, - "channel_4": { - "b0": 5.44, - "b1": -0.10152, - "b2": 0.00046964, - "centroid_wavenumber": 927.2763, - "space_radiance": -4.98, - "to_eff_blackbody_intercept": 0.564181969408163, - "to_eff_blackbody_slope": 0.998493273650062 - }, - "channel_5": { - "b0": 3.84, - "b1": -0.06249, - "b2": 0.00025239, - "centroid_wavenumber": 837.80762, - "space_radiance": -3.4, - "to_eff_blackbody_intercept": 0.3842947903481519, - "to_eff_blackbody_slope": 0.9988748673494177 - }, - "date_of_launch": "2006-10-19T19:37:12.000000Z", - "thermometer_1": { - "d0": 276.6194, - "d1": 0.050919, - "d2": 1.471e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.6511, - "d1": 0.050892, - "d2": 1.489e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.6597, - "d1": 0.050845, - "d2": 1.521e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.3685, - "d1": 0.050992, - "d2": 1.482e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "metopb": { - "channel_1": { - "dark_count": 39.7, - "gain_switch": 501.12, - "s0": 0.11066666666666668, - "s1": 2.019, - "s2": -0.201 - }, - "channel_2": { - "dark_count": 40.0, - "gain_switch": 500.82, - "s0": 0.122, - "s1": 1.476, - "s2": -0.137 - }, - "channel_3a": { - "dark_count": 40.3, - "gain_switch": 501.32, - "s0": 0.11485714285714287, - "s1": 1.748, - "s2": -0.033 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2664.3384, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.765846445005454, - "to_eff_blackbody_slope": 0.9970158319134996 - }, - "channel_4": { - "b0": 5.44, - "b1": -0.10152, - "b2": 0.00046964, - "centroid_wavenumber": 933.71521, - "space_radiance": -4.98, - "to_eff_blackbody_intercept": 0.5178945149373193, - "to_eff_blackbody_slope": 0.9986240957209157 - }, - "channel_5": { - "b0": 3.84, - "b1": -0.06249, - "b2": 0.00025239, - "centroid_wavenumber": 839.72764, - "space_radiance": -3.4, - "to_eff_blackbody_intercept": 0.40012963829726456, - "to_eff_blackbody_slope": 0.9988311677674785 - }, - "date_of_launch": "2012-10-08T19:40:48.000000Z", - "thermometer_1": { - "d0": 276.6194, - "d1": 0.050919, - "d2": 1.471e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.6511, - "d1": 0.050892, - "d2": 1.489e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.6597, - "d1": 0.050845, - "d2": 1.521e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.3685, - "d1": 0.050992, - "d2": 1.482e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "metopc": { - "channel_1": { - "dark_count": 40.41, - "gain_switch": 498.68, - "s0": 0.10699999999916181, - "s1": 0.0, - "s2": -0.0 - }, - "channel_2": { - "dark_count": 40.94, - "gain_switch": 500.01, - "s0": 0.10633333333441988, - "s1": 0.0, - "s2": -0.0 - }, - "channel_3a": { - "dark_count": 40.57, - "gain_switch": 498.72, - "s0": 0.1032, - "s1": 0.0, - "s2": -0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2707.6457, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.7824614096281413, - "to_eff_blackbody_slope": 0.9976376937050757 - }, - "channel_4": { - "b0": 6.58, - "b1": -0.13203, - "b2": 0.00065922, - "centroid_wavenumber": 931.89092, - "space_radiance": -6.27, - "to_eff_blackbody_intercept": 0.5647288036150199, - "to_eff_blackbody_slope": 0.9984918778676688 - }, - "channel_5": { - "b0": 3.23, - "b1": -0.05692, - "b2": 0.00024963, - "centroid_wavenumber": 832.69445, - "space_radiance": -2.55, - "to_eff_blackbody_intercept": 0.391621708386672, - "to_eff_blackbody_slope": 0.9988509218994469 - }, - "date_of_launch": "2018-11-06T18:54:35.423996Z", - "thermometer_1": { - "d0": 276.5862, - "d1": 0.051051, - "d2": 1.474208e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.6136, - "d1": 0.051029, - "d2": 1.472138e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.5975, - "d1": 0.051065, - "d2": 1.469268e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.4595, - "d1": 0.05099, - "d2": 1.506223e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa10": { - "channel_1": { - "dark_count": 39.44, - "gain_switch": null, - "s0": 0.111, - "s1": 6.087, - "s2": -1.039 - }, - "channel_2": { - "dark_count": 39.4, - "gain_switch": null, - "s0": 0.137, - "s1": 0.119, - "s2": 0.123 - }, - "channel_3a": { - "dark_count": 37.51, - "gain_switch": null, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2672.6164, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.7939697951173739, - "to_eff_blackbody_slope": 0.9973743123852146 - }, - "channel_4": { - "b0": 5.76, - "b1": -0.1157, - "b2": 0.0005882, - "centroid_wavenumber": 910.49626, - "space_radiance": -7.29, - "to_eff_blackbody_intercept": 0.4565104004365842, - "to_eff_blackbody_slope": 0.9987743041739178 - }, - "channel_5": { - "b0": 5.76, - "b1": -0.1157, - "b2": 0.0005882, - "centroid_wavenumber": 910.49626, - "space_radiance": -7.29, - "to_eff_blackbody_intercept": 0.4565104004365842, - "to_eff_blackbody_slope": 0.9987743041739178 - }, - "date_of_launch": "1986-09-17T21:07:12.000000Z", - "thermometer_1": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa11": { - "channel_1": { - "dark_count": 40.0, - "gain_switch": null, - "s0": 0.11, - "s1": 0.632, - "s2": -0.044 - }, - "channel_2": { - "dark_count": 40.0, - "gain_switch": null, - "s0": 0.118, - "s1": -0.037, - "s2": 0.072 - }, - "channel_3a": { - "dark_count": 40.0, - "gain_switch": null, - "s0": 0.0, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2680.05, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.7331599814223095, - "to_eff_blackbody_slope": 0.9966572117119181 - }, - "channel_4": { - "b0": 7.21, - "b1": -0.1588, - "b2": 0.0008739, - "centroid_wavenumber": 927.462, - "space_radiance": -8.055, - "to_eff_blackbody_intercept": 0.3208098576426795, - "to_eff_blackbody_slope": 0.9987884695863918 - }, - "channel_5": { - "b0": 2.92, - "b1": -0.054, - "b2": 0.0002504, - "centroid_wavenumber": 840.746, - "space_radiance": -3.51, - "to_eff_blackbody_intercept": 0.04861971650823853, - "to_eff_blackbody_slope": 0.9993364406034393 - }, - "date_of_launch": "1988-09-24T13:06:14.399994Z", - "thermometer_1": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa12": { - "channel_1": { - "dark_count": 41.0, - "gain_switch": null, - "s0": 0.121, - "s1": 2.032, - "s2": -0.032 - }, - "channel_2": { - "dark_count": 40.0, - "gain_switch": null, - "s0": 0.148, - "s1": 1.323, - "s2": -0.008 - }, - "channel_3a": { - "dark_count": 40.0, - "gain_switch": null, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2651.7708, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.8995562357304514, - "to_eff_blackbody_slope": 0.9969990329109382 - }, - "channel_4": { - "b0": 5.11, - "b1": -0.1107, - "b2": 0.0005968, - "centroid_wavenumber": 922.36261, - "space_radiance": -5.51, - "to_eff_blackbody_intercept": 0.6329612453773935, - "to_eff_blackbody_slope": 0.9982953109270609 - }, - "channel_5": { - "b0": 1.91, - "b1": -0.037, - "b2": 0.0001775, - "centroid_wavenumber": 838.02678, - "space_radiance": -2.51, - "to_eff_blackbody_intercept": 0.4103730120125729, - "to_eff_blackbody_slope": 0.9988004406707545 - }, - "date_of_launch": "1991-05-14T22:02:38.400002Z", - "thermometer_1": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa14": { - "channel_1": { - "dark_count": 41.0, - "gain_switch": null, - "s0": 0.121, - "s1": 3.555, - "s2": -0.339 - }, - "channel_2": { - "dark_count": 41.0, - "gain_switch": null, - "s0": 0.152, - "s1": 0.254, - "s2": 0.201 - }, - "channel_3a": { - "dark_count": 39.0, - "gain_switch": null, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": -0.0031, - "b1": 0.00359, - "b2": 0.0, - "centroid_wavenumber": 2654.25, - "space_radiance": 0.0069, - "to_eff_blackbody_intercept": 1.8781198977126812, - "to_eff_blackbody_slope": 0.996175681558497 - }, - "channel_4": { - "b0": 3.72, - "b1": -0.07622, - "b2": 0.0003822, - "centroid_wavenumber": 928.349, - "space_radiance": -4.05, - "to_eff_blackbody_intercept": 0.30793964309501387, - "to_eff_blackbody_slope": 0.9985590792486442 - }, - "channel_5": { - "b0": 2.0, - "b1": -0.03806, - "b2": 0.0001742, - "centroid_wavenumber": 833.04, - "space_radiance": -2.29, - "to_eff_blackbody_intercept": -0.022159078415812293, - "to_eff_blackbody_slope": 0.9994622892883629 - }, - "date_of_launch": "1994-12-30T18:12:57.599991Z", - "thermometer_1": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.597, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa15": { - "channel_1": { - "dark_count": 39.0, - "gain_switch": 500.0, - "s0": 0.11933333333333333, - "s1": -0.069, - "s2": 0.002 - }, - "channel_2": { - "dark_count": 40.0, - "gain_switch": 500.0, - "s0": 0.13733333333333334, - "s1": 0.339, - "s2": -0.01 - }, - "channel_3a": { - "dark_count": 39.0, - "gain_switch": 500.0, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2695.9743, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.6212563211771787, - "to_eff_blackbody_slope": 0.9980149482678952 - }, - "channel_4": { - "b0": 4.76, - "b1": -0.0932, - "b2": 0.0004524, - "centroid_wavenumber": 925.4075, - "space_radiance": -4.5, - "to_eff_blackbody_intercept": 0.3378095902956507, - "to_eff_blackbody_slope": 0.9987186439797741 - }, - "channel_5": { - "b0": 3.83, - "b1": -0.0659, - "b2": 0.0002811, - "centroid_wavenumber": 839.8979, - "space_radiance": -3.61, - "to_eff_blackbody_intercept": 0.3045584463978693, - "to_eff_blackbody_slope": 0.9990239535973354 - }, - "date_of_launch": "1998-05-13T21:30:57.600006Z", - "thermometer_1": { - "d0": 276.60157, - "d1": 0.051045, - "d2": 1.36328e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.62531, - "d1": 0.050909, - "d2": 1.47266e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.67413, - "d1": 0.050907, - "d2": 1.47656e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.59258, - "d1": 0.050966, - "d2": 1.47656e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa16": { - "channel_1": { - "dark_count": 39.3, - "gain_switch": 498.96, - "s0": 0.11, - "s1": 0.839, - "s2": -0.051 - }, - "channel_2": { - "dark_count": 38.9, - "gain_switch": 500.17, - "s0": 0.11933333333333333, - "s1": 0.786, - "s2": -0.031 - }, - "channel_3a": { - "dark_count": 38.4, - "gain_switch": 499.43, - "s0": 0.10685714285714286, - "s1": 0.29, - "s2": -0.294 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2681.254, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.674558933750318, - "to_eff_blackbody_slope": 0.9982713932554388 - }, - "channel_4": { - "b0": 2.96, - "b1": -0.05411, - "b2": 0.00024532, - "centroid_wavenumber": 922.3479, - "space_radiance": -2.467, - "to_eff_blackbody_intercept": 0.5555332488394067, - "to_eff_blackbody_slope": 0.9985101230454039 - }, - "channel_5": { - "b0": 2.25, - "b1": -0.03665, - "b2": 0.00014854, - "centroid_wavenumber": 834.61814, - "space_radiance": -2.009, - "to_eff_blackbody_intercept": 0.4138044554994394, - "to_eff_blackbody_slope": 0.9987848783170394 - }, - "date_of_launch": "2000-09-21T13:04:30.719994Z", - "thermometer_1": { - "d0": 276.355, - "d1": 0.05562, - "d2": -1.59e-05, - "d3": 2.486e-08, - "d4": -1.199e-11 - }, - "thermometer_2": { - "d0": 276.142, - "d1": 0.05605, - "d2": -1.707e-05, - "d3": 2.595e-08, - "d4": -1.224e-11 - }, - "thermometer_3": { - "d0": 275.996, - "d1": 0.05486, - "d2": -1.223e-05, - "d3": 1.862e-08, - "d4": -8.53e-12 - }, - "thermometer_4": { - "d0": 276.132, - "d1": 0.05494, - "d2": -1.344e-05, - "d3": 2.112e-08, - "d4": -1.001e-11 - } - }, - "noaa17": { - "channel_1": { - "dark_count": 39.99, - "gain_switch": 501.12, - "s0": 0.11466666666666665, - "s1": 1.007, - "s2": -0.044 - }, - "channel_2": { - "dark_count": 39.09, - "gain_switch": 500.73, - "s0": 0.14, - "s1": 1.474, - "s2": -0.118 - }, - "channel_3a": { - "dark_count": 42.09, - "gain_switch": 501.37, - "s0": 0.11942857142857143, - "s1": 2.787, - "s2": -0.292 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2669.1414, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.695762344709997, - "to_eff_blackbody_slope": 0.997334722687091 - }, - "channel_4": { - "b0": 8.22, - "b1": -0.15795, - "b2": 0.00075579, - "centroid_wavenumber": 928.29959, - "space_radiance": -8.55, - "to_eff_blackbody_intercept": 0.5654877558672039, - "to_eff_blackbody_slope": 0.9984818084103121 - }, - "channel_5": { - "b0": 4.31, - "b1": -0.07318, - "b2": 0.00030976, - "centroid_wavenumber": 840.20289, - "space_radiance": -3.97, - "to_eff_blackbody_intercept": 0.37224447975949276, - "to_eff_blackbody_slope": 0.9989170740000766 - }, - "date_of_launch": "2002-06-24T21:05:28.319992Z", - "thermometer_1": { - "d0": 276.628, - "d1": 0.05098, - "d2": 1.371e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.538, - "d1": 0.05098, - "d2": 1.371e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.761, - "d1": 0.05097, - "d2": 1.369e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.66, - "d1": 0.051, - "d2": 1.348e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa18": { - "channel_1": { - "dark_count": 39.44, - "gain_switch": 500.54, - "s0": 0.114, - "s1": 0.603, - "s2": -0.0 - }, - "channel_2": { - "dark_count": 39.4, - "gain_switch": 500.4, - "s0": 0.128, - "s1": 0.632, - "s2": 0.045 - }, - "channel_3a": { - "dark_count": 37.51, - "gain_switch": 500.56, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2660.6468, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.7173477182782537, - "to_eff_blackbody_slope": 0.9971448750791857 - }, - "channel_4": { - "b0": 5.82, - "b1": -0.11069, - "b2": 0.00052337, - "centroid_wavenumber": 928.73452, - "space_radiance": -5.53, - "to_eff_blackbody_intercept": 0.5461660253184831, - "to_eff_blackbody_slope": 0.9985440229601218 - }, - "channel_5": { - "b0": 2.67, - "b1": -0.0436, - "b2": 0.00017715, - "centroid_wavenumber": 834.08306, - "space_radiance": -2.22, - "to_eff_blackbody_intercept": 0.3989160707985957, - "to_eff_blackbody_slope": 0.9988289729121578 - }, - "date_of_launch": "2005-05-20T21:42:28.799988Z", - "thermometer_1": { - "d0": 276.601, - "d1": 0.0509, - "d2": 1.657e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.683, - "d1": 0.05101, - "d2": 1.482e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.565, - "d1": 0.05117, - "d2": 1.313e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.615, - "d1": 0.05103, - "d2": 1.484e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa19": { - "channel_1": { - "dark_count": 38.8, - "gain_switch": 496.43, - "s0": 0.108, - "s1": 0.626, - "s2": -0.044 - }, - "channel_2": { - "dark_count": 39.0, - "gain_switch": 500.37, - "s0": 0.122, - "s1": 0.95, - "s2": -0.039 - }, - "channel_3a": { - "dark_count": 39.4, - "gain_switch": 496.11, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2670.2425, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.6820200170457578, - "to_eff_blackbody_slope": 0.9974112191806167 - }, - "channel_4": { - "b0": 5.7, - "b1": -0.11187, - "b2": 0.00054668, - "centroid_wavenumber": 927.92374, - "space_radiance": -5.49, - "to_eff_blackbody_intercept": 0.39366677255917354, - "to_eff_blackbody_slope": 0.9986718662850276 - }, - "channel_5": { - "b0": 3.58, - "b1": -0.05991, - "b2": 0.00024985, - "centroid_wavenumber": 831.28619, - "space_radiance": -3.39, - "to_eff_blackbody_intercept": 0.2633947633588976, - "to_eff_blackbody_slope": 0.9990463103920997 - }, - "date_of_launch": "2009-02-05T00:57:36.000000Z", - "thermometer_1": { - "d0": 276.6067, - "d1": 0.051111, - "d2": 1.405783e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.6119, - "d1": 0.05109, - "d2": 1.496037e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.6311, - "d1": 0.051033, - "d2": 1.49699e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.6268, - "d1": 0.051058, - "d2": 1.49311e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa6": { - "channel_1": { - "dark_count": 39.44, - "gain_switch": null, - "s0": 0.113, - "s1": 0.9, - "s2": 0.0 - }, - "channel_2": { - "dark_count": 39.4, - "gain_switch": null, - "s0": 0.128, - "s1": 0.699, - "s2": 0.0 - }, - "channel_3a": { - "dark_count": 37.51, - "gain_switch": null, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2671.5433, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.7624057951236716, - "to_eff_blackbody_slope": 0.9975631527305099 - }, - "channel_4": { - "b0": 2.24, - "b1": -0.03964, - "b2": 0.00016925, - "centroid_wavenumber": 913.46088, - "space_radiance": -3.26, - "to_eff_blackbody_intercept": 0.5032756477395923, - "to_eff_blackbody_slope": 0.9986426449170288 - }, - "channel_5": { - "b0": 2.24, - "b1": -0.03964, - "b2": 0.00016925, - "centroid_wavenumber": 913.46088, - "space_radiance": -3.26, - "to_eff_blackbody_intercept": 0.5032756477395923, - "to_eff_blackbody_slope": 0.9986426449170288 - }, - "date_of_launch": "1979-06-28T20:23:59.999992Z", - "thermometer_1": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa7": { - "channel_1": { - "dark_count": 36.0, - "gain_switch": null, - "s0": 0.115, - "s1": 3.792, - "s2": -0.269 - }, - "channel_2": { - "dark_count": 37.0, - "gain_switch": null, - "s0": 0.127, - "s1": 2.685, - "s2": -0.101 - }, - "channel_3a": { - "dark_count": 39.0, - "gain_switch": null, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2684.5233, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.9431412686479361, - "to_eff_blackbody_slope": 0.9970825364982062 - }, - "channel_4": { - "b0": 5.25, - "b1": -0.10217, - "b2": 0.0004819, - "centroid_wavenumber": 928.23757, - "space_radiance": -5.16, - "to_eff_blackbody_intercept": 0.5273396378823769, - "to_eff_blackbody_slope": 0.9985980681720933 - }, - "channel_5": { - "b0": 3.93, - "b1": -0.06317, - "b2": 0.0002425, - "centroid_wavenumber": 841.52137, - "space_radiance": -4.28, - "to_eff_blackbody_intercept": 0.4050927062086506, - "to_eff_blackbody_slope": 0.9988224881686979 - }, - "date_of_launch": "1981-06-23T21:15:50.400009Z", - "thermometer_1": { - "d0": 277.099, - "d1": 0.05048, - "d2": 2.823e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.734, - "d1": 0.05069, - "d2": 2.493e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.876, - "d1": 0.05148, - "d2": 1.04e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.16, - "d1": 0.05128, - "d2": 1.414e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa8": { - "channel_1": { - "dark_count": 39.44, - "gain_switch": null, - "s0": 0.119, - "s1": 6.065, - "s2": 0.0 - }, - "channel_2": { - "dark_count": 39.4, - "gain_switch": null, - "s0": 0.136, - "s1": 7.248, - "s2": 0.0 - }, - "channel_3a": { - "dark_count": 37.51, - "gain_switch": null, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2651.3776, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.7721113578458658, - "to_eff_blackbody_slope": 0.9975798712323902 - }, - "channel_4": { - "b0": 2.24, - "b1": -0.03964, - "b2": 0.00016925, - "centroid_wavenumber": 915.3033, - "space_radiance": -3.26, - "to_eff_blackbody_intercept": 0.49950763272635035, - "to_eff_blackbody_slope": 0.9986558092807081 - }, - "channel_5": { - "b0": 2.24, - "b1": -0.03964, - "b2": 0.00016925, - "centroid_wavenumber": 915.3033, - "space_radiance": -3.26, - "to_eff_blackbody_intercept": 0.49950763272635035, - "to_eff_blackbody_slope": 0.9986558092807081 - }, - "date_of_launch": "1983-03-29T23:09:36.000000Z", - "thermometer_1": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - } - }, - "noaa9": { - "channel_1": { - "dark_count": 38.0, - "gain_switch": null, - "s0": 0.108, - "s1": 4.255, - "s2": 0.64 - }, - "channel_2": { - "dark_count": 40.0, - "gain_switch": null, - "s0": 0.122, - "s1": 0.31, - "s2": 0.642 - }, - "channel_3a": { - "dark_count": 38.0, - "gain_switch": null, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2690.0451, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.8778246397589067, - "to_eff_blackbody_slope": 0.9971105729816139 - }, - "channel_4": { - "b0": 5.24, - "b1": -0.1136, - "b2": 0.0006033, - "centroid_wavenumber": 930.5023, - "space_radiance": -5.53, - "to_eff_blackbody_intercept": 0.5108402897268406, - "to_eff_blackbody_slope": 0.99864483895354 - }, - "channel_5": { - "b0": 2.42, - "b1": -0.0469, - "b2": 0.0002198, - "centroid_wavenumber": 845.75, - "space_radiance": -3.06, - "to_eff_blackbody_intercept": 0.3877802982856218, - "to_eff_blackbody_slope": 0.9988802552338829 - }, - "date_of_launch": "1984-12-12T23:13:55.200005Z", - "thermometer_1": { - "d0": 277.018, - "d1": 0.05128, - "d2": 0.0, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.75, - "d1": 0.05128, - "d2": 0.0, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.862, - "d1": 0.05128, - "d2": 0.0, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.546, - "d1": 0.05128, - "d2": 0.0, - "d3": 0.0, - "d4": 0.0 - } - }, - "tirosn": { - "channel_1": { - "dark_count": 39.44, - "gain_switch": null, - "s0": 0.115, - "s1": 5.11, - "s2": 0.0 - }, - "channel_2": { - "dark_count": 39.4, - "gain_switch": null, - "s0": 0.133, - "s1": 0.717, - "s2": 0.0 - }, - "channel_3a": { - "dark_count": 37.51, - "gain_switch": null, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.00195, - "b1": -0.015, - "b2": 0.011, - "centroid_wavenumber": 2655.7409, - "space_radiance": -0.0039, - "to_eff_blackbody_intercept": 1.645107312780676, - "to_eff_blackbody_slope": 0.9979149564899099 - }, - "channel_4": { - "b0": 6.13, - "b1": -0.131942, - "b2": 0.000673193, - "centroid_wavenumber": 913.05397, - "space_radiance": -8.13, - "to_eff_blackbody_intercept": 0.5305934198578978, - "to_eff_blackbody_slope": 0.9985677542700504 - }, - "channel_5": { - "b0": 6.13, - "b1": -0.131942, - "b2": 0.000673193, - "centroid_wavenumber": 913.05397, - "space_radiance": -8.13, - "to_eff_blackbody_intercept": 0.5305934198578978, - "to_eff_blackbody_slope": 0.9985677542700504 - }, - "date_of_launch": "1978-10-13T19:04:47.999992Z", - "thermometer_1": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.659, - "d1": 0.051275, - "d2": 1.363e-06, - "d3": 0.0, - "d4": 0.0 - } - } -} - diff --git a/pygac/gac_io.py b/pygac/gac_io.py index 8b08b2d5..67c28d92 100644 --- a/pygac/gac_io.py +++ b/pygac/gac_io.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- # Copyright (c) 2012, 2014 Abhay Devasthale @@ -33,6 +34,7 @@ import h5py import numpy as np +from pygac.configuration import get_config from pygac.utils import slice_channel, strip_invalid_lat, check_user_scanlines LOG = logging.getLogger(__name__) @@ -42,6 +44,19 @@ MISSING_DATA_LATLON = -999999 +def read_config(): + """Read output dir etc from config file.""" + conf = get_config() + OUTDIR = conf.get('output', 'output_dir', raw=True) + OUTPUT_FILE_PREFIX = conf.get('output', 'output_file_prefix', raw=True) + + SUNSATANGLES_DIR = os.environ.get('SM_SUNSATANGLES_DIR', OUTDIR) + AVHRR_DIR = os.environ.get('SM_AVHRR_DIR', OUTDIR) + QUAL_DIR = os.environ.get('SM_AVHRR_DIR', OUTDIR) + + return OUTPUT_FILE_PREFIX, SUNSATANGLES_DIR, AVHRR_DIR, QUAL_DIR + + def save_gac(satellite_name, xutcs, lats, lons, @@ -49,8 +64,7 @@ def save_gac(satellite_name, bt3, bt4, bt5, sun_zen, sat_zen, sun_azi, sat_azi, rel_azi, qual_flags, start_line, end_line, - gac_file, meta_data, - output_file_prefix, avhrr_dir, qual_dir, sunsatangles_dir): + gac_file, meta_data): midnight_scanline = meta_data['midnight_scanline'] miss_lines = meta_data['missing_scanlines'] @@ -193,7 +207,7 @@ def save_gac(satellite_name, sun_zen, sat_zen, sun_azi, sat_azi, rel_azi, qual_flags, start_line, end_line, total_number_of_scan_lines, last_scan_line_number, corr, gac_file, midnight_scanline, - miss_lines, output_file_prefix, avhrr_dir, qual_dir, sunsatangles_dir) + miss_lines) def avhrrGAC_io(satellite_name, xutcs, startdate, enddate, starttime, endtime, @@ -201,7 +215,11 @@ def avhrrGAC_io(satellite_name, xutcs, startdate, enddate, starttime, endtime, arrSZA, arrSTZ, arrSAA, arrSTA, arrRAA, qual_flags, start_line, end_line, total_number_of_scan_lines, last_scan_line_number, corr, gac_file, midnight_scanline, - miss_lines, output_file_prefix, avhrr_dir, qual_dir, sunsatangles_dir): + miss_lines): + import os + + # Read output dir etc from config file + OUTPUT_FILE_PREFIX, SUNSATANGLES_DIR, AVHRR_DIR, QUAL_DIR = read_config() # Calculate start and end time in sec1970 t_obj = time.strptime(startdate + starttime[0:6], "%Y%m%d%H%M%S") @@ -209,9 +227,9 @@ def avhrrGAC_io(satellite_name, xutcs, startdate, enddate, starttime, endtime, t_obj = time.strptime(enddate + endtime[0:6], "%Y%m%d%H%M%S") endtime_sec1970 = calendar.timegm(t_obj) - LOG.info('Output file prefix = ' + str(output_file_prefix)) - LOG.info('AVHRR data will be written to ' + str(avhrr_dir)) - ofn = os.path.join(avhrr_dir, (output_file_prefix + '_avhrr_' + + LOG.info('Output file prefix = ' + str(OUTPUT_FILE_PREFIX)) + LOG.info('AVHRR data will be written to ' + str(AVHRR_DIR)) + ofn = os.path.join(AVHRR_DIR, (OUTPUT_FILE_PREFIX + '_avhrr_' + satellite_name + '_99999_' + startdate + 'T' + starttime + 'Z_' + enddate + 'T' + endtime + 'Z.h5')) @@ -420,9 +438,9 @@ def avhrrGAC_io(satellite_name, xutcs, startdate, enddate, starttime, endtime, fout.close() LOG.info('Sun and Satellite viewing angles will be ' + - 'written to ' + str(sunsatangles_dir)) - ofn = os.path.join(sunsatangles_dir, - (output_file_prefix + '_sunsatangles_' + + 'written to ' + str(SUNSATANGLES_DIR)) + ofn = os.path.join(SUNSATANGLES_DIR, + (OUTPUT_FILE_PREFIX + '_sunsatangles_' + satellite_name + '_99999_' + startdate + 'T' + starttime + 'Z_' + enddate + 'T' + endtime + 'Z.h5')) @@ -519,7 +537,7 @@ def avhrrGAC_io(satellite_name, xutcs, startdate, enddate, starttime, endtime, g4.attrs["dataset_name"] = np.string_('Solar azimuth angle') g4.attrs["units"] = np.string_('Deg') g4.attrs["gain"] = np.float32(0.01) - g4.attrs["offset"] = np.float32(0.0) + g4.attrs["offset"] = np.float32(180.0) g4.attrs["missingdata"] = np.int32(MISSING_DATA) g4.attrs["nodata"] = np.int32(MISSING_DATA) g4.attrs["starttime"] = np.string_(starttime[0:6]) @@ -532,7 +550,7 @@ def avhrrGAC_io(satellite_name, xutcs, startdate, enddate, starttime, endtime, g5.attrs["dataset_name"] = np.string_('Satellite azimuth angle') g5.attrs["units"] = np.string_('Deg') g5.attrs["gain"] = np.float32(0.01) - g5.attrs["offset"] = np.float32(0.0) + g5.attrs["offset"] = np.float32(180.0) g5.attrs["missingdata"] = np.int32(MISSING_DATA) g5.attrs["nodata"] = np.int32(MISSING_DATA) g5.attrs["starttime"] = np.string_(starttime[0:6]) @@ -584,9 +602,9 @@ def avhrrGAC_io(satellite_name, xutcs, startdate, enddate, starttime, endtime, fout.close() LOG.info('Quality flags will be ' + - 'written to ' + str(qual_dir)) - ofn = os.path.join(qual_dir, - (output_file_prefix + '_qualflags_' + + 'written to ' + str(QUAL_DIR)) + ofn = os.path.join(QUAL_DIR, + (OUTPUT_FILE_PREFIX + '_qualflags_' + satellite_name + '_99999_' + startdate + 'T' + starttime + 'Z_' + enddate + 'T' + endtime + 'Z.h5')) diff --git a/pygac/klm_reader.py b/pygac/klm_reader.py index b9272519..852c3374 100644 --- a/pygac/klm_reader.py +++ b/pygac/klm_reader.py @@ -33,11 +33,6 @@ import datetime import logging -try: - from enum import IntFlag -except ImportError: - # python version < 3.6, use a simple object without nice representation - IntFlag = object import numpy as np @@ -47,54 +42,6 @@ LOG = logging.getLogger(__name__) - -class KLM_QualityIndicator(IntFlag): - """Quality Indicators. - - Source: - KLM guide - Table 8.3.1.3.3.1-1. Format of packed LAC/HRPT Data Sets (Version 2, pre-April 28, 2005). - Table 8.3.1.3.3.2-1. Format of LAC/HRPT Data Record for NOAA-N (Version 5, post-November 14, - 2006, all spacecraft). - Table 8.3.1.4.3.1-1. Format of packed GAC Data Record for NOAA KLM (Version 2, pre-April 28, 2005). - Table 8.3.1.4.3.2-1. Format of GAC Data Record for NOAA-N (Version 4, post-January 25, 2006, - all spacecraft). - - Note: - Table 8.3.1.3.3.1-1. and Table 8.3.1.4.3.1-1. define bit: 21 as - "frame sync word not valid" - Table 8.3.1.3.3.2-1. and Table 8.3.1.4.3.2-1. define bit: 21 as - "flywheeling detected during this frame" - """ - FATAL_FLAG = 2**31 # Data should not be used for product generation - TIME_ERROR = 2**30 # Time sequence error detected within this scan - DATA_GAP = 2**29 # Data gap precedes this scan - CALIBRATION = 2**28 # Insufficient data for calibration - NO_EARTH_LOCATION = 2**27 # Earth location data not available - CLOCK_UPDATE = 2**26 # First good time following a clock update (nominally 0) - INSTRUMENT_CHANGE = 2**25 # Instrument status changed with this scan - BIT_SYNC_STATUS = 2**24 # Sync lock dropped during this frame - SYNC_ERROR = 2**23 # Frame sync word error greater than zero - FRAME_SYNC_LOCK = 2**22 # Frame sync previously dropped lock - SYNC_INVALID = 2**21 # Frame sync word not valid - FLYWHEELING = 2**21 # Flywheeling detected during this frame - BIT_SLIPPAGE = 2**20 # Bit slippage detected during this frame - # Note: Bit 19 - 9 are not defined for KLMs - TIP_PARITY = 2**8 # TIP parity error detected - # Reflected Sunlight (RS) detected (solar blackbody contamination) - CH_3B_RS = 2**7 - CH_3B_RS_ANOMALY = 2**6 - CH_3_CONTAMINATION = CH_3B_RS | CH_3B_RS_ANOMALY # POD compatible alias - CH_4_RS = 2**5 - CH_4_RS_ANOMALY = 2**4 - CH_4_CONTAMINATION = CH_4_RS | CH_4_RS_ANOMALY # POD compatible alias - CH_5_RS = 2**3 - CH_5_RS_ANOMALY = 2**2 - CH_5_CONTAMINATION = CH_5_RS | CH_5_RS_ANOMALY # POD compatible alias - DATA_JITTER = 2**1 # Resync occurred on this frame - PSEUDO_NOISE = 2**0 # Pseudo noise occurred on this frame - - # GAC header object header = np.dtype([("data_set_creation_site_id", "S3"), @@ -616,7 +563,6 @@ class KLMReader(Reader): 8: 'noaa19', 12: 'metopa', 11: 'metopb', - 13: 'metopc', } spacecrafts_orbital = {4: 'noaa 15', 2: 'noaa 16', @@ -625,14 +571,10 @@ class KLMReader(Reader): 8: 'noaa 19', 12: 'metop 02', 11: 'metop 01', - 13: 'metop 03', } tsm_affected_intervals = TSM_AFFECTED_INTERVALS_KLM - QFlag = KLM_QualityIndicator - _quality_indicators_key = "quality_indicator_bit_field" - def read(self, filename, fileobj=None): """Read the data. @@ -793,6 +735,32 @@ def get_ch3_switch(self): """ return self.scans["scan_line_bit_field"][:] & 3 + def _get_corrupt_mask(self): + """Get mask for corrupt scanlines.""" + mask = ((self.scans["quality_indicator_bit_field"] >> 31) | + ((self.scans["quality_indicator_bit_field"] << 3) >> 31) | + ((self.scans["quality_indicator_bit_field"] << 4) >> 31)) + return mask.astype(bool) + + def get_qual_flags(self): + """Read quality flags.""" + number_of_scans = self.scans["telemetry"].shape[0] + qual_flags = np.zeros((int(number_of_scans), 7)) + qual_flags[:, 0] = self.scans["scan_line_number"] + qual_flags[:, 1] = (self.scans["quality_indicator_bit_field"] >> 31) + qual_flags[:, 2] = ( + (self.scans["quality_indicator_bit_field"] << 3) >> 31) + qual_flags[:, 3] = ( + (self.scans["quality_indicator_bit_field"] << 4) >> 31) + qual_flags[:, 4] = ( + (self.scans["quality_indicator_bit_field"] << 24) >> 30) + qual_flags[:, 5] = ( + (self.scans["quality_indicator_bit_field"] << 26) >> 30) + qual_flags[:, 6] = ( + (self.scans["quality_indicator_bit_field"] << 28) >> 30) + + return qual_flags + def postproc(self, channels): """Apply KLM specific postprocessing. @@ -805,11 +773,8 @@ def postproc(self, channels): channels[:, :, 3][switch == 2] = np.nan def _adjust_clock_drift(self): - """Adjust the geolocation to compensate for the clock error. - Note: - Clock drift correction is only applied to POD satellites. - On the KLM series, the clock is updated daily. - """ + """Clock drift correction is only applied to POD satellites.""" + pass def get_tsm_pixels(self, channels): """Determine pixels affected by the scan motor issue. diff --git a/pygac/pod_reader.py b/pygac/pod_reader.py index be7e6cf6..db100aae 100644 --- a/pygac/pod_reader.py +++ b/pygac/pod_reader.py @@ -36,65 +36,15 @@ import datetime import logging -try: - from enum import IntFlag -except ImportError: - # python version < 3.6, use a simple object without nice representation - IntFlag = object import numpy as np -from pyorbital.geoloc_instrument_definitions import avhrr_gac -from pyorbital.geoloc import compute_pixels, get_lonlatalt - -from pygac.clock_offsets_converter import get_offsets from pygac.correct_tsm_issue import TSM_AFFECTED_INTERVALS_POD, get_tsm_idx from pygac.reader import Reader, ReaderError -from pygac.slerp import slerp from pygac.utils import file_opener LOG = logging.getLogger(__name__) - -class POD_QualityIndicator(IntFlag): - """Quality Indicators. - - Source: - POD guide Table 3.1.2.1-2. Format of quality indicators. - """ - # POD guide Table 3.1.2.1-2. Format of quality indicators. - FATAL_FLAG = 2**31 # Data should not be used for product generation - TIME_ERROR = 2**30 # A time sequence error was detected while Processing - # this frame - DATA_GAP = 2**29 # A gap precedes this frame - DATA_JITTER = 2**28 # Resync occurred on this frame - CALIBRATION = 2**27 # Insufficient data for calibration - NO_EARTH_LOCATION = 2**26 # Earth location data not available - ASCEND_DESCEND = 2**25 # AVHRR Earth location indication of Ascending (=0) - # or descending (=1) data - PSEUDO_NOISE = 2**24 # Pseudo Noise (P/N) occurred (=1) on the frame, - # data not used for calibration computations - BIT_SYNC_STATUS = 2**23 # Drop lock during frame - SYNC_ERROR = 2**22 # Frame Sync word error greater than zero - FRAME_SYNC_LOCK = 2**21 # Frame Sync previously dropped lock - FLYWHEELING = 2**20 # Flywheeling detected during this frame - BIT_SLIPPAGE = 2**19 # Bit slippage detected during this frame - # Solar blackbody contamination indicator - # 0 = no correction - # 1 = solar contamination corrected - CH_3_CONTAMINATION = 2**18 # Channel 3 solar blackbody contamination - CH_4_CONTAMINATION = 2**17 # Channel 4 solar blackbody contamination - CH_5_CONTAMINATION = 2**16 # Channel 5 solar blackbody contamination - # TIP Parity - TIP_PARITY_1 = 2**15 # In first minor frame - TIP_PARITY_2 = 2**14 # In second minor frame - TIP_PARITY_3 = 2**13 # In third minor frame - TIP_PARITY_4 = 2**12 # In fourth minor frame - TIP_PARITY_5 = 2**11 # In fifth minor frame - # Note: Bit 10 to 8, and 1 to 0 are spare bits. 7 to 2 define - # "SYNC ERRORS - Number of bit errors in frame sync" (6 bit integer?) - - # common header header0 = np.dtype([("noaa_spacecraft_identification_code", ">u1"), ("data_type_code", ">u1"), @@ -237,9 +187,6 @@ class PODReader(Reader): tsm_affected_intervals = TSM_AFFECTED_INTERVALS_POD - QFlag = POD_QualityIndicator - _quality_indicators_key = "quality_indicators" - def correct_scan_line_numbers(self): """Correct the scan line numbers.""" # Perform common corrections first. @@ -353,7 +300,7 @@ def read_header(cls, filename, fileobj=None): @classmethod def _validate_header(cls, header): - """Check if the header belongs to this reader.""" + """Check if the header belongs to this reader""" # call super to enter the Method Resolution Order (MRO) super(PODReader, cls)._validate_header(header) LOG.debug("validate header") @@ -417,101 +364,79 @@ def decode_timestamps(encoded): def _get_times(self): return self.decode_timestamps(self.scans["time_code"]) - def _compute_missing_lonlat(self, missed_utcs): - """compute lon lat values using pyorbital""" - tic = datetime.datetime.now() - - scan_rate = datetime.timedelta(milliseconds=1/self.scan_freq).total_seconds() - sgeom = avhrr_gac(missed_utcs.astype(datetime.datetime), - self.scan_points, frequency=scan_rate) - t0 = missed_utcs[0].astype(datetime.datetime) - s_times = sgeom.times(t0) - tle1, tle2 = self.get_tle_lines() - - rpy = self.get_attitude_coeffs() - pixels_pos = compute_pixels((tle1, tle2), sgeom, s_times, rpy) - pos_time = get_lonlatalt(pixels_pos, s_times) - - missed_lons, missed_lats = pos_time[:2] - - pixels_per_line = self.lats.shape[1] - missed_lons = missed_lons.reshape(-1, pixels_per_line) - missed_lats = missed_lats.reshape(-1, pixels_per_line) - - toc = datetime.datetime.now() - LOG.warning("Computation of geolocation: %s", str(toc - tic)) - - return missed_lons, missed_lats - def _adjust_clock_drift(self): - """Adjust the geolocation to compensate for the clock error.""" + """Adjust the geolocation to compensate for the clock error. + + TODO: bad things might happen when scanlines are skipped. + """ tic = datetime.datetime.now() self.get_times() + from pygac.clock_offsets_converter import get_offsets try: - error_utcs, clock_error = get_offsets(self.spacecraft_name) + offset_times, clock_error = get_offsets(self.spacecraft_name) except KeyError: LOG.info("No clock drift info available for %s", self.spacecraft_name) - return - - error_utcs = np.array(error_utcs, dtype='datetime64[ms]') - # interpolate to get the clock offsets at the scan line utcs - # the clock_error is given in seconds, so offsets are in seconds, too. - offsets = np.interp(self.utcs.astype(np.uint64), - error_utcs.astype(np.uint64), - clock_error) - LOG.info("Adjusting for clock drift of %s to %s seconds.", - str(min(offsets)), - str(max(offsets))) - - # For the interpolation of geolocations, we need to prepend/append - # lines. The conversion from offset to line numbers is given by the - # scan rate = 1/scan frequency. - scan_rate = datetime.timedelta(milliseconds=1/self.scan_freq) - offset_lines = offsets / scan_rate.total_seconds() - - # To avoid trouble with missing lines, we will construct an - # array that covers the whole interpolation range. - scan_lines = self.scans["scan_line_number"] - shifted_lines = scan_lines - offset_lines - shifted_lines_floor = np.floor(shifted_lines).astype(int) - # compute the line range, note that the max requires a "+1" - # to cover the interpolation range because of the floor. - min_line = min(scan_lines.min(), shifted_lines_floor.min()) - max_line = max(scan_lines.max(), shifted_lines_floor.max()+1) - num_lines = max_line - min_line + 1 - missed_lines = np.setdiff1d(np.arange(min_line, max_line+1), scan_lines) - missed_utcs = ((missed_lines - scan_lines[0])*np.timedelta64(scan_rate, "ms") - + self.utcs[0]) - # calculate the missing geo locations - missed_lons, missed_lats = self._compute_missing_lonlat(missed_utcs) - - # create arrays of lons and lats for interpolation. The locations - # correspond to not yet corrected utcs, i.e. the time difference from - # one line to the other should be equal to the scan rate. - pixels_per_line = self.lats.shape[1] - complete_lons = np.full((num_lines, pixels_per_line), np.nan, - dtype=np.float) - complete_lats = np.full((num_lines, pixels_per_line), np.nan, - dtype=np.float) - - complete_lons[scan_lines - min_line] = self.lons - complete_lats[scan_lines - min_line] = self.lats - complete_lons[missed_lines - min_line] = missed_lons - complete_lats[missed_lines - min_line] = missed_lats - - # perform the slerp interpolation to the corrected utc times - slerp_t = shifted_lines - shifted_lines_floor # in [0, 1) - slerp_res = slerp(complete_lons[shifted_lines_floor - min_line, :], - complete_lats[shifted_lines_floor - min_line, :], - complete_lons[shifted_lines_floor - min_line + 1, :], - complete_lats[shifted_lines_floor - min_line + 1, :], - slerp_t[:, np.newaxis, np.newaxis]) - - # set corrected values - self.lons = slerp_res[:, :, 0] - self.lats = slerp_res[:, :, 1] - self.utcs -= (offsets * 1000).astype('timedelta64[ms]') + else: + offset_times = np.array(offset_times, dtype='datetime64[ms]') + offsets = np.interp(self.utcs.astype(np.uint64), + offset_times.astype(np.uint64), + clock_error) + LOG.info("Adjusting for clock drift of %s to %s", + str(min(offsets)), + str(max(offsets))) + self.times = (self.utcs + + offsets.astype('timedelta64[s]')).astype(datetime.datetime) + offsets *= -2 + + int_offsets = np.floor(offsets).astype(np.int) + + # filling out missing geolocations with computation from pyorbital. + line_indices = (self.scans["scan_line_number"] + + int_offsets) + + missed = sorted((set(line_indices) | + set(line_indices + 1)) + - set(self.scans["scan_line_number"])) + + min_idx = min(line_indices) + max_idx = max(max(line_indices), + max(self.scans["scan_line_number"] - min_idx)) + 1 + idx_len = max_idx - min_idx + 2 + + complete_lons = np.full((idx_len, self.lats.shape[1]), np.nan, + dtype=np.float) + complete_lats = np.full((idx_len, self.lats.shape[1]), np.nan, + dtype=np.float) + + complete_lons[self.scans["scan_line_number"] - min_idx] = self.lons + complete_lats[self.scans["scan_line_number"] - min_idx] = self.lats + + missed_utcs = ((np.array(missed) - 1) * np.timedelta64(500, "ms") + + self.utcs[0]) + try: + mlons, mlats = self.compute_lonlat(width=self.lats.shape[1], + utcs=missed_utcs, + clock_drift_adjust=True) + except IndexError as err: + LOG.warning( + 'Cannot perform clock drift correction: %s', str(err)) + return + + complete_lons[missed - min_idx] = mlons + complete_lats[missed - min_idx] = mlats + + from pygac.slerp import slerp + off = offsets - np.floor(offsets) + res = slerp(complete_lons[line_indices - min_idx, :], + complete_lats[line_indices - min_idx, :], + complete_lons[line_indices - min_idx + 1, :], + complete_lats[line_indices - min_idx + 1, :], + off[:, np.newaxis, np.newaxis]) + + self.lons = res[:, :, 0] + self.lats = res[:, :, 1] + self.utcs += offsets.astype('timedelta64[s]') toc = datetime.datetime.now() LOG.debug("clock drift adjustment took %s", str(toc - tic)) @@ -554,6 +479,27 @@ def get_telemetry(self): return prt_counts, ict_counts, space_counts + def _get_corrupt_mask(self): + """Get mask for corrupt scanlines.""" + mask = ((self.scans["quality_indicators"] >> 31) | + ((self.scans["quality_indicators"] << 4) >> 31) | + ((self.scans["quality_indicators"] << 5) >> 31)) + return mask.astype(bool) + + def get_qual_flags(self): + """Read quality flags.""" + number_of_scans = self.scans["telemetry"].shape[0] + qual_flags = np.zeros((int(number_of_scans), 7)) + qual_flags[:, 0] = self.scans["scan_line_number"] + qual_flags[:, 1] = (self.scans["quality_indicators"] >> 31) + qual_flags[:, 2] = ((self.scans["quality_indicators"] << 4) >> 31) + qual_flags[:, 3] = ((self.scans["quality_indicators"] << 5) >> 31) + qual_flags[:, 4] = ((self.scans["quality_indicators"] << 13) >> 31) + qual_flags[:, 5] = ((self.scans["quality_indicators"] << 14) >> 31) + qual_flags[:, 6] = ((self.scans["quality_indicators"] << 15) >> 31) + + return qual_flags + def postproc(self, channels): """No POD specific postprocessing to be done.""" pass diff --git a/pygac/reader.py b/pygac/reader.py index 1c4348df..1f48450b 100644 --- a/pygac/reader.py +++ b/pygac/reader.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- # Copyright (c) 2014, 2019 Pygac Developers @@ -35,12 +36,13 @@ import warnings import pyorbital +from pygac.configuration import get_config from pygac.utils import (centered_modulus, calculate_sun_earth_distance_correction, get_absolute_azimuth_angle_diff) from pyorbital.orbital import Orbital from pyorbital import astronomy -from pygac.calibration import Calibrator, calibrate_solar, calibrate_thermal +from pygac.calibration import calibrate_solar, calibrate_thermal from pygac import gac_io from distutils.version import LooseVersion @@ -88,8 +90,7 @@ class Reader(six.with_metaclass(ABCMeta)): r'\w{3}\.\w{4}\.\w{2}.D\d{5}\.S\d{4}\.E\d{4}\.B\d{7}\.\w{2}') def __init__(self, interpolate_coords=True, adjust_clock_drift=True, - tle_dir=None, tle_name=None, tle_thresh=7, creation_site=None, - custom_calibration=None, calibration_file=None): + tle_dir=None, tle_name=None, tle_thresh=7, creation_site=None): """Init the reader. Args: @@ -102,9 +103,7 @@ def __init__(self, interpolate_coords=True, adjust_clock_drift=True, tle_thresh: Maximum number of days between observation and nearest TLE creation_site: The three-letter identifier of the creation site (eg 'NSS') - custom_calibration: dictionary with a subset of user defined satellite specific - calibration coefficients - calibration_file: path to json file containing default calibrations + filename: GAC/LAC filename """ self.meta_data = {} @@ -114,8 +113,6 @@ def __init__(self, interpolate_coords=True, adjust_clock_drift=True, self.tle_name = tle_name self.tle_thresh = tle_thresh self.creation_site = (creation_site or 'NSS').encode('utf-8') - self.custom_calibration = custom_calibration - self.calibration_file = calibration_file self.head = None self.scans = None self.spacecraft_name = None @@ -123,15 +120,10 @@ def __init__(self, interpolate_coords=True, adjust_clock_drift=True, self.utcs = None self.lats = None self.lons = None + self.times = None self.tle_lines = None self.filename = None self._mask = None - self._rpy = None - - @property - def times(self): - """The UTCs as datetime.datetime""" - return self.to_datetime(self.utcs) @property def filename(self): @@ -144,23 +136,12 @@ def filename(self, filepath): if filepath is None: self._filename = None else: - filepath = os.fspath(filepath) match = self.data_set_pattern.search(filepath) if match: self._filename = match.group() else: self._filename = os.path.basename(filepath) - @property - def calibration(self): - """Get the property 'calibration'.""" - calibration = Calibrator( - self.spacecraft_name, - custom_coeffs=self.custom_calibration, - coeffs_file=self.calibration_file - ) - return calibration - @abstractmethod def read(self, filename, fileobj=None): """Read the GAC/LAC data. @@ -244,7 +225,7 @@ def _validate_header(cls, header): # each child class which implements this method, should call the # super method to enter into the method resolution order. # See https://docs.python.org/3/library/functions.html#super - # second use case "diamond diagrams". + # second use case “diamond diagrams”. # Check if the data set name matches the pattern LOG.debug("validate header") data_set_name = header['data_set_name'].decode(errors='ignore') @@ -323,12 +304,8 @@ def _get_calibrated_channels_uniform_shape(self): assert channels.shape[-1] == 6 return channels - def save(self, start_line, end_line, output_file_prefix="PyGAC", output_dir="./", - avhrr_dir=None, qual_dir=None, sunsatangles_dir=None): + def save(self, start_line, end_line): """Convert the Reader instance content into hdf5 files""" - avhrr_dir = avhrr_dir or output_dir - qual_dir = qual_dir or output_dir - sunsatangles_dir = sunsatangles_dir or output_dir self.get_lonlat() channels = self._get_calibrated_channels_uniform_shape() sat_azi, sat_zen, sun_azi, sun_zen, rel_azi = self.get_angles() @@ -344,8 +321,7 @@ def save(self, start_line, end_line, output_file_prefix="PyGAC", output_dir="./" channels[:, :, 4], channels[:, :, 5], sun_zen, sat_zen, sun_azi, sat_azi, rel_azi, qual_flags, start_line, end_line, - self.filename, self.meta_data, - output_file_prefix, avhrr_dir, qual_dir, sunsatangles_dir + self.filename, self.meta_data ) @abstractmethod @@ -426,6 +402,9 @@ def get_times(self): self.utcs = self.to_datetime64(year=year, jday=jday, msec=msec) self.correct_times_thresh() + # Convert timestamps to datetime objects + self.times = self.to_datetime(self.utcs) + return self.utcs @staticmethod @@ -441,8 +420,8 @@ def to_datetime64(year, jday, msec): numpy.datetime64: Converted timestamps """ - return (year.astype(str).astype('datetime64[Y]') - + (jday - 1).astype('timedelta64[D]') + return (((year - 1970).astype('datetime64[Y]') + + (jday - 1).astype('timedelta64[D]')).astype('datetime64[ms]') + msec.astype('timedelta64[ms]')) @staticmethod @@ -473,6 +452,74 @@ def lineno2msec(self, scan_line_number): """ return (scan_line_number - 1) / self.scan_freq + def compute_lonlat(self, width, utcs=None, clock_drift_adjust=True): + """Compute lat/lon coordinates. + + Args: + width: Number of coordinates per scanlines + utcs: Scanline timestamps + clock_drift_adjust: If True, adjust clock drift. + + """ + if utcs is None: + utcs = self.get_times() + + # adjusting clock for drift + tic = datetime.datetime.now() + if clock_drift_adjust: + from pygac.clock_offsets_converter import get_offsets + try: + offset_times, clock_error = get_offsets(self.spacecraft_name) + except KeyError: + LOG.info("No clock drift info available for %s", + self.spacecraft_name) + else: + offset_times = np.array(offset_times, dtype='datetime64[ms]') + offsets = np.interp(utcs.astype(np.uint64), + offset_times.astype(np.uint64), + clock_error) + utcs = utcs - (offsets * 1000).astype('timedelta64[ms]') + + t = utcs[0].astype(datetime.datetime) + + if "constant_yaw_attitude_error" in self.head.dtype.fields: + rpy = np.deg2rad([self.head["constant_roll_attitude_error"] / 1e3, + self.head["constant_pitch_attitude_error"] / 1e3, + self.head["constant_yaw_attitude_error"] / 1e3]) + else: + try: + # This needs to be checked thoroughly first + # rpy_spacecraft = rpy_coeffs[self.spacecraft_name] + # rpy = [rpy_spacecraft['roll'], + # rpy_spacecraft['pitch'], + # rpy_spacecraft['yaw']] + # LOG.debug("Using static attitude correction") + raise KeyError + except KeyError: + LOG.debug("Not applying attitude correction") + rpy = [0, 0, 0] + + LOG.info("Using rpy: %s", str(rpy)) + + from pyorbital.geoloc_instrument_definitions import avhrr_gac + from pyorbital.geoloc import compute_pixels, get_lonlatalt + # TODO: Are we sure all satellites have this scan width in degrees ? + sgeom = avhrr_gac(utcs.astype(datetime.datetime), + self.scan_points, 55.385) + s_times = sgeom.times(t) + tle1, tle2 = self.get_tle_lines() + + pixels_pos = compute_pixels((tle1, tle2), sgeom, s_times, rpy) + pos_time = get_lonlatalt(pixels_pos, s_times) + + toc = datetime.datetime.now() + + LOG.warning("Computation of geolocation: %s", str(toc - tic)) + + lons, lats = pos_time[:2] + + return lons.reshape(-1, width), lats.reshape(-1, width) + def get_sun_earth_distance_correction(self): """Get the julian day and the sun-earth distance correction.""" self.get_times() @@ -488,33 +535,26 @@ def update_meta_data(self): self.meta_data['midnight_scanline'] = self.get_midnight_scanline() if 'missing_scanlines' not in self.meta_data: self.meta_data['missing_scanlines'] = self.get_miss_lines() - if 'gac_header' not in self.meta_data: - self.meta_data['gac_header'] = self.head.copy() - self.meta_data['calib_coeffs_version'] = self.calibration.version def get_calibrated_channels(self): """Calibrate and return the channels.""" channels = self.get_counts() - times = self.times self.get_times() self.update_meta_data() - year = times[0].year - delta = times[0].date() - datetime.date(year, 1, 1) + year = self.times[0].year + delta = self.times[0].date() - datetime.date(year, 1, 1) jday = delta.days + 1 corr = self.meta_data['sun_earth_distance_correction_factor'] - calibration_coeffs = self.calibration # how many reflective channels are there ? tot_ref = channels.shape[2] - 3 - channels[:, :, 0:tot_ref] = calibrate_solar( - channels[:, :, 0:tot_ref], - np.arange(tot_ref), - year, jday, - calibration_coeffs, - corr - ) + channels[:, :, 0:tot_ref] = calibrate_solar(channels[:, :, 0:tot_ref], + np.arange(tot_ref), + year, jday, + self.spacecraft_name, + corr) prt, ict, space = self.get_telemetry() for chan in [3, 4, 5]: channels[:, :, chan - 6] = calibrate_thermal( @@ -524,8 +564,7 @@ def get_calibrated_channels(self): space[:, chan - 3], self.scans["scan_line_number"], chan, - calibration_coeffs - ) + self.spacecraft_name) # Mask out corrupt values channels[self.mask] = np.nan @@ -580,34 +619,10 @@ def mask(self): self._mask = self._get_corrupt_mask() return self._mask - def _get_corrupt_mask(self, flags=None): - """Readout of corrupt scanline mask. - - Args: - flags (QFlag.flag): An "ORed" bitmask that defines corrupt values. - Defauts to (QFlag.FATAL_FLAG | QFlag.CALIBRATION - | QFlag.NO_EARTH_LOCATION) - - Note: - The Quality flags mapping (QFlag) is KLM/POD specific. - """ - QFlag = self.QFlag - if flags is None: - flags = QFlag.FATAL_FLAG | QFlag.CALIBRATION | QFlag.NO_EARTH_LOCATION - return (self.scans[self._quality_indicators_key] & int(flags)).astype(bool) - - def get_qual_flags(self): - """Read quality flags.""" - number_of_scans = self.scans["telemetry"].shape[0] - qual_flags = np.zeros((int(number_of_scans), 7)) - qual_flags[:, 0] = self.scans["scan_line_number"] - qual_flags[:, 1] = self._get_corrupt_mask(flags=self.QFlag.FATAL_FLAG) - qual_flags[:, 2] = self._get_corrupt_mask(flags=self.QFlag.CALIBRATION) - qual_flags[:, 3] = self._get_corrupt_mask(flags=self.QFlag.NO_EARTH_LOCATION) - qual_flags[:, 4] = self._get_corrupt_mask(flags=self.QFlag.CH_3_CONTAMINATION) - qual_flags[:, 5] = self._get_corrupt_mask(flags=self.QFlag.CH_4_CONTAMINATION) - qual_flags[:, 6] = self._get_corrupt_mask(flags=self.QFlag.CH_5_CONTAMINATION) - return qual_flags + @abstractmethod + def _get_corrupt_mask(self): + """KLM/POD specific readout of corrupt scanline mask.""" + raise NotImplementedError @abstractmethod def postproc(self, channels): @@ -643,10 +658,13 @@ def tle2datetime64(times): def get_tle_file(self): """Find TLE file for the current satellite.""" tle_dir, tle_name = self.tle_dir, self.tle_name - if tle_dir is None: - raise RuntimeError("TLE directory not specified!") - if tle_name is None: - raise RuntimeError("TLE name not specified!") + + # If user didn't specify TLE dir/name, try config file + if tle_dir is None or tle_name is None: + conf = get_config() + tle_dir = conf.get('tle', 'tledir', raw=True) + tle_name = conf.get('tle', 'tlename', raw=True) + values = {"satname": self.spacecraft_name, } tle_filename = os.path.join(tle_dir, tle_name % values) LOG.info('TLE filename = ' + str(tle_filename)) @@ -669,7 +687,7 @@ def get_tle_lines(self): return self.tle_lines self.get_times() tle_data = self.read_tle_file(self.get_tle_file()) - sdate = self.utcs[0] + sdate = np.datetime64(self.times[0], '[ms]') dates = self.tle2datetime64( np.array([float(line[18:32]) for line in tle_data[::2]])) @@ -759,7 +777,7 @@ def get_angles(self): sun_zenith = astronomy.sun_zenith_angle(self.times[:, np.newaxis], self.lons, self.lats) - alt, sun_azi = astronomy.get_alt_az(times[:, np.newaxis], + alt, sun_azi = astronomy.get_alt_az(self.times[:, np.newaxis], self.lons, self.lats) del alt sun_azi = np.rad2deg(sun_azi) @@ -1029,7 +1047,8 @@ def is_tsm_affected(self): """ self.get_times() - ts, te = self.to_datetime(self.utcs[[0, -1]]) + ts = self.times[0] + te = self.times[-1] try: for interval in self.tsm_affected_intervals[self.spacecraft_id]: if ts >= interval[0] and te <= interval[1]: @@ -1090,29 +1109,6 @@ def get_tsm_pixels(self, channels): """ raise NotImplementedError - def get_attitude_coeffs(self): - """Return the roll, pitch, yaw values""" - if self._rpy is None: - if "constant_yaw_attitude_error" in self.head.dtype.fields: - rpy = np.deg2rad([self.head["constant_roll_attitude_error"] / 1e3, - self.head["constant_pitch_attitude_error"] / 1e3, - self.head["constant_yaw_attitude_error"] / 1e3]) - else: - try: - # This needs to be checked thoroughly first - # rpy_spacecraft = rpy_coeffs[self.spacecraft_name] - # rpy = np.array([rpy_spacecraft['roll'], - # rpy_spacecraft['pitch'], - # rpy_spacecraft['yaw']]) - # LOG.debug("Using static attitude correction") - raise KeyError - except KeyError: - LOG.debug("Not applying attitude correction") - rpy = np.zeros(3) - LOG.info("Using rpy: %s", str(rpy)) - self._rpy = rpy - return self._rpy - def inherit_doc(cls): """Make a class method inherit its docstring from the parent class. diff --git a/pygac/runner.py b/pygac/runner.py index 7fd72140..10d08204 100644 --- a/pygac/runner.py +++ b/pygac/runner.py @@ -29,14 +29,12 @@ class for a given file. import datetime import logging -import os from pygac.gac_klm import GACKLMReader from pygac.gac_pod import GACPODReader from pygac.lac_klm import LACKLMReader from pygac.lac_pod import LACPODReader from pygac.utils import file_opener -from pygac.configuration import get_config LOG = logging.getLogger(__name__) @@ -71,45 +69,20 @@ def process_file(filename, start_line, end_line, fileobj=None): config file. The three files contain the avhrr data, quality flags, and sunsatangles. - Argsuments - filename (str): Path to GAC/LAC file - start_line (int): First scanline to be processed (0-based) - end_line (int): Last scanline to be processed (0-based), - set to 0 for the last available scanline - fileobj: An open file object to read from. (optional) - - Note - This function expects an initialized config file. + Args: + filename (str): Path to GAC/LAC file + start_line (int): First scanline to be processed (0-based) + end_line (int): Last scanline to be processed (0-based), + set to 0 for the last available scanline + fileobj: An open file object to read from. (optional) """ tic = datetime.datetime.now() LOG.info("Process file: %s", str(filename)) - - # reader specific values - config = get_config() - tle_dir = config.get('tle', 'tledir', raw=True) - tle_name = config.get('tle', 'tlename', raw=True) - coeffs_file = config.get("calibration", "coeffs_file", fallback='') - # output specific values - output_dir = config.get('output', 'output_dir', raw=True) - output_file_prefix = config.get('output', 'output_file_prefix', raw=True) - avhrr_dir = os.environ.get('SM_AVHRR_DIR') - qual_dir = os.environ.get('SM_AVHRR_DIR') - sunsatangles_dir = os.environ.get('SM_SUNSATANGLES_DIR') - # Keep the file open while searching for the reader class and later # creation of the instance. with file_opener(fileobj or filename) as open_file: reader_cls = get_reader_class(filename, fileobj=open_file) - reader = reader_cls( - tle_dir=tle_dir, tle_name=tle_name, - calibration_file=coeffs_file - ) + reader = reader_cls() reader.read(filename, fileobj=fileobj) - reader.save( - start_line, end_line, - output_file_prefix=output_file_prefix, - output_dir=output_dir, - avhrr_dir=avhrr_dir, qual_dir=qual_dir, - sunsatangles_dir=sunsatangles_dir - ) + reader.save(start_line, end_line) LOG.info("Processing took: %s", str(datetime.datetime.now() - tic)) diff --git a/pygac/tests/__init__.py b/pygac/tests/__init__.py index 84bf9a56..56bd5bac 100644 --- a/pygac/tests/__init__.py +++ b/pygac/tests/__init__.py @@ -26,8 +26,7 @@ from pygac.tests import (test_calibrate_pod, test_slerp, test_calibrate_klm, test_pod, test_tsm, test_reader, test_io, - test_angles, test_init, test_utils, - test_calibration_coefficients) + test_angles, test_init, test_utils) import unittest @@ -37,7 +36,7 @@ def suite(): mysuite = unittest.TestSuite() tests = (test_slerp, test_calibrate_klm, test_calibrate_pod, test_pod, test_tsm, test_reader, test_io, test_angles, - test_init, test_utils, test_calibration_coefficients) + test_init, test_utils) for test in tests: mysuite.addTests(test.suite()) diff --git a/pygac/tests/test_calibrate_klm.py b/pygac/tests/test_calibrate_klm.py index 5d80ee27..8a489ce8 100644 --- a/pygac/tests/test_calibrate_klm.py +++ b/pygac/tests/test_calibrate_klm.py @@ -25,13 +25,10 @@ import unittest -try: - import mock -except ImportError: - from unittest import mock + import numpy as np -from pygac.calibration import Calibrator, calibrate_solar, calibrate_thermal +from pygac.calibration import calibrate_solar, calibrate_thermal class TestGenericCalibration(unittest.TestCase): @@ -47,21 +44,23 @@ def test_calibration_vis(self): year = 2010 jday = 1 spacecraft_id = "noaa19" - cal = Calibrator(spacecraft_id) corr = 1 channel = 0 - ref1 = calibrate_solar(counts[:, channel::5], channel, year, jday, cal, corr) + ref1 = calibrate_solar(counts[:, channel::5], channel, year, jday, + spacecraft_id, corr) channel = 1 - ref2 = calibrate_solar(counts[:, channel::5], channel, year, jday, cal, corr) + ref2 = calibrate_solar(counts[:, channel::5], channel, year, jday, + spacecraft_id, corr) channel = 2 data = np.ma.array(counts[:, channel::5], mask=True) - ref3 = calibrate_solar(data, channel, year, jday, cal, corr) + ref3 = calibrate_solar(data, channel, year, jday, + spacecraft_id, corr) expected = (np.array([[np.nan, 27.37909518, 110.60103456], [0.11943135, 6.03671211, 57.99695154]]), @@ -92,18 +91,17 @@ def test_calibration_ir(self): [986.3, 992.3, 988.9]]) spacecraft_id = "noaa19" - cal = Calibrator(spacecraft_id) ch3 = calibrate_thermal(counts[:, 2::5], prt_counts, ict_counts[:, 0], space_counts[:, 0], line_numbers=np.array([1, 2, 3]), channel=3, - cal=cal) + spacecraft=spacecraft_id) - expected_ch3 = np.array([[298.36742, 305.248478, 293.238328], - [296.960275, 306.493766, 294.488956], - [295.476935, 305.101309, 305.829827]]) + expected_ch3 = np.array([[298.36772477, 305.24899954, 293.23847375], + [296.96053595, 306.49432811, 294.48914038], + [295.47715016, 305.10182601, 305.83036782]]) np.testing.assert_allclose(expected_ch3, ch3) @@ -113,11 +111,11 @@ def test_calibration_ir(self): space_counts[:, 1], line_numbers=np.array([1, 2, 3]), channel=4, - cal=cal) + spacecraft=spacecraft_id) - expected_ch4 = np.array([[326.576534, 275.348988, 197.688755], - [323.013104, 313.207077, 249.36352], - [304.58091, 293.579308, 264.0631]]) + expected_ch4 = np.array([[326.57669548, 275.34893211, 197.68844955], + [323.01324859, 313.20717645, 249.3633716], + [304.58097221, 293.57932356, 264.0630027]]) np.testing.assert_allclose(expected_ch4, ch4) @@ -127,11 +125,11 @@ def test_calibration_ir(self): space_counts[:, 2], line_numbers=np.array([1, 2, 3]), channel=5, - cal=cal) + spacecraft=spacecraft_id) - expected_ch5 = np.array([[326.96161, 272.090164, 188.267991], - [323.156317, 312.673269, 244.184452], - [303.439383, 291.649444, 259.973091]]) + expected_ch5 = np.array([[326.96168274, 272.09013413, 188.26784127], + [323.15638147, 312.67331324, 244.18437795], + [303.43940924, 291.64944851, 259.97304154]]) np.testing.assert_allclose(expected_ch5, ch5) diff --git a/pygac/tests/test_calibrate_pod.py b/pygac/tests/test_calibrate_pod.py index 39f7fd9b..fe1bffc4 100644 --- a/pygac/tests/test_calibrate_pod.py +++ b/pygac/tests/test_calibrate_pod.py @@ -25,13 +25,10 @@ import unittest -try: - import mock -except ImportError: - from unittest import mock + import numpy as np -from pygac.calibration import Calibrator, calibrate_solar, calibrate_thermal +from pygac.calibration import calibrate_solar, calibrate_thermal class TestGenericCalibration(unittest.TestCase): @@ -47,22 +44,24 @@ def test_calibration_vis(self): year = 1997 jday = 196 spacecraft_id = "noaa14" - cal = Calibrator(spacecraft_id) corr = 1 channel = 0 - ref1 = calibrate_solar(counts[:, channel::5], channel, year, jday, cal, corr) + ref1 = calibrate_solar(counts[:, channel::5], channel, year, jday, + spacecraft_id, corr) channel = 1 - ref2 = calibrate_solar(counts[:, channel::5], channel, year, jday, cal, corr) + ref2 = calibrate_solar(counts[:, channel::5], channel, year, jday, + spacecraft_id, corr) channel = 2 data = np.ma.array(counts[:, channel::5], mask=True) - ref3 = calibrate_solar(data, channel, year, jday, cal, corr) + ref3 = calibrate_solar(data, channel, year, jday, + spacecraft_id, corr) expected = (np.array([[np.nan, 60.891074, 126.953364], [0., 14.091565, 85.195791]]), @@ -94,18 +93,17 @@ def test_calibration_ir(self): [986.3, 992.3, 988.9]]) spacecraft_id = "noaa14" - cal = Calibrator(spacecraft_id) ch3 = calibrate_thermal(counts[:, 2::5], prt_counts, ict_counts[:, 0], space_counts[:, 0], line_numbers=np.array([1, 2, 3]), channel=3, - cal=cal) + spacecraft=spacecraft_id) - expected_ch3 = np.array([[298.28466, 305.167571, 293.16182], - [296.878502, 306.414234, 294.410224], - [295.396779, 305.020259, 305.749526]]) + expected_ch3 = np.array([[298.28524223, 305.16852862, 293.16212655], + [296.87900835, 306.41526012, 294.41059746], + [295.39720547, 305.02120845, 305.75051609]]) np.testing.assert_allclose(expected_ch3, ch3) @@ -115,11 +113,11 @@ def test_calibration_ir(self): space_counts[:, 1], line_numbers=np.array([1, 2, 3]), channel=4, - cal=cal) + spacecraft=spacecraft_id) - expected_ch4 = np.array([[325.828062, 275.414804, 196.214709], - [322.359517, 312.785057, 249.380649], - [304.326806, 293.490822, 264.148021]]) + expected_ch4 = np.array([[325.828192, 275.414762, 196.214464], + [322.359634, 312.785138, 249.380531], + [304.326858, 293.490837, 264.147945]]) np.testing.assert_allclose(expected_ch4, ch4) @@ -129,11 +127,11 @@ def test_calibration_ir(self): space_counts[:, 2], line_numbers=np.array([1, 2, 3]), channel=5, - cal=cal) + spacecraft=spacecraft_id) - expected_ch5 = np.array([[326.460316, 272.146547, 187.434456], - [322.717606, 312.388155, 244.241633], - [303.267012, 291.590832, 260.05426]]) + expected_ch5 = np.array([[326.47287181, 272.14169523, 187.40907142], + [322.72885806, 312.39588991, 244.22910864], + [303.27173737, 291.59183911, 260.0459766]]) np.testing.assert_allclose(expected_ch5, ch5) diff --git a/pygac/tests/test_calibration_coefficients.py b/pygac/tests/test_calibration_coefficients.py deleted file mode 100644 index f4776215..00000000 --- a/pygac/tests/test_calibration_coefficients.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2014-2020 Pytroll Developers - -# Author(s): - -# Carlos Horn - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program 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 General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -"""Test function for the calibration coeffictions handling. -""" - -import sys -import unittest -try: - import mock -except ImportError: - from unittest import mock -import numpy as np - -from pygac.calibration import Calibrator, calibrate_solar, CoeffStatus - -# dummy user json file including only noaa19 data with changed channel 1 coefficients -user_json_file = b"""{ - "noaa19": { - "channel_1": { - "dark_count": 0, - "gain_switch": 1000, - "s0": 2, - "s1": 0, - "s2": 0 - }, - "channel_2": { - "dark_count": 39.0, - "gain_switch": 500.37, - "s0": 0.122, - "s1": 0.95, - "s2": -0.039 - }, - "channel_3a": { - "dark_count": 39.4, - "gain_switch": 496.11, - "s0": 0.1, - "s1": 0.0, - "s2": 0.0 - }, - "channel_3b": { - "b0": 0.0, - "b1": 0.0, - "b2": 0.0, - "centroid_wavenumber": 2670.2425, - "space_radiance": 0.0, - "to_eff_blackbody_intercept": 1.6863857, - "to_eff_blackbody_slope": 0.9974112191806167 - }, - "channel_4": { - "b0": 5.7, - "b1": -0.11187000000000002, - "b2": 0.00054668, - "centroid_wavenumber": 927.92374, - "space_radiance": -5.49, - "to_eff_blackbody_intercept": 0.39419031, - "to_eff_blackbody_slope": 0.9986718662850276 - }, - "channel_5": { - "b0": 3.58, - "b1": -0.05991000000000002, - "b2": 0.00024985, - "centroid_wavenumber": 831.28619, - "space_radiance": -3.39, - "to_eff_blackbody_intercept": 0.2636462, - "to_eff_blackbody_slope": 0.9990463103920997 - }, - "date_of_launch": "2009-02-05T00:57:36.000000Z", - "thermometer_1": { - "d0": 276.6067, - "d1": 0.051111, - "d2": 1.405783e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_2": { - "d0": 276.6119, - "d1": 0.05109, - "d2": 1.496037e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_3": { - "d0": 276.6311, - "d1": 0.051033, - "d2": 1.49699e-06, - "d3": 0.0, - "d4": 0.0 - }, - "thermometer_4": { - "d0": 276.6268, - "d1": 0.051058, - "d2": 1.49311e-06, - "d3": 0.0, - "d4": 0.0 - } - } -}""" - - -class TestCalibrationCoefficientsHandling(unittest.TestCase): - - @mock.patch('pygac.calibration.open', mock.mock_open(read_data=user_json_file)) - def test_user_coefficients_file(self): - if sys.version_info.major < 3: - cal = Calibrator('noaa19', coeffs_file="/path/to/unknow/defaults.json") - else: - with self.assertWarnsRegex(RuntimeWarning, - "Unknown calibration coefficients version!"): - cal = Calibrator('noaa19', coeffs_file="/path/to/unknow/defaults.json") - - self.assertEqual(cal.dark_count[0], 0) - self.assertEqual(cal.gain_switch[0], 1000) - self.assertEqual(cal.s0[0], 2) - self.assertEqual(cal.s1[0], 0) - self.assertEqual(cal.s2[0], 0) - # check that the version is set to None if an unknown file is used - if sys.version_info.major > 2: - self.assertIsNone(cal.version) - - def test_custom_coefficients(self): - custom_coeffs = { - "channel_1": { - "dark_count": 0, - "gain_switch": 1000, - "s0": 2, - "s1": 0, - "s2": 0 - } - } - # The coefficients are choosen to preserve the counts of channel 1 if counts are less than 1000 - counts = np.arange(10) - year = 2010 - jday = 1 - spacecraft_id = "noaa19" - channel = 0 - cal = Calibrator(spacecraft_id, custom_coeffs=custom_coeffs) - scaled_radiance = calibrate_solar(counts, channel, year, jday, cal) - np.testing.assert_allclose(scaled_radiance, counts) - # check that the version is set to None if custom coeffs are used - if sys.version_info.major > 2: - self.assertIsNone(cal.version) - - @unittest.skipIf(sys.version_info.major < 3, "Skipped in python2!") - def test_vis_deprecation_warning(self): - counts = np.arange(10) - year = 2010 - jday = 1 - spacecraft_id = "noaa19" - channel = 0 - corr = 2 - message = ( - "Using the 'corr' argument is depricated in favor of making the units" - " of the function result clear. Please make any unit conversion outside this function." - ) - cal = Calibrator(spacecraft_id) - with self.assertWarnsRegex(DeprecationWarning, message): - calibrate_solar(counts, channel, year, jday, cal, corr=corr) - # check that the version is set in this case - self.assertIsNotNone(cal.version) - - def test_default_coeffs(self): - """Test identification of default coefficients.""" - _, version = Calibrator.read_coeffs(None) - self.assertIsNotNone(version) - - @unittest.skipIf(sys.version_info.major < 3, "Skipped in python2!") - def test_read_coeffs_warnings(self): - """Test warnings issued by Calibrator.read_coeffs.""" - version_dicts = [ - # Non-nominal coefficients - {'name': 'v123', - 'status': CoeffStatus.PROVISIONAL}, - # Unknown coefficients - {'name': None, - 'status': None} - ] - with mock.patch.object(Calibrator, 'version_hashs') as version_hashs: - for version_dict in version_dicts: - version_hashs.get.return_value = version_dict - with self.assertWarns(RuntimeWarning): - Calibrator.read_coeffs(None) - - -def suite(): - """The suite for test_slerp - """ - loader = unittest.TestLoader() - mysuite = unittest.TestSuite() - mysuite.addTest(loader.loadTestsFromTestCase(TestCalibrationCoefficientsHandling)) - - return mysuite - - -if __name__ == '__main__': - unittest.main() diff --git a/pygac/tests/test_io.py b/pygac/tests/test_io.py index 46c64f39..40db30b0 100644 --- a/pygac/tests/test_io.py +++ b/pygac/tests/test_io.py @@ -212,11 +212,7 @@ def test_save_gac(self, check_user_scanlines, slice_channel, avhrr_gac_io, rel_azi=mm, qual_flags=mm, gac_file=mm, - meta_data=mm, - output_file_prefix=mm, - avhrr_dir=mm, - qual_dir=mm, - sunsatangles_dir=mm + meta_data=mm ) slice_channel.return_value = mm, 'miss', 'midnight' strip_invalid_lat.return_value = 0, 0 @@ -226,8 +222,7 @@ def test_save_gac(self, check_user_scanlines, slice_channel, avhrr_gac_io, slice_channel.assert_called_with(mock.ANY, start_line='start', end_line='end', first_valid_lat=mock.ANY, - last_valid_lat=mock.ANY - ) + last_valid_lat=mock.ANY) expected_args = [ mock.ANY, mock.ANY, @@ -256,11 +251,7 @@ def test_save_gac(self, check_user_scanlines, slice_channel, avhrr_gac_io, mock.ANY, mock.ANY, 'midnight', - 'miss', - mock.ANY, - mock.ANY, - mock.ANY, - mock.ANY + 'miss' ] avhrr_gac_io.assert_called_with(*expected_args) diff --git a/pygac/tests/test_klm.py b/pygac/tests/test_klm.py index ee3161db..b80d855a 100644 --- a/pygac/tests/test_klm.py +++ b/pygac/tests/test_klm.py @@ -182,26 +182,6 @@ def test_get_tsm_pixels(self, get_tsm_idx): CalledWithArray(ch4), CalledWithArray(ch5)) - def test_quality_indicators(self): - """Test the quality indicator unpacking.""" - reader = self.reader - QFlag = reader.QFlag - quality_indicators = np.array([ - 0, # nothing flagged - -1, # everything flagged - QFlag.CALIBRATION | QFlag.NO_EARTH_LOCATION, - QFlag.TIME_ERROR | QFlag.DATA_GAP, - QFlag.FATAL_FLAG - ], dtype=np.uint32) - reader.scans = {self.reader._quality_indicators_key: quality_indicators} - # test mask, i.e. QFlag.FATAL_FLAG | QFlag.CALIBRATION | QFlag.NO_EARTH_LOCATION - expected_mask = np.array([False, True, True, False, True], dtype=bool) - numpy.testing.assert_array_equal(reader.mask, expected_mask) - # test individual flags - self.assertTrue(reader._get_corrupt_mask(flags=QFlag.FATAL_FLAG).any()) - # count the occurence (everything flagged and last entrance => 2) - self.assertEqual(reader._get_corrupt_mask(flags=QFlag.FATAL_FLAG).sum(), 2) - if __name__ == '__main__': unittest.main() diff --git a/pygac/tests/test_pod.py b/pygac/tests/test_pod.py index cb374c0f..c19c29df 100644 --- a/pygac/tests/test_pod.py +++ b/pygac/tests/test_pod.py @@ -30,7 +30,6 @@ except ImportError: import mock -from pygac.clock_offsets_converter import txt as clock_offsets_txt from pygac.reader import ReaderError from pygac.gac_pod import GACPODReader from pygac.lac_pod import LACPODReader @@ -149,140 +148,6 @@ def test_get_tsm_pixels(self, get_tsm_idx): CalledWithArray(ch4), CalledWithArray(ch5)) - def test_quality_indicators(self): - """Test the quality indicator unpacking.""" - reader = self.reader - QFlag = reader.QFlag - quality_indicators = np.array([ - 1, # 00...001 - QFlag.FATAL_FLAG, # 100...00 - QFlag.CALIBRATION | QFlag.NO_EARTH_LOCATION, - QFlag.TIME_ERROR | QFlag.DATA_GAP, - ], dtype='>u4') - # check if the bits look as expected - bits = np.unpackbits(quality_indicators.view(np.uint8)).reshape((-1, 32)) - # For a big endian integer, the number 1 fills only the last of the 32 bits - self.assertEqual(bits[0].sum(), 1) # only one bit is filled - self.assertEqual(bits[0][-1], 1) # the last bit is filled - # The fatal flag fills only the first bit - self.assertEqual(bits[1].sum(), 1) # only one bit is filled - self.assertEqual(bits[1][0], 1) # the first bit is filled - - # setup reader and test - reader.scans = {self.reader._quality_indicators_key: quality_indicators} - - # default mask is QFlag.FATAL_FLAG | QFlag.CALIBRATION | QFlag.NO_EARTH_LOCATION - expected_mask = np.array([False, True, True, False], dtype=bool) - numpy.testing.assert_array_equal(reader.mask, expected_mask) - - # test individual flags - expected_mask = np.array([False, False, False, True], dtype=bool) - numpy.testing.assert_array_equal( - reader._get_corrupt_mask(flags=QFlag.TIME_ERROR), - expected_mask - ) - # test combination of flags - expected_mask = np.array([False, False, True, True], dtype=bool) - flags = QFlag.DATA_GAP | QFlag.NO_EARTH_LOCATION - numpy.testing.assert_array_equal( - reader._get_corrupt_mask(flags=flags), - expected_mask - ) - - @mock.patch('pygac.pod_reader.get_lonlatalt') - @mock.patch('pygac.pod_reader.compute_pixels') - @mock.patch('pygac.reader.Reader.get_tle_lines') - @mock.patch('pygac.pod_reader.avhrr_gac') - def test__adjust_clock_drift(self, avhrr_gac, get_tle_lines, - compute_pixels, get_lonlatalt): - """Test the clock drift adjustment.""" - sat_name = "fake_sat" - reader = self.reader - - # We construct the following input - # the scan lines do not start with 1 and have a gap - scan_lines = np.array([15, 16, 17, 18, 22, 23, 24, 25]) - scan_rate = 0.5 # seconds/line - # the first valid scans starts 1980-01-01 (without clock correction) - # which leads to the following utcs for the given scan lines - # ['1980-01-01T00:00:00.000', '1980-01-01T00:00:00.500', - # '1980-01-01T00:00:01.000', '1980-01-01T00:00:01.500', - # '1980-01-01T00:00:03.500', '1980-01-01T00:00:04.000', - # '1980-01-01T00:00:04.500', '1980-01-01T00:00:05.000'] - scan_utcs = ( - (1000 * scan_rate * (scan_lines - scan_lines[0])).astype('timedelta64[ms]') - + np.datetime64("1980", "ms") - ) - # For the geolocations, we assume an artificial swath of two pixels width - # from north to south with constant lon, lat difference of 3deg for simplicity - # lons = [[0, 3], [0, 3], [0, 3], [0, 3], - # [0, 3], [0, 3], [0, 3], [0, 3]], - # lats = [[45, 45], [48, 48], [51, 51], [54, 54], - # [66, 66], [69, 69], [72, 72], [75, 75]] - scan_angle = 3.0 # deg - scan_lons, scan_lats = np.meshgrid(scan_angle*np.arange(2), scan_angle*scan_lines) - - # we assume a constant clock offset of 3.75 seconds - # which should lead to the following adjustment on utcs - # ['1979-12-31T23:59:56.250', '1979-12-31T23:59:56.750', - # '1979-12-31T23:59:57.250', '1979-12-31T23:59:57.750', - # '1979-12-31T23:59:59.750', '1980-01-01T00:00:00.250', - # '1980-01-01T00:00:00.750', '1980-01-01T00:00:01.250'] - offset = 3.75 - scan_offsets = offset*np.ones_like(scan_lines, dtype=float) # seconds - expected_utcs = scan_utcs - (1000*scan_offsets).astype('timedelta64[ms]') - - # the adjustment of geolocations should keep the lons unchanged, - # but should shift the lats by scan_angel * offset / scan_rate - # = 3deg/line * 3.75sec / 0.5sec/line = 22.5deg - # [[22.5, 22.5], [25.5, 25.5], [28.5, 28.5], [31.5, 31.5], - # [43.5, 43.5], [46.5, 46.5], [49.5, 49.5], [52.5, 52.5]] - expected_lons = scan_lons - lats_shift = scan_angle*offset/scan_rate - expected_lats = scan_lats - lats_shift - - # prepare the reader - reader.scans = {"scan_line_number": scan_lines} - reader.utcs = scan_utcs - reader.lons = scan_lons - reader.lats = scan_lats - reader.spacecraft_name = sat_name - - # prepare offsets - clock_offsets_txt[sat_name] = ("75001 000000 {offset} " - "85001 000000 {offset}").format(offset=offset) - # set attitude coeffs - reader._rpy = np.zeros(3) - - # set mocks for reader._compute_missing_lonlat call - sgeom = mock.Mock() - sgeom.times.return_value = [None] - avhrr_gac.return_value = sgeom - get_tle_lines.return_value = [None, None] - compute_pixels.return_value = None - # for the following mock, we need to know the missing values in advanced, - # which we do, because we can convert the offset seconds into line number. - offset_lines = offset / scan_rate - min_line = np.floor(scan_lines[0] - offset_lines).astype(int) - max_line = scan_lines[-1] - missed_lines = np.setdiff1d(np.arange(min_line, max_line+1), scan_lines) - n_missed = len(missed_lines) - missed_lons = np.tile([0., scan_angle], n_missed) - missed_lats = np.repeat(scan_angle*missed_lines, 2) - get_lonlatalt.return_value = [missed_lons, missed_lats] - - # adjust clock drift - reader._adjust_clock_drift() - - # check output - # use allclose for geolocations, because the slerp interpolation - # includes a transormation to cartesian coordinates and back to lon, lats. - numpy.testing.assert_array_equal(reader.utcs, expected_utcs) - numpy.testing.assert_allclose(reader.lons, expected_lons) - numpy.testing.assert_allclose(reader.lats, expected_lats) - - # undo changes to clock_offsets_txt - clock_offsets_txt.pop(sat_name) def suite(): """Test suite for test_pod.""" diff --git a/pygac/tests/test_reader.py b/pygac/tests/test_reader.py index 201bfb07..d688fb4a 100644 --- a/pygac/tests/test_reader.py +++ b/pygac/tests/test_reader.py @@ -23,7 +23,6 @@ import datetime import unittest import sys -import os try: import mock except ImportError: @@ -56,23 +55,12 @@ def test_filename(self): filepath = '/path/to/' + filename + '.gz' self.reader.filename = filepath self.assertEqual(self.reader.filename, filename) - self.reader.filename = None - self.assertIsNone(self.reader.filename) - - class TestPath(os.PathLike): - def __init__(self, path): - self.path = str(path) - - def __fspath__(self): - return self.path - self.reader.filename = TestPath(filepath) - self.assertEqual(self.reader.filename, filename) @unittest.skipIf(sys.version_info.major < 3, "Skipped in python2!") def test__read_scanlines(self): """Test the scanline extraction.""" self.reader.scanline_type = np.dtype([ - ('a', 'S2'), ('b', '. import gzip -import io import logging - -from contextlib import contextmanager, nullcontext - import numpy as np +import sys +from contextlib import contextmanager LOG = logging.getLogger(__name__) -def gzip_inspected(open_file): - """Try to gzip decompress the file object if applicable.""" +def is_file_object(filename): + """Check if the input is a file object. + + Args: + filename - object to check + + Note: + This method only check if the object implements the + interface of a file object to allow duck types like + gzip.GzipFile instances. + """ + has_close = hasattr(filename, 'close') + has_read = hasattr(filename, 'read') + if hasattr(filename, 'seekable'): + is_seekable = filename.seekable() + else: + is_seekable = False + return has_close and has_read and is_seekable + + +@contextmanager +def _file_opener(file): + """Open a file depending on the input. + + Args: + file - path to file or file object + """ + # open file if necessary + if is_file_object(file): + open_file = file + close = False + else: + open_file = open(file, mode='rb') + close = True + # check if it is a gzip file try: - file_object = gzip.GzipFile(mode='rb', fileobj=open_file) + file_object = gzip.open(open_file) file_object.read(1) except OSError: file_object = open_file finally: file_object.seek(0) - return file_object + # provide file_object with the context + try: + yield file_object + finally: + if close: + file_object.close() @contextmanager -def file_opener(file): - if isinstance(file, io.IOBase) and file.seekable(): - # avoid closing the file using nullcontext - open_file = nullcontext(file) - elif hasattr(file, 'open'): - try: - open_file = file.open(mode='rb') - except TypeError: - open_file = file.open() - else: - open_file = open(file, mode='rb') - # set open_file into context in case of lazy loading in __enter__ method. - with open_file as file_object: - yield gzip_inspected(file_object) +def _file_opener_py2(file): + """Open a file depending on the input. + + Args: + file - path to file + """ + close = True + # check if it is a gzip file + try: + file_object = gzip.open(file) + file_object.read(1) + # Note: in python 2, this is an IOError, but we keep the + # OSError for testing. + except (OSError, IOError): + file_object = open(file, mode='rb') + except TypeError: + # In python 2 gzip.open cannot handle file objects + LOG.debug("Gzip cannot open file objects in python2!") + if is_file_object(file): + file_object = file + close = False + finally: + file_object.seek(0) + # provide file_object with the context + try: + yield file_object + finally: + if close: + file_object.close() + + +if sys.version_info.major < 3: + file_opener = _file_opener_py2 +else: + file_opener = _file_opener def get_absolute_azimuth_angle_diff(sat_azi, sun_azi): diff --git a/pygac/version.py b/pygac/version.py index f61d286e..8c5bc8e1 100644 --- a/pygac/version.py +++ b/pygac/version.py @@ -22,4 +22,4 @@ """Just holding the version of the pygac module.""" -__version__ = '1.4.0' +__version__ = '1.3.1' diff --git a/setup.py b/setup.py index f0f00d6f..22bd50ce 100644 --- a/setup.py +++ b/setup.py @@ -32,20 +32,51 @@ import imp import sys import os +from distutils.extension import Extension +from setuptools.command.build_ext import build_ext as _build_ext + +version = imp.load_source('pygac.version', 'pygac/version.py') + + +def set_builtin(name, value): + """Set builtin.""" + if isinstance(__builtins__, dict): + __builtins__[name] = value + else: + setattr(__builtins__, name, value) + + +class build_ext(_build_ext): # noqa + """Work around to bootstrap numpy includes in to extensions. + + Copied from: + http://stackoverflow.com/questions/19919905/how-to-bootstrap-numpy-installation-in-setup-py + """ + + def finalize_options(self): + """Finalize options.""" + _build_ext.finalize_options(self) + # Prevent numpy from thinking it is still in its setup process: + set_builtin('__NUMPY_SETUP__', False) + import numpy + self.include_dirs.append(numpy.get_include()) + if __name__ == '__main__': version = imp.load_source('pygac.version', 'pygac/version.py') - requirements = ['docutils>=0.3', - 'numpy>=1.8.0', - 'pyorbital>=v0.3.2', - 'h5py>=2.0.1', - 'scipy>=0.8.0', - 'python-geotiepoints>=1.1.8', - 'bottleneck>=1.0.0'] - if sys.version_info < (3, 7): - # To parse ISO timestamps in calibration.py - requirements.append('python-dateutil>=2.8.0') + # Build extensions. On the development side, i.e. if the module is built + # using the 'build_ext' or 'sdist' arguments, compile *.pyx using Cython. + # On the user side, compile *.c files. + use_cython = 'build_ext' in sys.argv or 'sdist' in sys.argv + file_ext = '.pyx' if use_cython else '.c' + extensions = [ + Extension('pygac._filter', + sources=['pygac/_filter' + file_ext]) + ] + if use_cython: + from Cython.Build import cythonize + extensions = cythonize(extensions) setup(name='pygac', version=version.__version__, @@ -64,16 +95,22 @@ license='GPLv3', packages=['pygac'], - package_data={'pygac': ['data/calibration.json']}, + cmdclass={'build_ext': build_ext}, + ext_modules=extensions, # Project should use reStructuredText, so ensure that the docutils get # installed or upgraded on the target machine - install_requires=requirements, + install_requires=['docutils>=0.3', + 'numpy>=1.8.0', + 'pyorbital>=v0.3.2', + 'h5py>=2.0.1', + 'scipy>=0.8.0', + 'python-geotiepoints>=1.1.8'], scripts=[os.path.join('bin', item) for item in os.listdir('bin')], data_files=[('etc', ['etc/pygac.cfg.template']), ('gapfilled_tles', ['gapfilled_tles/TLE_noaa16.txt'])], test_suite="pygac.tests.suite", tests_require=[], - python_requires='>=3.6', + python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*', zip_safe=False )