Source code for polar2grid.core.dtype

#!/usr/bin/env python3
# encoding: utf-8
# Copyright (C) 2014 Space Science and Engineering Center (SSEC),
# University of Wisconsin-Madison.
#
# 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 <http://www.gnu.org/licenses/>.
#
# This file is part of the polar2grid software package. Polar2grid takes
# satellite observation data, remaps it, and writes it to a file format for
#     input into another program.
# Documentation: http://www.ssec.wisc.edu/software/polar2grid/
"""Functions that handle polar2grid data types."""

import logging

import numpy as np

log = logging.getLogger(__name__)

DTYPE_UINT8 = "uint1"
DTYPE_UINT16 = "uint2"
DTYPE_UINT32 = "uint4"
DTYPE_UINT64 = "uint8"
DTYPE_INT8 = "int1"
DTYPE_INT16 = "int2"
DTYPE_INT32 = "int4"
DTYPE_INT64 = "int8"
DTYPE_FLOAT32 = "real4"
DTYPE_FLOAT64 = "real8"

NUMPY_DTYPE_STRS = [
    "uint8",
    "uint16",
    "uint32",
    "uint64",
    "int8",
    "int16",
    "int32",
    "int64",
    "float32",
    "float64",
]

# Map data type to np type for conversion
str2dtype = {
    DTYPE_UINT8: np.uint8,
    DTYPE_UINT16: np.uint16,
    DTYPE_UINT32: np.uint32,
    DTYPE_UINT64: np.uint64,
    DTYPE_INT8: np.int8,
    DTYPE_INT16: np.int16,
    DTYPE_INT32: np.int32,
    DTYPE_INT64: np.int64,
    DTYPE_FLOAT32: np.float32,
    DTYPE_FLOAT64: np.float64,
}
dtype2str = dict((v, k) for k, v in str2dtype.items())

# Map data type to valid data range
# Since float32 is polar2grid's intermediate type, float32 and float64 don't
# get clipped
dtype2range = {
    DTYPE_UINT8: (0, 2**8 - 1),
    DTYPE_UINT16: (0, 2**16 - 1),
    DTYPE_UINT32: (0, 2**32 - 1),
    DTYPE_UINT64: (0, 2**64 - 1),
    DTYPE_INT8: (-1 * (2**7), 2**7 - 1),
    DTYPE_INT16: (-1 * (2**15), 2**15 - 1),
    DTYPE_INT32: (-1 * (2**31), 2**31 - 1),
    DTYPE_INT64: (-1 * (2**63), 2**63 - 1),
    DTYPE_FLOAT32: None,
    DTYPE_FLOAT64: None,
}


[docs]def normalize_dtype_string(dtype_str): if dtype_str in str2dtype: return dtype_str else: msg = "Unknown data type string '%s'" % (dtype_str,) log.error(msg) raise ValueError(msg)
[docs]def str_to_dtype(dtype_str): if np.issubclass_(dtype_str, np.number): # if they gave us a np dtype return dtype_str elif isinstance(dtype_str, str) and hasattr(np, dtype_str): # they gave us the np name of the dtype return getattr(np, dtype_str) try: return str2dtype[dtype_str] except KeyError: raise ValueError("Not a valid data type string: %s" % (dtype_str,))
[docs]def dtype_to_str(numpy_dtype): if isinstance(numpy_dtype, str): # if they gave us a string, make sure it's valid return normalize_dtype_string(numpy_dtype) try: return dtype2str[np.dtype(numpy_dtype).type] except KeyError: raise ValueError("Unsupported np data type: %r" % (numpy_dtype,))
[docs]def clip_to_data_type(data, data_type): if np.issubdtype(np.dtype(data_type), np.floating): return data info = np.iinfo(data_type) rmin = info.min rmax = info.max log.debug("Clipping data to a %d - %d data range" % (rmin, rmax)) return data.clip(rmin, rmax)
[docs]def int_or_float(val): """Convert a string to integer or float. If we can't make it an integer then make it a float. """ try: return int(val) except ValueError: return float(val)