File indexing completed on 2025-08-05 08:16:05
0001 #include "PHParameters.h"
0002
0003 #include <pdbcalbase/PdbBankID.h>
0004 #include <pdbcalbase/PdbCalBank.h>
0005 #include <pdbcalbase/PdbParameterMap.h>
0006 #include <pdbcalbase/PdbParameterMapContainer.h>
0007
0008 #include <phool/PHCompositeNode.h>
0009 #include <phool/PHIODataNode.h>
0010 #include <phool/PHTimeStamp.h>
0011 #include <phool/getClass.h>
0012 #include <phool/phool.h>
0013
0014 #include <TBufferXML.h>
0015 #include <TFile.h>
0016 #include <TSystem.h>
0017
0018 #include <boost/foreach.hpp>
0019 #pragma GCC diagnostic push
0020 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0021 #include <boost/functional/hash.hpp>
0022 #pragma GCC diagnostic pop
0023 #include <boost/lexical_cast.hpp>
0024 #include <boost/tokenizer.hpp>
0025
0026 #pragma GCC diagnostic push
0027 #pragma GCC diagnostic ignored "-Wshadow"
0028 #include <boost/stacktrace.hpp>
0029 #pragma GCC diagnostic pop
0030
0031 #include <unistd.h>
0032 #include <algorithm>
0033 #include <cassert>
0034 #include <cctype>
0035 #include <cstdlib>
0036 #include <ctime>
0037 #include <filesystem>
0038 #include <iostream>
0039 #include <iterator> // for reverse_iterator
0040 #include <sstream>
0041
0042 PHParameters::PHParameters(const PHParameters ¶ms, const std::string &name)
0043 : m_Detector(name)
0044 {
0045 FillFrom(¶ms);
0046 }
0047
0048 PHParameters::~PHParameters()
0049 {
0050 m_DoubleParMap.clear();
0051 m_IntParMap.clear();
0052 m_StringParMap.clear();
0053 }
0054
0055 void PHParameters::Reset()
0056 {
0057 m_DoubleParMap.clear();
0058 m_IntParMap.clear();
0059 m_StringParMap.clear();
0060 }
0061
0062 void PHParameters::set_int_param(const std::string &name, const int ival)
0063 {
0064 m_IntParMap[name] = ival;
0065 }
0066
0067 int PHParameters::get_int_param(const std::string &name) const
0068 {
0069 if (m_IntParMap.find(name) != m_IntParMap.end())
0070 {
0071 return m_IntParMap.find(name)->second;
0072 }
0073 std::cout << PHWHERE << " integer parameter " << name
0074 << " does not exist (forgot to set?)" << std::endl;
0075 std::cout << "Here is the stacktrace: " << std::endl;
0076 std::cout << boost::stacktrace::stacktrace();
0077 std::cout << std::endl
0078 << "DO NOT PANIC - this is not a segfault" << std::endl;
0079 std::cout << "Check the stacktrace for the guilty party (typically #2)" << std::endl;
0080 gSystem->Exit(1);
0081 exit(1);
0082 }
0083
0084 bool PHParameters::exist_int_param(const std::string &name) const
0085 {
0086 return m_IntParMap.find(name) != m_IntParMap.end();
0087 }
0088
0089 void PHParameters::printint() const
0090 {
0091 std::cout << "int parameters: " << std::endl;
0092 for (const auto &iter : m_IntParMap)
0093 {
0094 std::cout << iter.first << ": " << iter.second << std::endl;
0095 }
0096 return;
0097 }
0098
0099 void PHParameters::set_double_param(const std::string &name, const double dval)
0100 {
0101 m_DoubleParMap[name] = dval;
0102 }
0103
0104 double
0105 PHParameters::get_double_param(const std::string &name) const
0106 {
0107 if (m_DoubleParMap.find(name) != m_DoubleParMap.end())
0108 {
0109 return m_DoubleParMap.find(name)->second;
0110 }
0111 std::cout << PHWHERE << " double parameter " << name
0112 << " does not exist (forgot to set?)" << std::endl;
0113 std::cout << "Here is the stacktrace: " << std::endl;
0114 std::cout << boost::stacktrace::stacktrace();
0115 std::cout << std::endl
0116 << "DO NOT PANIC - this is not a segfault" << std::endl;
0117 std::cout << "Check the stacktrace for the guilty party (typically #2)" << std::endl;
0118
0119 gSystem->Exit(1);
0120 exit(1);
0121 }
0122
0123 bool PHParameters::exist_double_param(const std::string &name) const
0124 {
0125 return m_DoubleParMap.find(name) != m_DoubleParMap.end();
0126 }
0127
0128 void PHParameters::Print(Option_t * ) const
0129 {
0130 std::cout << "Parameters for " << m_Detector << std::endl;
0131 printint();
0132 printdouble();
0133 printstring();
0134 return;
0135 }
0136
0137 size_t
0138 PHParameters::get_hash() const
0139 {
0140 size_t seed = 0;
0141
0142 for (const auto &iter : m_DoubleParMap)
0143 {
0144
0145 boost::hash_combine(seed, iter.first);
0146 boost::hash_combine(seed, iter.second);
0147
0148 }
0149
0150 for (const auto &iter : m_IntParMap)
0151 {
0152
0153 boost::hash_combine(seed, iter.first);
0154 boost::hash_combine(seed, iter.second);
0155
0156 }
0157
0158 for (const auto &iter : m_StringParMap)
0159 {
0160
0161 boost::hash_combine(seed, iter.first);
0162 boost::hash_combine(seed, iter.second);
0163
0164 }
0165
0166 return seed;
0167 }
0168
0169 void PHParameters::printdouble() const
0170 {
0171 std::cout << "double parameters: " << std::endl;
0172 for (const auto &iter : m_DoubleParMap)
0173 {
0174 std::cout << iter.first << ": " << iter.second << std::endl;
0175 }
0176 return;
0177 }
0178
0179 void PHParameters::set_string_param(const std::string &name, const std::string &str)
0180 {
0181 m_StringParMap[name] = str;
0182 }
0183
0184 std::string
0185 PHParameters::get_string_param(const std::string &name) const
0186 {
0187 if (m_StringParMap.find(name) != m_StringParMap.end())
0188 {
0189 return m_StringParMap.find(name)->second;
0190 }
0191 std::cout << PHWHERE << " string parameter " << name
0192 << " does not exist (forgot to set?)" << std::endl;
0193 std::cout << "Here is the stacktrace: " << std::endl;
0194 std::cout << boost::stacktrace::stacktrace();
0195 std::cout << std::endl
0196 << "DO NOT PANIC - this is not a segfault" << std::endl;
0197 std::cout << "Check the stacktrace for the guilty party (typically #2)" << std::endl;
0198 gSystem->Exit(1);
0199 exit(1);
0200 }
0201
0202 bool PHParameters::exist_string_param(const std::string &name) const
0203 {
0204 return m_StringParMap.find(name) != m_StringParMap.end();
0205 }
0206
0207 void PHParameters::printstring() const
0208 {
0209 std::cout << "string parameters: " << std::endl;
0210 for (const auto &iter : m_StringParMap)
0211 {
0212 std::cout << iter.first << ": " << iter.second << std::endl;
0213 }
0214 return;
0215 }
0216
0217 void PHParameters::FillFrom(const PdbParameterMap *saveparams)
0218 {
0219 assert(saveparams);
0220
0221 std::pair<std::map<const std::string, double>::const_iterator,
0222 std::map<const std::string, double>::const_iterator>
0223 begin_end_d = saveparams->get_dparam_iters();
0224 for (std::map<const std::string, double>::const_iterator iter = begin_end_d.first;
0225 iter != begin_end_d.second; ++iter)
0226 {
0227 m_DoubleParMap[iter->first] = iter->second;
0228 }
0229 std::pair<std::map<const std::string, int>::const_iterator,
0230 std::map<const std::string, int>::const_iterator>
0231 begin_end_i = saveparams->get_iparam_iters();
0232 for (std::map<const std::string, int>::const_iterator iter = begin_end_i.first;
0233 iter != begin_end_i.second; ++iter)
0234 {
0235 m_IntParMap[iter->first] = iter->second;
0236 }
0237 std::pair<std::map<const std::string, std::string>::const_iterator,
0238 std::map<const std::string, std::string>::const_iterator>
0239 begin_end_s = saveparams->get_cparam_iters();
0240 for (std::map<const std::string, std::string>::const_iterator iter = begin_end_s.first;
0241 iter != begin_end_s.second; ++iter)
0242 {
0243 m_StringParMap[iter->first] = iter->second;
0244 }
0245
0246 return;
0247 }
0248
0249 void PHParameters::FillFrom(const PdbParameterMapContainer *saveparamcontainer, const int detid)
0250 {
0251
0252
0253 const PdbParameterMap *saveparams = saveparamcontainer->GetParameters(detid);
0254 if (!saveparams)
0255 {
0256 return;
0257 }
0258 std::pair<std::map<const std::string, double>::const_iterator,
0259 std::map<const std::string, double>::const_iterator>
0260 begin_end_d = saveparams->get_dparam_iters();
0261 for (std::map<const std::string, double>::const_iterator iter = begin_end_d.first;
0262 iter != begin_end_d.second; ++iter)
0263 {
0264 m_DoubleParMap[iter->first] = iter->second;
0265 }
0266 std::pair<std::map<const std::string, int>::const_iterator,
0267 std::map<const std::string, int>::const_iterator>
0268 begin_end_i = saveparams->get_iparam_iters();
0269 for (std::map<const std::string, int>::const_iterator iter = begin_end_i.first;
0270 iter != begin_end_i.second; ++iter)
0271 {
0272 m_IntParMap[iter->first] = iter->second;
0273 }
0274 std::pair<std::map<const std::string, std::string>::const_iterator,
0275 std::map<const std::string, std::string>::const_iterator>
0276 begin_end_s = saveparams->get_cparam_iters();
0277 for (std::map<const std::string, std::string>::const_iterator iter = begin_end_s.first;
0278 iter != begin_end_s.second; ++iter)
0279 {
0280 m_StringParMap[iter->first] = iter->second;
0281 }
0282
0283 return;
0284 }
0285
0286 void PHParameters::FillFrom(const PHParameters *saveparams)
0287 {
0288 assert(saveparams);
0289
0290 for (const auto &iter : saveparams->m_DoubleParMap)
0291 {
0292 m_DoubleParMap[iter.first] = iter.second;
0293 }
0294
0295 for (const auto &iter : saveparams->m_IntParMap)
0296 {
0297 m_IntParMap[iter.first] = iter.second;
0298 }
0299
0300 for (const auto &iter : saveparams->m_StringParMap)
0301 {
0302 m_StringParMap[iter.first] = iter.second;
0303 }
0304 return;
0305 }
0306
0307 void PHParameters::SaveToNodeTree(PHCompositeNode *topNode, const std::string &nodename)
0308 {
0309
0310 PdbParameterMap *nodeparams = findNode::getClass<PdbParameterMap>(topNode, nodename);
0311 if (!nodeparams)
0312 {
0313 nodeparams = new PdbParameterMap();
0314 PHIODataNode<PdbParameterMap> *newnode = new PHIODataNode<PdbParameterMap>(nodeparams, nodename);
0315 topNode->addNode(newnode);
0316 }
0317 else
0318 {
0319 nodeparams->Reset();
0320 }
0321 CopyToPdbParameterMap(nodeparams);
0322 return;
0323 }
0324
0325 void PHParameters::UpdateNodeTree(PHCompositeNode *topNode, const std::string &nodename)
0326 {
0327 PdbParameterMap *nodeparams = findNode::getClass<PdbParameterMap>(topNode, nodename);
0328 if (!nodeparams)
0329 {
0330 std::cout << PHWHERE << " could not find PdbParameterMap " << nodename
0331 << " which must exist" << std::endl;
0332 gSystem->Exit(1);
0333 }
0334 CopyToPdbParameterMap(nodeparams);
0335 return;
0336 }
0337
0338 void PHParameters::SaveToNodeTree(PHCompositeNode *topNode, const std::string &nodename, const int detid)
0339 {
0340
0341 PdbParameterMapContainer *nodeparamcontainer = findNode::getClass<PdbParameterMapContainer>(topNode, nodename);
0342 if (!nodeparamcontainer)
0343 {
0344 nodeparamcontainer = new PdbParameterMapContainer();
0345 PHIODataNode<PdbParameterMapContainer> *newnode =
0346 new PHIODataNode<PdbParameterMapContainer>(nodeparamcontainer, nodename);
0347 topNode->addNode(newnode);
0348 }
0349 PdbParameterMap *nodeparams = nodeparamcontainer->GetParametersToModify(detid);
0350 if (nodeparams)
0351 {
0352 nodeparams->Reset();
0353 }
0354 else
0355 {
0356 nodeparams = new PdbParameterMap();
0357 nodeparamcontainer->AddPdbParameterMap(detid, nodeparams);
0358 }
0359 CopyToPdbParameterMap(nodeparams);
0360 return;
0361 }
0362
0363 void PHParameters::UpdateNodeTree(PHCompositeNode *topNode, const std::string &nodename, const int detid)
0364 {
0365 PdbParameterMapContainer *nodeparamcontainer = findNode::getClass<PdbParameterMapContainer>(topNode, nodename);
0366 if (!nodeparamcontainer)
0367 {
0368 std::cout << PHWHERE << " could not find PdbParameterMapContainer " << nodename
0369 << " which must exist" << std::endl;
0370 gSystem->Exit(1);
0371 }
0372 PdbParameterMap *nodeparams = nodeparamcontainer->GetParametersToModify(detid);
0373 if (!nodeparams)
0374 {
0375 std::cout << PHWHERE << " could not find PdbParameterMap for detector " << detid
0376 << " which must exist" << std::endl;
0377 gSystem->Exit(1);
0378 }
0379 CopyToPdbParameterMap(nodeparams);
0380 return;
0381 }
0382
0383 int PHParameters::WriteToCDBFile(const std::string &filename)
0384 {
0385 PdbParameterMap *myparm = new PdbParameterMap();
0386 CopyToPdbParameterMap(myparm);
0387 TFile *f = TFile::Open(filename.c_str(), "recreate");
0388 myparm->Write();
0389 delete f;
0390 delete myparm;
0391 return 0;
0392 }
0393
0394 int PHParameters::WriteToFile(const std::string &extension, const std::string &dir)
0395 {
0396 std::ostringstream fullpath;
0397 std::ostringstream fnamestream;
0398 PdbBankID bankID(0);
0399 PHTimeStamp TStart(0);
0400 PHTimeStamp TStop(0xffffffff);
0401 fullpath << dir;
0402
0403 if (*(dir.rbegin()) != '/')
0404 {
0405 fullpath << "/";
0406 }
0407 fnamestream << m_Detector << "_geoparams"
0408 << "-" << bankID.getInternalValue()
0409 << "-" << TStart.getTics() << "-" << TStop.getTics() << "-" << time(nullptr)
0410 << "." << extension;
0411 std::string fname = fnamestream.str();
0412 std::transform(fname.begin(), fname.end(), fname.begin(), ::tolower);
0413 fullpath << fname;
0414
0415 std::cout << "PHParameters::WriteToFile - save to " << fullpath.str() << std::endl;
0416
0417 PdbParameterMap *myparm = new PdbParameterMap();
0418 CopyToPdbParameterMap(myparm);
0419 TFile *f = TFile::Open(fullpath.str().c_str(), "recreate");
0420
0421
0422 std::string floatformat = TBufferXML::GetFloatFormat();
0423 TBufferXML::SetFloatFormat("%.17g");
0424 myparm->Write();
0425 delete f;
0426
0427 TBufferXML::SetFloatFormat(floatformat.c_str());
0428 std::cout << "sleeping 1 second to prevent duplicate inserttimes" << std::endl;
0429 sleep(1);
0430 return 0;
0431 }
0432
0433 int PHParameters::ReadFromFile(const std::string &name, const std::string &extension, const int detid, const int issuper, const std::string &dir)
0434 {
0435 PHTimeStamp TSearch(10);
0436 PdbBankID bankID(0);
0437 std::ostringstream fnamestream;
0438 fnamestream << name << "_geoparams"
0439 << "-" << bankID.getInternalValue();
0440 std::string fileprefix = fnamestream.str();
0441 std::transform(fileprefix.begin(), fileprefix.end(), fileprefix.begin(),
0442 ::tolower);
0443 std::filesystem::path targetDir(dir);
0444
0445 std::filesystem::recursive_directory_iterator diriter(targetDir);
0446 std::filesystem::recursive_directory_iterator eod;
0447 boost::char_separator<char> sep("-.");
0448 std::map<unsigned int, std::string> calibfiles;
0449 BOOST_FOREACH (std::filesystem::path const &i, std::make_pair(diriter, eod))
0450 {
0451 if (is_regular_file(i))
0452 {
0453
0454
0455
0456 std::string basename = i.filename().string();
0457 if (basename.compare(0, fileprefix.size(), fileprefix) != 0)
0458 {
0459 continue;
0460 }
0461
0462
0463
0464 if (i.extension().string().find(extension) == std::string::npos || i.extension().string().size() != extension.size() + 1)
0465 {
0466 continue;
0467 }
0468 boost::tokenizer<boost::char_separator<char> > tok(basename, sep);
0469 boost::tokenizer<boost::char_separator<char> >::iterator iter =
0470 tok.begin();
0471 ++iter;
0472 ++iter;
0473 PHTimeStamp TStart(ConvertStringToUint(*iter));
0474 if (TSearch < TStart)
0475 {
0476 continue;
0477 }
0478 ++iter;
0479 PHTimeStamp TStop(ConvertStringToUint(*iter));
0480 if (TSearch >= TStop)
0481 {
0482 continue;
0483 }
0484 ++iter;
0485 calibfiles[ConvertStringToUint(*iter)] = i.string();
0486 }
0487 }
0488 if (calibfiles.empty())
0489 {
0490 std::cout << "No calibration file like " << dir << "/" << fileprefix << " found" << std::endl;
0491 gSystem->Exit(1);
0492 exit(1);
0493 }
0494 std::cout << "PHParameters::ReadFromFile - Reading from File: " << (calibfiles.rbegin())->second << " ... ";
0495 std::string fname = (calibfiles.rbegin())->second;
0496 TFile *f = TFile::Open(fname.c_str());
0497 if (issuper)
0498 {
0499 PdbParameterMapContainer *myparm = dynamic_cast<PdbParameterMapContainer *>(f->Get("PdbParameterMapContainer"));
0500 assert(myparm);
0501
0502 if (myparm->GetParameters(detid) == nullptr)
0503 {
0504 std::cout << "Missing PdbParameterMapContainer Detector Id " << detid << std::endl;
0505 gSystem->Exit(1);
0506 }
0507
0508 std::cout << "Received PdbParameterMapContainer Detector Id " << detid << " with (Hash = 0x" << std::hex << myparm->GetParameters(detid)->get_hash() << std::dec << ")" << std::endl;
0509
0510 FillFrom(myparm, detid);
0511 delete myparm;
0512 }
0513 else
0514 {
0515 PdbParameterMap *myparm = dynamic_cast<PdbParameterMap *>(f->Get("PdbParameterMap"));
0516 assert(myparm);
0517 std::cout << "Received PdbParameterMap with (Hash = 0x" << std::hex << myparm->get_hash() << std::dec << ")" << std::endl;
0518
0519 FillFrom(myparm);
0520 delete myparm;
0521 }
0522 delete f;
0523
0524 return 0;
0525 }
0526
0527 int PHParameters::ReadFromCDBFile(const std::string &url)
0528 {
0529 TFile *f = TFile::Open(url.c_str());
0530 if (!f)
0531 {
0532 std::cout << "could not open " << url << std::endl;
0533 gSystem->Exit(1);
0534 }
0535 PdbParameterMap *myparm = dynamic_cast<PdbParameterMap *>(f->Get("PdbParameterMap"));
0536 if (!myparm)
0537 {
0538 std::cout << "could not get PdbParameterMap from " << url << std::endl;
0539 gSystem->Exit(1);
0540 }
0541 FillFrom(myparm);
0542 delete myparm;
0543 delete f;
0544 return 0;
0545 }
0546
0547 void PHParameters::CopyToPdbParameterMap(PdbParameterMap *myparm)
0548 {
0549 for (std::map<const std::string, double>::const_iterator iter = m_DoubleParMap.begin();
0550 iter != m_DoubleParMap.end(); ++iter)
0551 {
0552 myparm->set_double_param(iter->first, iter->second);
0553 }
0554 for (std::map<const std::string, int>::const_iterator iter = m_IntParMap.begin();
0555 iter != m_IntParMap.end(); ++iter)
0556 {
0557 myparm->set_int_param(iter->first, iter->second);
0558 }
0559 for (std::map<const std::string, std::string>::const_iterator iter = m_StringParMap.begin();
0560 iter != m_StringParMap.end(); ++iter)
0561 {
0562 myparm->set_string_param(iter->first, iter->second);
0563 }
0564 }
0565
0566 unsigned int
0567 PHParameters::ConvertStringToUint(const std::string &str)
0568 {
0569 unsigned int tics;
0570 try
0571 {
0572 tics = boost::lexical_cast<unsigned int>(str);
0573 }
0574 catch (boost::bad_lexical_cast const &)
0575 {
0576 std::cout << "Cannot extract timestamp from " << str << std::endl;
0577 gSystem->Exit(1);
0578 exit(1);
0579 }
0580 return tics;
0581 }