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 type = "") 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 ProductBase::completeEncoding(dst.odim, 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>
252 const std::string quantity, const std::string type) const {
253
254 drain::Logger mout(__FILE__, __FUNCTION__);
255
256 if (dstData.odim.quantity.empty())
257 dstData.odim.quantity = quantity;
258
259 if (!type.empty())
260 dstData.odim.type = type;
261
262 const std::string & qty = quantity.empty() ? dstData.odim.quantity : quantity;
263
264 if (qty.empty()){
265 mout.warn("No quantity in metadata or as argument" );
266 }
267
268 const QuantityMap & qmap = getQuantityMap();
269 qmap.setQuantityDefaults(dstData, qty, dstData.odim.type);
270 dstData.odim.updateValues(targetEncoding);
271 qmap.setQuantityDefaults(dstData, qty, dstData.odim.type); // type also?
272 dstData.odim.updateValues(targetEncoding);
273 // update
274 dstData.data.setScaling(odim.scaling);
275
277 // dstData.odim.product = odim.product; ?
278}
279
280/*
281template <class MS, class MD>
282void ProductOp<MS,MD>::setEncodingNEW(PlainData<dst_t> & dst, const std::string quantity = "", const std::string type = "") const {
283
284 drain::Logger mout(__FILE__, __FUNCTION__);
285
286 if (odim.quantity.empty())
287 odim.quantity = quantity;
288
289 if (!type.empty())
290 odim.type = type;
291
292 const std::string & qty = quantity.empty() ? odim.quantity : quantity;
293
294 const QuantityMap & qmap = getQuantityMap();
295 qmap.setQuantityDefaults(dst, qty, odim.type);
296 dst.odim.updateValues(targetEncoding);
297 qmap.setQuantityDefaults(dst, qty, dst.odim.type); // type also?
298 dst.odim.updateValues(targetEncoding);
299 // update
300 dst.data.setScaling(dst.odim.scaling);
301
303 // dst.odim.product = odim.product; ?
304}
305*/
306
307template <class MS, class MD>
308void RadarProductOp<MS,MD>::setEncoding(const ODIM & inputODIM, PlainData<dst_t> & dst) const {
309
310 ProductBase::applyODIM(dst.odim, this->odim);
311 ProductBase::applyODIM(dst.odim, inputODIM, true); // New. Use defaults if still unset
312 ProductBase::completeEncoding(dst.odim, this->targetEncoding);
313
314 // Set actual scaling up to date with metadata)
315 dst.data.setScaling(dst.odim.scaling);
317 // dst.odim.product = odim.product;
318}
319
320
321template <class MS, class MD> // copied from VolumeOp::processVolume
322void RadarProductOp<MS,MD>::processH5(const Hi5Tree &src, Hi5Tree &dst) const {
323
324 //drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(VolumeOp<M>)", __FUNCTION__);
325 drain::Logger mout(__FILE__, __FUNCTION__);
326
327 mout.debug("start");
328 mout.warn(*this);
329 mout.debug2("DataSelector: ", this->dataSelector);
330
331 // Step 1: collect sweeps (/datasetN/)
332 //DataSetMap<src_t> sweeps;
333 DataSetMap<src_t> sweeps;
334
336 mout.debug3("collect the applicable paths");
337 ODIMPathList dataPaths; // Down to ../dataN/ level, eg. /dataset5/data4
338 int index = 0;
339
340
341 mout.unimplemented("No index generator defined!");
342 // NEW
343 this->dataSelector.getPaths(src, dataPaths); //, ODIMPathElem::DATASET);
344 mout.debug3("populate the dataset map, paths=" , dataPaths.size() );
345 //for (ODIMPathList::const_iterator it = dataPaths.begin(); it != dataPaths.end(); ++it){
346 for (const ODIMPath & path: dataPaths){
347 mout.debug3("add: " , index , '\t' , path );
348 //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] .
349 sweeps.insert(typename DataSetMap<src_t>::value_type("indexxx", DataSet<src_t>(src(path), this->dataSelector.getQuantitySelector() ))); // Something like: sweeps[elangle] = src[parent] .
350 }
351
352
353 // OLD
354 /*
355 this->dataSelector.getPaths(src, dataPaths, ODIMPathElem::DATA);
356
357 mout.debug3("populate the dataset map, paths=" , dataPaths.size() );
358 std::set<ODIMPath> parents;
359
360 for (ODIMPathList::const_iterator it = dataPaths.begin(); it != dataPaths.end(); ++it){
361
362 ODIMPath parent = *it;
363 parent.pop_back();
364
365 mout.debug3("check " , *it );
366
367 if (parents.find(parent) == parents.end()){
368 mout.debug3("add " , parent , "=>" , index );
369 // kludge (index ~ elevation)
370 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] .
371 //elangles << elangle;
372 }
373 }
374 */
375
376
377 mout.debug2("DataSets: " , sweeps.size() );
378
379
380 // Copy metadata from the input volume (note that dst may have been cleared above)
381 for (const auto key: {ODIMPathElem::WHAT, ODIMPathElem::WHERE, ODIMPathElem::HOW}){
382 // .data.attributes
383 mout.unimplemented("consider and test .data.attributes instead");
384 dst[key] = src[key];
385 }
386 // odim.copyToRoot(dst); NO! Mainly overwrites original data. fgrep 'declare(rootAttribute' odim/*.cpp
387
388 //ODIMPath dataSetPath;
389 ODIMPathElem parent(ODIMPathElem::DATASET); // /dataset1
390 ODIMPathElem child(ODIMPathElem::DATA); // /dataset1
391
392 mout.note(DRAIN_LOG_VAR(ProductBase::appendResults));
393 if (ProductBase::appendResults.getType() == ODIMPathElem::DATASET){
394 ODIMPathTools::getNextChild(dst, parent);
395 }
396
397 ODIMPathTools::getNextChild(dst[parent], child);
398
399 mout.attention("storing product in path: " , parent , '|' , child );
400 Hi5Tree & dstProduct = dst[parent][child]; // (dataSetPath);
401
403 {
404 DataSet<dst_t> dstProductDataset(dstProduct); // PATH
405 this->computeSingleProduct(sweeps, dstProductDataset);
406 }
407
408 dst["what"].data.attributes["object"] = this->odim.object;
409 dstProduct["what"].data.attributes["product"] = odim.product;
410 dstProduct["what"].data.attributes["prodpar"] = odim.prodpar;
411
412 ProductBase::setRackVersion(dstProduct["how"].data.attributes);
413 // how["elangles"] = elangles; // This service could be lower in hierarchy (but for PseudoRHI and pCappi ok here)
414
415}
416
417
418//template <class M>
419template <class MS, class MD>
421
422 drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(VolumeOp<M>)", __FUNCTION__);
423 mout.debug3("start" );
424
425 if (src.size() == 0)
426 mout.warn("no data" );
427
428 //for (typename DataSetMap<src_t >::const_iterator it = src.begin(); it != src.end(); ++it) {
429 for (const auto & entry: src) {
430 mout.debug3("calling processDataSet for elev=", entry.first, " #datasets=", entry.second.size());
431 processDataSet(entry.second, dstProduct);
432 // TODO: detect first init?
433 // mout.warn("OK" );
434 }
435
437 // mout.warn("getFirst data" );
438 //@ Data<DstType<MD> > & dstData = dstProduct.getFirstData(); // main data
439 //@ dstProduct.updateTree(dstData.odim);
440 // mout.warn("end" );
441}
442
443
444//template <class M>
445template <class MS, class MD>
446void RadarProductOp<MS,MD>::processDataSet(const DataSet<src_t > & srcSweep, DataSet<DstType<MD> > & dstProduct) const {
447
448 //drain::Logger mout(__FILE__, __FUNCTION__); //REPL this->name+"(ProductOp<MS,MD>)", __FUNCTION__);
449 drain::Logger mout(__FILE__, __FUNCTION__);
450
451 mout.debug("start" );
452
453 const Data<src_t > & srcData = srcSweep.getFirstData();
454
455 mout.debug("target quantity: " , odim.quantity );
456
457 // NEW 2020/06
458 const std::string & quantity = !odim.quantity.empty() ? odim.quantity : srcData.odim.quantity;
459 Data<DstType<MD> > & dstData = dstProduct.getData(quantity);
460 dstData.odim.quantity = quantity;
461
462 // OLD
463 // Data<DstType<MD> > & dstData = !odim.quantity.empty() ? dstProduct.getData(odim.quantity) : dstProduct.getFirstData();
464 //if (dstData.odim.quantity.empty())
465 // dstData.odim.quantity = odim.quantity;
466
467 //mout.debug("calling setEncoding" );
468 //setEncoding(srcData.odim, dstData.odim);
469 this->initDst(srcData.odim, dstData);
470
471 //mout.warn("calling processData" );
472 processData(srcData, dstData);
473 //mout.warn("updateTree" );
474 //@ dstData.updateTree();
475}
476
477
478
479
480
481} // namespace rack
482
483
484#endif /* RACKOP_H_ */
485
486// Rack
487 // REP
488 // 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:312
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:430
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:666
Logger & note(const TT &... args)
For top-level information.
Definition Log.h:489
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition Log.h:476
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition Log.h:511
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:676
Definition Path.h:112
Definition Data.h:1370
A map of radar data, indexed by quantity code (DBZH, VRAD, etc).
Definition Data.h:1215
Data structure consisting of plain data and an optional quality data.
Definition Data.h:1146
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
Definition QuantityMap.h:50
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
void setEncodingNEW(PlainData< dst_t > &dstData, const std::string quantity="", const std::string type="") const
Sets applicable encoding parametes (type, gain, offset, undetect, nodata) for this product.
Definition RadarProductOp.h:251
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:322
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
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:420
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:308
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:446
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