Back to home page

sPhenix code displayed by LXR

 
 

    


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 // stacktrace gives a shadow warning
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 &params, const std::string &name)
0043   : m_Detector(name)
0044 {
0045   FillFrom(&params);
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 * /*option*/) 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     //      size_t seed = 0;
0145     boost::hash_combine(seed, iter.first);
0146     boost::hash_combine(seed, iter.second);
0147     //      std::cout << iter->first << ": " << iter->second <<" -> "<<seed<< std::endl;
0148   }
0149 
0150   for (const auto &iter : m_IntParMap)
0151   {
0152     //      size_t seed = 0;
0153     boost::hash_combine(seed, iter.first);
0154     boost::hash_combine(seed, iter.second);
0155     //      std::cout << iter->first << ": " << iter->second <<" -> "<<seed<< std::endl;
0156   }
0157 
0158   for (const auto &iter : m_StringParMap)
0159   {
0160     //      size_t seed = 0;
0161     boost::hash_combine(seed, iter.first);
0162     boost::hash_combine(seed, iter.second);
0163     //      std::cout << iter->first << ": " << iter->second <<" -> "<<seed<< std::endl;
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   //  assert(saveparamcontainer != nullptr);
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   // write itself since this class is fine with saving by root
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();  // just clear previous content in case variables were deleted
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   // write itself since this class is fine with saving by root
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);  // lets start at zero
0399   PHTimeStamp TStart(0);
0400   PHTimeStamp TStop(0xffffffff);
0401   fullpath << dir;
0402   // add / if directory lacks ending /
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   // force xml file writing to use extended precision shown experimentally
0421   // to not modify input parameters (.17g)
0422   std::string floatformat = TBufferXML::GetFloatFormat();
0423   TBufferXML::SetFloatFormat("%.17g");  // for IEEE 754 double
0424   myparm->Write();
0425   delete f;
0426   // restore previous xml float format
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       // leaf() gives the filename without path,
0454       // the string.compare(0...) checks if the filename starts with fileprefix
0455       // if not coninue
0456       std::string basename = i.filename().string();
0457       if (basename.compare(0, fileprefix.size(), fileprefix) != 0)
0458       {
0459         continue;
0460       }
0461       // extension() contains the . - like .xml, so we
0462       // just compare the extensions instead of !=
0463       // and check that the size makes sense
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;  // that skips the file prefix excluding bank id
0472       ++iter;  // that skips the bank id we checked already as part of the filename
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 }