/usr/share/pyshared/chaco/log_mapper.py is in python-chaco 4.1.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | """ Defines the LogMapper and InvalidDataRangeException classes.
"""
# Major library imports
from numpy import array, isnan, log, log10, exp, zeros, sometrue,\
floor, ceil, ndarray
# Enthought library imports
from traits.api import Bool, Float
#Local relative imports
from base_1d_mapper import Base1DMapper
LOG_MINIMUM = 0.0
class InvalidDataRangeException(Exception):
pass
class LogMapper(Base1DMapper):
""" Defines a 1-D logarithmic scale mapping from a 1-D region in input
space to a 1-D region in output space.
"""
# The value to map when asked to map values <= LOG_MINIMUM to screen space.
fill_value = Float(1.0)
#------------------------------------------------------------------------
# Private traits
#------------------------------------------------------------------------
_inter_scale = Float(0.0)
_inter_offset = Float(0.0)
_screen_scale = Float(0.0)
_screen_offset = Float(0.0)
_null_screen_range = Bool(False)
_null_data_range = Bool(False)
#------------------------------------------------------------------------
# Public methods
#------------------------------------------------------------------------
def map_screen(self, data_array):
""" map_screen(data_array) -> screen_array
Overrides AbstractMapper. Maps values from data space to screen space.
"""
# Ensure that data_array is actually an array.
if not isinstance(data_array, ndarray):
data_array = array(data_array, ndmin=1)
# First convert to a [0,1] space, then to the screen space.
if not self._cache_valid:
self._compute_scale()
if self._inter_scale == 0.0:
intermediate = data_array*0.0
else:
try:
mask = (data_array <= LOG_MINIMUM) | isnan(data_array)
if sometrue(mask):
data_array = array(data_array, copy=True, ndmin=1)
data_array[mask] = self.fill_value
intermediate = (log(data_array) - self._inter_offset)/self._inter_scale
except ValueError:
intermediate = zeros(len(data_array))
result = intermediate * self._screen_scale + self._screen_offset
return result
def map_data(self, screen_val):
""" map_data(screen_val) -> data_val
Overrides Abstract Mapper. Maps values from screen space into data space.
"""
if not self._cache_valid:
self._compute_scale()
if self._null_screen_range or self._null_data_range:
return array([self.range.low])
#First convert to a [0,1] space, then to the data space
intermediate = (screen_val-self._screen_offset)/self._screen_scale
return exp(self._inter_scale*intermediate + self._inter_offset)
def map_data_array(self, screen_vals):
return self.map_data(screen_vals)
#------------------------------------------------------------------------
# Private methods
#------------------------------------------------------------------------
def _get_safe_scale(self, range):
orig_low = range.low
orig_high = range.high
if orig_low < LOG_MINIMUM:
low = LOG_MINIMUM
else:
low = orig_low
if orig_high < LOG_MINIMUM:
high = LOG_MINIMUM
else:
high = orig_high
if low == high:
if low == LOG_MINIMUM:
low = 1.0
high = 10.0
else:
log_val = log10(low)
low = pow(10, floor(log_val))
if ceil(log_val) != floor(log_val):
high = pow(10, ceil(log_val))
else:
high = pow(10, ceil(log_val) + 1)
return (low, high)
def _compute_scale(self):
if self._cache_valid:
return
if self.range is None:
self._cache_valid = False
return
screen_range = self.high_pos - self.low_pos
if screen_range == 0.0:
self._null_screen_range = True
# Get dataspace low and high from the range that are "safe" for a
# logarithmic mapper, i.e. constrained to be between LOG_MINIMUM and inf.
low, high = self._get_safe_scale(self.range)
if high - low == 0:
self._null_data_range = True
else:
if low == LOG_MINIMUM:
self._inter_scale = log(high)
self._inter_offset = 0.0
else:
self._inter_scale = log(high)-log(low)
self._inter_offset = log(low)
self._screen_scale = screen_range
self._screen_offset = self.low_pos
self._cache_valid = True
return
# EOF
|