3Copyright (C) 2011- Swedish Meteorological and Hydrological Institute (SMHI)
5This file is part of the bRopo extension to RAVE.
7RAVE is free software: you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
12RAVE is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15See the GNU Lesser General Public License for more details.
17You should have received a copy of the GNU Lesser General Public License
18along with RAVE. If not, see <http://www.gnu.org/licenses/>.
28from rave_defines
import UTF8
38import xml.etree.ElementTree
as ET
39from rave_quality_plugin
import QUALITY_CONTROL_MODE_ANALYZE_AND_APPLY
40from rave_quality_plugin
import QUALITY_CONTROL_MODE_ANALYZE
43CONFIG_FILE = os.path.join(os.path.join(os.path.split(os.path.split(_ropogenerator.__file__)[0])[0],
44 'config'),
'ropo_options.xml')
53THRESHOLDS = {
"COLD" : (-6, -4, -2, 0, 2, 4, 6, 4, 2, 0, -2, -4),
54 "VERY_COLD" : (-12, -10, -6, -4, 0, 4, 6, 4, -4, -8, -10, -12),
55 "TEMPERATE" : (0, 2, 4, 6, 8, 10, 10, 8, 6, 4, 2, 0),
56 "FLAT-10" : (-10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10),
57 "FLAT-24" : (-24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24),
58 "FLAT-30" : (-30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30),
61THRESHOLDS[
"DEFAULT"] = THRESHOLDS[
"FLAT-24"]
70 if initialized:
return
72 C = ET.parse(CONFIG_FILE)
75 for site
in list(OPTIONS):
78 for k
in site.attrib.keys():
79 if k ==
"parameters": opts.params = site.attrib[k]
80 elif k ==
"threshold": opts.threshold = site.attrib[k]
81 elif k ==
"highest-elev": opts.elev = float(site.attrib[k])
82 elif k ==
"restore": opts.restore = eval(site.attrib[k])
83 elif k ==
"restore-fill": opts.restore2 = eval(site.attrib[k])
84 elif k ==
"restore-thresh": opts.restore_thresh = eval(site.attrib[k])
85 elif k ==
"softcut": opts.softcut = eval(site.attrib[k])
86 elif k ==
"speckNormOld": opts.speckNormOld = eval(site.attrib[k])
87 elif k ==
"emitter2": opts.emitter2 = eval(site.attrib[k])
88 elif k ==
"ship": opts.ship = eval(site.attrib[k])
89 elif k ==
"speck": opts.speck = eval(site.attrib[k])
118 odim_source.CheckSource(inobj)
119 S = odim_source.ODIM_Source(inobj.source)
121 return copy.deepcopy(ARGS[S.nod])
123 return copy.deepcopy(ARGS[
"default"])
131 outo.beamwidth = ino.beamwidth
134 outo.height = ino.height
135 outo.latitude = ino.latitude
136 outo.longitude = ino.longitude
137 outo.source = ino.source
145def process_scan(scan, options, quality_control_mode=QUALITY_CONTROL_MODE_ANALYZE_AND_APPLY):
146 newscan, gates =
PadNrays(scan, options)
148 image = _fmiimage.fromRave(newscan, options.params)
149 param = newscan.getParameter(options.params)
150 rg = _ropogenerator.new(image)
151 if options.threshold:
152 raw_thresh = int((options.threshold - image.offset) / image.gain)
153 rg.threshold(raw_thresh)
157 if scan.elangle * rd < options.elev:
158 if options.speckNormOld:
159 a, b, c = options.speckNormOld
160 rg.speckNormOld(a, b, c)
162 a, b, c = options.softcut
168 a, b, c = options.emitter2
171 classification = rg.classify().classification.toRaveField()
173 restored = rg.restore(int(options.restore_thresh)).toPolarScan()
174 elif options.restore2:
175 restored = rg.restore2(int(options.restore_thresh)).toPolarScan()
177 restored, classification =
UnpadNrays(restored, classification, gates)
178 dbzh = scan.getParameter(
"DBZH")
179 if quality_control_mode != QUALITY_CONTROL_MODE_ANALYZE:
180 dbzh.setData(restored.getParameter(
"DBZH").getData())
181 scan.addParameter(dbzh)
182 scan.addOrReplaceQualityField(classification)
191def process_pvol(pvol, options, quality_control_mode=QUALITY_CONTROL_MODE_ANALYZE_AND_APPLY):
194 out = _polarvolume.new()
200 month = int(pvol.date[4:6]) - 1
201 options.threshold = THRESHOLDS[options.threshold][month]
203 for a
in pvol.getAttributeNames():
204 out.addAttribute(a, pvol.getAttribute(a))
206 for s
in range(pvol.getNumberOfScans()):
207 scan = pvol.getScan(s)
208 scan =
process_scan(scan, options, quality_control_mode)
218def generate(inobj, reprocess_quality_flag=True, quality_control_mode=QUALITY_CONTROL_MODE_ANALYZE_AND_APPLY):
219 if _polarscan.isPolarScan(inobj) ==
False and _polarvolume.isPolarVolume(inobj) ==
False:
220 raise IOError(
"Input file must be either polar scan or volume.")
222 if reprocess_quality_flag ==
False:
223 if _polarscan.isPolarScan(inobj)
and inobj.findQualityFieldByHowTask(
"fi.fmi.ropo.detector.classification"):
225 elif _polarvolume.isPolarVolume(inobj):
227 for i
in range(inobj.getNumberOfScans()):
228 scan = inobj.getScan(i)
229 if not scan.findQualityFieldByHowTask(
"fi.fmi.ropo.detector.classification"):
236 if _polarvolume.isPolarVolume(inobj):
237 ret =
process_pvol(inobj, options, quality_control_mode)
238 elif _polarscan.isPolarScan(inobj):
239 month = int(inobj.date[4:6]) - 1
240 options.threshold = THRESHOLDS[options.threshold][month]
241 ret =
process_scan(inobj, options, quality_control_mode)
255 from numpy
import vstack
257 width = float(options.emitter2[2])
258 gatew = 360.0 / scan.nrays
259 gates = (width / gatew)
260 if (gates - 1) > 0.0:
261 gates = int(gates + 1)
265 newscan = _polarscan.new()
267 dbzh = scan.getParameter(
"DBZH").clone()
268 data = dbzh.getData()
269 toprays = data[0:gates, ]
270 botrays = data[scan.nrays - gates:, ]
271 data = vstack((botrays, data, toprays))
273 dbzh.quantity =
"DBZH"
274 newscan.addParameter(dbzh)
275 newscan.elangle = scan.elangle
276 return newscan, gates
285 dbzh = scan.getParameter(
"DBZH")
286 data = dbzh.getData()
287 data = data[gates:scan.nrays - gates, ]
290 qdata = classification.getData()
291 qdata = qdata[gates:scan.nrays - gates, ]
292 classification.setData(qdata)
294 scan.removeParameter(
"DBZH")
295 scan.addParameter(dbzh)
296 return scan, classification
303if __name__ ==
"__main__":
Class used to organize options and argument values to ropo.
process_scan(scan, options, quality_control_mode=QUALITY_CONTROL_MODE_ANALYZE_AND_APPLY)
TODO: activate parameters list.
UnpadNrays(scan, classification, gates)
Internal function to unwrap a scan from overlapping rays.
get_options(inobj)
Based on the /what/source attribute, find site-specific options/arguments.
init()
Initializes the ARGS dictionary by reading content from XML file.
process_pvol(pvol, options, quality_control_mode=QUALITY_CONTROL_MODE_ANALYZE_AND_APPLY)
Loops through a volume and processes scans using process_scan.
generate(inobj, reprocess_quality_flag=True, quality_control_mode=QUALITY_CONTROL_MODE_ANALYZE_AND_APPLY)
Generate - does the real work.
PadNrays(scan, options)
Internal function to wrap rays near 360-0 degrees.
copy_topwhat(ino, outo)
Copies the top-level 'what' attributes from one object to another.