Skip to content

Commit 19e9b75

Browse files
committed
config: added sections defining default settings
1 parent 0cd8417 commit 19e9b75

File tree

3 files changed

+63
-19
lines changed

3 files changed

+63
-19
lines changed

doc/configurationParameters.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ The *receiverFMQ-\** section defines parameters for the test receiverFMQ.exe pro
1111

1212
Please see the provided example configuration files to see how they are usually arranged.
1313

14+
It is possible to define some default parameters to be used in all matching sections by creating a section which name ends with "-\*" and containing some key-value pairs. These pairs are applied to all sections with similar names. Existing key-value pairs are not overwritten, but are defined according to these defaults if they don't exist. It can be useful to create multiple equipments with similar settings.
15+
1416
## Parameter types
1517

1618
The following table describes the types used in the configuration, giving:

doc/releaseNotes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,6 @@ This file describes the main feature changes for each readout.exe released versi
520520
- added equipment-cruemulator-*.PayloadSizeStdev: generate payload with random size (gaussian distribution mean=PayloadSize sigma=PayloadSizeStdev).
521521
- added equipment-cruemulator-*.linkThroughput: set incoming link data throughput (in Gbps).
522522
- Minor logging updates.
523+
524+
## nect version
525+
- Updated configuration syntax: section names ending with "-*" can be used to define default parameters. They are applied to all section with similar names. Existing key-value pairs are not overwritten, but are defined according to defaults if they don't exist. For example, it is possible to define the TFperiod for all equipments by adding a section named "equipment-*" with "TFperiod=32".

src/mainReadout.cxx

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,9 @@ int Readout::configure(const boost::property_tree::ptree& properties)
603603
return -1;
604604
}
605605

