Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-17 09:19:35

0001 #include "CDBTTree.h"
0002 
0003 #include <phool/phool.h>
0004 
0005 #include <TBranch.h>      // for TBranch
0006 #include <TCollection.h>  // for TIter
0007 #include <TDirectory.h>   // for TDirectoryAtomicAdapter, TDirectory, gDirec...
0008 #include <TFile.h>
0009 #include <TLeaf.h>      // for TLeaf
0010 #include <TObjArray.h>  // for TObjArray
0011 #include <TROOT.h>
0012 #include <TSystem.h>
0013 #include <TTree.h>
0014 
0015 #include <climits>
0016 #include <cmath>    // for NAN, isfinite
0017 #include <cstdint>  // for uint64_t
0018 #include <iostream>
0019 #include <limits>   // for numeric_limits, numeric_limits<>::max_digits10
0020 #include <set>      // for set
0021 #include <utility>  // for pair, make_pair
0022 
0023 int CDBTTree::verbosity = 0;  // the verbosity can be set by the static SetVerbosity(int v) method
0024 
0025 CDBTTree::CDBTTree(const std::string &fname)
0026   : m_Filename(fname)
0027 {
0028 }
0029 
0030 CDBTTree::~CDBTTree()
0031 {
0032   m_FloatEntryMap.clear();
0033   m_SingleFloatEntryMap.clear();
0034 }
0035 
0036 void CDBTTree::SetFloatValue(int channel, const std::string &name, float value)
0037 {
0038   if (name == "ID")
0039   {
0040     std::cout << "Sorry ID is reserved as fieldname, pick anything else" << std::endl;
0041     gSystem->Exit(1);
0042   }
0043   std::string fieldname = "F" + name;
0044   if (m_Locked[MultipleEntries])
0045   {
0046     std::cout << "Trying to add field " << name << " after another entry was committed" << std::endl;
0047     std::cout << "That does not work, restructure your code" << std::endl;
0048     gSystem->Exit(1);
0049   }
0050   m_FloatEntryMap[channel].insert(std::make_pair(fieldname, value));
0051 }
0052 
0053 void CDBTTree::SetDoubleValue(int channel, const std::string &name, double value)
0054 {
0055   if (name == "ID")
0056   {
0057     std::cout << "Sorry ID is reserved as fieldname, pick anything else" << std::endl;
0058     gSystem->Exit(1);
0059   }
0060   std::string fieldname = "D" + name;
0061   if (m_Locked[MultipleEntries])
0062   {
0063     std::cout << "Trying to add field " << name << " after another entry was committed" << std::endl;
0064     std::cout << "That does not work, restructure your code" << std::endl;
0065     gSystem->Exit(1);
0066   }
0067   m_DoubleEntryMap[channel].insert(std::make_pair(fieldname, value));
0068 }
0069 
0070 void CDBTTree::SetIntValue(int channel, const std::string &name, int value)
0071 {
0072   if (name == "ID")
0073   {
0074     std::cout << "Sorry ID is reserved as fieldname, pick anything else" << std::endl;
0075     gSystem->Exit(1);
0076   }
0077   std::string fieldname = "I" + name;
0078   if (m_Locked[MultipleEntries])
0079   {
0080     std::cout << "Trying to add field " << name << " after another entry was committed" << std::endl;
0081     std::cout << "That does not work, restructure your code" << std::endl;
0082     gSystem->Exit(1);
0083   }
0084   m_IntEntryMap[channel].insert(std::make_pair(fieldname, value));
0085 }
0086 
0087 void CDBTTree::SetUInt64Value(int channel, const std::string &name, uint64_t value)
0088 {
0089   if (name == "ID")
0090   {
0091     std::cout << "Sorry ID is reserved as fieldname, pick anything else" << std::endl;
0092     gSystem->Exit(1);
0093   }
0094   std::string fieldname = "g" + name;
0095   if (m_Locked[MultipleEntries])
0096   {
0097     std::cout << "Trying to add field " << name << " after another entry was committed" << std::endl;
0098     std::cout << "That does not work, restructure your code" << std::endl;
0099     gSystem->Exit(1);
0100   }
0101   m_UInt64EntryMap[channel].insert(std::make_pair(fieldname, value));
0102 }
0103 
0104 void CDBTTree::Commit()
0105 {
0106   m_Locked[MultipleEntries] = true;
0107 }
0108 
0109 void CDBTTree::WriteMultipleCDBTTree()
0110 {
0111   m_TTree[MultipleEntries] = new TTree(m_TTreeName[MultipleEntries].c_str(), m_TTreeName[MultipleEntries].c_str());
0112   std::set<int> id_set;
0113   std::map<std::string, float> floatmap;
0114   std::map<std::string, double> doublemap;
0115   std::map<std::string, int> intmap;
0116   std::map<std::string, uint64_t> uint64map;
0117   intmap.insert(std::make_pair("IID", std::numeric_limits<int>::min()));
0118   for (auto &f_entry : m_FloatEntryMap)
0119   {
0120     id_set.insert(f_entry.first);
0121     for (auto &f_val : f_entry.second)
0122     {
0123       floatmap.insert(std::make_pair(f_val.first, std::numeric_limits<float>::quiet_NaN()));
0124     }
0125   }
0126   for (auto &f_val : floatmap)
0127   {
0128     std::string fielddescriptor = f_val.first + "/F";
0129     m_TTree[MultipleEntries]->Branch(f_val.first.c_str(), &f_val.second, fielddescriptor.c_str());
0130   }
0131 
0132   for (auto &f_entry : m_DoubleEntryMap)
0133   {
0134     id_set.insert(f_entry.first);
0135     for (auto &f_val : f_entry.second)
0136     {
0137       doublemap.insert(std::make_pair(f_val.first, std::numeric_limits<double>::quiet_NaN()));
0138     }
0139   }
0140   for (auto &f_val : doublemap)
0141   {
0142     std::string fielddescriptor = f_val.first + "/D";
0143     m_TTree[MultipleEntries]->Branch(f_val.first.c_str(), &f_val.second, fielddescriptor.c_str());
0144   }
0145 
0146   for (auto &i_entry : m_IntEntryMap)
0147   {
0148     id_set.insert(i_entry.first);
0149     for (auto &i_val : i_entry.second)
0150     {
0151       intmap.insert(std::make_pair(i_val.first, std::numeric_limits<int>::min()));
0152     }
0153   }
0154   for (auto &i_val : intmap)
0155   {
0156     std::string fielddescriptor = i_val.first + "/I";
0157     m_TTree[MultipleEntries]->Branch(i_val.first.c_str(), &i_val.second, fielddescriptor.c_str());
0158   }
0159 
0160   for (auto &i_entry : m_UInt64EntryMap)
0161   {
0162     id_set.insert(i_entry.first);
0163     for (auto &i_val : i_entry.second)
0164     {
0165       uint64map.insert(std::make_pair(i_val.first, std::numeric_limits<uint64_t>::max()));
0166     }
0167   }
0168   for (auto &i_val : uint64map)
0169   {
0170     std::string fielddescriptor = i_val.first + "/g";
0171     m_TTree[MultipleEntries]->Branch(i_val.first.c_str(), &i_val.second, fielddescriptor.c_str());
0172   }
0173   // fill ttree
0174   for (auto ids : id_set)
0175   {
0176     intmap["IID"] = ids;
0177     auto fmapiter = m_FloatEntryMap.find(ids);
0178     if (fmapiter != m_FloatEntryMap.end())
0179     {
0180       for (auto &f_val : fmapiter->second)
0181       {
0182         floatmap[f_val.first] = f_val.second;
0183       }
0184     }
0185     auto dmapiter = m_DoubleEntryMap.find(ids);
0186     if (dmapiter != m_DoubleEntryMap.end())
0187     {
0188       for (auto &d_val : dmapiter->second)
0189       {
0190         doublemap[d_val.first] = d_val.second;
0191       }
0192     }
0193     auto imapiter = m_IntEntryMap.find(ids);
0194     if (imapiter != m_IntEntryMap.end())
0195     {
0196       for (auto &i_val : imapiter->second)
0197       {
0198         intmap[i_val.first] = i_val.second;
0199       }
0200     }
0201     auto uint64mapiter = m_UInt64EntryMap.find(ids);
0202     if (uint64mapiter != m_UInt64EntryMap.end())
0203     {
0204       for (auto &uint64_val : uint64mapiter->second)
0205       {
0206         uint64map[uint64_val.first] = uint64_val.second;
0207       }
0208     }
0209     m_TTree[MultipleEntries]->Fill();
0210     for (auto &f_val : floatmap)
0211     {
0212       f_val.second = std::numeric_limits<float>::quiet_NaN();
0213     }
0214     for (auto &f_val : doublemap)
0215     {
0216       f_val.second = std::numeric_limits<double>::quiet_NaN();
0217     }
0218     for (auto &i_val : intmap)
0219     {
0220       i_val.second = std::numeric_limits<int>::min();
0221     }
0222     for (auto &i_val : uint64map)
0223     {
0224       i_val.second = std::numeric_limits<uint64_t>::max();
0225     }
0226   }
0227   return;
0228 }
0229 
0230 void CDBTTree::SetSingleFloatValue(const std::string &name, float value)
0231 {
0232   std::string fieldname = "F" + name;
0233 //  if (!m_SingleFloatEntryMap.contains(fieldname))
0234   // NOLINTNEXTLINE(readability-container-contains)
0235   if (m_SingleFloatEntryMap.find(fieldname) == m_SingleFloatEntryMap.end())
0236   {
0237     if (m_Locked[SingleEntries])
0238     {
0239       std::cout << "Trying to add field " << name << " after another entry was committed" << std::endl;
0240       std::cout << "That does not work, restructure your code" << std::endl;
0241       gSystem->Exit(1);
0242     }
0243     m_SingleFloatEntryMap.insert(std::make_pair(fieldname, value));
0244     return;
0245   }
0246   m_SingleFloatEntryMap[fieldname] = value;
0247 }
0248 
0249 void CDBTTree::SetSingleDoubleValue(const std::string &name, double value)
0250 {
0251   std::string fieldname = "D" + name;
0252 //  if (!m_SingleDoubleEntryMap.contains(fieldname))
0253   // NOLINTNEXTLINE(readability-container-contains)
0254   if (m_SingleDoubleEntryMap.find(fieldname) == m_SingleDoubleEntryMap.end())
0255   {
0256     if (m_Locked[SingleEntries])
0257     {
0258       std::cout << "Trying to add field " << name << " after another entry was committed" << std::endl;
0259       std::cout << "That does not work, restructure your code" << std::endl;
0260       gSystem->Exit(1);
0261     }
0262     m_SingleDoubleEntryMap.insert(std::make_pair(fieldname, value));
0263     return;
0264   }
0265   m_SingleDoubleEntryMap[fieldname] = value;
0266 }
0267 
0268 void CDBTTree::SetSingleIntValue(const std::string &name, int value)
0269 {
0270   std::string fieldname = "I" + name;
0271 //  if (!m_SingleIntEntryMap.contains(fieldname))
0272   // NOLINTNEXTLINE(readability-container-contains)
0273   if (m_SingleIntEntryMap.find(fieldname) == m_SingleIntEntryMap.end())
0274   {
0275     if (m_Locked[SingleEntries])
0276     {
0277       std::cout << "Trying to add field " << name << " after another entry was committed" << std::endl;
0278       std::cout << "That does not work, restructure your code" << std::endl;
0279       gSystem->Exit(1);
0280     }
0281     m_SingleIntEntryMap.insert(std::make_pair(fieldname, value));
0282     return;
0283   }
0284   m_SingleIntEntryMap[fieldname] = value;
0285 }
0286 
0287 void CDBTTree::SetSingleUInt64Value(const std::string &name, uint64_t value)
0288 {
0289   std::string fieldname = "g" + name;
0290 //  if (m_SingleUInt64EntryMap.contains(fieldname))
0291   // NOLINTNEXTLINE(readability-container-contains)
0292   if (m_SingleUInt64EntryMap.find(fieldname) == m_SingleUInt64EntryMap.end())
0293   {
0294     if (m_Locked[SingleEntries])
0295     {
0296       std::cout << "Trying to add field " << name << " after another entry was committed" << std::endl;
0297       std::cout << "That does not work, restructure your code" << std::endl;
0298       gSystem->Exit(1);
0299     }
0300     m_SingleUInt64EntryMap.insert(std::make_pair(fieldname, value));
0301     return;
0302   }
0303   m_SingleUInt64EntryMap[fieldname] = value;
0304 }
0305 
0306 void CDBTTree::CommitSingle()
0307 {
0308   m_Locked[SingleEntries] = true;
0309   return;
0310 }
0311 
0312 void CDBTTree::WriteSingleCDBTTree()
0313 {
0314   m_TTree[SingleEntries] = new TTree(m_TTreeName[SingleEntries].c_str(), m_TTreeName[SingleEntries].c_str());
0315   for (auto &field : m_SingleFloatEntryMap)
0316   {
0317     std::string fielddescriptor = field.first + "/F";
0318     m_TTree[SingleEntries]->Branch(field.first.c_str(), &field.second, fielddescriptor.c_str());
0319   }
0320   for (auto &field : m_SingleDoubleEntryMap)
0321   {
0322     std::string fielddescriptor = field.first + "/D";
0323     m_TTree[SingleEntries]->Branch(field.first.c_str(), &field.second, fielddescriptor.c_str());
0324   }
0325   for (auto &field : m_SingleIntEntryMap)
0326   {
0327     std::string fielddescriptor = field.first + "/I";
0328     m_TTree[SingleEntries]->Branch(field.first.c_str(), &field.second, fielddescriptor.c_str());
0329   }
0330   for (auto &field : m_SingleUInt64EntryMap)
0331   {
0332     std::string fielddescriptor = field.first + "/g";
0333     m_TTree[SingleEntries]->Branch(field.first.c_str(), &field.second, fielddescriptor.c_str());
0334   }
0335 
0336   m_TTree[SingleEntries]->Fill();
0337   return;
0338 }
0339 
0340 void CDBTTree::Print()
0341 {
0342   if (!m_FloatEntryMap.empty())
0343   {
0344     std::cout << "Number of float entries: " << m_FloatEntryMap.size() << std::endl;
0345     for (auto &field : m_FloatEntryMap)
0346     {
0347       std::cout << "ID: " << field.first << std::endl;
0348       for (auto &calibs : field.second)
0349       {
0350         std::string tmpstring = calibs.first;
0351         tmpstring.erase(0, 1);
0352         std::cout << "name " << tmpstring << " value: " << calibs.second << std::endl;
0353       }
0354     }
0355     std::cout << "--------------------------------------------------" << std::endl
0356               << std::endl;
0357   }
0358   if (!m_DoubleEntryMap.empty())
0359   {
0360     std::cout << "Number of double entries: " << m_DoubleEntryMap.size() << std::endl;
0361     for (auto &field : m_DoubleEntryMap)
0362     {
0363       std::cout << "ID: " << field.first << std::endl;
0364       for (auto &calibs : field.second)
0365       {
0366         std::string tmpstring = calibs.first;
0367         tmpstring.erase(0, 1);
0368         std::cout << "name " << tmpstring << " value: " << calibs.second << std::endl;
0369       }
0370     }
0371     std::cout << "--------------------------------------------------" << std::endl
0372               << std::endl;
0373   }
0374   if (!m_IntEntryMap.empty())
0375   {
0376     std::cout << "Number of int entries: " << m_IntEntryMap.size() << std::endl;
0377     for (auto &field : m_IntEntryMap)
0378     {
0379       std::cout << "ID: " << field.first << std::endl;
0380       for (auto &calibs : field.second)
0381       {
0382         std::string tmpstring = calibs.first;
0383         tmpstring.erase(0, 1);
0384         std::cout << "name " << tmpstring << " value: " << calibs.second << std::endl;
0385       }
0386     }
0387   }
0388   if (!m_UInt64EntryMap.empty())
0389   {
0390     std::cout << "Number of uint64 entries: " << m_UInt64EntryMap.size() << std::endl;
0391     for (auto &field : m_UInt64EntryMap)
0392     {
0393       std::cout << "ID: " << field.first << std::endl;
0394       for (auto &calibs : field.second)
0395       {
0396         std::string tmpstring = calibs.first;
0397         tmpstring.erase(0, 1);
0398         std::cout << "name " << tmpstring << " value: " << calibs.second << std::endl;
0399       }
0400     }
0401   }
0402 
0403   if (!m_SingleFloatEntryMap.empty())
0404   {
0405     std::cout << "Number of single float fields: " << m_SingleFloatEntryMap.size() << std::endl;
0406     for (auto &field : m_SingleFloatEntryMap)
0407     {
0408       std::string tmpstring = field.first;
0409       tmpstring.erase(0, 1);
0410       std::cout << tmpstring << " value " << field.second << std::endl;
0411     }
0412   }
0413   if (!m_SingleDoubleEntryMap.empty())
0414   {
0415     std::cout << "Number of single double fields: " << m_SingleDoubleEntryMap.size() << std::endl;
0416     // some acrobatics to restore the old state of cout after changing the precision for double printout
0417     std::ios oldState(nullptr);
0418     oldState.copyfmt(std::cout);
0419     std::cout.precision(std::numeric_limits<double>::max_digits10);
0420     for (auto &field : m_SingleDoubleEntryMap)
0421     {
0422       std::string tmpstring = field.first;
0423       tmpstring.erase(0, 1);
0424       std::cout << tmpstring << " value " << field.second << std::endl;
0425     }
0426     std::cout.copyfmt(oldState);
0427   }
0428   if (!m_SingleIntEntryMap.empty())
0429   {
0430     std::cout << "Number of single int fields: " << m_SingleIntEntryMap.size() << std::endl;
0431     for (auto &field : m_SingleIntEntryMap)
0432     {
0433       std::string tmpstring = field.first;
0434       tmpstring.erase(0, 1);
0435       std::cout << tmpstring << " value " << field.second << std::endl;
0436     }
0437   }
0438   if (!m_SingleUInt64EntryMap.empty())
0439   {
0440     std::cout << "Number of single uint64 fields: " << m_SingleUInt64EntryMap.size() << std::endl;
0441     for (auto &field : m_SingleUInt64EntryMap)
0442     {
0443       std::string tmpstring = field.first;
0444       tmpstring.erase(0, 1);
0445       std::cout << tmpstring << " value " << field.second << std::endl;
0446     }
0447   }
0448 }
0449 
0450 void CDBTTree::WriteCDBTTree()
0451 {
0452   bool empty_single = m_SingleFloatEntryMap.empty() && m_SingleDoubleEntryMap.empty() &&
0453                       m_SingleIntEntryMap.empty() && m_SingleUInt64EntryMap.empty();
0454   if (!empty_single && !m_Locked[SingleEntries])
0455   {
0456     std::cout << "You need to call CDBTTree::CommitSingle() before writing" << std::endl;
0457     return;
0458   }
0459   bool empty_multiple = m_FloatEntryMap.empty() && m_DoubleEntryMap.empty() &&
0460                         m_IntEntryMap.empty() && m_UInt64EntryMap.empty();
0461   if (!empty_multiple && !m_Locked[MultipleEntries])
0462   {
0463     std::cout << "You need to call CDBTTree::Commit() before writing" << std::endl;
0464     return;
0465   }
0466   if (empty_single && empty_multiple)
0467   {
0468     std::cout << "no values to be saved" << std::endl;
0469     return;
0470   }
0471 
0472   std::string currdir = gDirectory->GetPath();
0473 
0474   TFile *f = TFile::Open(m_Filename.c_str(), "RECREATE");
0475   if (!empty_single)
0476   {
0477     WriteSingleCDBTTree();
0478     m_TTree[SingleEntries]->Write();
0479   }
0480   if (!empty_multiple)
0481   {
0482     WriteMultipleCDBTTree();
0483     m_TTree[MultipleEntries]->Write();
0484   }
0485   f->Close();
0486 
0487   gROOT->cd(currdir.c_str());  // restore previous directory
0488 }
0489 
0490 void CDBTTree::LoadCalibrations()
0491 {
0492   std::string currdir = gDirectory->GetPath();
0493 
0494   if (m_Filename.empty())
0495   {
0496     std::cout << PHWHERE << "No filename given in ctor or via SetFilename()" << std::endl;
0497     gSystem->Exit(1);
0498     exit(1);
0499   }
0500   TFile *f = TFile::Open(m_Filename.c_str());
0501   if (!f)
0502   {
0503     std::cout << PHWHERE << "TFile::Open(" << m_Filename << ") failed" << std::endl;
0504     gSystem->Exit(1);
0505     exit(1);
0506   }
0507   f->GetObject(m_TTreeName[SingleEntries].c_str(), m_TTree[SingleEntries]);
0508   f->GetObject(m_TTreeName[MultipleEntries].c_str(), m_TTree[MultipleEntries]);
0509   if (m_TTree[SingleEntries] != nullptr)
0510   {
0511     TObjArray *branches = m_TTree[SingleEntries]->GetListOfBranches();
0512     TIter iter(branches);
0513     while (TBranch *thisbranch = static_cast<TBranch *>(iter.Next()))
0514     {
0515       // this convoluted expression returns the data type of a split branch
0516       std::string DataType = thisbranch->GetLeaf(thisbranch->GetName())->GetTypeName();
0517       if (DataType == "Float_t")
0518       {
0519         auto itermap = m_SingleFloatEntryMap.insert(std::make_pair(thisbranch->GetName(), std::numeric_limits<float>::quiet_NaN()));
0520         m_TTree[SingleEntries]->SetBranchAddress(thisbranch->GetName(), &(itermap.first)->second);
0521       }
0522       else if (DataType == "Double_t")
0523       {
0524         auto itermap = m_SingleDoubleEntryMap.insert(std::make_pair(thisbranch->GetName(), std::numeric_limits<double>::quiet_NaN()));
0525         m_TTree[SingleEntries]->SetBranchAddress(thisbranch->GetName(), &(itermap.first)->second);
0526       }
0527       else if (DataType == "Int_t")
0528       {
0529         auto itermap = m_SingleIntEntryMap.insert(std::make_pair(thisbranch->GetName(), -99999));
0530         m_TTree[SingleEntries]->SetBranchAddress(thisbranch->GetName(), &(itermap.first)->second);
0531       }
0532       else if (DataType == "ULong_t")
0533       {
0534         auto itermap = m_SingleUInt64EntryMap.insert(std::make_pair(thisbranch->GetName(), std::numeric_limits<uint64_t>::max()));
0535         m_TTree[SingleEntries]->SetBranchAddress(thisbranch->GetName(), &(itermap.first)->second);
0536       }
0537       else
0538       {
0539         std::cout << __PRETTY_FUNCTION__ << " data type " << DataType
0540                   << " in " << m_TTree[SingleEntries]->GetName()
0541                   << " from " << f->GetName()
0542                   << " not implemented" << std::endl;
0543         gSystem->Exit(1);
0544       }
0545     }
0546     m_TTree[SingleEntries]->GetEntry(0);
0547   }
0548   if (m_TTree[MultipleEntries] != nullptr)
0549   {
0550     TObjArray *branches = m_TTree[MultipleEntries]->GetListOfBranches();
0551     TIter iter(branches);
0552     std::map<std::string, float> floatvalmap;
0553     std::map<std::string, double> doublevalmap;
0554     std::map<std::string, int> intvalmap;
0555     std::map<std::string, uint64_t> uint64valmap;
0556     while (TBranch *thisbranch = static_cast<TBranch *>(iter.Next()))
0557     {
0558       // this convoluted expression returns the data type of a split branch
0559       std::string DataType = thisbranch->GetLeaf(thisbranch->GetName())->GetTypeName();
0560       if (DataType == "Float_t")
0561       {
0562         auto itermap = floatvalmap.insert(std::make_pair(thisbranch->GetName(), std::numeric_limits<float>::quiet_NaN()));
0563         m_TTree[MultipleEntries]->SetBranchAddress(thisbranch->GetName(), &(itermap.first)->second);
0564       }
0565       if (DataType == "Double_t")
0566       {
0567         auto itermap = doublevalmap.insert(std::make_pair(thisbranch->GetName(), std::numeric_limits<double>::quiet_NaN()));
0568         m_TTree[MultipleEntries]->SetBranchAddress(thisbranch->GetName(), &(itermap.first)->second);
0569       }
0570       if (DataType == "Int_t")
0571       {
0572         auto itermap = intvalmap.insert(std::make_pair(thisbranch->GetName(), std::numeric_limits<int>::min()));
0573         m_TTree[MultipleEntries]->SetBranchAddress(thisbranch->GetName(), &(itermap.first)->second);
0574       }
0575       if (DataType == "ULong_t")
0576       {
0577         auto itermap = uint64valmap.insert(std::make_pair(thisbranch->GetName(), std::numeric_limits<uint64_t>::max()));
0578         m_TTree[MultipleEntries]->SetBranchAddress(thisbranch->GetName(), &(itermap.first)->second);
0579       }
0580     }
0581     for (auto entry = 0; entry < m_TTree[MultipleEntries]->GetEntries(); ++entry)
0582     {
0583       for (auto &field : floatvalmap)
0584       {
0585         field.second = std::numeric_limits<float>::quiet_NaN();
0586       }
0587       for (auto &field : doublevalmap)
0588       {
0589         field.second = std::numeric_limits<double>::quiet_NaN();
0590       }
0591       for (auto &field : intvalmap)
0592       {
0593         field.second = std::numeric_limits<int>::min();
0594       }
0595       for (auto &field : uint64valmap)
0596       {
0597         field.second = std::numeric_limits<uint64_t>::max();
0598       }
0599       m_TTree[MultipleEntries]->GetEntry(entry);
0600       int ID = intvalmap.find("IID")->second;
0601       std::map<std::string, float> tmp_floatvalmap;
0602       for (auto &field : floatvalmap)
0603       {
0604         if (!std::isnan(field.second))
0605         {
0606           tmp_floatvalmap.insert(std::make_pair(field.first, field.second));
0607         }
0608       }
0609       if (!tmp_floatvalmap.empty())
0610       {
0611         m_FloatEntryMap.insert(std::make_pair(ID, tmp_floatvalmap));
0612       }
0613 
0614       std::map<std::string, double> tmp_doublevalmap;
0615       for (auto &field : doublevalmap)
0616       {
0617         if (!std::isnan(field.second))
0618         {
0619           tmp_doublevalmap.insert(std::make_pair(field.first, field.second));
0620         }
0621       }
0622       if (!tmp_doublevalmap.empty())
0623       {
0624         m_DoubleEntryMap.insert(std::make_pair(ID, tmp_doublevalmap));
0625       }
0626 
0627       std::map<std::string, int> tmp_intvalmap;
0628       for (auto &field : intvalmap)
0629       {
0630         if (field.second != std::numeric_limits<int>::min() && field.first != "IID")
0631         {
0632           tmp_intvalmap.insert(std::make_pair(field.first, field.second));
0633         }
0634       }
0635       if (!tmp_intvalmap.empty())
0636       {
0637         m_IntEntryMap.insert(std::make_pair(ID, tmp_intvalmap));
0638       }
0639 
0640       std::map<std::string, uint64_t> tmp_uint64valmap;
0641       for (auto &field : uint64valmap)
0642       {
0643         if (field.second != std::numeric_limits<uint64_t>::max())
0644         {
0645           tmp_uint64valmap.insert(std::make_pair(field.first, field.second));
0646         }
0647       }
0648       if (!tmp_uint64valmap.empty())
0649       {
0650         m_UInt64EntryMap.insert(std::make_pair(ID, tmp_uint64valmap));
0651       }
0652     }
0653   }
0654   for (auto *ttree : m_TTree)
0655   {
0656     delete ttree;
0657     ttree = nullptr;
0658   }
0659   f->Close();
0660   gROOT->cd(currdir.c_str());  // restore previous directory
0661 }
0662 
0663 float CDBTTree::GetSingleFloatValue(const std::string &name, int verbose)
0664 {
0665   if (m_SingleFloatEntryMap.empty())
0666   {
0667     LoadCalibrations();
0668   }
0669   std::string fieldname = "F" + name;
0670   auto singleiter = m_SingleFloatEntryMap.find(fieldname);
0671   if (singleiter == m_SingleFloatEntryMap.end())
0672   {
0673     if (verbosity > 0 || verbose > 0)
0674     {
0675       std::cout << "Could not find " << name << " in single float calibrations" << std::endl;
0676       std::cout << "Existing values:" << std::endl;
0677       for (auto &eiter : m_SingleFloatEntryMap)
0678       {
0679         std::string tmpstring = eiter.first;
0680         tmpstring.erase(0, 1);
0681         std::cout << "name : " << tmpstring << ", value " << eiter.second
0682                   << std::endl;
0683       }
0684     }
0685     return std::numeric_limits<float>::quiet_NaN();
0686   }
0687   return singleiter->second;
0688 }
0689 
0690 float CDBTTree::GetFloatValue(int channel, const std::string &name, int verbose)
0691 {
0692   if (m_FloatEntryMap.empty())
0693   {
0694     LoadCalibrations();
0695   }
0696   auto channelmapiter = m_FloatEntryMap.find(channel);
0697   if (channelmapiter == m_FloatEntryMap.end())
0698   {
0699     if (verbosity > 0 || verbose > 0)
0700     {
0701       std::cout << PHWHERE << " Could not find channel " << channel
0702                 << " for " << name << " in float calibrations" << std::endl;
0703     }
0704     return std::numeric_limits<float>::quiet_NaN();
0705   }
0706   std::string fieldname = "F" + name;
0707   auto calibiter = channelmapiter->second.find(fieldname);
0708   if (calibiter == channelmapiter->second.end())
0709   {
0710     if (verbosity > 0 || verbose > 0)
0711     {
0712       std::cout << "Could not find " << name << " among float calibrations of channel " << channel << std::endl;
0713     }
0714     return std::numeric_limits<float>::quiet_NaN();
0715   }
0716   return calibiter->second;
0717 }
0718 
0719 double CDBTTree::GetSingleDoubleValue(const std::string &name, int verbose)
0720 {
0721   if (m_SingleDoubleEntryMap.empty())
0722   {
0723     LoadCalibrations();
0724   }
0725   std::string fieldname = "D" + name;
0726   auto singleiter = m_SingleDoubleEntryMap.find(fieldname);
0727   if (singleiter == m_SingleDoubleEntryMap.end())
0728   {
0729     if (verbosity > 0 || verbose > 0)
0730     {
0731       std::cout << "Could not find " << name << " in single double calibrations" << std::endl;
0732       std::cout << "Existing values:" << std::endl;
0733       for (auto &eiter : m_SingleDoubleEntryMap)
0734       {
0735         std::string tmpstring = eiter.first;
0736         tmpstring.erase(0, 1);
0737         std::cout << "name : " << tmpstring << ", value " << eiter.second
0738                   << std::endl;
0739       }
0740     }
0741     return std::numeric_limits<double>::quiet_NaN();
0742   }
0743   return singleiter->second;
0744 }
0745 
0746 double CDBTTree::GetDoubleValue(int channel, const std::string &name, int verbose)
0747 {
0748   if (m_DoubleEntryMap.empty())
0749   {
0750     LoadCalibrations();
0751   }
0752   auto channelmapiter = m_DoubleEntryMap.find(channel);
0753   if (channelmapiter == m_DoubleEntryMap.end())
0754   {
0755     if (verbosity > 0 || verbose > 0)
0756     {
0757       std::cout << PHWHERE << " Could not find channel " << channel
0758                 << " for " << name << " in double calibrations" << std::endl;
0759     }
0760     return std::numeric_limits<double>::quiet_NaN();
0761   }
0762   std::string fieldname = "D" + name;
0763   auto calibiter = channelmapiter->second.find(fieldname);
0764   if (calibiter == channelmapiter->second.end())
0765   {
0766     if (verbosity > 0 || verbose > 0)
0767     {
0768       std::cout << "Could not find " << name << " among double calibrations for channel " << channel << std::endl;
0769     }
0770     return std::numeric_limits<double>::quiet_NaN();
0771   }
0772   return calibiter->second;
0773 }
0774 
0775 int CDBTTree::GetSingleIntValue(const std::string &name, int verbose)
0776 {
0777   if (m_SingleIntEntryMap.empty())
0778   {
0779     LoadCalibrations();
0780   }
0781   std::string fieldname = "I" + name;
0782   auto singleiter = m_SingleIntEntryMap.find(fieldname);
0783   if (singleiter == m_SingleIntEntryMap.end())
0784   {
0785     if (verbosity > 0 || verbose > 0)
0786     {
0787       std::cout << "Could not find " << name << " in single int calibrations" << std::endl;
0788       std::cout << "Existing values:" << std::endl;
0789       for (auto &eiter : m_SingleIntEntryMap)
0790       {
0791         std::string tmpstring = eiter.first;
0792         tmpstring.erase(0, 1);
0793         std::cout << "name : " << tmpstring << ", value " << eiter.second
0794                   << std::endl;
0795       }
0796     }
0797     return std::numeric_limits<int>::min();
0798   }
0799   return singleiter->second;
0800 }
0801 
0802 int CDBTTree::GetIntValue(int channel, const std::string &name, int verbose)
0803 {
0804   if (m_IntEntryMap.empty())
0805   {
0806     LoadCalibrations();
0807   }
0808   auto channelmapiter = m_IntEntryMap.find(channel);
0809   if (channelmapiter == m_IntEntryMap.end())
0810   {
0811     if (verbosity > 0 || verbose > 0)
0812     {
0813       std::cout << PHWHERE << " Could not find channel " << channel
0814                 << " for " << name << " in int calibrations" << std::endl;
0815     }
0816     return std::numeric_limits<int>::min();
0817   }
0818   std::string fieldname = "I" + name;
0819   auto calibiter = channelmapiter->second.find(fieldname);
0820   if (calibiter == channelmapiter->second.end())
0821   {
0822     if (verbosity > 0 || verbose > 0)
0823     {
0824       std::cout << "Could not find " << name << " among int calibrations for channel " << channel << std::endl;
0825     }
0826     return std::numeric_limits<int>::min();
0827   }
0828   return calibiter->second;
0829 }
0830 
0831 uint64_t CDBTTree::GetSingleUInt64Value(const std::string &name, int verbose)
0832 {
0833   if (m_SingleUInt64EntryMap.empty())
0834   {
0835     LoadCalibrations();
0836   }
0837   std::string fieldname = "g" + name;
0838   auto singleiter = m_SingleUInt64EntryMap.find(fieldname);
0839   if (singleiter == m_SingleUInt64EntryMap.end())
0840   {
0841     if (verbosity > 0 || verbose > 0)
0842     {
0843       std::cout << "Could not find " << name << " in single uint64 calibrations" << std::endl;
0844       std::cout << "Existing values:" << std::endl;
0845       for (auto &eiter : m_SingleUInt64EntryMap)
0846       {
0847         std::string tmpstring = eiter.first;
0848         tmpstring.erase(0, 1);
0849         std::cout << "name : " << tmpstring << ", value " << eiter.second
0850                   << std::endl;
0851       }
0852     }
0853     return std::numeric_limits<uint64_t>::max();
0854   }
0855   return singleiter->second;
0856 }
0857 
0858 uint64_t CDBTTree::GetUInt64Value(int channel, const std::string &name, int verbose)
0859 {
0860   if (m_UInt64EntryMap.empty())
0861   {
0862     LoadCalibrations();
0863   }
0864   auto channelmapiter = m_UInt64EntryMap.find(channel);
0865   if (channelmapiter == m_UInt64EntryMap.end())
0866   {
0867     if (verbosity > 0 || verbose > 0)
0868     {
0869       std::cout << "Could not find channel " << channel << " in unint64 calibrations" << std::endl;
0870     }
0871     return std::numeric_limits<uint64_t>::max();
0872   }
0873   std::string fieldname = "g" + name;
0874   auto calibiter = channelmapiter->second.find(fieldname);
0875   if (calibiter == channelmapiter->second.end())
0876   {
0877     if (verbosity > 0 || verbose > 0)
0878     {
0879       std::cout << PHWHERE << " Could not find channel " << channel
0880                 << " for " << name << " in uint64_t calibrations" << std::endl;
0881     }
0882     return std::numeric_limits<uint64_t>::max();
0883   }
0884   return calibiter->second;
0885 }