diff --git a/demo/make-image-product.sh b/demo/make-image-product.sh index 8ece594f3..8889de093 100755 --- a/demo/make-image-product.sh +++ b/demo/make-image-product.sh @@ -81,7 +81,8 @@ eval $cmd #if [ ! -f $OUTFILE_LEGEND ]; then echo "# Creating legend..." #cmd="convert tmp.svg $OUTFILE_LEGEND" -cmd="inkscape -z --export-png $OUTFILE_LEGEND tmp.svg" +#cmd="inkscape -z --export-png $OUTFILE_LEGEND tmp.svg" +cmd="convert tmp.svg $OUTFILE_LEGEND" # -filter point -resize 400 echo $cmd eval $cmd #fi diff --git a/demo/test-content.sh b/demo/test-content.sh index de1e8a3b9..c93f3718e 100755 --- a/demo/test-content.sh +++ b/demo/test-content.sh @@ -57,6 +57,7 @@ REQUIRE dataset1 # Technical tests only (not commands) START example-select-test.inc +INFILE='volume.h5' OUTFILE='volume-select.txt' TITLE "Index range: select dataset3, including its subgroups. " diff --git a/src/andre/DetectorOp.cpp b/src/andre/DetectorOp.cpp index 28acb1952..7ffec29c7 100644 --- a/src/andre/DetectorOp.cpp +++ b/src/andre/DetectorOp.cpp @@ -139,10 +139,10 @@ void DetectorOp::runDetection(const DataSetMap & srcVolume, DataSetMap // PROBABILITY OF THE CLASS APPROXIMATED BY THIS DETECTOR PlainData & dstProb = (SUPPORT_UNIVERSAL && UNIVERSAL) ? dstDataSet.getQualityData(CLASSNAME) : dstData.getQualityData(CLASSNAME); - //dstProb.tree.data.noSave = !DetectorOp::STORE; + //dstProb.tree.data.exclude = !DetectorOp::STORE; initDataDst(srcData, dstProb); mout.debug("outputDataVerbosity ", outputDataVerbosity); - dstProb.setNoSave(outputDataVerbosity==0); + dstProb.setExcluded(outputDataVerbosity==0); //mout.warn("dstProb: " , dstProb ); /// MAIN COMMAND @@ -214,10 +214,10 @@ void DetectorOp::runDetection(const DataSetMap & srcVolume, DataSetMap // PROBABILITY OF THE CLASS APPROXIMATED BY THIS DETECTOR PlainData & dstProb = (SUPPORT_UNIVERSAL && UNIVERSAL) ? dstDataSet.getQualityData(CLASSNAME) : dstData.getQualityData(CLASSNAME); - //dstProb.tree.data.noSave = !DetectorOp::STORE; + //dstProb.tree.data.exclude = !DetectorOp::STORE; initDataDst(srcData, dstProb); mout.debug("outputDataVerbosity ", outputDataVerbosity); - dstProb.setNoSave(outputDataVerbosity==0); + dstProb.setExcluded(outputDataVerbosity==0); // mout.debug2("dstProb: ", dstProb); /// MAIN COMMAND diff --git a/src/data/Data.h b/src/data/Data.h index eea983606..159ba0ab5 100644 --- a/src/data/Data.h +++ b/src/data/Data.h @@ -185,8 +185,8 @@ class TreeWrapper { // Mark this data temporary so that it will not be save by Hi5::write(). inline - void setNoSave(bool noSave = true){ - this->tree.data.noSave = noSave; + void setExcluded(bool exclude = true){ + this->tree.data.exclude = exclude; }; @@ -215,7 +215,7 @@ class TreeWrapper { ~TreeWrapper(){ /* drain::Logger mout("TreeWrapper", __FUNCTION__); - if (this->tree.data.noSave){ + if (this->tree.data.exclude){ mout.note("deleting (children only?)" ); this->tree.clear(); } @@ -746,7 +746,7 @@ class DataGroup : public TreeWrapper, public std::maptree); - //if (!DataTools::removeIfNoSave(this->tree)) + //if (!DataTools::removeIfExcluded(this->tree)) ODIM::copyToH5(odim, this->tree); DataTools::updateInternalAttributes(this->tree); // images, including DataSet.data, TODO: skip children } @@ -1153,7 +1153,7 @@ class DataSet : public DataGroup,ODIMPathElem::DATA>, public QualityDat inline void updateTree3(const typename DT::odim_t & odim){ // //odim.copyToDataSet(this->tree); - //if (!DataTools::removeIfNoSave(this->tree)) + //if (!DataTools::removeIfExcluded(this->tree)) ODIM::copyToH5(odim, this->tree); DataTools::updateInternalAttributes(this->tree); // TEST2019/09 // images, including DataSet.data, TODO: skip children //DataTools::updateInternalAttributes(this->tree, drain::FlexVariableMap()); // TEST2019/09 // images, including DataSet.data, TODO: skip children diff --git a/src/data/DataSelector.cpp b/src/data/DataSelector.cpp index 18eda07d5..e27a03d8a 100644 --- a/src/data/DataSelector.cpp +++ b/src/data/DataSelector.cpp @@ -29,6 +29,9 @@ by the European Union (European Regional Development Fund and European Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013) */ +#include +#include // levels: LOG_ERROR etc. + #include "drain/util/Type.h" #include "drain/util/RegExp.h" @@ -62,7 +65,329 @@ const drain::FlaggerDict drain::EnumDict::dict = { {"DOUBLE", rack::DataSelector::DOUBLE} }; -// using namespace hi5; +/// PRESELECT +/* + * Consider replacing props with direct group attribs, like [WHERE].attr["elangle"] and [WHAT].attr["time"] + * + */ +void DataSelector::selectPaths(const Hi5Tree & src, std::list & pathContainer) const { + + drain::Logger mout(__FILE__, __FUNCTION__); + + //if (basepath.empty()){ + mout.attention("quantityRegExp: ", quantityRegExp, ", qualityRegExp: ", qualityRegExp); + //} + + //, const ODIMPath & basepath = + collectPaths(src, pathContainer, ODIMPath()); + + prunePaths(src, pathContainer); + +} + +bool DataSelector::collectPaths(const Hi5Tree & src, std::list & pathContainer, const ODIMPath & basepath) const { + + drain::Logger mout(__FILE__, __FUNCTION__); + + /* + if (basepath.empty()){ + mout.attention("quantityRegExp: ", quantityRegExp, ", qualityRegExp: ", qualityRegExp); + } + */ + + bool result = false; + + for (const auto & entry: src(basepath)) { + + const ODIMPathElem & currentElem = entry.first; + ODIMPath path(basepath, currentElem); + //mout.debug3("currentElem='" , currentElem , "'" ); + + const drain::image::Image & data = entry.second.data.dataSet; // for ODIM + const drain::FlexVariableMap & props = data.getProperties(); + + + // Check ELANGLE (in datasets) or quantity (in data/quality) + if (currentElem.is(ODIMPathElem::DATASET)){ + + mout.debug("DATASET = '" ,path , "'" ); + + // PRF criterion applies? + if (selectPRF != ANY){ + double lowPRF = props.get("how:lowprf", 0.0); + double hightPRF = props.get("how:highprf", lowPRF); + if ((lowPRF == hightPRF) == (selectPRF == Prf::SINGLE)){ + mout.accept("PRF=", lowPRF, '/', hightPRF, ", required ", selectPRF, ": including " , path); + } + else { + mout.reject("PRF=", lowPRF, '/', hightPRF, ", required ", selectPRF, ": excluding " , path); + continue; // yes, subtrees skipped ok + } + } + + /* + if (!pathMatcher.matchElem(currentElem, true)){ + // pathMatcher does not accept this dataset at all + mout.reject(currentElem); + continue; + } + */ + + if (props.hasKey("where:elangle")){ + double e = props["where:elangle"]; + if (!elangle.contains(e)){ + mout.reject("elangle ",e," outside range ",elangle); + continue; + } + } + + if (collectPaths(src, pathContainer, path)){ + + result = true; + + if (pathMatcher.match(path)){ + mout.accept("DATASET path matches (subtree OK) " , path ); + addPath(pathContainer, props, path); + } + } + + } + //else if (currentElem.belongsTo(ODIMPathElem::DATA | ODIMPathElem::DATA)){ + else if (currentElem.belongsTo(ODIMPathElem::DATA | ODIMPathElem::QUALITY)){ // 2021/04 + + + const std::string retrievedQuantity = props["what:quantity"].toStr(); + + mout.debug("DATA = '" ,path , "' [", retrievedQuantity, "]"); + + // QUANTITY criterion applies? + if (quantityRegExp.isSet() || qualityRegExp.isSet()){ + + + if (qualityRegExp.isSet()){ // At least: do not test quantity after this + //quantityOk = false; + if (currentElem.is(ODIMPathElem::QUALITY) && qualityRegExp.test(retrievedQuantity)){ + mout.note("QUALITY quantity matches: [", retrievedQuantity, "]: ", basepath, '|', currentElem); + //quantityOk = true; + result = true; + if (pathMatcher.match(path)){ + mout.accept("QUALITY path matches: " , path, " [", retrievedQuantity, "]"); + addPath(pathContainer, props, path); + } + } + } + else if (quantityRegExp.test(retrievedQuantity)){ + mout.accept("quantity matches: [", retrievedQuantity, "]: ", basepath, '|', currentElem); + result = true; + if (pathMatcher.match(path)){ + mout.accept("DATA path matches: ", path, " [", retrievedQuantity, "]"); + addPath(pathContainer, props, path); + } + } + else { + mout.debug3("unmatching DATA quantity [" , retrievedQuantity , "], skipping" ); + // no continue + } + } + + + if (result){ + // else { + // mout.note("quantity matches: [" , retrievedQuantity , "], but DATA/QUALITY path not: " , path ); + // } + } + + result |= collectPaths(src, pathContainer, path); + + } + else if (currentElem.belongsTo(ODIMPathElem::ATTRIBUTE_GROUPS)){ + + // Does not affect result. + if (pathMatcher.match(path)){ + addPath(pathContainer, props, path); + } + + } + else { + // mout.warn(" skipping odd group: /" , currentElem ); + } + + } + + return result; +} + + + + +/** Future C++20 option: +template +class SuperElemLess { + inline + bool operator()(const SuperElem & e1, const SuperElem & e2) const { + } +} +*/ + + +/// Using \c criterion TIME and \c order (MIN or MAX) +void DataSelector::prunePaths(const Hi5Tree & src, std::list & pathList) const { + + drain::Logger mout(__FILE__, __FUNCTION__); + + // Step 1: collect a set of major groups (dataset1, dataset2...) fulfilling elangle and time criterion + std::set retrieved; + for (ODIMPath & path: pathList) { + + // Check... (Should not be needed) + while ((!path.empty()) && path.front().empty()){ + mout.warn("Rooted path '", path, "' striping leading slach"); + path.pop_front(); + } + + retrieved.insert(path.front()); + } + + + // Step 2: collect a set of major groups (dataset1, dataset2...) fulfilling elangle and time criterion + std::vector accepted; // sortable + accepted.reserve(src.getChildren().size()); + + for (const auto & entry: src) { + + const ODIMPathElem & elem = entry.first; + + if (elem.is(ODIMPathElem::DATASET)){ + + if (retrieved.find(elem) != retrieved.end()){ + mout.debug(elem); + const drain::image::Image & data = entry.second.data.dataSet; // for ODIM + const drain::FlexVariableMap & props = data.getProperties(); + accepted.push_back(ODIMPathElem2(elem, props.get("where:elangle", 0.0), props.get("what:startdate",""), props.get("what:starttime",""))); + } + else { + mout.debug("not in list of retrieved paths, skipping: ", elem); + continue; + } + + /** Not needed, if called after selectPaths(), it's implicit there. + if (!pathMatcher.matchElem(elem, true)){ // <- if no dataset test involved, return 'true' + // pathMatcher did not accept this dataset at all + mout.reject(elem); + continue; + } + */ + + /// Elangle test NOT NEEDED (repeated) + /* + if (props.hasKey("where:elangle")){ + double e = props["where:elangle"]; + if (!this->elangle.contains(e)){ + mout.reject("elangle ", e, " outside range: ", this->elangle); + continue; + } + } + */ + + } + + /* not needed, including DATASET's only + if (elem.belongsTo(ODIMPathElem::ATTRIBUTE_GROUPS)){ + mout.debug("skipping attribute group (for now): ", elem); + continue; + } + */ + + /* + if (std::find(accepted.begin(), accepted.end(), elem) == accepted.end()){ // clumsy, but list needed (instead of set). + accepted.push_back(elem); + } + */ + + } + + mout.accept("DATASETs before sorting and pruning: ", drain::sprinter(accepted)); + + /// Step 3: sort + switch (order.criterion) { + case DataOrder::DATA: + // Already in order + // std::sort(accepted.begin(), accepted.end(), ODIMPathLess()); + mout.debug("criterion: DATA path"); + break; + case DataOrder::TIME: + std::sort(accepted.begin(), accepted.end(), ODIMPathLessTime()); + mout.debug("criterion: TIME"); + break; + case DataOrder::ELANGLE: + std::sort(accepted.begin(), accepted.end(), ODIMPathLessElangle()); + mout.debug("criterion: ELANGLE"); + break; + // case DataOrder::NONE "random" ? + default: + mout.error("something went wrong, order.criterion=", order.criterion); + } + + + mout.debug("sorted DATASETs: ", drain::sprinter(accepted)); + + /// Step 4: save the first or last n entries (ie. delete others) + size_t n = count; ; + n = std::min(n, accepted.size()); + + std::vector::iterator it = accepted.begin(); + switch (order.operation){ + case DataOrder::MIN: + std::advance(it, n); + accepted.erase(it, accepted.end()); + break; + case DataOrder::MAX: + std::advance(it, accepted.size()-n); + accepted.erase(accepted.begin(), it); + break; + default: + mout.error("something went wrong, order.operation=", order.operation); + } + + mout.accept("Final (", n, ") DATASETs: ", drain::sprinter(accepted)); // without ATTRIBUTES + + /// Step 5. Compare list of retrieved paths and the set of accepted \c dataset elems. + std::list finalPaths; + + for (const ODIMPath & path: pathList){ + + const ODIMPathElem & stem = path.front(); + + // rack --inputSelect '/where|what|dataset2:11,count=3,order=TIME:MAX,quantity=^DBZH$,prf=DOUBLE' + + if (stem.belongsTo(ODIMPathElem::ATTRIBUTE_GROUPS)){ + if (pathMatcher.match(path)){ + mout.special("adding back ATTRIBUTE_GROUP: ", stem); + finalPaths.push_back(path); + } + continue; + } + + for (const ODIMPathElem & a: accepted){ + if (stem == a){ + finalPaths.push_back(path); + break; + } + } + + + } + + pathList.swap(finalPaths); + + /* + mout.attention("final list:"); + for (const ODIMPath & path: pathContainer){ + mout.ok(path); + } + */ + +} DataSelector::DataSelector( diff --git a/src/data/DataSelector.h b/src/data/DataSelector.h index 64dab546d..329096638 100644 --- a/src/data/DataSelector.h +++ b/src/data/DataSelector.h @@ -447,8 +447,29 @@ class DataSelector : public drain::BeanLike { void copyPaths(M & pathMap, DataOrder::Oper oper, std::list & mapList) const ; // void pruneMap(std::list & pathContainer, DataOrder::Oper oper=DataOrder::Oper::MIN) const ; +// EXPERIMENTAL + /// Collect paths (only) with criteria: path, elevation(range), PRF, quantity. + /** + * + * \return true, if contained something accepted by tests + */ + bool collectPaths(const Hi5Tree & src, std::list & pathContainer, const ODIMPath & basepath = ODIMPath()) const; + + /// Use #DataOrder::criterion \c DATA , \c TIME or \c ELANGLE and #DataOrder::order \c MIN or MAX to sort paths. + void prunePaths(const Hi5Tree & src, std::list & pathContainer) const; + + +public: + + /// Collect paths with all the criteria: path, elevation(range), PRF, quantity... + /** + * + * + */ + void selectPaths(const Hi5Tree & src, std::list & pathContainer) const; + }; @@ -584,8 +605,6 @@ void DataSelector::getMainPaths(const Hi5Tree & src, T & pathContainer, bool LIM const drain::image::Image & data = entry.second.data.dataSet; // for ODIM const drain::FlexVariableMap & props = data.getProperties(); - // ODIMPath path; - // path << currentElem; ODIMPath path(currentElem); // Check ELANGLE (in datasets) or quantity (in data/quality) @@ -673,8 +692,6 @@ bool DataSelector::getSubPaths(const Hi5Tree & src, T & pathContainer, const ODI const drain::FlexVariableMap & props = data.getProperties(); ODIMPath p(path, currentElem); - // ODIMPath p(path); - // p << currentElem; // also for attrib groups // if (currentElem.belongsTo(ODIMPathElem::DATA | ODIMPathElem::QUALITY)){ diff --git a/src/data/DataTools.cpp b/src/data/DataTools.cpp index 3c2410c32..73578525c 100644 --- a/src/data/DataTools.cpp +++ b/src/data/DataTools.cpp @@ -106,7 +106,7 @@ void DataTools::updateInternalAttributes(Hi5Tree & src, const drain::FlexVariab for (auto & entry: src){ if (entry.first.belongsTo(ODIMPathElem::DATA | ODIMPathElem::QUALITY)){ - if (!entry.second.data.noSave){ + if (!entry.second.data.exclude){ mout.debug3(entry.first , " => ensure '/data' groups " ); entry.second[ODIMPathElem::ARRAY].data.dataSet; } @@ -158,25 +158,25 @@ void DataTools::updateInternalAttributes(Hi5Tree & src, const drain::FlexVariab } -void DataTools::markNoSave(Hi5Tree &src, bool noSave){ +void DataTools::markExcluded(Hi5Tree &src, bool exclude){ // drain::Logger mout(ctx.log, __FILE__, __FUNCTION__); for (auto & entry: src) { //if (it->first.isIndexed()){ if (!entry.first.belongsTo(ODIMPathElem::ATTRIBUTE_GROUPS)){ - entry.second.data.noSave = noSave; - markNoSave(entry.second, noSave); + entry.second.data.exclude = exclude; + markExcluded(entry.second, exclude); } } } -bool DataTools::removeIfNoSave(Hi5Tree & dst){ - if (dst.data.noSave){ +bool DataTools::removeIfExcluded(Hi5Tree & dst){ + if (dst.data.exclude){ drain::Logger mout("DataTools", __FUNCTION__); - mout.note("// about to resetting noSave struct: " , dst.data ); + mout.note("// about to resetting exclude struct: " , dst.data ); /* dst.data.attributes.clear(); dst.data.dataSet.resetGeometry(); @@ -192,7 +192,10 @@ void DataTools::updateCoordinatePolicy(Hi5Tree & src, const drain::image::Coordi drain::Logger mout(__FILE__, __FUNCTION__); - //mout.deprecating("This may be better handled with updateInternalAttributes"); + // mout.deprecating("This may be better handled with updateInternalAttributes"); + mout.warn("Removed: ", __FUNCTION__); + + return; drain::image::Image & data = src.data.dataSet; diff --git a/src/data/DataTools.h b/src/data/DataTools.h index b9d0730c1..07e9f87b3 100644 --- a/src/data/DataTools.h +++ b/src/data/DataTools.h @@ -131,23 +131,23 @@ class DataTools { //: public drain::BeanLike { typedef std::map quantity_map; static - void markNoSave(Hi5Tree &src, bool noSave=true); + void markExcluded(Hi5Tree &src, bool exclude=true); protected: - /// Removes the children of the tree if Node::noSave is set. + /// Removes the children of the tree if Node::exclude is set. /** * \return - true if children were removed */ static - bool removeIfNoSave(Hi5Tree & dst); + bool removeIfExcluded(Hi5Tree & dst); /// Does nothing /** * \return - false (always, as nothing will be removed) */ static - bool removeIfNoSave(const Hi5Tree & src){ + bool removeIfExcluded(const Hi5Tree & src){ return false; }; diff --git a/src/data/ODIMPath.h b/src/data/ODIMPath.h index c089073e9..51e0b102b 100644 --- a/src/data/ODIMPath.h +++ b/src/data/ODIMPath.h @@ -410,6 +410,48 @@ struct ODIMPathLess { }; // end class +class ODIMPathElem2 : public ODIMPathElem { + +public: + + inline + ODIMPathElem2(): elangle(0.0) {}; + + virtual inline + ~ODIMPathElem2(){}; + + inline + ODIMPathElem2(const ODIMPathElem & elem, const double elangle, const std::string & date, const std::string & time): + ODIMPathElem(elem), elangle(elangle), timestamp(date+time) { + } + + double elangle; + std::string timestamp; + +}; + + +inline +std::ostream & operator<<(std::ostream & ostr, const ODIMPathElem2 & elem) { + return ostr << (const ODIMPathElem &)elem << '-' << elem.timestamp << '-' << elem.elangle; +} + + +struct ODIMPathLessTime { + inline + bool operator()(const ODIMPathElem2 & e1, const ODIMPathElem2 & e2) const { + return e1.timestamp < e2.timestamp; + } +}; + +struct ODIMPathLessElangle { + inline + bool operator()(const ODIMPathElem2 & e1, const ODIMPathElem2 & e2) const { + return e1.elangle < e2.elangle; + } +}; + + /* inline std::ostream & operator<<(std::ostream & ostr, const ODIMPath & p) { diff --git a/src/drain/util/Log.h b/src/drain/util/Log.h index b04c9d128..4e561552e 100644 --- a/src/drain/util/Log.h +++ b/src/drain/util/Log.h @@ -414,11 +414,11 @@ class Logger : public std::stringstream { //: public LogBase { /// Possible error, but execution can continue. Special type of Logger::warn(). - template + template inline Logger & fail(const TT &... args){ static const Notification notif(__FUNCTION__, 33); - initMessage(notif); + initMessage(notif); flush(args...); return *this; }; @@ -435,11 +435,11 @@ class Logger : public std::stringstream { //: public LogBase { }; /// Possible error, but execution can continue. Special type of Logger::warn(). - template + template inline Logger & attention(const TT &... args){ static const Notification notif(__FUNCTION__, 46); - initMessage(notif); + initMessage(notif); flush(args...); return *this; }; @@ -479,11 +479,11 @@ class Logger : public std::stringstream { //: public LogBase { }; /// Other useful information - template + template inline Logger & special(const TT &... args){ static const Notification notif(__FUNCTION__, 36); - initMessage(notif); + initMessage(notif); flush(args...); return *this; }; @@ -526,39 +526,39 @@ class Logger : public std::stringstream { //: public LogBase { return *this; }; - template + template inline Logger & ok(const TT &... args){ static const Notification notif(__FUNCTION__, 32); - initMessage(notif); + initMessage(notif); flush(args...); return *this; }; - template + template inline Logger & accept(const TT &... args){ static const Notification notif(__FUNCTION__, 42); - initMessage(notif); + initMessage(notif); flush(args...); return *this; }; - template + template inline Logger & reject(const TT &... args){ static const Notification notif(__FUNCTION__, 41); - initMessage(notif); + initMessage(notif); flush(args...); return *this; }; - template + template inline Logger & success(const TT &... args){ static const Notification notif(__FUNCTION__, 92); - initMessage(notif); + initMessage(notif); flush(args...); return *this; }; diff --git a/src/drain/util/RegExp.cpp b/src/drain/util/RegExp.cpp index c3e6cf73a..ebf8f527f 100644 --- a/src/drain/util/RegExp.cpp +++ b/src/drain/util/RegExp.cpp @@ -39,6 +39,7 @@ Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013) // g++ deer_regexp.cpp -o deer_regexp #include "RegExp.h" +#include "Sprinter.h" // // using namespace std; @@ -189,9 +190,14 @@ void RegExp::replace(const std::string &src, const std::string & replacement, st std::ostream & operator<<(std::ostream &ostr, const drain::RegExp & r){ - ostr << r.toStr() << ", flags=" << r.flags; - for (std::vector::const_iterator it = r.result.begin(); it != r.result.end(); ++it){ - ostr << '|' << *it; + if (r.isSet()){ + ostr << r.toStr() << ", flags=" << r.flags; + Sprinter::sequenceToStream(ostr, r.result, Sprinter::jsonLayout); + /* + for (const std::string & s : r.result){ + ostr << '|' << s; + } + */ } return ostr; } @@ -199,6 +205,3 @@ std::ostream & operator<<(std::ostream &ostr, const drain::RegExp & r){ } // drain - - -// Drain diff --git a/src/hi5/Hi5.cpp b/src/hi5/Hi5.cpp index fa87ffdfa..c5a768ab7 100644 --- a/src/hi5/Hi5.cpp +++ b/src/hi5/Hi5.cpp @@ -65,7 +65,7 @@ void NodeHi5::writeText(std::ostream &ostr, const rack::ODIMPath & prefix) const // if (attributes.empty() && dataSet.isEmpty()){ // if (!prefix.empty()) ostr << prefix; - if (noSave) + if (exclude) ostr << '~'; ostr << '\n'; @@ -83,7 +83,7 @@ void NodeHi5::writeText(std::ostream &ostr, const rack::ODIMPath & prefix) const if (dataSet.getVolume() > 0){ ostr << prefix; - //if (noSave) ostr << '~'; + //if (exclude) ostr << '~'; ostr << ':'; //'\t'; //mout.note() << dataSet.getGeometry() << mout.endl; @@ -443,22 +443,22 @@ void Hi5Base::parsePath(const std::string & line, Hi5Tree::path_t & path, std::s } // Marks CHILDREN of src for deleting -void Hi5Base::markNoSave(Hi5Tree &src, bool noSave){ +void Hi5Base::markExcluded(Hi5Tree &src, bool exclude){ //drain::Logger mout(ctx.log, __FILE__, __FUNCTION__); for (auto & entry: src) { //if (it->first.isIndexed()){ //if (!entry.first.belongsTo(ODIMPathElem::ATTRIBUTE_GROUPS)){ - entry.second.data.noSave = noSave; - markNoSave(entry.second, noSave); + entry.second.data.exclude = exclude; + markExcluded(entry.second, exclude); //} } } -void Hi5Base::deleteNoSave(Hi5Tree &src){ +void Hi5Base::deleteExcluded(Hi5Tree &src){ drain::Logger mout(__FILE__, __FUNCTION__); @@ -467,9 +467,9 @@ void Hi5Base::deleteNoSave(Hi5Tree &src){ //for (Hi5Tree::iterator it = src.begin(); it != src.end(); ++it) { for (auto & entry: src) { - if (! entry.second.data.noSave){ // needed? + if (! entry.second.data.exclude){ // needed? //mout.debug2() << "delete: " << it->first << mout.endl; - deleteNoSave(entry.second); + deleteExcluded(entry.second); } else { elems.push_back(entry.first); @@ -487,13 +487,13 @@ void Hi5Base::deleteNoSave(Hi5Tree &src){ } /* -void Hi5Base::markNoSave(Hi5Tree &src, bool noSave){ +void Hi5Base::markExcluded(Hi5Tree &src, bool exclude){ //drain::Logger mout(__FILE__, __FUNCTION__); for (Hi5Tree::iterator it = src.begin(); it != src.end(); ++it) { - it->second.data.noSave = noSave; - markNoSave(it->second, noSave); + it->second.data.exclude = exclude; + markExcluded(it->second, exclude); } diff --git a/src/hi5/Hi5.h b/src/hi5/Hi5.h index 25065fe28..c33f69b17 100644 --- a/src/hi5/Hi5.h +++ b/src/hi5/Hi5.h @@ -84,10 +84,10 @@ struct NodeHi5 { drain::VariableMap attributes; - NodeHi5() : noSave(false) {}; + NodeHi5() : exclude(false) {}; inline - NodeHi5(const NodeHi5 & n) : noSave(n.noSave) { + NodeHi5(const NodeHi5 & n) : exclude(n.exclude) { attributes.importMap(n.attributes); }; @@ -100,7 +100,7 @@ struct NodeHi5 { void writeText(std::ostream & ostr = std::cout, const rack::ODIMPath & prefix = rack::ODIMPath()) const; /// Experimental - bool noSave; // OK! + bool exclude; // OK! }; @@ -219,23 +219,23 @@ class Hi5Base { // static void readTextLine(Hi5Tree & dst, const Hi5Tree::path_t & path, const std::string & key, const std::string & value); - /// Traverse subtree setting noSave=true . + /// Traverse subtree setting exclude=true . /* static - void markNoSave(Hi5Tree &src, bool noSave=true); + void markExcluded(Hi5Tree &src, bool exclude=true); */ - /// Traverse tree, marking every group nodes for deletion by Hi5Base::deleteNoSave + /// Traverse tree, marking every group nodes for deletion by Hi5Base::deleteExcluded /** * This function traverses all the children, and their children, recursively. */ static - void markNoSave(Hi5Tree &src, bool noSave=true); + void markExcluded(Hi5Tree &src, bool exclude=true); - /// Delete branches that have been marked with noSave=true . + /// Delete branches that have been marked with exclude=true . static - void deleteNoSave(Hi5Tree &src); + void deleteExcluded(Hi5Tree &src); }; diff --git a/src/hi5/Hi5Read.cpp b/src/hi5/Hi5Read.cpp index 64c5825d4..6b1e0d06c 100644 --- a/src/hi5/Hi5Read.cpp +++ b/src/hi5/Hi5Read.cpp @@ -46,7 +46,7 @@ template <> const drain::FlaggerDict drain::EnumDict::dict = { {"ATTRIBUTES", hi5::Reader::ATTRIBUTES}, {"DATASETS", hi5::Reader::DATASETS}, - {"MARKED", hi5::Reader::MARKED} + {"MARKED", hi5::Reader::EXCLUSIVE} }; @@ -54,7 +54,7 @@ void Reader::readFile(const std::string & filename, Hi5Tree & tree, ModeFlagger: drain::Logger mout(getLogH5(), __FILE__, __FUNCTION__); - if ((mode & MARKED) > 0){ + if ((mode & EXCLUSIVE) > 0){ mout.experimental("Selective read: mode: ", mode); } else { @@ -133,8 +133,8 @@ Reader::h5FileToTree(hid_t file_id, const Hi5Tree::path_t &path, Hi5Tree &tree, // std::cerr << "Deeper " << __FUNCTION__ << ':' << p << std::endl; // mout.warn("Selective? : mode=", mode, " noSave=", subtree.data.noSave, ", path: ", p); - if ((mode & MARKED) > 0) { - if (subtree.data.noSave) { + if ((mode & EXCLUSIVE) > 0) { + if (subtree.data.exclude) { mout.reject("Selective read: skipping ", p); continue; } diff --git a/src/hi5/Hi5Read.h b/src/hi5/Hi5Read.h index 4ef81409f..baa7186b3 100644 --- a/src/hi5/Hi5Read.h +++ b/src/hi5/Hi5Read.h @@ -63,7 +63,11 @@ class Reader : public Hi5Base { public: - enum Mode {ATTRIBUTES=1, DATASETS=2, MARKED=4}; // NoSave; consider + enum Mode { + ATTRIBUTES=1, /** Read attributes */ + DATASETS=2, /** Read data arrays */ + EXCLUSIVE=4 /** Do not read groups marked 'exclude' */ + }; typedef drain::EnumFlagger > ModeFlagger; diff --git a/src/hi5/Hi5Write.cpp b/src/hi5/Hi5Write.cpp index 3bb2afcef..cae1c1c06 100644 --- a/src/hi5/Hi5Write.cpp +++ b/src/hi5/Hi5Write.cpp @@ -118,7 +118,7 @@ void Writer::treeToH5File(const Hi5Tree &tree, hid_t fid, const Hi5Tree::path_t const drain::VariableMap & attributes = node.attributes; const drain::image::Image & image = node.dataSet; - if (node.noSave){ // attributes["~tmp~"].getS + if (node.exclude){ // attributes["~tmp~"].getS mout.debug2() << "skipping temporary object " << path << mout.endl; return; } diff --git a/src/main/cartesian-motion.cpp b/src/main/cartesian-motion.cpp index 864eefcc9..0a264edb3 100644 --- a/src/main/cartesian-motion.cpp +++ b/src/main/cartesian-motion.cpp @@ -177,9 +177,9 @@ void CartesianOpticalFlow::getSrcData(ImageTray & srcTray) const // mout.error("thats it" ); Data & srcDataMod = dstDataSet.getData(quantityMod); - mout.experimental("noSave selector modified/supressed"); - // srcDataMod.setNoSave(ProductBase::outputDataVerbosity==0); - srcDataMod.setNoSave(ctx.outputDataVerbosity==0); + mout.experimental("exclude selector modified/supressed"); + // srcDataMod.setExcluded(ProductBase::outputDataVerbosity==0); + srcDataMod.setExcluded(ctx.outputDataVerbosity==0); // mout.note("srcQuality scalingC: " , srcQuality.data.getScaling() ); @@ -274,8 +274,8 @@ void CartesianOpticalFlow::getDiff(size_t width, size_t height, double max, Imag Hi5Tree & dstH5 = (ctx.cartesianHi5)[parent]; - mout.unimplemented("noSave selector supressed"); - // dstH5.data.noSave = (ProductBase::outputDataVerbosity==0); + mout.unimplemented("exclude selector supressed"); + // dstH5.data.exclude = (ProductBase::outputDataVerbosity==0); DataSet dstDataSet(dstH5); @@ -426,7 +426,7 @@ void CartesianOpticalFlow::getMotion(size_t width, size_t height, ImageTray { /// Select parts of hierarchical data using path, quantity, elevation angle and PRF mode as selection criteria. /** - In \b Rack , many operations implictly select a subset of available data instead of using it all. + This command determines the data to be applied in subsequent input read or product generation commands. + + In \b Rack, many operations implictly select a subset of available data instead of using it all. For example, in computing a Pseudo CAPPI image, \c DBZH data from single-PRF sweeps is used by default. \b Synopsis @@ -142,14 +144,11 @@ class CmdBaseSelective : public drain::SimpleCommand<> { \include example-select-test.inc - \subsubsection CmdSelect_also See also - - \ref CmdDelete - - \ref CmdKeep - - \ref CmdSetODIM - - \subsubsection CmdSelect_code Related code - - #rack::CmdSelect - - #rack::DataSelector + \see CmdDelete + \see CmdKeep + \see CmdSetODIM + \see #rack::CmdSelect (code) + \see #rack::DataSelector (code) */ class CmdSelect : public drain::BasicCommand { @@ -372,9 +371,21 @@ class CmdSelectQuantity : public drain::SimpleCommand { const std::map CmdSelectQuantity::transTable = {{",", "|"}, {"*",".*"}, {"?","."}}; +/// Convert data with desired encoding +/** + Volume data can be converted to desired scale and encoding with \c --encoding followed by \c --convert . + If the input file contains several quantities, the target quantity can be selected with \c --select (\c -s) command: + \code + rack volume-double.h5 -Q DBZH --encoding C,0.5,-32 --convert -o volume-new.h5 + rack volume-uint16.h5 -Q DBZH --encoding d --convert -Q VRAD --encoding C,0.025,-7.65506,0,255 --convert -o volume-new.h5 + \endcode + \see #rack::CmdEncoding (code) + \see #rack::CmdSetODIM (code) + +*/ class CmdConvert : public drain::BasicCommand { public: @@ -597,8 +608,9 @@ class CmdCreateDefaultQuality : public drain::BasicCommand { // public drain::S If selection parameters of both levels are issued in the same command, implicit \c AND function applies in selection. - \b See\ also - - \ref CmdKeep + \see CmdKeep + \see modifypage + */ class CmdDelete : public CmdBaseSelective { @@ -625,7 +637,7 @@ class CmdDelete : public CmdBaseSelective { // Step 0 mout.info("delete existing no-save structures "); - hi5::Hi5Base::deleteNoSave(dst); + hi5::Hi5Base::deleteExcluded(dst); mout.debug("selector: ", selector, ", matcher=", selector.pathMatcher); @@ -657,7 +669,8 @@ class CmdDelete : public CmdBaseSelective { Examples: \include example-keep.inc - See also: \ref CmdDelete + \see CmdDelete + \see modifypage */ class CmdKeep : public CmdBaseSelective { @@ -678,10 +691,10 @@ class CmdKeep : public CmdBaseSelective { // Step 0 mout.debug("delete existing no-save structures "); - hi5::Hi5Base::deleteNoSave(dst); + hi5::Hi5Base::deleteExcluded(dst); // Initially, mark all paths excluded. - DataTools::markNoSave(dst); + DataTools::markExcluded(dst); DataSelector selector; selector.setParameters(value); @@ -699,7 +712,7 @@ class CmdKeep : public CmdBaseSelective { ODIMPath p; for (const ODIMPathElem & elem: path){ p << elem; - dst(p).data.noSave = false; + dst(p).data.exclude = false; } //mout.debug("marked for save: " , *it ); // Accept also tail (attribute groups) @@ -709,7 +722,7 @@ class CmdKeep : public CmdBaseSelective { if (entry.first.is(ODIMPathElem::ARRAY)){ mout.debug2("also save: ", p, '|', entry.first); // if (dit->first.belongsTo(ODIMPathElem::ATTRIBUTE_GROUPS)) - entry.second.data.noSave = false; + entry.second.data.exclude = false; } } // @@ -717,7 +730,7 @@ class CmdKeep : public CmdBaseSelective { // debug: hi5::Hi5Base::writeText(dst, std::cerr); - hi5::Hi5Base::deleteNoSave(dst); + hi5::Hi5Base::deleteExcluded(dst); }; @@ -741,6 +754,10 @@ class CmdKeep : public CmdBaseSelective { Examples: \include example-move.inc + \see CmdDelete + \see CmdKeep + \see modifypage + */ class CmdMove : public drain::BasicCommand { @@ -844,18 +861,18 @@ class CmdMove : public drain::BasicCommand { //mout.warn(dstRoot ); Hi5Tree & dst1 = dstRoot(path1); if (!dstRoot.hasPath(path2)) // make it temporary (yet allocating it for now) - dstRoot(path2).data.noSave = true; + dstRoot(path2).data.exclude = true; Hi5Tree & dst2 = dstRoot(path2); - const bool noSave1 = dst1.data.noSave; - const bool noSave2 = dst2.data.noSave; + const bool exclude1 = dst1.data.exclude; + const bool exclude2 = dst2.data.exclude; dst2.swap(dst1); - dst1.data.noSave = noSave2; - dst2.data.noSave = noSave1; + dst1.data.exclude = exclude2; + dst2.data.exclude = exclude1; dst2.data.attributes.swap(dst1.data.attributes); // dstRoot.erase(path1); ? - dstRoot(path1).data.noSave = true; + dstRoot(path1).data.exclude = true; //DataTools::updateInternalAttributes(dst1); // recurse subtrees //DataTools::updateInternalAttributes(dst2); // recurse subtrees @@ -920,9 +937,19 @@ class CmdRename : public CmdMove { }; +/// Ensure correct ODIM types after setting attributes +/** + The OPERA data information model (ODIM) defines conventions for weather radar data. + Some important ODIM attributes can be added automatically with \c --completeODIM command, which sets \c nbins , \c nrays , \c xsize , and \c ysize + equal to data dimensions, if already loaded as image. + \b Synopsis + \include completeODIM.hlp + \see #rack::CmdSetODIM (code) + \see CmdSetODIM + */ class CmdCompleteODIM : public drain::BasicCommand { public: @@ -1378,6 +1405,17 @@ class CmdHelpExample : public drain::SimpleCommand { // static drain::CommandEntry cmdHelpExample("helpExample", 0); + +/// Explain.. +/** + + Text + + \b Synopsis + \include JSON.hlp + + \see #::Command + */ class CmdJSON : public drain::SimpleCommand { // drain::BasicCommand { public: diff --git a/src/main/file-dot-graph.cpp b/src/main/file-dot-graph.cpp index a7c00baea..7eacc9270 100644 --- a/src/main/file-dot-graph.cpp +++ b/src/main/file-dot-graph.cpp @@ -166,7 +166,7 @@ void writeGroupToDot(std::ostream & ostr, const Hi5Tree & group, int & index, // END LABEL // STYLE - if (group.data.noSave) + if (group.data.exclude) node.attributes["style"] = "dotted"; //ostr << " style=\"dotted\" "; else if (e.isIndexed()){ node.attributes["style"] = "filled"; // ostr << " style=\"filled\""; diff --git a/src/main/fileio-read.cpp b/src/main/fileio-read.cpp index 14b8da355..079b3fd64 100644 --- a/src/main/fileio-read.cpp +++ b/src/main/fileio-read.cpp @@ -184,67 +184,62 @@ void CmdInputFile::readFileH5(const std::string & fullFilename) const { // TODO // InputSelect needed? Hi5Tree srcTmp; - if (!ctx.select.empty()){ + if (!ctx.inputSelect.empty()){ //mout.special() << "Input selector (" << ctx.select << ") applies, pre-reading attributes first:\n"; - mout.special("Input selector (", ctx.select, ") set -> selective read"); - mout.special("Pre-reading attributes first:\n"); + mout.special("Input selector (", ctx.inputSelect, ") set -> selective read."); + mout.debug("First, reading attributes only:\n"); hi5::Reader::readFile(fullFilename, srcTmp, hi5::Reader::ATTRIBUTES); DataTools::updateInternalAttributes(srcTmp); // to support DataSelector with what:quantity and what:elangle // Initially, mark all deleted... - DataTools::markNoSave(srcTmp); + DataTools::markExcluded(srcTmp); // drain::TreeUtils::dump(srcTmp, std::cout, CmdOutputTree::dataToStream); // true); DataSelector selector(ODIMPathElem::DATASET, ODIMPathElem::DATA); // NO QUALITY? - selector.setParameters(ctx.select); + selector.setParameters(ctx.inputSelect); mout.special("selector: ", selector, ", matcher=", selector.pathMatcher); + ODIMPathList paths; - selector.getPaths(srcTmp, paths); + // OLD selector.getPaths(srcTmp, paths); + // NEW + selector.selectPaths(srcTmp, paths); for (const ODIMPath & path: paths){ - - mout.special("set save through path: ", path); + /* + mout.special("set included THROUGH path: ", path, ", leaf would suffit?"); ODIMPath p; for (const ODIMPathElem & elem: path){ p << elem; - srcTmp(p).data.noSave = false; + srcTmp(p).data.exclude = false; + } + */ + if (srcTmp.hasPath(path)){ // otherwise path query would create one... + mout.debug("Including: ", path); + srcTmp(path).data.exclude = false; } } //mout.debug("marked for save: " , *it ); - /* - for (const ODIMPath & path: paths){ - mout.warn("deleting: ", path); - srcTmp.erase(path); - } - */ - // hi5::Hi5Base::deleteNoSave(srcTmp); - // drain::TreeUtils::dump(srcTmp, std::cout, CmdOutputTree::dataToStream); // true); - mout.special("noSave marking completed: ", fullFilename); - // mout << mout.endl; - // return; - hi5::Reader::readFile(fullFilename, srcTmp, hi5::Reader::MARKED | hi5::Reader::ATTRIBUTES | hi5::Reader::DATASETS); + // mout.special("marking 'excluded' completed: ", fullFilename); + hi5::Reader::readFile(fullFilename, srcTmp, hi5::Reader::EXCLUSIVE | hi5::Reader::ATTRIBUTES | hi5::Reader::DATASETS); } else { hi5::Reader::readFile(fullFilename, srcTmp); } - //, resources.inputSelect); //, 0); // 0 = read no attributes or datasets (yet) - //hi5::Reader::readFile(fullFilename, srcTmp, ctx.inputFilter.value); //, resources.inputSelect); //, 0); // 0 = read no attributes or datasets (yet) - - if (!ctx.select.empty()){ // or stg like: hi5::Reader::MARKED + if (!ctx.inputSelect.empty()){ // or stg like: hi5::Reader::MARKED mout.special("Input selection: removing excluded subtrees"); - hi5::Hi5Base::deleteNoSave(srcTmp); + hi5::Hi5Base::deleteExcluded(srcTmp); // drain::TreeUtils::dump(srcTmp, std::cout, CmdOutputTree::dataToStream); // true if (ctx.SCRIPT_DEFINED){ - mout.note("Script defined. NOT clearing input data selector (", ctx.select, ')'); + mout.note("Script defined. NOT clearing input data selector (", ctx.inputSelect, ')'); //mout.info(ctx.select); } else { - mout.note("Clearing input data selector (", ctx.select, ')'); - ctx.select.clear(); + mout.note("Clearing input data selector (", ctx.inputSelect, ')'); + ctx.inputSelect.clear(); } } @@ -428,7 +423,7 @@ void CmdInputFile::attachCartesianH5(Hi5Tree & src, Hi5Tree & dst) const { dst[it->first].swap(it->second); // overwrite what, where, } - src[it->first].data.noSave = true; + src[it->first].data.exclude = true; } diff --git a/src/main/fileio-read.h b/src/main/fileio-read.h index 58e64feee..8ca82857a 100644 --- a/src/main/fileio-read.h +++ b/src/main/fileio-read.h @@ -57,10 +57,16 @@ class CmdInputSelect : public drain::BasicCommand { }; */ +/// Path prefix string for subsequent input files. +/** + * \see rack::CmdInput + * \see rack::CmdInputSelect + */ class CmdInputPrefix : public drain::SimpleCommand { public: + inline CmdInputPrefix() : drain::SimpleCommand(__FUNCTION__, "Path prefix for input files."){ //RackContext & ctx = getContext(); // DO NOT LINK, dynamic context! //parameters.link("path", getResources().inputPrefix = ""); @@ -74,10 +80,18 @@ class CmdInputPrefix : public drain::SimpleCommand { +/// Input HDF5, PNG or text file. +/** + * In \b Rack, this command is also the default option, hence plain argument will be treated as files to read. + * + * \see rack::CmdInputPrefix + * \see rack::CmdInputSelect + */ class CmdInputFile : public drain::SimpleCommand { public: + inline CmdInputFile() : drain::SimpleCommand(__FUNCTION__, "Read HDF5, text or image file", "filename", "", ".[h5|hdf5|png|pgm|ppm|txt]"){ //, inputComplete(true) { //execRoutine = true; @@ -136,6 +150,25 @@ class CmdInputFile : public drain::SimpleCommand { +/// Data selector for subsequent input files. +/** + * \see rack::CmdInput + * \see rack::CmdInputSelect + */ +class CmdInputSelect : public drain::SimpleCommand { + +public: + + inline + CmdInputSelect() : drain::SimpleCommand(__FUNCTION__, "Selector for input data."){ + }; + + inline + void exec() const { + getContext().inputSelect = value; + } +}; + } // rack diff --git a/src/main/fileio.cpp b/src/main/fileio.cpp index 6d23d6c74..befb82bc9 100644 --- a/src/main/fileio.cpp +++ b/src/main/fileio.cpp @@ -621,7 +621,7 @@ bool CmdOutputTree::dataToStream(const Hi5Tree::node_data_t & data, std::ostream drain::TextDecorator & decorator = attrs.get("format", "") == "vt100" ? vt100Deco : noDeco; decorator.setSeparator(":"); - if (data.noSave){ + if (data.exclude){ ostr << "~"; return false; } @@ -791,6 +791,7 @@ FileModule::FileModule(drain::CommandBank & bank) : module_t(bank) { // :(){ // install(); install(); + install(); install(); install('O').addSection(IMAGES); install(); diff --git a/src/main/images.cpp b/src/main/images.cpp index 73d151a89..94be03a62 100644 --- a/src/main/images.cpp +++ b/src/main/images.cpp @@ -766,7 +766,7 @@ class CmdPalette : public drain::SimpleCommand { //Data & data = dstProduct.getData(encoding.quantity); const size_t origSize = dstProduct.size(); Data & data = dstProduct.getData(dstQuantity); // NEW 2023/03 ! - data.setNoSave(NO_SAVE); + data.setExcluded(NO_SAVE); if (origSize == dstProduct.size()){ mout.note("Storing processed image in: ", elem, "/data?/ [", dstQuantity, ']'); // NEW 2023 diff --git a/src/main/rack.h b/src/main/rack.h index eb384c8ab..defda8482 100644 --- a/src/main/rack.h +++ b/src/main/rack.h @@ -36,7 +36,9 @@ Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013) /** * Version 7.8 - * -- Revised Variable, ReferenceVariable, FlexibleVariable definitions + * -- New functionality: selective read --inputSelect + * -- Log: adjustable sublevels: accept(...) , fail(...) + * -- Revised definitions: Variable, ReferenceVariable, FlexibleVariable * -- Image processing: keys instead of numeric indices * -- Check rscale, nbins, nrays in compositing * diff --git a/src/main/resources-base.h b/src/main/resources-base.h index 69dd1efa8..71b8d0838 100644 --- a/src/main/resources-base.h +++ b/src/main/resources-base.h @@ -203,6 +203,7 @@ class Hdf5Context { Hdf5Context(const Hdf5Context &ctx); std::string select; + std::string inputSelect; diff --git a/src/product/DataConversionOp.h b/src/product/DataConversionOp.h index 830b0c8a6..d91977c66 100644 --- a/src/product/DataConversionOp.h +++ b/src/product/DataConversionOp.h @@ -165,7 +165,7 @@ PlainData< DstType > & DataConversionOp::getNormalizedData(const DataSet & dstDataNew = normDataSet.getData(quantityExt); - dstDataNew.setNoSave(); + dstDataNew.setExcluded(); DataConversionOp op; //op.odim.importMap(odimNorm); // mout.warn("odimNorm: " , odimNorm ); @@ -269,7 +269,7 @@ void DataConversionOp::processDataSet(const DataSet & srcSweep, DataSe const Data & srcData = entry.second; Data & dstData = dstProduct.getData(quantityTmp); // todo: getNewData - //dstProduct.getData(quantity).setNoSave(true); + //dstProduct.getData(quantity).setExcluded(true); mout.attention("srcData: ", entry.second); mout.debug2(EncodingODIM(this->odim)); @@ -336,7 +336,7 @@ void DataConversionOp::processDataSet(const DataSet & srcSweep, DataSe dstDataOrig.swap(dstDataConv); // calls updateTree2 (consider what:quantity) dstDataConv.odim.quantity = quantityTmp; - dstDataConv.setNoSave(true); + dstDataConv.setExcluded(true); } }