Skip to content

Commit 4f238d7

Browse files
authored
Merge pull request #267 from sy-c/master
v2.21.5
2 parents 6dc5013 + 6e120e6 commit 4f238d7

File tree

5 files changed

+95
-21
lines changed

5 files changed

+95
-21
lines changed

doc/configurationParameters.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ The parameters related to 3rd-party libraries are described here for convenience
199199
| readout | aggregatorSliceTimeout | double | 0 | When set, slices (groups) of pages are flushed if not updated after given timeout (otherwise closed only on beginning of next TF, or on stop). |
200200
| readout | aggregatorStfTimeout | double | 0 | When set, subtimeframes are buffered until timeout (otherwise, sent immediately and independently for each data source). |
201201
| readout | customCommands | string | | List of key=value pairs defining some custom shell commands to be executed at before/after state change commands. |
202+
| readout | defaults | string | | If set, the corresponding configuration URI is loaded and merged with current readout configuration. Existing parameters in current config are NOT overwritten. |
202203
| readout | disableAggregatorSlicing | int | 0 | When set, the aggregator slicing is disabled, data pages are passed through without grouping/slicing. |
203204
| readout | disableTimeframes | int | 0 | When set, all timeframe related features are disabled (this may supersede other config parameters). |
204205
| readout | exitTimeout | double | -1 | Time in seconds after which the program exits automatically. -1 for unlimited. |

doc/releaseNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,3 +593,7 @@ This file describes the main feature changes for each readout.exe released versi
593593
- Updated configuration parameters:
594594
- consumer-fileRecorder-*.filesMax: if negative value, the files are written round-robin indefinitely. For example, if value is -4, there will be files 001 to 004 used as circular buffer. This implies limits are defined with the other parameters (e.g. maximum size, number of tf, or pages).
595595
- Log messages cosmetics: details in orbits warning, special chars in RDH errors.
596+
597+
## v2.21.5 - 13/10/2023
598+
- Updated configuration parameters:
599+
- added readout.defaults: if set, the corresponding configuration URI is loaded and merged with current readout configuration. Existing parameters in current config are NOT overwritten. Useful to put in a single place settings which are shared by many configs.

src/ReadoutVersion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12-
#define READOUT_VERSION "2.21.4"
12+
#define READOUT_VERSION "2.21.5"
1313

src/mainReadout.cxx

Lines changed: 88 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,47 @@ int Readout::_init(int argc, char* argv[])
723723

724724
//#include <boost/property_tree/json_parser.hpp>
725725

