Ticket 720: WRWP, adjustement to be able to cope with volumes only having scans with...
[baltrad-wrwp.git] / pywrwp / baltrad_wrwp_pgf_plugin.py
1 '''
2 Copyright (C) 2010- Swedish Meteorological and Hydrological Institute (SMHI)
3
4 This file is part of RAVE.
5
6 RAVE is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 RAVE is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with RAVE.  If not, see <http://www.gnu.org/licenses/>.
18
19 '''
20 ## Plugin for generating the wrwp product generation that is initiated from the beast
21 ## framework.
22 ## Register in pgf with
23 ## --name=eu.baltrad.beast.generatewrwp
24 ## --floats=minelevationangle,velocitythreshold --ints=interval,maxheight,mindistance,maxdistance --strings=fields -m baltrad_wrwp_pgf_plugin -f generate
25 ##
26 ## The WRWP generation is executed by providing a polar volume that a wind profile is calculated on
27 ##
28 ## wrwp = _wrwp.new()
29 ## wrwp.interval = ...
30 ## wrwp.maxheight = ...
31 ## ...
32 ## result = wrwp.generate(pvol)
33 ## 
34 ## @file
35 ## @author Anders Henja, SMHI
36 ## @date 2013-09-25
37 ##
38 ## @co-autor Ulf E. Nordh, SMHI
39 ## @date 2018-02-08
40 ##
41 ## Slight adjustment done to the call to wrwp.generate in function generate.
42 ## The call is done with try-except to deal with the situation that
43 ## the returned result is NULL. In addition, logging is inserted.
44
45 import _wrwp
46 import _rave
47 import _raveio
48 import _polarvolume
49 import string
50 import logging
51 import rave_pgf_logger
52 import rave_tempfile
53 import odim_source
54 import math
55
56 from rave_defines import CENTER_ID, GAIN, OFFSET
57
58 logger = rave_pgf_logger.create_logger()
59
60 ravebdb = None
61 try:
62   import rave_bdb
63   ravebdb = rave_bdb.rave_bdb()
64 except:
65   pass
66
67 ## Creates a dictionary from a rave argument list
68 #@param arglist the argument list
69 #@return a dictionary
70 def arglist2dict(arglist):
71   result={}
72   for i in range(0, len(arglist), 2):
73     result[arglist[i]] = arglist[i+1]
74   return result
75
76 ##
77 # Converts a string into a number, either int or float
78 # @param sval the string to translate
79 # @return the translated value
80 # @throws ValueError if value not could be translated
81 #
82     
83 def strToNumber(sval):
84   if type(sval) is not str: # Avoid doing anything if it is not a string as input
85     return sval
86   else:
87     try:
88       return int(sval)
89     except ValueError, e:
90       return float(sval)
91
92 ## Creates a vertical profile
93 #@param files the list of files to be used for generating the vertical profile
94 #@param arguments the arguments defining the vertical profile
95 #@return a temporary h5 file with the vertical profile
96 def generate(files, arguments):
97
98   args = arglist2dict(arguments)
99   wrwp = _wrwp.new()
100   fields = None
101   if "interval" in args.keys():
102     wrwp.dz = strToNumber(args["interval"])
103   if "maxheight" in args.keys():
104     wrwp.hmax = strToNumber(args["maxheight"])
105   if "mindistance" in args.keys():
106     wrwp.dmin = strToNumber(args["mindistance"])
107   if "maxdistance" in args.keys():
108     wrwp.dmax = strToNumber(args["maxdistance"]) 
109   if "minelevationangle" in args.keys():
110     wrwp.emin = strToNumber(args["minelevationangle"])
111   if "velocitythreshold" in args.keys():
112     wrwp.vmin = strToNumber(args["velocitythreshold"])
113   if "fields" in args.keys():
114     fields = args["fields"]
115
116   if len(files) != 1:
117     raise AttributeError, "Must call plugin with _one_ polar volume"
118   
119   logger.debug("Start generating vertical profile from polar volume %s"%files[0])
120
121   obj = None
122   if ravebdb != None:
123     obj = ravebdb.get_rave_object(files[0])
124   else:
125     rio = _raveio.open(files[0])
126     obj = rio.object
127
128   if not _polarvolume.isPolarVolume(obj):
129     raise AttributeError, "Must call plugin with a polar volume"
130
131   try:
132     profile = wrwp.generate(obj, fields)  
133     fileno, outfile = rave_tempfile.mktemp(suffix='.h5', close="True")
134     ios = _raveio.new()
135     ios.object = profile
136     ios.filename = outfile
137     ios.save()
138     logger.debug("Finished generating vertical profile from polar volume %s"%files[0])
139     return outfile
140   except:
141     logger.info("No vertical profile could be generated from polar volume %s"%files[0])
142     return None