__init__.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import math
  2. import time
  3. import logging
  4. import subprocess
  5. import sys
  6. from threading import Thread, RLock
  7. from collections import namedtuple
  8. import colorsys
  9. import numpy as np
  10. from path import path
  11. # ==================================================
  12. # probably make this a real extension module
  13. from distutils.extension import Extension
  14. utils_path = path(__file__).parent.parent.joinpath('utils')
  15. msvc_compile_args = ['/openmp', '/wd4244', '/O2']
  16. gcc_compile_args = ['-fopenmp']
  17. gcc_link_args=['-fopenmp']
  18. if sys.platform != 'win32':
  19. compile_args = gcc_compile_args
  20. link_args = gcc_link_args
  21. else:
  22. compile_args = msvc_compile_args
  23. link_args = []
  24. ext_modules = [Extension("utils.accelerated",
  25. [str(utils_path.joinpath("accelerated.pyx").abspath())],
  26. extra_compile_args=compile_args,
  27. extra_link_args=link_args)
  28. ]
  29. import pyximport; pyximport.install(setup_args={'include_dirs': [np.get_include(), str(utils_path)], 'ext_modules': ext_modules})
  30. from utils import accelerated
  31. # ==================================================
  32. log = logging.getLogger()
  33. def _debug():
  34. """rpdb2 debug starter"""
  35. import rpdb2
  36. print 'stopping for embedded rpdb2 debugging...'
  37. rpdb2.start_embedded_debugger('debug', timeout=60 * 20)
  38. # add to builtins
  39. import __builtin__; __builtin__._debug = _debug
  40. def extract(Z, shape, position, fill=np.NaN):
  41. """ Extract a sub-array from Z using given shape and centered on position. If some part of the sub-array is out of Z bounds, result is
  42. padded with fill value.
  43. **Parameters**
  44. `Z` : array_like
  45. Input array.
  46. `shape` : tuple
  47. Shape of the output array
  48. `position` : tuple
  49. Position within Z
  50. `fill` : scalar
  51. Fill value
  52. **Returns**
  53. `out` : array_like
  54. Z slice with given shape and center
  55. **Examples**
  56. >>> Z = np.arange(0,16).reshape((4,4))
  57. >>> extract(Z, shape=(3,3), position=(0,0))
  58. [[ NaN NaN NaN]
  59. [ NaN 0. 1.]
  60. [ NaN 4. 5.]]
  61. Schema:
  62. +-----------+
  63. | 0 0 0 | = extract (Z, shape=(3,3), position=(0,0))
  64. | +---------------+
  65. | 0 | 0 1 | 2 3 | = Z
  66. | | | |
  67. | 0 | 4 5 | 6 7 |
  68. +---|-------+ |
  69. | 8 9 10 11 |
  70. | |
  71. | 12 13 14 15 |
  72. +---------------+
  73. >>> Z = np.arange(0,16).reshape((4,4))
  74. >>> extract(Z, shape=(3,3), position=(3,3))
  75. [[ 10. 11. NaN]
  76. [ 14. 15. NaN]
  77. [ NaN NaN NaN]]
  78. Schema:
  79. +---------------+
  80. | 0 1 2 3 | = Z
  81. | |
  82. | 4 5 6 7 |
  83. | +-----------+
  84. | 8 9 |10 11 | 0 | = extract (Z, shape=(3,3), position=(3,3))
  85. | | | |
  86. | 12 13 |14 15 | 0 |
  87. +---------------+ |
  88. | 0 0 0 |
  89. +-----------+
  90. """
  91. # assert(len(position) == len(Z.shape))
  92. # if len(shape) < len(Z.shape):
  93. # shape = shape + Z.shape[len(Z.shape)-len(shape):]
  94. R = np.ones(shape, dtype=Z.dtype)*fill
  95. P = np.array(list(position)).astype(int)
  96. Rs = np.array(list(R.shape)).astype(int)
  97. Zs = np.array(list(Z.shape)).astype(int)
  98. R_start = np.zeros((len(shape),)).astype(int)
  99. R_stop = np.array(list(shape)).astype(int)
  100. Z_start = (P-Rs//2)
  101. Z_stop = (P+Rs//2) + Rs % 2
  102. R_start = (R_start - np.minimum(Z_start,0)).tolist()
  103. Z_start = (np.maximum(Z_start,0)).tolist()
  104. R_stop = (R_stop - np.maximum(Z_stop-Zs,0)).tolist()
  105. Z_stop = (np.minimum(Z_stop,Zs)).tolist()
  106. r = [slice(start,stop) for start,stop in zip(R_start,R_stop)]
  107. z = [slice(start,stop) for start,stop in zip(Z_start,Z_stop)]
  108. R[r] = Z[z]
  109. return R
  110. _MATPLOTLIB = None
  111. plotLock = RLock()
  112. def getPyPlot():
  113. '''for lazy loading matplotlib to decrease startup time'''
  114. global _MATPLOTLIB
  115. if _MATPLOTLIB is None:
  116. t = time.time()
  117. import matplotlib
  118. matplotlib.use('Agg')
  119. from matplotlib import pyplot
  120. import pylab
  121. from matplotlib import dates
  122. from matplotlib import font_manager
  123. from matplotlib import ticker
  124. _MATPLOTLIB = [pyplot, pylab, dates, font_manager, ticker]
  125. log.debug('loaded matplotlib in %.3f sec' % (time.time() - t))
  126. return _MATPLOTLIB
  127. def cython_annotate(fname):
  128. ''' create cython annotation html (next to fname) '''
  129. #~ f = path(sys.executable).parent.joinpath('Scripts/cython.py')
  130. f = path(sys.executable).parent.joinpath('Scripts/cython-script.py')
  131. try:
  132. subprocess.check_call([sys.executable, f, '-a', fname])
  133. except subprocess.CalledProcessError:
  134. log.exception('Error during cython annotation')
  135. def daemonthread(target, name=None, autostart=True, args=(), kwargs=None):
  136. """Start a thread as daemon thread
  137. """
  138. thread = Thread(target=target, name=name, args=args, kwargs=kwargs)
  139. thread.setDaemon(True)
  140. if autostart:
  141. thread.start()
  142. return thread
  143. MAX_RSSI = 140.0
  144. RSSI_EQ = 90.0
  145. def normalizeLogarithmic(x, max_rssi=MAX_RSSI, rssi_eq=RSSI_EQ):
  146. if int(rssi_eq) == 0:
  147. return x
  148. # we work with positive values
  149. rssi_eq = abs(rssi_eq)
  150. a = math.exp(math.log(max_rssi)/(100-rssi_eq) - math.log(rssi_eq)/(100-rssi_eq))
  151. b = (rssi_eq * math.log(a) - math.log(rssi_eq)) / math.log(a)
  152. if -x > rssi_eq:
  153. return -(b + math.log(-x, a))
  154. else:
  155. return x
  156. def normalizeDeviceAdaption(x, da_values, adaptMin=-150):
  157. da_values.insert(0, (adaptMin, -100 - adaptMin))
  158. for left, right in zip(da_values, da_values[1:]):
  159. if left[0] <= x < right[0]:
  160. diff1 = right[0] - left[0]
  161. diff2 = right[0] + right[1] - (left[0] + left[1])
  162. m = diff2 / float(diff1)
  163. return left[0] + left[1] + (x - left[0]) * m
  164. return x
  165. Location = namedtuple('Location', 'id x y z')
  166. def loadLocations(f):
  167. f = path(f)
  168. log.debug('loading locations from %s' % f.abspath())
  169. lines = [l for l in f.lines() if l.strip() and not l.strip().startswith('#')]
  170. res = {}
  171. for l in lines:
  172. i, x, y, z = [float(e.strip()) for e in l.split()]
  173. i = int(i)
  174. res[i] = Location(i, x, y, z)
  175. return res
  176. def pos2rgb(i, max, offset=0.0, spread=1.0, saturation=1.0):
  177. rgb = list(colorsys.hsv_to_rgb(spread * i / float(max) + offset, saturation, 1.0))
  178. for j in range(3):
  179. rgb[j] = int(rgb[j] * 255)
  180. return ("#%02x%02x%02x" % tuple(rgb)).upper()