31#ifndef RADAR_ACCUMULATOR_H
32#define RADAR_ACCUMULATOR_H
38#include <drain/image/AccumulatorGeo.h>
42#include "data/ODIMPath.h"
44#include "data/DataSelector.h"
45#include "data/DataCoder.h"
46#include "data/QuantityMap.h"
84 typedef std::map<int,std::string> legend_t;
98 const std::string & getTargetEncoding(){
99 return targetEncoding;
108 std::string targetEncoding;
120template <
class AC,
class OD>
168 drain::image::Accumulator::FieldList fields;
169 drain::image::Accumulator::getFields(fieldStr, fields);
170 extract(dstProduct, fields, encoding, cropArea);
173 void extract(DataSet<DstType<OD> > & dstProduct,
const drain::image::Accumulator::FieldList & fields,
const std::string & encoding=
"C",
const drain::Rectangle<int> & cropArea={0,0});
193 void consumeTargetEncoding(std::string & encoding){
201 std::ostream & toStream(std::ostream & ostr)
const {
204 this->AC::toStream(ostr);
216 return RadarAccumulatorBase::checkCompositingMethod(this->getMethod(), dataODIM);
224template <
class AC,
class OD>
229 targetEncoding = encoding;
231 if (encoding.empty()){
235 std::string quantityPrev = odim.quantity;
248 odim.updateValues(encoding);
251 if (!quantityPrev.empty()){
252 if (odim.quantity != quantityPrev){
253 mout.
warn(
"Quantity changed from [", quantityPrev,
"] to [", odim.quantity,
"]");
256 mout.info(
"Confirming quantity [", odim.quantity,
"] explicitly");
261 mout.
attention(
"Target encoding: [", encoding,
"] odim: ", odim);
266template <
class AC,
class OD>
273 if (!srcQuality.data.isEmpty()){
274 mout.info(
"Quality data available with input; using quality as weights in compositing.");
275 DataCoder converter(srcData.odim, srcQuality.odim);
277 AC::addData(srcData.data, srcQuality.data, converter, weight, i0, j0);
280 mout.info(
"No quality data available with input, ok.");
284 DataCoder converter(srcData.odim, qualityOdim);
286 AC::addData(srcData.data, converter, weight, i0, j0);
290 odim.updateLenient(srcData.odim);
293 counter += std::max(1L, srcData.odim.ACCnum);
301template <
class AC,
class OD>
306 DataCoder converter(srcData.odim, srcQuality.odim);
307 AC::addData(srcData.data, srcQuality.data, srcCount.data, converter);
309 odim.updateLenient(srcData.odim);
310 counter = std::max(1L, srcData.odim.ACCnum);
351template <
class AC,
class OD>
359 pdata_dst_t & dstData = extract(dstProduct, field, encoding, cropArea);
361 if (ODIM::versionFlagger.isSet(ODIM::RACK_EXTENSIONS) && !legend.empty()){
362 mout.experimental(
"Copying (moving) legend for ", field);
363 dstData.getWhat()[
"legend"] = drain::sprinter(legend,
"|",
",",
":").str();
372template <
class AC,
class OD>
378 mout.
debug(
"extracting FIELD: ", field);
380 char fieldChar = (char)(((
int)field)&127);
381 if (fieldChar != drain::image::Accumulator::getFieldChar(field)){
382 mout.
fail(
"program error: ", field,
'=', fieldChar,
"!=", drain::image::Accumulator::getFieldChar(field));
386 if (!cropArea.
empty()){
387 mout.
note(
"Applying cropping: bbox=", cropArea,
" [pix] from ", this->accArray.getGeometry());
409 DataCoder dataCoder(odimData, odimQuality);
412 mout.
attention(
"extracting field '", field,
"'");
420 mout.
debug(DRAIN_LOG_VAR(dataCoder));
421 mout.
debug2(DRAIN_LOG_VAR(dataCoder.dataODIM));
422 mout.
debug2(DRAIN_LOG_VAR(dataCoder.qualityODIM));
427 if (field == field_t::DATA){
437 mout.
debug(
"extracting DATA/" , field,
" [", odimData.
quantity,
']');
439 if (!encoding.empty()){
440 mout.
accept(
"User-defined encoding for data [", odimData.
quantity,
"]: ", encoding);
442 odimData.completeEncoding(encoding);
444 else if (!getTargetEncoding().empty()){
445 mout.ok<LOG_NOTICE>(
"Using initial/default encoding for data [", odimData.
quantity,
"]: ", getTargetEncoding());
447 odimData.completeEncoding(getTargetEncoding());
451 mout.
error(
"unspecified quantity");
457 extractFinally(*
this, field, odimData, dataCoder, dstData.odim, dstData.data, cropArea);
479 case field_t::WEIGHT_DS:
480 case field_t::WEIGHT:
483 case field_t::COUNT_DS:
487 case field_t::DEVIATION:
488 odimQuality.
quantity = this->odim.quantity +
"DEV";
491 mout.
error(
"Unsupported field marker: ", field,
"='", fieldChar,
"'");
495 mout.
debug(
"extracting QUALITY/" , field,
" [", odimQuality.
quantity,
']');
499 mout.
accept<LOG_DEBUG>(
"found quantityConf[", odimQuality.
quantity,
"], type=", odimQuality.
type);
501 mout.
special<LOG_DEBUG>(
"Quality: ", odimQuality);
503 else if (!encoding.empty()){
504 mout.
accept<LOG_INFO>(
"User-defined encoding for quality [", odimQuality.
quantity,
"]: ", encoding);
505 odimQuality.completeEncoding(encoding);
506 mout.
debug(
"User-defined encoding for QUALITY: -> ", odimQuality);
519 odimQuality.
setType(
typeid(
float));
520 mout.
warn(
"quantyConf[" , odimQuality.
quantity ,
"] not found, using float" );
533 extractFinally(*
this, field, odimQuality, dataCoder, dstQuality.odim, dstQuality.data, cropArea);
566template <
class AC,
class OD>
575 typedef enum {DATA,QUALITY} datatype;
579 odimData.scaling.scale = 0.0;
588 bool DATA_SPECIFIC_QUALITY =
false;
591 for (
size_t i = 0; i < fields.length(); ++i) {
598 datatype type = DATA;
599 char field = fields.at(i);
602 DATA_SPECIFIC_QUALITY =
true;
608 mout.
warn() <<
"non-standard layer code; use 'd' for 'data' instead" << mout.endl;
637 mout.
warn(
"experimental: quality [QIND] type copied from data [" , odimOut.quantity ,
']' );
648 odimQuality = odimOut;
652 mout.
accept<LOG_NOTICE>(
"found quantyConf[", odimQuality.
quantity,
"], type=", odimQuality.
type);
655 mout.
special(
"Quality: ", odimQuality);
658 odimQuality.scaling.
scale *= 20.0;
660 odimQuality.scaling.
offset = round(drain::Type::call<drain::typeMin, double>(t) + drain::Type::call<drain::typeMax, double>(t))/2.0;
662 mout.
warn(
"quantyConf[" , odimQuality.
quantity ,
"] not found, using somewhat arbitary scaling:" );
667 mout.
error(
"Unsupported field code: '", field,
"'");
671 mout.
debug(
"extracting field ", field);
674 mout.experimental(
"Applying cropping: bbox=", crop,
" [pix]");
680 else if (type == QUALITY){
684 if (odimData.quantity.empty()){
685 odimData.quantity =
"UNKNOWN";
686 mout.
note(
"quantity=", odimData.quantity);
690 mout.
debug(
"searching dstData... DATA=", (type == DATA));
697 DataCoder dataCoder(odimData, odimQuality);
698 mout.
debug(
"dataCoder: ", dataCoder);
699 mout.
debug2(
"dataCoder: data: ", dataCoder.dataODIM);
700 mout.
debug2(
"dataCoder: qind: ", dataCoder.qualityODIM);
703 mout.
unimplemented(
"crop ", crop,
", dstData.data resize + Accumulator::extractField ");
707 mout.
debug(
"DATA/" , field,
" [", odimData.quantity,
']');
709 pdata_dst_t & dstData = dstProduct.getData(odimData.quantity);
710 dstData.odim.importMap(odimData);
711 dstData.data.setType(odimData.type);
712 mout.debug3(
"dstData: " , dstData );
717 mout.
debug(
"QUALITY/" , field ,
" [", odimQuality.
quantity,
']');
720 q_data_t & qualityOwner = (DATA_SPECIFIC_QUALITY) ? (q_data_t &) dstProduct.getData(odimData.quantity) : (q_data_t &) dstProduct;
722 dstData.odim.updateFromMap(odimQuality);
723 mout.debug3(
"dstData: " , dstData );
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 & special(const TT &... args)
Other useful information.
Definition Log.h:531
Logger & fail(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition Log.h:453
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition Log.h:476
Logger & error(const TT &... args)
Echoes.
Definition Log.h:416
Logger & accept(const TT &... args)
Some input has been accepted, for example by a syntax.
Definition Log.h:582
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
static const std::type_info & getTypeInfo(char t)
Returns the base type associated with a character key.
Definition Type.h:134
double & scale
Multiplicative coefficient \i a in: y = ax + b.
Definition ValueScaling.h:68
double & offset
Additive coefficient \i b in: y = ax + b.
Definition ValueScaling.h:71
Function for accumulating data: maximum, average, weighted average etc.
Definition AccumulationMethods.h:65
Definition Accumulator.h:76
static bool isSpecific(FieldType field)
Future option to mark scaled/normalized etc.
Definition Accumulator.h:114
void extractField(char field, const AccumulationConverter &converter, Image &dst, const drain::Rectangle< int > &crop) const
Extracts the accumulated quantity or secondary quantities like weight and standard deviation.
Definition Accumulator.h:245
FieldType
Definition Accumulator.h:84
Class for multi-channel digital images. Supports dynamic typing with base types (char,...
Definition Image.h:193
Converts ODIM encoded data (with markers) to natural values and backwards.
Definition DataCoder.h:61
Tool for selecting datasets based on paths, quantities and min/max elevations.
Definition DataSelector.h:112
A map of radar data, indexed by quantity code (DBZH, VRAD, etc).
Definition Data.h:1215
Structure for data storage type, scaling and marker codes. Does not contain quantity.
Definition EncodingODIM.h:75
void setType(const std::type_info &type)
Complete with setTypeDefaults()
Definition EncodingODIM.h:187
std::string type
This is non-standard (not in ODIM), but a practical means of handling storage type of datasets.
Definition EncodingODIM.h:152
static const group_t QUALITY
Special group on first or second level, /quality + digit , used for storing quality data.
Definition ODIMPath.h:115
static const group_t DATA
Second level group, /data + digit .
Definition ODIMPath.h:109
ODIM metadata (quantity, gain, offset, undetect, nodata, date, time)
Definition ODIM.h:79
std::string quantity
dataX/what (obligatory)
Definition ODIM.h:181
Essential class for storing radar data.
Definition Data.h:300
Base class providing quality support for Dataand DataSet
Definition Data.h:1034
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
bool hasQuantity(const std::string &key) const
Checks if an exact match or a variant, is found.
Definition QuantityMap.h:119
Todo: consider non-template class:
Definition RadarAccumulator.h:63
size_t counter
Book-keeping for new data. Finally, in extraction phase, added to odim.ACCnum .
Definition RadarAccumulator.h:95
DataSelector dataSelector
Input data selector.
Definition RadarAccumulator.h:80
double defaultQuality
If source data has no quality field, this value is applied for (detected) data.
Definition RadarAccumulator.h:89
Data array for creating composites and accumulated polar products (Surface rain fall or cluttermaps)
Definition RadarAccumulator.h:122
OD odim
For storing the scaling and encoding of (1st) input or user-defined values. Also for bookkeeping of d...
Definition RadarAccumulator.h:185
void addData(const pdata_src_t &srcData, const pdata_src_t &srcQuality, double weight, int i0, int j0)
Adds data that is in the same coordinate system as the accumulator. Weighted with quality.
Definition RadarAccumulator.h:267
void extractOLD(const OD &odimOut, DataSet< DstType< OD > > &dstProduct, const std::string &fields, const drain::Rectangle< int > &crop={0, 0, 0, 0}) const
Definition RadarAccumulator.h:567
RadarAccumulator()
Default constructor.
Definition RadarAccumulator.h:133
void addData(const pdata_src_t &srcData, const pdata_src_t &srcQuality, const pdata_src_t &srcCount)
Adds data that is in the same coordinate system as the accumulator.
Definition RadarAccumulator.h:302
bool checkCompositingMethod(const ODIM &dataODIM)
Warns if data scaling involves risks in using WAVG (weighted averaging)
Definition RadarAccumulator.h:215
PlainData< SrcType< OD const > > pdata_src_t
Input data type.
Definition RadarAccumulator.h:127
pdata_dst_t & extract(DataSet< DstType< OD > > &dstProduct, field_t field=field_t::DATA, const std::string &encoding="C", const drain::Rectangle< int > &cropArea={0, 0})
Definition RadarAccumulator.h:373
void setTargetEncoding(const std::string &encoding)
Not critical. If set, needed to warn if input data does not match the expected / potential targetEnco...
Definition RadarAccumulator.h:225
Definition DataSelector.cpp:44
QuantityMap & getQuantityMap()
Definition QuantityMap.cpp:279
Rectange defined through lower left and upper right coordinates.
Definition Rectangle.h:65
bool empty() const
Return true if the area is zero.
Definition Rectangle.h:111
Writable data type.
Definition Data.h:120