32#ifndef DATACONVERSIONOP2_H_ 
   33#define DATACONVERSIONOP2_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> 
   58#include "data/ODIMPath.h" 
   59#include "data/Quantity.h" 
   60#include "data/QuantityMap.h" 
   63#include <product/RadarProductOp.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                RadarProductOp<M, M>(__FUNCTION__, 
"Converts HDF5 data to use desired data type, scaling and encoding") {
 
  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;
 
  221        if (path.front().is(ODIMPathElem::ROOT)){
 
  228        mout.
special(
"handling: ", parent, 
" -> ", path);
 
  230        if (parents.find(parent) == parents.end()){
 
  231            if (parent.getType() != ODIMPathElem::DATASET){
 
  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;
 
  291            if (ODIM::haveSimilarEncoding(srcData.odim, this->odim)){
 
  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");
 
  309            if (ODIM::haveSimilarEncoding(srcData.odim, this->odim)){
 
  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); 
 
  322            dstData.odim.completeEncoding( this->targetEncoding);
 
  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);
 
 
  358    odim.completeEncoding( this->targetEncoding);
 
  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);
 
  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.");
 
 
Definition CastableIterator.h:57
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 & 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
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:50
const std::type_info & getType() const
Deprecated! Use cast (above) instead?
Definition Type.h:106
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:64
const iterator & begin()
Returns iterator pointing to the first image element.
Definition ImageFrame.h:116
const iterator & end()
Returns the iterator pointing to the element after the last element of the image buffer.
Definition ImageFrame.h:122
FlexVariableMap properties
Container for user-defined KEY=VALUE metadata.
Definition ImageFrame.h:366
bool hasOverlap(const ImageFrame &image) const
Checks if images have a common memory segment.
Definition ImageFrame.h:338
const CoordinatePolicy & getCoordinatePolicy() const
Coord policy.
Definition ImageLike.h:174
const std::type_info & getType() const
Get the storage type.
Definition ImageLike.h:100
Class for multi-channel digital images. Supports dynamic typing with base types (char,...
Definition Image.h:193
void setType(const std::type_info &type)
Sets the storage type of the image - typically unsigned char, unsigned int or float.
Definition Image.h:277
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:97
Class for ensuring that variable of type D remains within limits of type S.
Definition TypeUtils.h:100
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
void setGeometry(const M &srcODIM, PlainData< dst_t > &dstData) const
Sets automagically the suitable dst parameters.
Definition DataConversionOp.h:135
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
Structure for data storage type, scaling and marker codes. Does not contain quantity.
Definition EncodingODIM.h:75
std::string type
This is non-standard (not in ODIM), but a practical means of handling storage type of datasets.
Definition EncodingODIM.h:152
double nodata
data[n]/what (obligatory)
Definition EncodingODIM.h:157
static const group_t DATASET
First level group, /dataset + digit .
Definition ODIMPath.h:106
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
Essential class for storing radar data.
Definition Data.h:300
drain::ReferenceMap allowedEncoding
Defines which encoding parameters can be changed by the user from command line.
Definition ProductBase.h:206
const EncodingODIM & get(char typecode='\0') const
Retrieve the scaling for a given storage type.
Definition Quantity.cpp:168
Polar and Cartesian products.
Definition RadarProductOp.h:78
M odim
The default data parameters for encoding output (the product).
Definition RadarProductOp.h:101
Definition DataSelector.cpp:44
Writable data type.
Definition Data.h:120
Read-only data type.
Definition Data.h:110