3737#endif
3838#include < cassert>
3939#include < iostream>
40+ #include < sstream>
4041#include < string>
4142#include < fairlogger/Logger.h>
4243#include < typeindex>
@@ -754,6 +755,29 @@ void ConfigurableParam::writeJSON(std::string const& filename, std::string const
754755
755756// ------------------------------------------------------------------
756757
758+ std::string ConfigurableParam::asJSON (std::string const & keyOnly)
759+ {
760+ initPropertyTree (); // update the boost tree before writing
761+ std::ostringstream os;
762+ if (!keyOnly.empty ()) { // write ini for selected key only
763+ try {
764+ boost::property_tree::ptree kTree ;
765+ auto keys = o2::utils::Str::tokenize (keyOnly, " ,;" , true , true );
766+ for (const auto & k : keys) {
767+ kTree .add_child (k, sPtree ->get_child (k));
768+ }
769+ boost::property_tree::write_json (os, kTree );
770+ } catch (const boost::property_tree::ptree_bad_path& err) {
771+ LOG (fatal) << " non-existing key " << keyOnly << " provided to writeJSON" ;
772+ }
773+ } else {
774+ boost::property_tree::write_json (os, *sPtree );
775+ }
776+ return os.str ();
777+ }
778+
779+ // ------------------------------------------------------------------
780+
757781void ConfigurableParam::initPropertyTree ()
758782{
759783 sPtree ->clear ();
@@ -870,26 +894,10 @@ void ConfigurableParam::printAllRegisteredParamNames()
870894
871895// ------------------------------------------------------------------
872896
873- // Update the storage map of params from the given configuration file.
874- // It can be in JSON or INI format.
875- // If nonempty comma-separated paramsList is provided, only those params will
876- // be updated, absence of data for any of requested params will lead to fatal
877- // If unchangedOnly is true, then only those parameters whose provenance is kCODE will be updated
878- // (to allow preference of run-time settings)
879- void ConfigurableParam::updateFromFile (std::string const & configFile, std::string const & paramsList, bool unchangedOnly)
897+ namespace
898+ {
899+ void updateFromPropertyTree (boost::property_tree::ptree const & pt, std::string const & source, std::string const & paramsList, bool unchangedOnly)
880900{
881- if (!sIsFullyInitialized ) {
882- initialize ();
883- }
884-
885- auto cfgfile = o2::utils::Str::trim_copy (configFile);
886-
887- if (cfgfile.length () == 0 ) {
888- return ;
889- }
890-
891- boost::property_tree::ptree pt = ConfigurableParamReaders::readConfigFile (cfgfile);
892-
893901 std::vector<std::pair<std::string, std::string>> keyValPairs;
894902 auto request = o2::utils::Str::tokenize (paramsList, ' ,' , true );
895903 std::unordered_map<std::string, int > requestMap;
@@ -913,7 +921,7 @@ void ConfigurableParam::updateFromFile(std::string const& configFile, std::strin
913921 auto name = subKey.first ;
914922 auto value = subKey.second .get_value <std::string>();
915923 std::string key = mainKey + " ." + name;
916- if (!unchangedOnly || getProvenance (key) == kCODE ) {
924+ if (!unchangedOnly || ConfigurableParam:: getProvenance (key) == ConfigurableParam:: kCODE ) {
917925 std::pair<std::string, std::string> pair = std::make_pair (key, o2::utils::Str::trim_copy (value));
918926 keyValPairs.push_back (pair);
919927 }
@@ -928,16 +936,62 @@ void ConfigurableParam::updateFromFile(std::string const& configFile, std::strin
928936 // make sure all requested params were retrieved
929937 for (const auto & req : requestMap) {
930938 if (req.second == 0 ) {
931- throw std::runtime_error (fmt::format (" Param {:s} was not found in {:s}" , req.first , configFile ));
939+ throw std::runtime_error (fmt::format (" Param {:s} was not found in {:s}" , req.first , source ));
932940 }
933941 }
934942
935943 try {
936- setValues (keyValPairs);
944+ ConfigurableParam:: setValues (keyValPairs);
937945 } catch (std::exception const & error) {
938946 LOG (error) << " Error while setting values " << error.what ();
939947 }
940948}
949+ } // namespace
950+
951+ // Update the storage map of params from the given configuration file.
952+ // It can be in JSON or INI format.
953+ // If nonempty comma-separated paramsList is provided, only those params will
954+ // be updated, absence of data for any of requested params will lead to fatal
955+ // If unchangedOnly is true, then only those parameters whose provenance is kCODE will be updated
956+ // (to allow preference of run-time settings)
957+ void ConfigurableParam::updateFromFile (std::string const & configFile, std::string const & paramsList, bool unchangedOnly)
958+ {
959+ if (!sIsFullyInitialized ) {
960+ initialize ();
961+ }
962+
963+ auto cfgfile = o2::utils::Str::trim_copy (configFile);
964+
965+ if (cfgfile.length () == 0 ) {
966+ return ;
967+ }
968+
969+ updateFromPropertyTree (ConfigurableParamReaders::readConfigFile (cfgfile), configFile, paramsList, unchangedOnly);
970+ }
971+
972+ // ------------------------------------------------------------------
973+
974+ void ConfigurableParam::updateFromJSONString (std::string const & configJSON, std::string const & paramsList, bool unchangedOnly)
975+ {
976+ if (!sIsFullyInitialized ) {
977+ initialize ();
978+ }
979+
980+ auto json = o2::utils::Str::trim_copy (configJSON);
981+ if (json.length () == 0 ) {
982+ return ;
983+ }
984+
985+ boost::property_tree::ptree pt;
986+ std::istringstream input (json);
987+ try {
988+ boost::property_tree::read_json (input, pt);
989+ } catch (const boost::property_tree::ptree_error& e) {
990+ LOG (fatal) << " Failed to read JSON config string (" << e.what () << " )" ;
991+ }
992+
993+ updateFromPropertyTree (pt, " provided JSON string" , paramsList, unchangedOnly);
994+ }
941995
942996// ------------------------------------------------------------------
943997// ------------------------------------------------------------------
0 commit comments