Loading...
Searching...
No Matches
RadarProductOp.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31/*
32 * ProductOp.h
33 *
34 * Created on: Mar 7, 2011
35 * Author: mpeura
36 */
37
38#ifndef RACK_PRODUCT_OP
39#define RACK_PRODUCT_OP "ProductOP"
40
41//#include <exception>
42#include <drain/Log.h>
43#include <iostream>
44#include <list>
45#include <map>
46#include <set>
47#include <string>
48
49#include <drain/RegExp.h>
50#include <drain/util/SmartMap.h>
51#include <drain/util/TreeOrdered.h>
52
53#include "data/Data.h"
54#include "data/DataSelector.h"
55#include "data/ODIM.h"
56#include "data/ODIMPath.h"
57#include "data/ODIMPathTools.h"
58#include "data/QuantityMap.h"
59
60#include "hi5/Hi5.h"
61//#include "main/rack.h"
62
63
64
65#include "ProductBase.h"
66
67namespace rack {
68
69using namespace drain::image;
70
71
73
77template <class MS, class MD>
79
80public:
81
84
87
88
90 inline
91 RadarProductOp(const std::string &name, const std::string & description) : ProductBase(name, description) {
92 // dataSelector.path = "^.* / da ta[0-9]+/?$"; /// Contract: in Op's, path filters should be copy to group level.
93 }
94
95 inline
96 RadarProductOp(const RadarProductOp & product) : ProductBase(product){
97 std::cerr << '#' << __FUNCTION__ << " copy ct " << product.getName() << this->dataSelector << '\n';
98 };
99
102
104 /*
105 virtual inline
106 const std::string & getOutputQuantity() const {
107 return odim.quantity; //outputQuantity;
108 }
109 */
110
112
115 virtual inline
116 const std::string & getOutputQuantity(const std::string & inputQuantity = "") const {
117 if (!odim.quantity.empty())
118 return odim.quantity; //outputQuantity;
119 else
120 return inputQuantity;
121 }
122
123
124 //void processH5() // see MotionFill
125 virtual // HistogramOp
126 void processH5(const Hi5Tree &src, Hi5Tree &dst) const;
127
128
130
134 virtual
135 void computeSingleProduct(const DataSetMap<src_t> & srcSweeps, DataSet<dst_t> & dstProduct) const;
136
138
145 virtual
146 void processDataSet(const DataSet<src_t > & srcSweep, DataSet<DstType<MD> > & dstProduct) const;
147
148 virtual
149 void processData(const Data<src_t > & srcData, Data<dst_t > & dstData) const {
150 drain::Logger mout(__FILE__, __FUNCTION__);
151 mout.unimplemented(__FUNCTION__);
152 };
153
154
155protected:
156
157
159
167 virtual
168 void setGeometry(const MS & srcODIM, PlainData<dst_t > & dstData) const = 0; // {};
169
170
172
175 virtual inline
176 void initDst(const MS & srcODIM, PlainData<dst_t > & dstData) const {
177
178 drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(VolumeOp<M>)", __FUNCTION__);
179
180 setEncoding(srcODIM, dstData);
181 setGeometry(srcODIM, dstData);
182
183 mout.debug("final dstData: " , dstData );
184 }
185
186
188
196 //virtual
197 //void setEncodingNEW(PlainData<dst_t > & dstData) const;
198
200
209 virtual
210 void setEncoding(const ODIM & srcODIM, PlainData<dst_t > & dstData) const;
211
213
224 // void ProductOp<MS,MD>::setEncodingNEW
225 void setEncodingNEW(PlainData<dst_t> & dstData, const std::string & quantity = "", const std::string & args = "") const;
226
227 /*
228 static
229 void handleEncodingRequest(const std::string & encoding, PlainData<dst_t> & dst){
230
231 drain::Logger mout(__FILE__, __FUNCTION__);
232
233 dst.odim.completeEncoding( encoding);
234
235 if (!dst.odim.type.empty())
236 dst.data.setType(dst.odim.type);
237 else
238 dst.odim.type = (const char)dst.data.getType2();
239
240 }
241 */
242};
243
251template <class MS, class MD>
252void RadarProductOp<MS,MD>::setEncodingNEW(PlainData<dst_t> & dstData, const std::string & quantity, const std::string & args) const {
253
254 drain::Logger mout(__FILE__, __FUNCTION__);
255
256 if (dstData.odim.quantity.empty()){
257 dstData.odim.quantity = quantity;
258 }
259
260 /*
261 if (!type.empty()){
262 dstData.odim.type = type;
263 }
264 */
265
266 const std::string & qty = quantity.empty() ? dstData.odim.quantity : quantity;
267
268 if (qty.empty()){
269 mout.warn("No quantity in metadata or as argument" );
270 }
271
272 const QuantityMap & qmap = getQuantityMap();
273
274 qmap.setQuantityDefaults(dstData, qty, args);
275
276 /*
277 qmap.setQuantityDefaults(dstData, qty, dstData.odim.type, );
278 dstData.odim.updateValues(targetEncoding);
279
280 // Why two times?
281 qmap.setQuantityDefaults(dstData, qty, dstData.odim.type); // type also?
282 dstData.odim.updateValues(targetEncoding);
283 */
284
285 // update
286 dstData.data.setScaling(odim.scaling);
287
289 // dstData.odim.product = odim.product; ?
290}
291
292/*
293template <class MS, class MD>
294void ProductOp<MS,MD>::setEncodingNEW(PlainData<dst_t> & dst, const std::string quantity = "", const std::string type = "") const {
295
296 drain::Logger mout(__FILE__, __FUNCTION__);
297
298 if (odim.quantity.empty())
299 odim.quantity = quantity;
300
301 if (!type.empty())
302 odim.type = type;
303
304 const std::string & qty = quantity.empty() ? odim.quantity : quantity;
305
306 const QuantityMap & qmap = getQuantityMap();
307 qmap.setQuantityDefaults(dst, qty, odim.type);
308 dst.odim.updateValues(targetEncoding);
309 qmap.setQuantityDefaults(dst, qty, dst.odim.type); // type also?
310 dst.odim.updateValues(targetEncoding);
311 // update
312 dst.data.setScaling(dst.odim.scaling);
313
315 // dst.odim.product = odim.product; ?
316}
317*/
318
319/*
320 * This is one of the many parallel similar implementations. To be removed.
321 * See also:
322 */
323template <class MS, class MD>
324void RadarProductOp<MS,MD>::setEncoding(const ODIM & inputODIM, PlainData<dst_t> & dst) const {
325
326 ProductBase::applyODIM(dst.odim, this->odim);
327 ProductBase::applyODIM(dst.odim, inputODIM, true); // New. Use defaults if still unset
328 dst.odim.completeEncoding( this->targetEncoding);
329
330 drain::Logger mout(__FILE__, __FUNCTION__);
331
332 mout.unimplemented<LOG_WARNING>("Does not set data storarge type?");
333
334 // Set actual scaling up to date with metadata)
335 dst.data.setScaling(dst.odim.scaling);
337 // dst.odim.product = odim.product;
338}
339
340
341template <class MS, class MD> // copied from VolumeOp::processVolume
342void RadarProductOp<MS,MD>::processH5(const Hi5Tree &src, Hi5Tree &dst) const {
343
344 //drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(VolumeOp<M>)", __FUNCTION__);
345 drain::Logger mout(__FILE__, __FUNCTION__);
346
347 mout.debug("start");
348 mout.warn(*this);
349 mout.debug2("DataSelector: ", this->dataSelector);
350
351 // Step 1: collect sweeps (/datasetN/)
352 //DataSetMap<src_t> sweeps;
353 DataSetMap<src_t> sweeps;
354
356 mout.debug3("collect the applicable paths");
357 ODIMPathList dataPaths; // Down to ../dataN/ level, eg. /dataset5/data4
358 int index = 0;
359
360
361 mout.unimplemented("No index generator defined!");
362 // NEW
363 this->dataSelector.getPaths(src, dataPaths); //, ODIMPathElem::DATASET);
364 mout.debug3("populate the dataset map, paths=" , dataPaths.size() );
365 //for (ODIMPathList::const_iterator it = dataPaths.begin(); it != dataPaths.end(); ++it){
366 for (const ODIMPath & path: dataPaths){
367 mout.debug3("add: " , index , '\t' , path );
368 //sweeps.insert(typename DataSetMap<src_t>::value_type("indexxx", DataSet<src_t>(src(path), drain::RegExp(this->dataSelector.getQuantity()) ))); // Something like: sweeps[elangle] = src[parent] .
369 sweeps.insert(typename DataSetMap<src_t>::value_type("indexxx", DataSet<src_t>(src(path), this->dataSelector.getQuantitySelector() ))); // Something like: sweeps[elangle] = src[parent] .
370 }
371
372
373 // OLD
374 /*
375 this->dataSelector.getPaths(src, dataPaths, ODIMPathElem::DATA);
376
377 mout.debug3("populate the dataset map, paths=" , dataPaths.size() );
378 std::set<ODIMPath> parents;
379
380 for (ODIMPathList::const_iterator it = dataPaths.begin(); it != dataPaths.end(); ++it){
381
382 ODIMPath parent = *it;
383 parent.pop_back();
384
385 mout.debug3("check " , *it );
386
387 if (parents.find(parent) == parents.end()){
388 mout.debug3("add " , parent , "=>" , index );
389 // kludge (index ~ elevation)
390 sweeps.insert(typename DataSetMap<src_t>::value_type(index, DataSet<src_t>(src(parent), drain::RegExp(this->dataSelector.quantity) ))); // Something like: sweeps[elangle] = src[parent] .
391 //elangles << elangle;
392 }
393 }
394 */
395
396
397 mout.debug2("DataSets: " , sweeps.size() );
398
399
400 // Copy metadata from the input volume (note that dst may have been cleared above)
401 for (const auto key: {ODIMPathElem::WHAT, ODIMPathElem::WHERE, ODIMPathElem::HOW}){
402 // .data.attributes
403 mout.unimplemented("consider and test .data.attributes instead");
404 dst[key] = src[key];
405 }
406 // odim.copyToRoot(dst); NO! Mainly overwrites original data. fgrep 'declare(rootAttribute' odim/*.cpp
407
408 //ODIMPath dataSetPath;
409 ODIMPathElem parent(ODIMPathElem::DATASET); // /dataset1
410 ODIMPathElem child(ODIMPathElem::DATA); // /dataset1
411
412 mout.note(DRAIN_LOG(ProductBase::appendResults));
413 if (ProductBase::appendResults.getType() == ODIMPathElem::DATASET){
414 ODIMPathTools::getNextChild(dst, parent);
415 }
416
417 ODIMPathTools::getNextChild(dst[parent], child);
418
419 mout.attention("storing product in path: " , parent , '|' , child );
420 Hi5Tree & dstProduct = dst[parent][child]; // (dataSetPath);
421
423 {
424 DataSet<dst_t> dstProductDataset(dstProduct); // PATH
425 this->computeSingleProduct(sweeps, dstProductDataset);
426 }
427
428 dst["what"].data.attributes["object"] = this->odim.object;
429 dstProduct["what"].data.attributes["product"] = odim.product;
430 dstProduct["what"].data.attributes["prodpar"] = odim.prodpar;
431
432 ProductBase::setRackVersion(dstProduct["how"].data.attributes);
433 // how["elangles"] = elangles; // This service could be lower in hierarchy (but for PseudoRHI and pCappi ok here)
434
435}
436
437
438//template <class M>
439template <class MS, class MD>
441
442 drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(VolumeOp<M>)", __FUNCTION__);
443 mout.debug3("start" );
444
445 if (src.size() == 0)
446 mout.warn("no data" );
447
448 //for (typename DataSetMap<src_t >::const_iterator it = src.begin(); it != src.end(); ++it) {
449 for (const auto & entry: src) {
450 mout.debug3("calling processDataSet for elev=", entry.first, " #datasets=", entry.second.size());
451 processDataSet(entry.second, dstProduct);
452 // TODO: detect first init?
453 // mout.warn("OK" );
454 }
455
457 // mout.warn("getFirst data" );
458 //@ Data<DstType<MD> > & dstData = dstProduct.getFirstData(); // main data
459 //@ dstProduct.updateTree(dstData.odim);
460 // mout.warn("end" );
461}
462
463
464//template <class M>
465template <class MS, class MD>
466void RadarProductOp<MS,MD>::processDataSet(const DataSet<src_t > & srcSweep, DataSet<DstType<MD> > & dstProduct) const {
467
468 //drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(ProductOp<MS,MD>)", __FUNCTION__);
469 drain::Logger mout(__FILE__, __FUNCTION__);
470
471 mout.debug("start" );
472
473 const Data<src_t > & srcData = srcSweep.getFirstData();
474
475 mout.debug("target quantity: " , odim.quantity );
476
477 // NEW 2020/06
478 const std::string & quantity = !odim.quantity.empty() ? odim.quantity : srcData.odim.quantity;
479 Data<DstType<MD> > & dstData = dstProduct.getData(quantity);
480 dstData.odim.quantity = quantity;
481
482 // OLD
483 // Data<DstType<MD> > & dstData = !odim.quantity.empty() ? dstProduct.getData(odim.quantity) : dstProduct.getFirstData();
484 //if (dstData.odim.quantity.empty())
485 // dstData.odim.quantity = odim.quantity;
486
487 //mout.debug("calling setEncoding" );
488 //setEncoding(srcData.odim, dstData.odim);
489 this->initDst(srcData.odim, dstData);
490
491 //mout.warn("calling processData" );
492 processData(srcData, dstData);
493 //mout.warn("updateTree" );
494 //@ dstData.updateTree();
495}
496
497
498
499
500
501} // namespace rack
502
503
504#endif /* RACKOP_H_ */
505
506// Rack
507 // REP
508 // REP // REP // REP // REP
virtual const std::string & getName() const
Return the name of an instance.
Definition BeanLike.h:82
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:431
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:667
Logger & note(const TT &... args)
For top-level information.
Definition Log.h:490
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition Log.h:477
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition Log.h:512
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:677
Definition Path.h:137
Definition Data.h:1419
A map of radar data, indexed by quantity code (DBZH, VRAD, etc).
Definition Data.h:1264
Data structure consisting of plain data and an optional quality data.
Definition Data.h:1195
Definition ODIMPath.h:82
ODIM metadata (quantity, gain, offset, undetect, nodata, date, time)
Definition ODIM.h:79
Essential class for storing radar data.
Definition Data.h:300
Base class for radar data processors. Input can be in polar or Cartesian coordinates.
Definition ProductBase.h:82
Registry for regular quantities appearing in weather radar.
Definition QuantityMap.h:67
bool setQuantityDefaults(EncodingODIM &dst, const std::string &quantity, const std::string &values="") const
Sets default values of given quantity without assigning the quantity. Optionally overrides with user ...
Definition QuantityMap.cpp:207
Polar and Cartesian products.
Definition RadarProductOp.h:78
DstType< MD > dst_t
Type of output, that is, destination.
Definition RadarProductOp.h:86
virtual void processH5(const Hi5Tree &src, Hi5Tree &dst) const
Definition RadarProductOp.h:342
SrcType< MS const > src_t
Type of input, that is, source.
Definition RadarProductOp.h:83
RadarProductOp(const std::string &name, const std::string &description)
Default constructor.
Definition RadarProductOp.h:91
void setEncodingNEW(PlainData< dst_t > &dstData, const std::string &quantity="", const std::string &args="") const
Sets applicable encoding parametes (type, gain, offset, undetect, nodata) for this product.
Definition RadarProductOp.h:252
virtual void computeSingleProduct(const DataSetMap< src_t > &srcSweeps, DataSet< dst_t > &dstProduct) const
Traverse the data applicable for this product and create new, processed data (volume or polar product...
Definition RadarProductOp.h:440
virtual void setEncoding(const ODIM &srcODIM, PlainData< dst_t > &dstData) const
Sets applicable encoding parametes (type, gain, offset, undetect, nodata) for this product.
Definition RadarProductOp.h:324
MD odim
The default data parameters for encoding output (the product).
Definition RadarProductOp.h:101
virtual const std::string & getOutputQuantity(const std::string &inputQuantity="") const
Returns the primary output quantity (ODIM what:quantity , like DBZH)
Definition RadarProductOp.h:116
virtual void processDataSet(const DataSet< src_t > &srcSweep, DataSet< DstType< MD > > &dstProduct) const
Process the data of a single sweep and and write the result to given product.
Definition RadarProductOp.h:466
virtual void initDst(const MS &srcODIM, PlainData< dst_t > &dstData) const
initialises dst data by setting suitable ODIM metadata and geometry.
Definition RadarProductOp.h:176
virtual void setGeometry(const MS &srcODIM, PlainData< dst_t > &dstData) const =0
Sets automagically the suitable dst parameters.
Namespace for images and image processing tools.
Definition AccumulationArray.cpp:45
Definition DataSelector.cpp:44
QuantityMap & getQuantityMap()
Definition QuantityMap.cpp:279
Writable data type.
Definition Data.h:120
Read-only data type.
Definition Data.h:110