606+
// TODO
607+
// save config somewhere ?
608+
606609
// apply provided occ properties over loaded configuration
607610
// with function to overwrtie configuration tree t1 with (selected) content of t2
608611
auto mergeConfig = [&](boost::property_tree::ptree& t1, const boost::property_tree::ptree& t2) {
@@ -618,7 +621,7 @@ int Readout::configure(const boost::property_tree::ptree& properties)
618621
// check for a consumer with same fairmq channel
619622
for (auto kName : ConfigFileBrowser(&cfg, "consumer-")) {
620623
std::string cfgType;
621-
cfgType = cfg.getValue<std::string>(kName + ".consumerType");
624+
cfg.getOptionalValue<std::string>(kName + ".consumerType", cfgType);
622625
if (cfgType == "FairMQChannel") {
623626
std::string cfgChannelName;
624627
cfg.getOptionalValue<std::string>(kName + ".fmq-name", cfgChannelName);
@@ -660,6 +663,43 @@ int Readout::configure(const boost::property_tree::ptree& properties)
660663
};
661664
mergeConfig(cfg.get(), properties);
662665

666+
// merge default trees
667+
const char *defaultTag = "-*";
668+
// if a section ends with above string, its parameters are copied to all matching section names, when these parameters are not already defined there
669+
// append configuration tree t1 with content of t2 (existing leaves in t1 not overwritten by same ones from t2)
670+
auto appendConfig = [&](boost::property_tree::ptree& t1, boost::property_tree::ptree& t2) {
671+
for (boost::property_tree::ptree::iterator it = t2.begin(); it != t2.end();++it) {
672+
if (!t1.get_child_optional(it->first)) {
673+
//printf("set %s = %s\n", it->first.c_str(),it->second.data().c_str());
674+
t1.put_child( it->first, it->second );
675+
}
676+
}
677+
};
678+
// function returns true when end of string matches tag
679+
auto isEndOfStringMatching = [&](const std::string &s, const char* tag) {
680+
if (s.length()<=strlen(tag)) return false;
681+
if (s.substr(s.length()-strlen(tag)) != tag) return false;
682+
return true;
683+
};
684+
for (boost::property_tree::ptree::iterator pos = cfg.get().begin(); pos != cfg.get().end();) {
685+
const std::string section = pos->first;
686+
if (!isEndOfStringMatching(section, defaultTag)) {
687+
++pos;
688+
continue;
689+
}
690+
auto smatch = section.substr(0,section.length()-strlen(defaultTag));
691+
for (boost::property_tree::ptree::iterator pos2 = cfg.get().begin(); pos2 != cfg.get().end();++pos2) {
692+
if (pos2 == pos) continue; // do not self-overwrite
693+
const std::string section2 = pos2->first;
694+
if (section2.compare(0,smatch.length(),smatch)) continue; // mismatch
695+
if (isEndOfStringMatching(section2, defaultTag)) continue; // do not overwrite other defaults sections
696+
theLog.log(LogInfoDevel_(3002), "Updating configuration section [%s] with defaults from [%s]", pos2->first.c_str(), pos->first.c_str());
697+
appendConfig(pos2->second,pos->second);
698+
}
699+
// delete section with defaults, to avoid it is used further
700+
pos = cfg.get().erase(pos);
701+
}
702+
663703
// extract optional configuration parameters
664704
// configuration parameter: | readout | customCommands | string | | List of key=value pairs defining some custom shell commands to be executed at before/after state change commands. |
665705
if (customCommandsShellPid) {
@@ -846,11 +886,8 @@ int Readout::configure(const boost::property_tree::ptree& properties)
846886
for (auto kName : ConfigFileBrowser(&cfg, "bank-")) {
847887
// skip disabled
848888
int enabled = 1;
849-
try {
850-
// configuration parameter: | bank-* | enabled | int | 1 | Enable (1) or disable (0) the memory bank. |
851-
enabled = cfg.getValue<int>(kName + ".enabled");
852-
} catch (...) {
853-
}
889+
// configuration parameter: | bank-* | enabled | int | 1 | Enable (1) or disable (0) the memory bank. |
890+
cfg.getOptionalValue<int>(kName + ".enabled", enabled);
854891
if (!enabled) {
855892
continue;
856893
}
@@ -868,13 +905,9 @@ int Readout::configure(const boost::property_tree::ptree& properties)
868905
// bank type
869906
// configuration parameter: | bank-* | type | string| | Support used to allocate memory. Possible values: malloc, MemoryMappedFile. |
870907
std::string cfgType = "";
871-
try {
872-
cfgType = cfg.getValue<std::string>(kName + ".type");
873-
} catch (...) {
874-
theLog.log(LogErrorSupport_(3100), "Skipping memory bank %s: no type specified", kName.c_str());
875-
continue;
876-
}
908+
cfg.getOptionalValue<std::string>(kName + ".type", cfgType);
877909
if (cfgType.length() == 0) {
910+
theLog.log(LogErrorSupport_(3100), "Skipping memory bank %s: no type specified", kName.c_str());
878911
continue;
879912
}
880913

@@ -934,11 +967,8 @@ int Readout::configure(const boost::property_tree::ptree& properties)
934967

935968
// skip disabled
936969
int enabled = 1;
937-
try {
938-
// configuration parameter: | consumer-* | enabled | int | 1 | Enable (value=1) or disable (value=0) the consumer. |
939-
enabled = cfg.getValue<int>(kName + ".enabled");
940-
} catch (...) {
941-
}
970+
// configuration parameter: | consumer-* | enabled | int | 1 | Enable (value=1) or disable (value=0) the consumer. |
971+
enabled = cfg.getOptionalValue<int>(kName + ".enabled", enabled);
942972
if (!enabled) {
943973
continue;
944974
}
@@ -957,7 +987,11 @@ int Readout::configure(const boost::property_tree::ptree& properties)
957987
try {
958988
// configuration parameter: | consumer-* | consumerType | string | | The type of consumer to be instanciated. One of:stats, FairMQDevice, DataSampling, FairMQChannel, fileRecorder, checker, processor, tcp. |
959989
std::string cfgType = "";
960-
cfgType = cfg.getValue<std::string>(kName + ".consumerType");
990+
cfg.getOptionalValue<std::string>(kName + ".consumerType", cfgType);
991+
if (cfgType.length() == 0) {
992+
theLog.log(LogErrorSupport_(3100), "Skipping consumer %s: no type specified", kName.c_str());
993+
continue;
994+
}
961995
theLog.log(LogInfoDevel, "Configuring consumer %s: %s", kName.c_str(), cfgType.c_str());
962996

963997
#ifdef WITH_NUMA
@@ -1090,7 +1124,12 @@ int Readout::configure(const boost::property_tree::ptree& properties)
10901124

10911125
// configuration parameter: | equipment-* | equipmentType | string | | The type of equipment to be instanciated. One of: dummy, rorc, cruEmulator |
10921126
std::string cfgEquipmentType = "";
1093-
cfgEquipmentType = cfg.getValue<std::string>(kName + ".equipmentType");
1127+
cfg.getOptionalValue<std::string>(kName + ".equipmentType", cfgEquipmentType);
1128+
if (cfgEquipmentType.length() == 0) {
1129+
theLog.log(LogErrorSupport_(3100), "Skipping equipment %s: no type specified", kName.c_str());
1130+
continue;
1131+
}
1132+
10941133
theLog.log(LogInfoDevel, "Configuring equipment %s: %s", kName.c_str(), cfgEquipmentType.c_str());
10951134

10961135
#ifdef WITH_NUMA

0 commit comments

Comments
 (0)