-
Notifications
You must be signed in to change notification settings - Fork 6
/
rave_hexquant.py
143 lines (108 loc) · 3.64 KB
/
rave_hexquant.py
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
#!/usr/bin/env python
'''
Copyright (C) 2014- Swedish Meteorological and Hydrological Institute (SMHI)
This file is part of RAVE.
RAVE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RAVE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with RAVE. If not, see <http://www.gnu.org/licenses/>.
'''
## Encodes/decodes ODIM quantities to/from hex for the purposes of creating
# simple file strings representing which quantities are in the contents.
## @file
## @author Daniel Michelson, SMHI
## @date 2014-10-19
import sys, os
from copy import deepcopy as copy
#from rave_defines import RAVECONFIG
import xml.etree.ElementTree as ET
import numpy as np
#QUANTFILE = os.path.join(RAVECONFIG, "odim_quantities.xml")
QUANTFILE = "odim_quantities.xml"
QUANTITIES = []
initialized = 0
bitl = list(np.zeros((64,), np.uint8)) # A 64-element long list of unsigned bytes. Used as an intermediate information holder.
## Initializes QUANTITIES by reading content from XML file.
# This is done once, after which the QUANTITIES are available in memory.
def init():
global initialized, QUANTITIES
if initialized: return
C = ET.parse(QUANTFILE)
QUANTS = C.getroot()
for q in QUANTS:
QUANTITIES.append(q.text)
QUANTITIES = tuple(QUANTITIES)
initialized = 1
## Initialize
init()
## Digs out all the quantities in a SCAN
# @param PolarScan object
# @returns list of quantity strings
def qFromScan(scan):
return scan.getParameterNames()
## Digs out all the quantities in a PVOL
# @param PolarVolume object
# @returns list of quantity strings
def qFromPvol(pvol):
quants = []
for i in range(pvol.getNumberOfScans()):
scan = pvol.getScan(i)
squants = qFromScan(scan)
for q in squants:
if q not in quants:
quants.append(q)
return quants
## Digs out the quantities from a given file string
# Assumes the hex string's location is fixed.
# @param string file name
# @returns list of quantity strings
def qFromFstr(fstr):
path, fstr = os.path.split(fstr)
stuff = fstr.split('.')[-2:] # Get the last two parts only
h = stuff[0].split('_')[-1:][0]
return hex2q(h)
## Converts a list of quantities to a hex string
# @param list of quantity strings
# @returns hex string
def q2hex(quants):
b = copy(bitl)
for q in quants:
i = QUANTITIES.index(q)
b[i] = 1
return hex(bitl2long(b))[:-1]
## Converts a hex string to a list of quantities
# @param hex string
# @returns list of quantity strings
def hex2q(h):
q = []
bits = long2bits(hex2long(h))
for i in range(len(bits)):
if bits[i] == "1":
q.append(QUANTITIES[i])
return q
## Bit list to long integer
# @param list of 8-bit bytes, each representing one bit in a 64-bit integer
# @returns long integer
def bitl2long(bitl):
out = 0L
for bit in bitl:
out = (out << 1) | bit
return out
## Long integer to bit string
# @param long integer
# @returns list of 8-bit bytes, each representing one bit in a 64-bit integer
def long2bits(l):
return format(l, '064b')
## hex string to long integer
# @param hex string
# @returns long integer
def hex2long(h):
return int(long(h+"L", 16))
if __name__ == "__main__":
pass