32 #ifndef DATACONVERSIONOP2_H_
33 #define DATACONVERSIONOP2_H_
41 #include <drain/Log.h>
42 #include <drain/RegExp.h>
43 #include <drain/Type.h>
44 #include <drain/TypeUtils.h>
45 #include <drain/util/StringMatcherList.h>
47 #include "drain/util/SmartMap.h"
48 #include "drain/util/TreeOrdered.h"
49 #include "drain/util/ValueScaling.h"
50 #include "drain/util/VariableMap.h"
52 #include "drain/image/Geometry.h"
53 #include "drain/image/Image.h"
54 #include "drain/image/ImageFrame.h"
56 #include "data/Data.h"
57 #include "data/ODIM.h"
58 #include "data/ODIMPath.h"
59 #include "data/Quantity.h"
60 #include "data/QuantityMap.h"
63 #include "ProductOp.h"
89 DataConversionOp(
const std::string & type=
"C",
double gain=1.0,
double offset=0.0,
90 double undetect=0.0,
double nodata=255.0, std::string
copyGroupSuffix=
"") :
91 ProductOp<M, M>(__FUNCTION__,
"Converts HDF5 data to use desired data type, scaling and encoding") {
93 this->allowedEncoding.link(
"what:type", this->odim.type = type);
94 this->allowedEncoding.link(
"what:gain", this->odim.scaling.scale = gain);
95 this->allowedEncoding.link(
"what:offset", this->odim.scaling.offset = offset);
96 this->allowedEncoding.link(
"what:undetect", this->odim.undetect = undetect);
97 this->allowedEncoding.link(
"what:nodata", this->odim.nodata = nodata);
111 void processH5(
const Hi5Tree &src, Hi5Tree &dst)
const;
119 processImage(src.odim, src.data, this->odim, dst);
154 const std::string & quantity) {
158 const std::string quantityExt = quantity+
"_norm";
162 if (it != normDataSet.end()){
163 mout.
note(
"using cached data: ", quantityExt);
168 const PlainData<src_t> & srcData = srcDataSet.getData(quantity);
169 const EncodingODIM & odimNorm = getQuantityMap().get(quantity).
get();
171 mout.info(
"converting and adding to cache: " , quantityExt ,
" odim: " , odimNorm );
172 PlainData<dst_t> & dstDataNew = normDataSet.getData(quantityExt);
173 dstDataNew.setExcluded();
174 DataConversionOp<M> op;
178 dstDataNew.odim.importMap(srcData.odim);
179 dstDataNew.odim.importMap(odimNorm);
180 dstDataNew.odim.quantity = quantity;
182 op.processImage(srcData.odim, srcData.data, dstDataNew.odim, dstDataNew.data);
183 dstDataNew.odim.quantity = quantityExt;
184 dstDataNew.updateTree2();
185 mout.
debug(
"obtained: " , dstDataNew );
202 mout.
debug(
"DataSelector: ", this->dataSelector);
205 ODIMPathList dataPaths;
206 this->dataSelector.getPaths(src, dataPaths);
208 mout.
special(
"obtained ", dataPaths.size(),
" paths.");
211 std::set<ODIMPathElem> parents;
228 mout.
special(
"handling: ", parent,
" -> ", path);
230 if (parents.find(parent) == parents.end()){
232 mout.
note(
"non-dataset group: ", parent);
234 mout.
note(
"now handling: ", parent);
235 parents.insert(parent);
240 processDataSet(srcDataSet, dstDataSet);
243 mout.
note(
"already exists(?): ", parent);
254 std::set<std::string> convertedQuantities;
258 mout.
debug(
"number of layers (sub groups of DataSet): ", srcSweep.size());
262 for (
const auto & entry: srcSweep){
264 const std::string & quantity = entry.first;
266 if (quantity.empty()){
267 mout.
warn(
"empty quantity for data, skipping");
272 const std::string quantityTmp = quantity+
'*';
274 mout.
debug(
"quantity: ", quantity);
277 Data<dst_t> & dstData = dstProduct.getData(quantityTmp);
279 mout.
attention<LOG_DEBUG>(
"srcData: ", entry.second);
288 const bool IN_PLACE =
false;
292 mout.info(
"already similar encoding – no need to convert (1)");
297 mout.
debug(
"in-place");
305 mout.info(
"using tmp data – in-place computation not possible");
310 mout.info(
"already similar encoding – no need to convert (2)");
314 convertedQuantities.insert(entry.first);
317 const M srcODIM(srcData.data);
318 mout.
attention(
"srcData.odim: ", srcData.odim);
320 dstData.odim.quantity = quantity;
321 dstData.odim.updateLenient(srcODIM);
325 processImage(srcODIM, srcData.data, dstData.odim, dstData.data);
332 mout.
debug(
"Swap & mark for deletion: ", drain::sprinter(convertedQuantities));
333 for (
const std::string & quantity: convertedQuantities){
335 const std::string quantityTmp = quantity +
'*';
337 mout.
special(
"Swapping quantity: ", quantity,
" <-> ", quantityTmp);
339 Data<dst_t> & dstDataOrig = dstProduct.getData(quantity);
340 Data<dst_t> & dstDataConv = dstProduct.getData(quantityTmp);
342 dstDataOrig.swap(dstDataConv);
344 dstDataConv.odim.quantity = quantityTmp;
345 dstDataConv.setExcluded(
true);
359 processImage(srcOdim, srcImage, odim, dstImage);
370 mout.
debug(
"type=", this->odim.
type,
", geom=", srcImage.getGeometry() );
377 mout.
attention<LOG_DEBUG>(
"srcOdim ", srcOdim);
378 mout.
attention<LOG_DEBUG>(
"srcImage:", srcImage);
381 if ((t.
getType() != srcImage.
getType()) || (g != dstImage.getGeometry())){
382 mout.
warn(
"using temp image + swap");
386 tmp.setScaling(dstOdim.scaling);
387 traverseImageFrame(srcOdim, srcImage, dstOdim, tmp);
393 mout.
warn(
"same type and geometry, hence only rescaling (in-place)");
410 dstImage.setScaling(dstOdim.scaling);
411 mout.
debug(
"dst:", dstImage);
412 traverseImageFrame(srcOdim, srcImage, dstOdim, dstImage);
415 mout.
attention<LOG_DEBUG>(
"dstOdim: ", dstOdim);
416 mout.
attention<LOG_DEBUG>(
"dstImage: ", dstImage);
429 mout.debug3(
"src props:", srcImage.
properties);
432 mout.
debug(
"dst:", dstImage);
437 dstImage.setScaling(dstOdim.scaling);
448 mout.
debug(
"scaling: ", scaling);
451 Limiter::value_t limit = drain::Type::call<Limiter>(dstOdim.
type);
453 Image::const_iterator s = srcImage.
begin();
454 Image::iterator d = dstImage.
begin();
458 if (
static_cast<double>(*d) != dstOdim.
nodata){
459 mout.
note(
"dstOdim.nodata=", dstOdim.
nodata,
" -> ",
static_cast<double>(*d));
460 mout.
note(
"type conversion ", srcOdim.
type,
" -> ", dstOdim.
type);
461 mout.
warn(
"type conversion ", dstOdim.
type,
" ~= ", drain::Type::getTypeChar(dstImage.
getType()),
" changed the value");
465 mout.
debug2(
"src: ", srcImage);
466 mout.
debug2(
"dst: ", dstImage);
468 while (s != srcImage.
end()){
472 if (x == srcOdim.undetect)
473 *d = dstOdim.undetect;
474 else if (x == srcOdim.
nodata)
484 *d = limit( scaling.
inv(x) );
492 mout.debug3(
"finished.");
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition: Log.h:472
Logger & special(const TT &... args)
Other useful information.
Definition: Log.h:527
Logger & unimplemented(const TT &... args)
Feature to be done. Special type of Logger::note().
Definition: Log.h:507
Logger & note(const TT &... args)
For top-level information.
Definition: Log.h:485
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Logger & debug(const TT &... args)
Public, yet typically used "internally", when TIMING=true.
Definition: Log.h:676
Logger & debug2(const TT &... args)
Debug information.
Definition: Log.h:686
void importCastableMap(const drain::SmartMap< T2 > &m)
Assign values from a map, possibly extending the map.
Definition: SmartMap.h:271
void updateFromCastableMap(const drain::SmartMap< T2 > &m)
Convenience.
Definition: SmartMap.h:301
Utilities related to std::type_info.
Definition: Type.h:51
const std::type_info & getType() const
Deprecated! Use cast (above) instead?
Definition: Type.h:107
Linear scaling and physical range for image intensities.
Definition: ValueScaling.h:64
double inv(double y) const
Inverse scaling: given physically meaningful value y, returns the corresponding code value.
Definition: ValueScaling.h:301
Definition: Geometry.h:145
Image with static geometry.
Definition: ImageFrame.h:67
const iterator & begin()
Returns iterator pointing to the first image element.
Definition: ImageFrame.h:119
const iterator & end()
Returns the iterator pointing to the element after the last element of the image buffer.
Definition: ImageFrame.h:125
FlexVariableMap properties
Container for user-defined KEY=VALUE metadata.
Definition: ImageFrame.h:369
bool hasOverlap(const ImageFrame &image) const
Checks if images have a common memory segment.
Definition: ImageFrame.h:341
const std::type_info & getType() const
Get the storage type.
Definition: ImageLike.h:100
const CoordinatePolicy & getCoordinatePolicy() const
Coord policy.
Definition: ImageLike.h:167
Class for multi-channel digital images. Supports dynamic typing with base types (char,...
Definition: Image.h:184
void setType(const std::type_info &type)
Sets the storage type of the image - typically unsigned char, unsigned int or float.
Definition: Image.h:268
virtual void setGeometry(size_t width, size_t height, size_t imageChannels=1, size_t alphaChannels=0)
Resizes the image, keeps the current type.
Definition: Image.h:95
Computes dot product of intensities of two images.
Definition: PixelVectorOp.h:364
Converts HDF5 data to use desired data type, scaling and encoding (ODIM gain, offset,...
Definition: DataConversionOp.h:82
virtual void processDataSet(const DataSet< src_t > &srcSweep, DataSet< dst_t > &dstProduct) const
Definition: DataConversionOp.h:250
virtual void processH5(const Hi5Tree &src, Hi5Tree &dst) const
Ensures data to be in standard type and scaling. Makes a converted copy if needed.
Definition: DataConversionOp.h:197
std::string copyGroupSuffix
Suffix for trailing path element ("/data") for storing the original.
Definition: DataConversionOp.h:147
void traverseImageFrame(const ODIM &odimSrc, const drain::image::ImageFrame &src, const ODIM &odimDst, drain::image::ImageFrame &dst) const
Definition: DataConversionOp.h:422
A map of radar data, indexed by quantity code (DBZH, VRAD, etc).
Definition: Data.h:1213
Data structure consisting of plain data and an optional quality data.
Definition: Data.h:1144
Structure for data storage type, scaling and marker codes. Does not contain quantity.
Definition: EncodingODIM.h:75
static bool haveSimilarEncoding(const EncodingODIM &odim1, const EncodingODIM &odim2)
Checks if data encoding is similar (storage type, gain, offset, undetect and nodata are the same).
Definition: EncodingODIM.h:167
std::string type
This is non-standard (not in ODIM), but a practical means of handling storage type of datasets.
Definition: EncodingODIM.h:146
double nodata
data[n]/what (obligatory)
Definition: EncodingODIM.h:151
Definition: ODIMPath.h:82
static const group_t DATASET
First level group, /dataset + digit .
Definition: ODIMPath.h:103
static const group_t ROOT
Definition: ODIMPath.h:99
static const group_t DATA
Second level group, /data + digit .
Definition: ODIMPath.h:106
ODIM metadata (quantity, gain, offset, undetect, nodata, date, time)
Definition: ODIM.h:79
Essential class for storing radar data.
Definition: Data.h:302
static void completeEncoding(ODIM &productODIM, const std::string &targetEncoding)
Modifies encoding. If type is changed, resets scaling first.
Definition: ProductBase.cpp:183
const EncodingODIM & get(char typecode='\0') const
Retrieve the scaling for a given storage type.
Definition: Quantity.h:108
Definition: DataSelector.cpp:44
Writable data type.
Definition: Data.h:122
Read-only data type.
Definition: Data.h:112