def gunzip(fstr): payload = gzip.open(fstr).read() fstr = rave_tempfile.mktemp(close='True')[1] fd = open(fstr, 'w') fd.write(payload) fd.close() return fstr
def generate(files, arguments): args = arglist2dict(arguments) for fname in files: logger.info("Input file: %s" % fname) obj = None if ravebdb != None: obj = ravebdb.get_rave_object(fname) else: rio = _raveio.open(fname) obj = rio.object v2b = _pyvol2bird.new(obj) # calculate a vertical profile of birds vpr = v2b.vol2bird(obj, 0.0) fileno, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") logger.info("Output file: %s" % outfile) ios = _raveio.new() ios.object = vpr ios.filename = outfile ios.save() return outfile
def generate(files, arguments): args = arglist2dict(arguments) logger.debug("rave_pgf_apply_qc_plugin called with arguments: %s", args) # should only be one file fname = files[0] volume = generate_new_volume_with_qc(fname, args) if volume == None: logger.info("No volume with QC applied could be generated!") return None _, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") ios = _raveio.new() ios.object = volume ios.filename = outfile ios.version = RAVE_IO_DEFAULT_VERSION ios.save() logger.info("Generated new volume with QC applied.") return outfile
def get_file(self, uuid): ''' returns a file name to a file that can be accessed. The uuid should be an identifier in bdb. The returned filename will be a temporary file so it is recommended to remove the file after usage. For example myname = None try: myname = bdb.get_file(uuid) ... process file ... finally: if myname != None and os.path.exists(myname): os.unlink(myname) :param fname: The file name :return a temporary file on success :raises an Exception on failure or no file could be found ''' content = self.get_database().get_file_content(uuid) if content: fpd, tmppath = rave_tempfile.mktemp(suffix='.h5', close="True") #fpd, tmppath = tempfile.mkstemp(suffix='.h5', prefix='ravetmp') try: with contextlib.closing(content): #with os.fdopen(fpd, "w") as outf: with open(tmppath, "wb") as outf: shutil.copyfileobj(content, outf) outf.close() return tmppath except Exception as e: if os.path.exists(tmppath): os.unlink(tmppath) raise e else: raise Exception("No content for file %s" % uuid)
def generate(files, arguments): args = arglist2dict(arguments) quality_control_mode = QUALITY_CONTROL_MODE_ANALYZE_AND_APPLY volume = generateVolume(files, args) fileno, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") if "anomaly-qc" in args.keys(): detectors = args["anomaly-qc"].split(",") else: detectors = [] if "qc-mode" in args.keys(): quality_control_mode = args["qc-mode"] volume = perform_quality_control(volume, detectors, quality_control_mode.lower()) ios = _raveio.new() ios.object = volume ios.filename = outfile ios.version = RAVE_IO_DEFAULT_VERSION ios.save() return outfile
def gunzip(fstr): #py3 type(payload) is <class 'bytes'>, need to add 'b' read/write mode payload = gzip.open(fstr,'rb').read() fstr = rave_tempfile.mktemp(close='True')[1] fd = open(fstr, 'wb') fd.write(payload) fd.close() return fstr
def debugme(files, args): import rave import rave_tempfile fileno, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") this = rave.open(files[0]) this.save(outfile) return outfile
def Array2Tempfile(value): import rave_tempfile _, fstr = rave_tempfile.mktemp() a = _pyhl.nodelist() b = _pyhl.node(_pyhl.GROUP_ID, "/dataset1") a.addNode(b) b = _pyhl.node(_pyhl.DATASET_ID, "/dataset1/data") h5typ = ARRAYTYPES[value.dtype.char] b.setArrayValue(-1, list(value.shape), value, h5typ, -1) a.addNode(b) a.write(fstr) return fstr
def MetadataAsXMLstring(element, encoding=ENCODING): import __builtin__, os import rave_tempfile # Write to tempfile fid, fstr = rave_tempfile.mktemp() os.close(fid) e = ElementTree(element) e.write(fstr, encoding=encoding) # Read tempfile into string and return it fd = __builtin__.open(fstr) rets = fd.read() fd.close() os.remove(fstr) return rets
def generate(infiles, gain=GAIN, offset=OFFSET, scale=2000.0): comp = compositing() #comp.filenames = infiles.split(",") comp.detectors = odc_polarQC.algorithm_ids comp.quantity = "DBZH" comp.set_product_from_string("PCAPPI") #comp.range = options.range comp.gain = gain comp.offset = offset comp.prodpar = 1000.0 comp.set_method_from_string("NEAREST_RADAR") comp.qitotal_field = None comp.pcsid = "gmaps" comp.xscale = scale comp.yscale = scale comp.zr_A = 200.0 comp.zr_b = 1.6 comp.applygapfilling = True comp.reprocess_quality_fields = True rio = _raveio.open(infiles) # There is only one file ... pvol = rio.object # Copy TH to DBZH for all scans in this pvol pvol = CopyDBZH(pvol) # Save to tempfile tmpf = rave_tempfile.mktemp(suffix=".h5", close="True") rio.object = pvol rio.save(tmpf[1]) comp.filenames = [tmpf[1]] DATE = rio.object.date TIME = rio.object.time try: result = comp.generate(DATE, TIME, None) except Exception, e: print "Error: %s" % e.__str__() print "removing %s" % tmpf[1] os.remove(tmpf[1])
def generate(args): TIME = args.pop() DATE = args.pop() areaid = args.pop() files = args.pop() start = time.time() # For performance benchmarking comp = compositing.compositing() comp.filenames = files comp.detectors = "ropo,beamb,radvol-att,radvol-broad,distance,qi-total".split(",") comp.quantity = ["TH", "DBZH"] # comp.set_product_from_string("MAX") comp.set_product_from_string("PCAPPI") comp.range = 200000.0 comp.gain = rave_defines.GAIN comp.offset = rave_defines.OFFSET comp.prodpar = 1000.0 comp.set_method_from_string("HEIGHT_ABOVE_SEALEVEL") comp.qitotal_field = "pl.imgw.quality.qi_total" comp.pcsid = PCSID comp.xscale = AREA.xscale comp.yscale = AREA.yscale comp.zr_A = rave_defines.ZR_A comp.zr_b = rave_defines.ZR_b comp.applygapfilling = False comp.verbose = True comp.reprocess_quality_fields = False result = comp.generate(DATE, TIME, areaid) rio = _raveio.new() rio.object = result # Create temporary file in a place with write access rio.filename = rave_tempfile.mktemp(suffix='_%s_%sT%sZ.h5' % (areaid, DATE, TIME), close="True")[1] rio.save() end = time.time() return (rio.filename, end-start)
def store_temporary_files(objects): tempobjects = {} try: for k in objects.keys(): rio = _raveio.new() rio.object = objects[k] rio.compression_level = 0 rio.fcp_istorek = 1 rio.fcp_metablocksize = 0 rio.fcp_sizes = (4, 4) rio.fcp_symk = (1, 1) rio.fcp_userblock = 0 fileno, rio.filename = rave_tempfile.mktemp(suffix='.h5', close="True") tempobjects[rio.filename] = rio.object rio.save() except Exception as e: for tmpfile in tempobjects.keys(): try: os.unlink(tmpfile) except: pass raise e return tempobjects
def generate(files, arguments): args = arglist2dict(arguments) comp = compositing(ravebdb) comp.filenames = files if "anomaly-qc" in args.keys(): comp.detectors = args["anomaly-qc"].split(",") if "qc-mode" in args.keys(): comp.set_quality_control_mode_from_string(args["qc-mode"]) if "ignore-malfunc" in args.keys(): try: if args["ignore-malfunc"].lower() in ["true", "yes", "y", "1"]: comp.ignore_malfunc = True except: pass comp.quantity = "DBZH" if "quantity" in args.keys(): comp.quantity = args["quantity"] comp.gain = GAIN comp.offset = OFFSET comp.set_product_from_string("pcappi") if "method" in args.keys(): comp.set_product_from_string(args["method"].lower()) comp.height = 1000.0 comp.elangle = 0.0 comp.range = 200000.0 if "prodpar" in args.keys(): comp.prodpar = args["prodpar"] if "range" in args.keys() and comp.product == _rave.Rave_ProductType_PMAX: comp.range = float(args["range"]) if "selection" in args.keys(): comp.set_method_from_string(args["selection"]) if "interpolation_method" in args.keys(): interpolation_method = args["interpolation_method"].upper() comp.set_interpolation_method_from_string(interpolation_method) if interpolation_method != "NEAREST_VALUE": if comp.quantity == "DBZH": comp.minvalue = -30.0 # use a minimum value of -30.0 for DBZH else: # interpolation for other quantities than DBZH has not been tested, therefore not yet considered # supported. Should in theory work, but the setting of minvalue must be adjusted for the quantity logger.info( "Interpolation method %s is currently only supported for quantity DBZH. Provided quantity: %s. No composite generated." % (interpolation_method, comp.quantity)) return None if "qitotal_field" in args.keys(): comp.qitotal_field = args["qitotal_field"] if "reprocess_qfields" in args.keys(): comp.reprocess_quality_field = args["reprocess_qfields"] else: comp.reprocess_quality_field = RAVE_PGF_QUALITY_FIELD_REPROCESSING comp.use_azimuthal_nav_information = USE_AZIMUTHAL_NAVIGATION comp.use_lazy_loading = USE_LAZY_LOADING comp.use_lazy_loading_preloads = USE_LAZY_LOADING_PRELOADS # We do not support best fit compositing right now #comp.pcsid = options.pcsid #comp.xscale = options.scale #comp.yscale = options.scale #if options.gf: Activate gap filling for rule # comp.applygapfilling = True # Optional cloud-type residual non-precip filter if "ctfilter" in args: if eval(args["ctfilter"]): comp.applyctfilter = True if "applygra" in args: comp.applygra = True if "zrA" in args: comp.zr_A = float(args["zrA"]) if "zrb" in args: comp.zr_b = float(args["zrb"]) if rave_tile_registry.has_tiled_area(args["area"]): comp = tiled_compositing(comp) result = comp.generate(args["date"], args["time"], args["area"]) if result == None: logger.info("No composite could be generated.") return None _, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") rio = _raveio.new() rio.object = result rio.filename = outfile rio.version = RAVE_IO_DEFAULT_VERSION rio.save() return outfile
def newSO(ipvol, opvol, aavg, ravg, maxelev): """ Generates a new SO: Selects non-overlapping scans. Prepares output pvol and adds required attributes. Arguments: pyobject ipvol: input pvol pyobject opvol: output pvol (SO) int aavg: Azimuthal resolution [# azimuth gates] of the SO. Note: the total number of azimuth gates per scan (ysize) must be divisible by aavg. int ravg: Radial resolution [m] of the SO. Note: ravg must be divisible by the distance [m] betweeen two successive range bins (xscale). int maxelev: Maximum elevation angle [degrees] used for SO production. Returns: pyobject ipvol: input pvol pyobject opvol: output pvol (SO) """ if (ravg % ipvol.get('/where/xscale') == 0.0): ravg = int(ravg / ipvol.get('/where/xscale')) else: raise IOError("Invalid radial integration length.") if (ipvol.get('/where/ysize') % float(aavg) == 0.0) and \ (ipvol.get('/where/xsize') % float(ravg) == 0.0): beamwidth = ipvol.get('/how/beamwidth') oscan = [] # Only select non-overlapping scans. iscan = ipvol.get('/how/scan') if ipvol.get('/scan%s/where/angle' % iscan[0]) > maxelev: raise IOError("Invalid elevation angles.") for s in range(len(iscan)): if iscan[s] == iscan[0]: oscan.append(iscan[s]) elif abs(ipvol.get('/scan%s/where/angle' % iscan[s])- ipvol.get('/scan%s/where/angle'%oscan[-1])) >= beamwidth/2.0 \ and ipvol.get('/scan%s/where/angle' % iscan[s]) <= maxelev: oscan.append(iscan[s]) #oscan.sort() ipvol.set('/how/scan', oscan) # Prepare output volume. opvol.set('/where/ysize', ipvol.get('/where/ysize') / aavg) opvol.set('/where/xsize', ipvol.get('/where/xsize') / ravg) opvol.set('/where/xscale', ipvol.get('/where/xscale') * ravg) # must be in m! # Add required info attributes opvol.set('/how/transform_weighting', NO_ZERO_WEIGHTS) opvol.set('/how/i_method', UNIFORM) # imethod opvol.set('/how/scan', oscan) opvol.set('/how/elev_usage', USE_SINGLE_ELEV) # elevUsage opvol.set('/how/rs', [0.0] * opvol.get('/where/xsize')) # search radii A = DatasetArray(xsize=opvol.get('/where/xsize'), ysize=opvol.get('/where/ysize'), \ typecode='d', initval=None) for i in oscan: opvol.set('/scan%s/data' % str(i), A) tmpfile = rave_tempfile.mktemp() os.close(tmpfile[0]) # tempfile.mkstemp() opens the file for us opvol.set('/how/tmpfile', tmpfile[1]) return ipvol, opvol else: raise IOError("Invalid integration lengths.")
def generate(files, arguments): args = arglist2dict(arguments) comp = compositing(ravebdb) if len(files) != 1: raise AttributeError( "Input files list must contain only one file string") comp.filenames = files if "anomaly-qc" in args.keys(): comp.detectors = args["anomaly-qc"].split(",") if "qc-mode" in args.keys(): comp.set_quality_control_mode_from_string(args["qc-mode"]) if "ignore-malfunc" in args.keys(): try: if args["ignore-malfunc"].lower() in ["true", "yes", "y", "1"]: comp.ignore_malfunc = True except: pass comp.quantity = "DBZH" if "quantity" in args.keys(): comp.quantity = args["quantity"] comp.gain = GAIN comp.offset = OFFSET comp.set_product_from_string("pcappi") if "method" in args.keys(): comp.set_product_from_string(args["method"].lower()) comp.height = 1000.0 comp.elangle = 0.0 comp.range = 200000.0 if "prodpar" in args.keys(): comp.prodpar = args["prodpar"] if "range" in args.keys() and comp.product == _rave.Rave_ProductType_PMAX: comp.range = float(args["range"]) if "pcsid" in args.keys(): comp.pcsid = args["pcsid"] if "xscale" in args.keys(): comp.xscale = float(args["xscale"]) if "yscale" in args.keys(): comp.yscale = float(args["yscale"]) #if options.gf: Activate gap filling for rule # comp.applygapfilling = True # Optional cloud-type residual non-precip filter if "ctfilter" in args: if eval(args["ctfilter"]): comp.applyctfilter = True if "applygra" in args: comp.applygra = True if "zrA" in args: comp.zr_A = float(args["zrA"]) if "zrb" in args: comp.zr_b = float(args["zrb"]) if "pcsid" in args: comp.pcsid = args["pcsid"] comp.xscale = float(args["xscale"]) comp.yscale = float(args["yscale"]) areaid = None if "area" in args: areaid = args["area"] comp.use_site_source = True result = comp.generate(None, None, areaid) if result == None: logger.info("No site2D-composite could be generated.") return None result.objectType = _rave.Rave_ObjectType_IMAGE fileno, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") rio = _raveio.new() rio.object = result rio.filename = outfile rio.version = RAVE_IO_DEFAULT_VERSION rio.save() return outfile
def generate(files, arguments): args = arglist2dict(arguments) zr_a = 200.0 zr_b = 1.6 quantity = "DBZH" accept = 0.0 distancefield = "se.smhi.composite.distance.radar" hours = 1 N = 5 applygra = False #Accept is the required limit for how many nodata-pixels that are allowed in order for the #data to be accumulated #If we expect to have 10 observations and an accept limit of 20, then it can be 0, 1 or 2 observations #with nodata for that position. etime = args["time"] edate = args["date"] img = None if "zra" in args.keys(): zr_a = float(args["zra"]) if "zrb" in args.keys(): zr_b = float(args["zrb"]) if "quantity" in args.keys(): quantity = args["quantity"] if "accept" in args.keys(): accept = float(args["accept"]) / 100.0 if "distancefield" in args.keys(): distancefield = args["distancefield"] if "hours" in args.keys(): hours = int(args["hours"]) if "N" in args.keys(): N = int(args["N"]) if "applygra" in args: applygra = True if distancefield == "eu.baltrad.composite.quality.distance.radar": distancefield = "se.smhi.composite.distance.radar" pdatetime = datetime.datetime.strptime( edate + etime, "%Y%m%d%H%M%S") - datetime.timedelta(minutes=60 * hours) sdate = pdatetime.strftime("%Y%m%d") stime = pdatetime.strftime("%H%M00") acrr = _acrr.new() acrr.nodata = -1.0 acrr.undetect = 0.0 acrr.quality_field_name = distancefield nodes = None for fname in files: obj = None if ravebdb != None: obj = ravebdb.get_rave_object(fname) else: rio = _raveio.open(fname) obj = rio.object if _cartesianvolume.isCartesianVolume(obj): obj = obj.getImage(0) if not _cartesian.isCartesian(obj): raise AttributeError("Must call plugin with cartesian products") if img == None: img = _cartesian.new() img.xscale = obj.xscale img.yscale = obj.yscale img.areaextent = obj.areaextent img.projection = obj.projection img.product = _rave.Rave_ProductType_RR img.source = obj.source img.time = etime img.date = edate img.startdate = sdate img.starttime = stime img.enddate = edate img.endtime = etime if obj.hasAttribute("how/nodes") and nodes == None: nodes = obj.getAttribute("how/nodes") if obj.xscale != img.xscale or obj.yscale != img.yscale or \ obj.projection.definition != img.projection.definition: raise AttributeError( "Scale or projdef inconsistancy for used area") par = obj.getParameter(quantity) if par == None: logger.warn("Could not find parameter (%s) for %s %s" % (quantity, obj.date, obj.time)) else: if par.getQualityFieldByHowTask(distancefield) != None: acrr.sum(par, zr_a, zr_b) # accept, N, hours result = acrr.accumulate(accept, N, hours) fileno, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") if nodes != None: img.addAttribute("how/nodes", nodes) img.addParameter(result) #logger.info("Apply gra: %s"%`applygra`) if applygra: db = rave_dom_db.create_db_from_conf() dt = datetime.datetime(int(edate[:4]), int(edate[4:6]), int(edate[6:]), int(etime[:2]), int(etime[2:4]), 0) dt = dt - datetime.timedelta( seconds=3600 * 12) # 12 hours back in time for now.. gra = _gra.new() gra.A = DEFAULTA gra.B = DEFAULTB gra.C = DEFAULTC gra.zrA = zr_a gra.zrb = zr_b grac = db.get_gra_coefficient(dt) if grac != None and not math.isnan(grac.a) and not math.isnan( grac.b) and not math.isnan(grac.c): logger.debug("Using gra coefficients from database, quantity: %s" % quantity) gra.A = grac.a gra.B = grac.b gra.C = grac.c else: logger.info( "Could not find coefficients for given time, trying to get aged or climatologic coefficients" ) nowdt = datetime.datetime(int(edate[:4]), int(edate[4:6]), int(edate[6:]), int(etime[:2]), int(etime[2:4]), 0) agedt = nowdt - datetime.timedelta( seconds=3600 * 48) # 2 days back sig, pts, loss, r, rsig, corr, gra.A, gra.B, gra.C, mean, dev = get_backup_gra_coefficient( db, agedt, nowdt) dfield = result.getQualityFieldByHowTask(distancefield) gra_field = gra.apply(dfield, result) gra_field.quantity = result.quantity + "_CORR" img.addParameter(gra_field) ios = _raveio.new() ios.object = img ios.filename = outfile ios.version = RAVE_IO_DEFAULT_VERSION ios.save() return outfile
def generate(self, dd, dt, tid): comp = compositing.compositing() comp.xscale = self.xscale comp.yscale = self.yscale comp.detectors = self.detectors comp.ignore_malfunc = self.ignore_malfunc comp.prodpar = self.prodpar comp.product = self.product comp.height = self.height comp.elangle = self.elangle comp.range = self.range comp.selection_method = self.selection_method comp.interpolation_method = self.interpolation_method comp.qitotal_field = self.qitotal_field comp.applygra = self.applygra comp.zr_A = self.zr_A comp.zr_b = self.zr_b comp.applygapfilling = self.applygapfilling comp.applyctfilter = self.applyctfilter comp.quantity = self.quantity comp.gain = self.gain comp.offset = self.offset comp.minvalue = self.minvalue comp.filenames = self.filenames comp.verbose = self.verbose comp.reprocess_quality_field = self.reprocess_quality_field comp.dump = self.dump comp.dumppath = self.dumppath comp.radar_index_mapping = self.radar_index_mapping pyarea = _area.new() pyarea.id = "tiled area subset %s" % tid pyarea.xsize = self.area_definition.xsize pyarea.ysize = self.area_definition.ysize pyarea.xscale = self.area_definition.xscale pyarea.yscale = self.area_definition.yscale pyarea.extent = self.area_definition.extent pyarea.projection = _projection.new("dynamic pcsid", "dynamic pcs name", self.area_definition.pcsdef) logger.info("Generating composite for tile %s" % self.area_definition.id) result = comp.generate(dd, dt, pyarea) if result == None: logger.info("No composite for tile %s could be generated.", self.area_definition.id) return (tid, None) else: logger.info("Finished generating composite for tile %s", self.area_definition.id) fileno, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") rio = _raveio.new() rio.object = result rio.filename = outfile rio.save() return (tid, rio.filename)
def generate(files, arguments): args = arglist2dict(arguments) wrwp = _wrwp.new() fields = None # Since the config can be placed in a few different places, we first check current directory, then the environment variable WRWP_CONFIG_FILE, if it doesn't exist or point to non-existing # config file. We try a file located relative to this script (WRWP_CONFIG_FILE) defined above. Finally we try anything under /etc/baltrad. # Hopefully, one of those places will be enough. path2config = None if os.path.exists("wrwp_config.xml"): path2config = "wrwp_config.xml" if path2config is None and "WRWP_CONFIG_FILE" in os.environ: if os.path.exists(os.environ["WRWP_CONFIG_FILE"]): path2config = os.environ["WRWP_CONFIG_FILE"] if path2config is None and os.path.exists(WRWP_CONFIG_FILE): path2config = WRWP_CONFIG_FILE if path2config is None: etcpaths = find('wrwp_config.xml', '/etc/baltrad') if len(etcpaths) > 0: path2config = etcpaths[0] if path2config is None or not os.path.exists(path2config): logger.info( "Could not find any wrwp_config.xml file in any of the expected locations" ) return None root = ET.parse(str(path2config)).getroot() for param in root.findall('param'): if param.get('name') == 'EMAX': wrwp.emax = strToNumber(param.find('value').text) if param.get('name') == 'EMIN': wrwp.emin = strToNumber(param.find('value').text) if param.get('name') == 'DMAX': wrwp.dmax = strToNumber(param.find('value').text) if param.get('name') == 'DMIN': wrwp.dmin = strToNumber(param.find('value').text) if param.get('name') == 'VMIN': wrwp.vmin = strToNumber(param.find('value').text) if param.get('name') == 'NMIN_WND': wrwp.nmin_wnd = strToNumber(param.find('value').text) if param.get('name') == 'NMIN_REF': wrwp.nmin_ref = strToNumber(param.find('value').text) if param.get('name') == 'FF-MAX': wrwp.ff_max = strToNumber(param.find('value').text) if param.get('name') == 'DZ': wrwp.dz = strToNumber(param.find('value').text) if param.get('name') == 'HMAX': wrwp.hmax = strToNumber(param.find('value').text) if param.get('name') == 'NODATA_VP': wrwp.nodata_VP = strToNumber(param.find('value').text) if param.get('name') == 'UNDETECT_VP': wrwp.undetect_VP = strToNumber(param.find('value').text) if param.get('name') == 'GAIN_VP': wrwp.gain_VP = strToNumber(param.find('value').text) if param.get('name') == 'OFFSET_VP': wrwp.offset_VP = strToNumber(param.find('value').text) if param.get('name') == 'QUANTITIES': QUANTITIES = param.find('value').text # Parameter values from the web-GUI, they overwright the ones above. if "interval" in args.keys(): wrwp.dz = strToNumber(args["interval"]) if "maxheight" in args.keys(): wrwp.hmax = strToNumber(args["maxheight"]) if "mindistance" in args.keys(): wrwp.dmin = strToNumber(args["mindistance"]) if "maxdistance" in args.keys(): wrwp.dmax = strToNumber(args["maxdistance"]) if "minelevationangle" in args.keys(): wrwp.emin = strToNumber(args["minelevationangle"]) if "maxelevationangle" in args.keys(): wrwp.emax = strToNumber(args["maxelevationangle"]) if "velocitythreshold" in args.keys(): wrwp.vmin = strToNumber(args["velocitythreshold"]) if "maxvelocitythreshold" in args.keys(): wrwp.ff_max = strToNumber(args["maxvelocitythreshold"]) if "minsamplesizereflectivity" in args.keys(): wrwp.nmin_ref = strToNumber(args["minsamplesizereflectivity"]) if "minsamplesizewind" in args.keys(): wrwp.nmin_wnd = strToNumber(args["minsamplesizewind"]) if "fields" in args.keys(): fields = args["fields"] if fields == None: fields = QUANTITIES # If no fields are given in the web-GUI, we build wrwp with all the supported quantities if len(files) != 1: raise AttributeError("Must call plugin with _one_ polar volume") logger.debug("Start generating vertical profile from polar volume %s" % files[0]) obj = None if ravebdb != None: obj = ravebdb.get_rave_object(files[0]) else: rio = _raveio.open(files[0]) obj = rio.object if not _polarvolume.isPolarVolume(obj): raise AttributeError("Must call plugin with a polar volume") try: profile = wrwp.generate(obj, fields) fileno, outfile = rave_tempfile.mktemp(suffix='.h5', close="True") ios = _raveio.new() ios.object = profile ios.filename = outfile ios.version = RAVE_IO_DEFAULT_VERSION ios.save() logger.debug( "Finished generating vertical profile from polar volume %s" % files[0]) return outfile except: logger.info( "No vertical profile could be generated from polar volume %s" % files[0]) return None