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
136
138
145 virtual
147
148 virtual
149 void processData(const Data<src_t > & srcData, Data<dst_t > & dstData) const {
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
250template <class MS, class MD>
251void RadarProductOp<MS,MD>::setEncodingNEW(PlainData<dst_t> & dstData, const std::string & quantity, const std::string & args) const {
252
254
255 if (dstData.odim.quantity.empty()){
256 dstData.odim.quantity = quantity;
257 }
258
259 /*
260 if (!type.empty()){
261 dstData.odim.type = type;
262 }
263 */
264
265 const std::string & qty = quantity.empty() ? dstData.odim.quantity : quantity;
266
267 if (qty.empty()){
268 mout.warn("No quantity in metadata or as argument" );
269 }
270
271 const QuantityMap & qmap = getQuantityMap();
272
273 qmap.setQuantityDefaults(dstData, qty, args);
274
275 /*
276 qmap.setQuantityDefaults(dstData, qty, dstData.odim.type, );
277 dstData.odim.updateValues(targetEncoding);
278
279 // Why two times?
280 qmap.setQuantityDefaults(dstData, qty, dstData.odim.type); // type also?
281 dstData.odim.updateValues(targetEncoding);
282 */
283
284 // update
285 dstData.data.setScaling(odim.scaling);
286
288 // dstData.odim.product = odim.product; ?
289}
290
291/*
292template <class MS, class MD>
293void ProductOp<MS,MD>::setEncodingNEW(PlainData<dst_t> & dst, const std::string quantity = "", const std::string type = "") const {
294
295 drain::Logger mout(__FILE__, __FUNCTION__);
296
297 if (odim.quantity.empty())
298 odim.quantity = quantity;
299
300 if (!type.empty())
301 odim.type = type;
302
303 const std::string & qty = quantity.empty() ? odim.quantity : quantity;
304
305 const QuantityMap & qmap = getQuantityMap();
306 qmap.setQuantityDefaults(dst, qty, odim.type);
307 dst.odim.updateValues(targetEncoding);
308 qmap.setQuantityDefaults(dst, qty, dst.odim.type); // type also?
309 dst.odim.updateValues(targetEncoding);
310 // update
311 dst.data.setScaling(dst.odim.scaling);
312
314 // dst.odim.product = odim.product; ?
315}
316*/
317
318/*
319 * This is one of the many parallel similar implementations. To be removed.
320 * See also:
321 */
322template <class MS, class MD>
324
325 ProductBase::applyODIM(dst.odim, this->odim);
326 ProductBase::applyODIM(dst.odim, inputODIM, true); // New. Use defaults if still unset
327 dst.odim.completeEncoding( this->targetEncoding);
328
330
331 //mout.unimplemented<LOG_WARNING>("Does not set data storage type?");
332
333 // Set actual scaling up to date with metadata)
334 dst.data.setScaling(dst.odim.scaling);
336 // dst.odim.product = odim.product;
337}
338
339
340template <class MS, class MD> // copied from VolumeOp::processVolume
341void RadarProductOp<MS,MD>::processH5(const Hi5Tree &src, Hi5Tree &dst) const {
342
343 //drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(VolumeOp<M>)", __FUNCTION__);
345
346 mout.debug("start");
347 mout.note(getName(), ':', *this);
348 mout.debug2("DataSelector: ", this->dataSelector);
349
350 // Step 1: collect sweeps (/datasetN/)
351 //DataSetMap<src_t> sweeps;
353
355 mout.debug3("collect the applicable paths");
356 ODIMPathList dataPaths; // Down to ../dataN/ level, eg. /dataset5/data4
357 int index = 0;
358
359
360 // mout.unimplemented<LOG_DEBUG>("No index generator defined!");
361
362
363 // NEW
364 this->dataSelector.getPaths(src, dataPaths); //, ODIMPathElem::DATASET);
365 mout.debug3("populate the dataset map, paths=" , dataPaths.size() );
366 //for (ODIMPathList::const_iterator it = dataPaths.begin(); it != dataPaths.end(); ++it){
367 for (const ODIMPath & path: dataPaths){
368 //mout.debug3("add: " , index , '\t' , path );
369 mout.experimental("adding: " , index , '\t' , path);
370 //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] .
371 sweeps.insert(typename DataSetMap<src_t>::value_type("indexxx", DataSet<src_t>(src(path), this->dataSelector.getQuantitySelector() ))); // Something like: sweeps[elangle] = src[parent] .
372 }
373
374
375 // OLD
376 /*
377 this->dataSelector.getPaths(src, dataPaths, ODIMPathElem::DATA);
378
379 mout.debug3("populate the dataset map, paths=" , dataPaths.size() );
380 std::set<ODIMPath> parents;
381
382 for (ODIMPathList::const_iterator it = dataPaths.begin(); it != dataPaths.end(); ++it){
383
384 ODIMPath parent = *it;
385 parent.pop_back();
386
387 mout.debug3("check " , *it );
388
389 if (parents.find(parent) == parents.end()){
390 mout.debug3("add " , parent , "=>" , index );
391 // kludge (index ~ elevation)
392 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] .
393 //elangles << elangle;
394 }
395 }
396 */
397
398
399 mout.debug2("DataSets: " , sweeps.size() );
400
401
402 // Copy metadata from the input volume (note that dst may have been cleared above)
403 for (const auto & key: {ODIMPathElem::WHAT, ODIMPathElem::WHERE, ODIMPathElem::HOW}){
404 // .data.attributes
405 mout.note("Copying: ", key);
406 mout.unimplemented("consider and test .data.attributes instead");
407 dst[key] = src[key];
408 }
409 // odim.copyToRoot(dst); NO! Mainly overwrites original data. fgrep 'declare(rootAttribute' odim/*.cpp
410
411 //ODIMPath dataSetPath;
414
415 mout.note(DRAIN_LOG(ProductBase::appendResults));
418 }
419
421
422 mout.attention("storing product in path: " , parent , '|' , child );
423 Hi5Tree & dstProduct = dst[parent][child]; // (dataSetPath);
424
426 {
428 this->computeSingleProduct(sweeps, dstProductDataset);
429 }
430
431 dst["what"].data.attributes["object"] = this->odim.object;
432 dstProduct["what"].data.attributes["product"] = odim.product;
433 dstProduct["what"].data.attributes["prodpar"] = odim.prodpar;
434
435 ProductBase::setRackVersion(dstProduct["how"].data.attributes);
436 // how["elangles"] = elangles; // This service could be lower in hierarchy (but for PseudoRHI and pCappi ok here)
437
438}
439
440
441//template <class M>
442template <class MS, class MD>
444
445 drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(VolumeOp<M>)", __FUNCTION__);
446 mout.debug3("start" );
447
448 if (src.size() == 0)
449 mout.warn("no data" );
450
451 //for (typename DataSetMap<src_t >::const_iterator it = src.begin(); it != src.end(); ++it) {
452 for (const auto & entry: src) {
453 mout.debug3("calling processDataSet for elev=", entry.first, " #datasets=", entry.second.size());
454 processDataSet(entry.second, dstProduct);
455 // TODO: detect first init?
456 // mout.warn("OK" );
457 }
458
460 // mout.warn("getFirst data" );
461 //@ Data<DstType<MD> > & dstData = dstProduct.getFirstData(); // main data
462 //@ dstProduct.updateTree(dstData.odim);
463 // mout.warn("end" );
464}
465
466
467//template <class M>
468template <class MS, class MD>
470
471 //drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(ProductOp<MS,MD>)", __FUNCTION__);
473
474 mout.debug("start" );
475
476 const Data<src_t > & srcData = srcSweep.getFirstData();
477
478 mout.debug("target quantity: " , odim.quantity );
479
480 // NEW 2020/06
481 const std::string & quantity = !odim.quantity.empty() ? odim.quantity : srcData.odim.quantity;
482 Data<DstType<MD> > & dstData = dstProduct.getData(quantity);
483 dstData.odim.quantity = quantity;
484
485 // OLD
486 // Data<DstType<MD> > & dstData = !odim.quantity.empty() ? dstProduct.getData(odim.quantity) : dstProduct.getFirstData();
487 //if (dstData.odim.quantity.empty())
488 // dstData.odim.quantity = odim.quantity;
489
490 //mout.debug("calling setEncoding" );
491 //setEncoding(srcData.odim, dstData.odim);
492 this->initDst(srcData.odim, dstData);
493
494 //mout.warn("calling processData" );
495 processData(srcData, dstData);
496 //mout.warn("updateTree" );
497 //@ dstData.updateTree();
498}
499
500
501
502
503
504} // namespace rack
505
506
507#endif /* RACKOP_H_ */
508
509// Rack
510 // REP
511 // REP // REP // REP // REP
const std::string description
Brief, human-readable description of this bean.
Definition BeanLike.h:309
virtual const std::string & getName() const
Return the name of an instance.
Definition BeanLike.h:89
const std::string name
Name of this bean, typically also the name of the (derived) class.
Definition BeanLike.h:306
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:326
Definition Path.h:135
Definition Data.h:1459
A map of radar data, indexed by quantity code (DBZH, VRAD, etc).
Definition Data.h:1293
DOC: Add class description.
Definition ODIMPath.h:82
static const group_t WHAT
Metadata group /what , at any depth.
Definition ODIMPath.h:127
static const group_t DATASET
First level group, /dataset + digit .
Definition ODIMPath.h:106
static const group_t HOW
Metadata group /how , at any depth.
Definition ODIMPath.h:133
static const group_t DATA
Second level group, /data + digit .
Definition ODIMPath.h:109
static const group_t WHERE
Metadata group /where , at any depth.
Definition ODIMPath.h:130
static bool getNextChild(const Hi5Tree &tree, ODIMPathElem &child)
Derive a child with index one greater than the largest index encountered.
Definition ODIMPathTools.cpp:106
ODIM metadata (quantity, gain, offset, undetect, nodata, date, time)
Definition ODIM.h:79
Base class for radar data processors. Input can be in polar or Cartesian coordinates.
Definition ProductBase.h:82
static void applyODIM(ODIM &productODIM, const ODIM &defaultODIM, bool useDefaults=false)
Modifies encoding. If type is changed, resets scaling first.
Definition ProductBase.cpp:120
ODIMPathElem appendResults
If set, appends outputs in an hdf5 structure instead of overwriting.
Definition ProductConf.h:92
Registry for regular quantities appearing in weather radar.
Definition QuantityMap.h:67
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:341
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:251
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:443
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:323
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:469
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 AltitudeOp.cpp:42
QuantityMap & getQuantityMap()
Definition QuantityMap.cpp:282