726+
// dump boost ptree on stdout
727+
void printTree (boost::property_tree::ptree &pt, int level) {
728+
if (pt.empty()) {
729+
std::cerr << "\""<< pt.data()<< "\"";
730+
}
731+
732+
else {
733+
if (level) std::cerr << std::endl;
734+
std::cerr << std::string(level*2, ' ') << "{" << std::endl;
735+
for (boost::property_tree::ptree::iterator pos = pt.begin(); pos != pt.end();) {
736+
std::cerr << std::string((level+1)*2, ' ') << "\"" << pos->first << "\": ";
737+
printTree(pos->second, level + 1);
738+
++pos;
739+
if (pos != pt.end()) {
740+
std::cerr << ",";
741+
}
742+
std::cerr << std::endl;
743+
}
744+
std::cerr << std::string(level*2, ' ') << " }";
745+
}
746+
return;
747+
}
748+
749+
// merge content of boost ptree pt2 into pt1
750+
// existing nodes are NOT overwritten
751+
void mergeTree (boost::property_tree::ptree &pt1, boost::property_tree::ptree &pt2) {
752+
// iterate each node in pt2
753+
for (boost::property_tree::ptree::iterator pos = pt2.begin(); pos != pt2.end(); ++pos) {
754+
auto nodeName = pos->first;
755+
// is there a key match in pt1 ?
756+
auto sub1 = pt1.get_child_optional(nodeName);
757+
if (!sub1) {
758+
// no match, insert
759+
pt1.put_child(nodeName, pos->second);
760+
} else {
761+
// match, merge subtrees
762+
mergeTree(sub1.get(), pos->second);
763+
}
764+
}
765+
}
766+
726767
int Readout::_configure(const boost::property_tree::ptree& properties)
727768
{
728769
theLog.log(LogInfoSupport_(3005), "Readout executing CONFIGURE");
@@ -735,31 +776,58 @@ int Readout::_configure(const boost::property_tree::ptree& properties)
735776

736777
// load configuration file
737778
theLog.log(LogInfoSupport, "Reading configuration from %s %s", cfgFileURI, cfgFileEntryPoint);
738-
try {
739-
// check URI prefix
740-
if (!strncmp(cfgFileURI, "file:", 5)) {
741-
// let's use the 'Common' config file library
742-
cfg.load(cfgFileURI);
743-
} else {
744-
// otherwise use the Configuration module, if available
745-
#ifdef WITH_CONFIG
746-
try {
747-
std::unique_ptr<o2::configuration::ConfigurationInterface> conf = o2::configuration::ConfigurationFactory::getConfiguration(cfgFileURI);
748-
boost::property_tree::ptree t = conf->getRecursive(cfgFileEntryPoint);
749-
cfg.load(t);
750-
// cfg.print();
751-
} catch (std::exception& e) {
752-
throw std::string(e.what());
779+
780+
auto loadConfig = [] (const char* cfgFileURI, const char *cfgFileEntryPoint, ConfigFile &cfg) {
781+
try {
782+
// check URI prefix
783+
if (!strncmp(cfgFileURI, "file:", 5)) {
784+
// let's use the 'Common' config file library
785+
cfg.load(cfgFileURI);
786+
} else {
787+
// otherwise use the Configuration module, if available
788+
#ifdef WITH_CONFIG
789+
try {
790+
std::unique_ptr<o2::configuration::ConfigurationInterface> conf = o2::configuration::ConfigurationFactory::getConfiguration(cfgFileURI);
791+
boost::property_tree::ptree t = conf->getRecursive(cfgFileEntryPoint);
792+
cfg.load(t);
793+
// cfg.print();
794+
} catch (std::exception& e) {
795+
throw std::string(e.what());
796+
}
797+
#else
798+
throw std::string("This type of URI is not supported");
799+
#endif
753800
}
754-
#else
755-
throw std::string("This type of URI is not supported");
756-
#endif
801+
} catch (std::string err) {
802+
theLog.log(LogErrorSupport_(3100), "Failed to read config: %s", err.c_str());
803+
return -1;
757804
}
758-
} catch (std::string err) {
759-
theLog.log(LogErrorSupport_(3100), "Failed to read config: %s", err.c_str());
805+
return 0;
806+
};
807+
808+
if (loadConfig(cfgFileURI, cfgFileEntryPoint, cfg)) {
760809
return -1;
761810
}
762811

812+
//printTree(cfg.get(),0);
813+
814+
// configuration parameter: | readout | defaults | string | | If set, the corresponding configuration URI is loaded and merged with current readout configuration. Existing parameters in current config are NOT overwritten. |
815+
816+
// try to load extra defaults, if defined, and merge
817+
std::string cfgDefaultsPath = "";
818+
if (cfg.getOptionalValue<std::string>("readout.defaults", cfgDefaultsPath) == 0) {
819+
ConfigFile cfgDefaults;
820+
theLog.log(LogInfoDevel, "Reading configuration defaults from %s %s", cfgDefaultsPath.c_str(), cfgFileEntryPoint);
821+
if (loadConfig(cfgDefaultsPath.c_str(), cfgFileEntryPoint, cfgDefaults) == 0) {
822+
//printTree(cfgDefaults.get(),0);
823+
// merge trees: defaults values used if not defined already
824+
mergeTree(cfg.get(), cfgDefaults.get());
825+
//printTree(cfg.get(),0);
826+
} else {
827+
return -1;
828+
}
829+
}
830+
763831
// TODO
764832
// save config somewhere ?
765833

src/readoutConfigEditor.tcl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ set configurationParametersDescriptor {
145145
| readout | aggregatorSliceTimeout | double | 0 | When set, slices (groups) of pages are flushed if not updated after given timeout (otherwise closed only on beginning of next TF, or on stop). |
146146
| readout | aggregatorStfTimeout | double | 0 | When set, subtimeframes are buffered until timeout (otherwise, sent immediately and independently for each data source). |
147147
| readout | customCommands | string | | List of key=value pairs defining some custom shell commands to be executed at before/after state change commands. |
148+
| readout | defaults | string | | If set, the corresponding configuration URI is loaded and merged with current readout configuration. Existing parameters in current config are NOT overwritten. |
148149
| readout | disableAggregatorSlicing | int | 0 | When set, the aggregator slicing is disabled, data pages are passed through without grouping/slicing. |
149150
| readout | disableTimeframes | int | 0 | When set, all timeframe related features are disabled (this may supersede other config parameters). |
150151
| readout | exitTimeout | double | -1 | Time in seconds after which the program exits automatically. -1 for unlimited. |

0 commit comments

Comments
 (0)