Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHParameters.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHParameters.cc
1 #include "PHParameters.h"
2 
3 #include <pdbcalbase/PdbApplication.h>
4 #include <pdbcalbase/PdbBankID.h>
5 #include <pdbcalbase/PdbBankManager.h>
6 #include <pdbcalbase/PdbCalBank.h>
7 #include <pdbcalbase/PdbParameterMap.h>
8 #include <pdbcalbase/PdbParameterMapContainer.h>
9 
11 
12 #include <phool/PHCompositeNode.h>
13 #include <phool/PHIODataNode.h>
14 #include <phool/PHTimeStamp.h>
15 #include <phool/getClass.h>
16 #include <phool/phool.h>
17 
18 #include <TBufferXML.h>
19 #include <TFile.h>
20 #include <TSystem.h>
21 
22 #include <boost/foreach.hpp>
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
25 #include <boost/functional/hash.hpp>
26 #pragma GCC diagnostic pop
27 #include <boost/lexical_cast.hpp>
28 #include <boost/tokenizer.hpp>
29 // stacktrace gives a shadow warning
30 #pragma GCC diagnostic push
31 #pragma GCC diagnostic ignored "-Wshadow"
32 #include <boost/stacktrace.hpp>
33 #pragma GCC diagnostic pop
34 
35 #include <unistd.h>
36 #include <algorithm>
37 #include <cassert>
38 #include <cctype>
39 #include <cstdlib>
40 #include <ctime>
41 #include <filesystem>
42 #include <iostream>
43 #include <iterator> // for reverse_iterator
44 #include <sstream>
45 
47  : m_Detector(name)
48 {
49  FillFrom(&params);
50 }
51 
53 {
54  m_DoubleParMap.clear();
55  m_IntParMap.clear();
56  m_StringParMap.clear();
57 }
58 
60 {
61  m_DoubleParMap.clear();
62  m_IntParMap.clear();
63  m_StringParMap.clear();
64 }
65 
66 void PHParameters::set_int_param(const std::string &name, const int ival)
67 {
68  m_IntParMap[name] = ival;
69 }
70 
72 {
73  if (m_IntParMap.find(name) != m_IntParMap.end())
74  {
75  return m_IntParMap.find(name)->second;
76  }
77  std::cout << PHWHERE << " integer parameter " << name
78  << " does not exist (forgot to set?)" << std::endl;
79  std::cout << "Here is the stacktrace: " << std::endl;
80  std::cout << boost::stacktrace::stacktrace();
81  std::cout << std::endl
82  << "DO NOT PANIC - this is not a segfault" << std::endl;
83  std::cout << "Check the stacktrace for the guilty party (typically #2)" << std::endl;
84  gSystem->Exit(1);
85  exit(1);
86 }
87 
89 {
90  if (m_IntParMap.find(name) != m_IntParMap.end())
91  {
92  return true;
93  }
94  return false;
95 }
96 
98 {
99  std::cout << "int parameters: " << std::endl;
100  for (const auto &iter : m_IntParMap)
101  {
102  std::cout << iter.first << ": " << iter.second << std::endl;
103  }
104  return;
105 }
106 
107 void PHParameters::set_double_param(const std::string &name, const double dval)
108 {
109  m_DoubleParMap[name] = dval;
110 }
111 
112 double
114 {
115  if (m_DoubleParMap.find(name) != m_DoubleParMap.end())
116  {
117  return m_DoubleParMap.find(name)->second;
118  }
119  std::cout << PHWHERE << " double parameter " << name
120  << " does not exist (forgot to set?)" << std::endl;
121  std::cout << "Here is the stacktrace: " << std::endl;
122  std::cout << boost::stacktrace::stacktrace();
123  std::cout << std::endl
124  << "DO NOT PANIC - this is not a segfault" << std::endl;
125  std::cout << "Check the stacktrace for the guilty party (typically #2)" << std::endl;
126 
127  gSystem->Exit(1);
128  exit(1);
129 }
130 
132 {
133  if (m_DoubleParMap.find(name) != m_DoubleParMap.end())
134  {
135  return true;
136  }
137  return false;
138 }
139 
140 void PHParameters::Print(Option_t * /*option*/) const
141 {
142  std::cout << "Parameters for " << m_Detector << std::endl;
143  printint();
144  printdouble();
145  printstring();
146  return;
147 }
148 
149 size_t
151 {
152  size_t seed = 0;
153 
154  for (const auto &iter : m_DoubleParMap)
155  {
156  // size_t seed = 0;
157  boost::hash_combine(seed, iter.first);
158  boost::hash_combine(seed, iter.second);
159  // std::cout << iter->first << ": " << iter->second <<" -> "<<seed<< std::endl;
160  }
161 
162  for (const auto &iter : m_IntParMap)
163  {
164  // size_t seed = 0;
165  boost::hash_combine(seed, iter.first);
166  boost::hash_combine(seed, iter.second);
167  // std::cout << iter->first << ": " << iter->second <<" -> "<<seed<< std::endl;
168  }
169 
170  for (const auto &iter : m_StringParMap)
171  {
172  // size_t seed = 0;
173  boost::hash_combine(seed, iter.first);
174  boost::hash_combine(seed, iter.second);
175  // std::cout << iter->first << ": " << iter->second <<" -> "<<seed<< std::endl;
176  }
177 
178  return seed;
179 }
180 
182 {
183  std::cout << "double parameters: " << std::endl;
184  for (const auto &iter : m_DoubleParMap)
185  {
186  std::cout << iter.first << ": " << iter.second << std::endl;
187  }
188  return;
189 }
190 
192 {
194 }
195 
198 {
199  if (m_StringParMap.find(name) != m_StringParMap.end())
200  {
201  return m_StringParMap.find(name)->second;
202  }
203  std::cout << PHWHERE << " string parameter " << name
204  << " does not exist (forgot to set?)" << std::endl;
205  std::cout << "Here is the stacktrace: " << std::endl;
206  std::cout << boost::stacktrace::stacktrace();
207  std::cout << std::endl
208  << "DO NOT PANIC - this is not a segfault" << std::endl;
209  std::cout << "Check the stacktrace for the guilty party (typically #2)" << std::endl;
210  gSystem->Exit(1);
211  exit(1);
212 }
213 
215 {
216  if (m_StringParMap.find(name) != m_StringParMap.end())
217  {
218  return true;
219  }
220  return false;
221 }
222 
224 {
225  std::cout << "string parameters: " << std::endl;
226  for (const auto &iter : m_StringParMap)
227  {
228  std::cout << iter.first << ": " << iter.second << std::endl;
229  }
230  return;
231 }
232 
234 {
235  assert(saveparams);
236 
237  std::pair<std::map<const std::string, double>::const_iterator,
238  std::map<const std::string, double>::const_iterator>
239  begin_end_d = saveparams->get_dparam_iters();
240  for (std::map<const std::string, double>::const_iterator iter = begin_end_d.first;
241  iter != begin_end_d.second; ++iter)
242  {
243  m_DoubleParMap[iter->first] = iter->second;
244  }
245  std::pair<std::map<const std::string, int>::const_iterator,
246  std::map<const std::string, int>::const_iterator>
247  begin_end_i = saveparams->get_iparam_iters();
248  for (std::map<const std::string, int>::const_iterator iter = begin_end_i.first;
249  iter != begin_end_i.second; ++iter)
250  {
251  m_IntParMap[iter->first] = iter->second;
252  }
253  std::pair<std::map<const std::string, std::string>::const_iterator,
254  std::map<const std::string, std::string>::const_iterator>
255  begin_end_s = saveparams->get_cparam_iters();
256  for (std::map<const std::string, std::string>::const_iterator iter = begin_end_s.first;
257  iter != begin_end_s.second; ++iter)
258  {
259  m_StringParMap[iter->first] = iter->second;
260  }
261 
262  return;
263 }
264 
265 void PHParameters::FillFrom(const PdbParameterMapContainer *saveparamcontainer, const int detid)
266 {
267  // assert(saveparamcontainer != nullptr);
268 
269  const PdbParameterMap *saveparams = saveparamcontainer->GetParameters(detid);
270  if (!saveparams)
271  {
272  return;
273  }
274  std::pair<std::map<const std::string, double>::const_iterator,
275  std::map<const std::string, double>::const_iterator>
276  begin_end_d = saveparams->get_dparam_iters();
277  for (std::map<const std::string, double>::const_iterator iter = begin_end_d.first;
278  iter != begin_end_d.second; ++iter)
279  {
280  m_DoubleParMap[iter->first] = iter->second;
281  }
282  std::pair<std::map<const std::string, int>::const_iterator,
283  std::map<const std::string, int>::const_iterator>
284  begin_end_i = saveparams->get_iparam_iters();
285  for (std::map<const std::string, int>::const_iterator iter = begin_end_i.first;
286  iter != begin_end_i.second; ++iter)
287  {
288  m_IntParMap[iter->first] = iter->second;
289  }
290  std::pair<std::map<const std::string, std::string>::const_iterator,
291  std::map<const std::string, std::string>::const_iterator>
292  begin_end_s = saveparams->get_cparam_iters();
293  for (std::map<const std::string, std::string>::const_iterator iter = begin_end_s.first;
294  iter != begin_end_s.second; ++iter)
295  {
296  m_StringParMap[iter->first] = iter->second;
297  }
298 
299  return;
300 }
301 
302 void PHParameters::FillFrom(const PHParameters *saveparams)
303 {
304  assert(saveparams);
305 
306  for (const auto &iter : saveparams->m_DoubleParMap)
307  {
308  m_DoubleParMap[iter.first] = iter.second;
309  }
310 
311  for (const auto &iter : saveparams->m_IntParMap)
312  {
313  m_IntParMap[iter.first] = iter.second;
314  }
315 
316  for (const auto &iter : saveparams->m_StringParMap)
317  {
318  m_StringParMap[iter.first] = iter.second;
319  }
320  return;
321 }
322 
324 {
325  // write itself since this class is fine with saving by root
326  PdbParameterMap *nodeparams = findNode::getClass<PdbParameterMap>(topNode, nodename);
327  if (!nodeparams)
328  {
329  nodeparams = new PdbParameterMap();
330  PHIODataNode<PdbParameterMap> *newnode = new PHIODataNode<PdbParameterMap>(nodeparams, nodename);
331  topNode->addNode(newnode);
332  }
333  else
334  {
335  nodeparams->Reset(); // just clear previous content in case variables were deleted
336  }
337  CopyToPdbParameterMap(nodeparams);
338  return;
339 }
340 
342 {
343  PdbParameterMap *nodeparams = findNode::getClass<PdbParameterMap>(topNode, nodename);
344  if (!nodeparams)
345  {
346  std::cout << PHWHERE << " could not find PdbParameterMap " << nodename
347  << " which must exist" << std::endl;
348  gSystem->Exit(1);
349  }
350  CopyToPdbParameterMap(nodeparams);
351  return;
352 }
353 
354 void PHParameters::SaveToNodeTree(PHCompositeNode *topNode, const std::string &nodename, const int detid)
355 {
356  // write itself since this class is fine with saving by root
357  PdbParameterMapContainer *nodeparamcontainer = findNode::getClass<PdbParameterMapContainer>(topNode, nodename);
358  if (!nodeparamcontainer)
359  {
360  nodeparamcontainer = new PdbParameterMapContainer();
362  new PHIODataNode<PdbParameterMapContainer>(nodeparamcontainer, nodename);
363  topNode->addNode(newnode);
364  }
365  PdbParameterMap *nodeparams = nodeparamcontainer->GetParametersToModify(detid);
366  if (nodeparams)
367  {
368  nodeparams->Reset();
369  }
370  else
371  {
372  nodeparams = new PdbParameterMap();
373  nodeparamcontainer->AddPdbParameterMap(detid, nodeparams);
374  }
375  CopyToPdbParameterMap(nodeparams);
376  return;
377 }
378 
379 void PHParameters::UpdateNodeTree(PHCompositeNode *topNode, const std::string &nodename, const int detid)
380 {
381  PdbParameterMapContainer *nodeparamcontainer = findNode::getClass<PdbParameterMapContainer>(topNode, nodename);
382  if (!nodeparamcontainer)
383  {
384  std::cout << PHWHERE << " could not find PdbParameterMapContainer " << nodename
385  << " which must exist" << std::endl;
386  gSystem->Exit(1);
387  }
388  PdbParameterMap *nodeparams = nodeparamcontainer->GetParametersToModify(detid);
389  if (!nodeparams)
390  {
391  std::cout << PHWHERE << " could not find PdbParameterMap for detector " << detid
392  << " which must exist" << std::endl;
393  gSystem->Exit(1);
394  }
395  CopyToPdbParameterMap(nodeparams);
396  return;
397 }
398 
400 {
401  PdbBankManager *bankManager = PdbBankManager::instance();
402  PdbApplication *application = bankManager->getApplication();
403  if (!application->startUpdate())
404  {
405  std::cout << PHWHERE << " Aborting, Database not writable" << std::endl;
406  application->abort();
407  gSystem->Exit(1);
408  exit(1);
409  }
410 
411  // Make a bank ID...
412  PdbBankID bankID(0); // lets start at zero
413  PHTimeStamp TStart(0);
414  PHTimeStamp TStop(0xffffffff);
415 
416  std::string tablename = m_Detector + "_geoparams";
417  std::transform(tablename.begin(), tablename.end(), tablename.begin(), ::tolower);
418  PdbCalBank *NewBank = bankManager->createBank("PdbParameterMapBank", bankID,
419  "Geometry Parameters", TStart, TStop, tablename);
420  if (NewBank)
421  {
422  NewBank->setLength(1);
423  PdbParameterMap *myparm = (PdbParameterMap *) &NewBank->getEntry(0);
424  CopyToPdbParameterMap(myparm);
425  application->commit(NewBank);
426  delete NewBank;
427  }
428  else
429  {
430  std::cout << PHWHERE " Committing to DB failed" << std::endl;
431  return -1;
432  }
433  return 0;
434 }
435 
436 int PHParameters::ReadFromDB(const std::string &name, const int detid)
437 {
438  PdbBankManager *bankManager = PdbBankManager::instance();
439  PdbApplication *application = bankManager->getApplication();
440  if (!application->startRead())
441  {
442  std::cout << PHWHERE << " Aborting, Database not readable" << std::endl;
443  application->abort();
444  gSystem->Exit(1);
445  exit(1);
446  }
447 
448  // Make a bank ID...
449  PdbBankID bankID(0); // lets start at zero
450  PHTimeStamp TSearch(10);
451 
452  std::string tablename = name + "_geoparams";
453  std::transform(tablename.begin(), tablename.end(), tablename.begin(), ::tolower);
454  PdbCalBank *NewBank = bankManager->fetchBank("PdbParameterMapContainerBank", bankID, tablename, TSearch);
455  if (NewBank)
456  {
457  PdbParameterMapContainer *myparm = (PdbParameterMapContainer *) &NewBank->getEntry(0);
458  FillFrom(myparm, detid);
459  delete NewBank;
460  }
461  else
462  {
463  std::cout << PHWHERE " Reading from DB failed" << std::endl;
464  return -1;
465  }
466  return 0;
467 }
468 
470 {
471  PdbBankManager *bankManager = PdbBankManager::instance();
472  PdbApplication *application = bankManager->getApplication();
473  if (!application->startRead())
474  {
475  std::cout << PHWHERE << " Aborting, Database not readable" << std::endl;
476  application->abort();
477  gSystem->Exit(1);
478  exit(1);
479  }
480 
481  // Make a bank ID...
482  PdbBankID bankID(0); // lets start at zero
483  PHTimeStamp TSearch(10);
484 
485  std::string tablename = m_Detector + "_geoparams";
486  std::transform(tablename.begin(), tablename.end(), tablename.begin(), ::tolower);
487  PdbCalBank *NewBank = bankManager->fetchBank("PdbParameterMapBank", bankID,
488  tablename, TSearch);
489  if (NewBank)
490  {
491  PdbParameterMap *myparm = (PdbParameterMap *) &NewBank->getEntry(0);
492  FillFrom(myparm);
493  delete NewBank;
494  }
495  else
496  {
497  std::cout << PHWHERE " Reading from DB failed" << std::endl;
498  return -1;
499  }
500  return 0;
501 }
502 
504 {
506  TFile *f = TFile::Open(url.c_str());
507  if (!f)
508  {
509  std::cout << "could not open " << url
510  << " for domain " << domain << std::endl;
511  gSystem->Exit(1);
512  }
513  PdbParameterMap *myparm = static_cast<PdbParameterMap *>(f->Get("PdbParameterMap"));
514  if (!myparm)
515  {
516  std::cout << "could not get PdbParameterMap from " << url << std::endl;
517  gSystem->Exit(1);
518  }
519  FillFrom(myparm);
520  delete myparm;
521  delete f;
522  return 0;
523 }
524 
526 {
527  PdbParameterMap *myparm = new PdbParameterMap();
528  CopyToPdbParameterMap(myparm);
529  TFile *f = TFile::Open(filename.c_str(), "recreate");
530  myparm->Write();
531  delete f;
532  delete myparm;
533  return 0;
534 }
535 
537 {
538  std::ostringstream fullpath;
539  std::ostringstream fnamestream;
540  PdbBankID bankID(0); // lets start at zero
541  PHTimeStamp TStart(0);
542  PHTimeStamp TStop(0xffffffff);
543  fullpath << dir;
544  // add / if directory lacks ending /
545  if (*(dir.rbegin()) != '/')
546  {
547  fullpath << "/";
548  }
549  fnamestream << m_Detector << "_geoparams"
550  << "-" << bankID.getInternalValue()
551  << "-" << TStart.getTics() << "-" << TStop.getTics() << "-" << time(nullptr)
552  << "." << extension;
553  std::string fname = fnamestream.str();
554  std::transform(fname.begin(), fname.end(), fname.begin(), ::tolower);
555  fullpath << fname;
556 
557  std::cout << "PHParameters::WriteToFile - save to " << fullpath.str() << std::endl;
558 
559  PdbParameterMap *myparm = new PdbParameterMap();
560  CopyToPdbParameterMap(myparm);
561  TFile *f = TFile::Open(fullpath.str().c_str(), "recreate");
562  // force xml file writing to use extended precision shown experimentally
563  // to not modify input parameters (.17g)
564  std::string floatformat = TBufferXML::GetFloatFormat();
565  TBufferXML::SetFloatFormat("%.17g"); // for IEEE 754 double
566  myparm->Write();
567  delete f;
568  // restore previous xml float format
569  TBufferXML::SetFloatFormat(floatformat.c_str());
570  std::cout << "sleeping 1 second to prevent duplicate inserttimes" << std::endl;
571  sleep(1);
572  return 0;
573 }
574 
575 int PHParameters::ReadFromFile(const std::string &name, const std::string &extension, const int detid, const int issuper, const std::string &dir)
576 {
577  PHTimeStamp TSearch(10);
578  PdbBankID bankID(0);
579  std::ostringstream fnamestream;
580  fnamestream << name << "_geoparams"
581  << "-" << bankID.getInternalValue();
582  std::string fileprefix = fnamestream.str();
583  std::transform(fileprefix.begin(), fileprefix.end(), fileprefix.begin(),
584  ::tolower);
585  std::filesystem::path targetDir(dir);
586 
587  std::filesystem::recursive_directory_iterator diriter(targetDir), eod;
588  boost::char_separator<char> sep("-.");
589  std::map<unsigned int, std::string> calibfiles;
590  BOOST_FOREACH (std::filesystem::path const &i, std::make_pair(diriter, eod))
591  {
592  if (is_regular_file(i))
593  {
594  // leaf() gives the filename without path,
595  // the string.compare(0...) checks if the filename starts with fileprefix
596  // if not coninue
597  std::string basename = i.filename().string();
598  if (basename.compare(0, fileprefix.size(), fileprefix) != 0)
599  {
600  continue;
601  }
602  // extension() contains the . - like .xml, so we
603  // just compare the extensions instead of !=
604  // and check that the size makes sense
605  if (i.extension().string().find(extension) == std::string::npos || i.extension().string().size() != extension.size() + 1)
606  {
607  continue;
608  }
609  boost::tokenizer<boost::char_separator<char> > tok(basename, sep);
610  boost::tokenizer<boost::char_separator<char> >::iterator iter =
611  tok.begin();
612  ++iter; // that skips the file prefix excluding bank id
613  ++iter; // that skips the bank id we checked already as part of the filename
614  PHTimeStamp TStart(ConvertStringToUint(*iter));
615  if (TSearch < TStart)
616  {
617  continue;
618  }
619  ++iter;
620  PHTimeStamp TStop(ConvertStringToUint(*iter));
621  if (TSearch >= TStop)
622  {
623  continue;
624  }
625  ++iter;
626  calibfiles[ConvertStringToUint(*iter)] = i.string();
627  }
628  }
629  if (calibfiles.empty())
630  {
631  std::cout << "No calibration file like " << dir << "/" << fileprefix << " found" << std::endl;
632  gSystem->Exit(1);
633  exit(1);
634  }
635  std::cout << "PHParameters::ReadFromFile - Reading from File: " << (calibfiles.rbegin())->second << " ... ";
636  std::string fname = (calibfiles.rbegin())->second;
637  TFile *f = TFile::Open(fname.c_str());
638  if (issuper)
639  {
640  PdbParameterMapContainer *myparm = static_cast<PdbParameterMapContainer *>(f->Get("PdbParameterMapContainer"));
641  assert(myparm);
642 
643  if (myparm->GetParameters(detid) == nullptr)
644  {
645  std::cout << "Missing PdbParameterMapContainer Detector Id " << detid << std::endl;
646  gSystem->Exit(1);
647  }
648 
649  std::cout << "Received PdbParameterMapContainer Detector Id " << detid << " with (Hash = 0x" << std::hex << myparm->GetParameters(detid)->get_hash() << std::dec << ")" << std::endl;
650 
651  FillFrom(myparm, detid);
652  delete myparm;
653  }
654  else
655  {
656  PdbParameterMap *myparm = static_cast<PdbParameterMap *>(f->Get("PdbParameterMap"));
657  assert(myparm);
658  std::cout << "Received PdbParameterMap with (Hash = 0x" << std::hex << myparm->get_hash() << std::dec << ")" << std::endl;
659 
660  FillFrom(myparm);
661  delete myparm;
662  }
663  delete f;
664 
665  return 0;
666 }
667 
669 {
670  TFile *f = TFile::Open(url.c_str());
671  PdbParameterMap *myparm = static_cast<PdbParameterMap *>(f->Get("PdbParameterMap"));
672  FillFrom(myparm);
673  delete myparm;
674  delete f;
675  return 0;
676 }
677 
679 {
680  for (std::map<const std::string, double>::const_iterator iter = m_DoubleParMap.begin();
681  iter != m_DoubleParMap.end(); ++iter)
682  {
683  myparm->set_double_param(iter->first, iter->second);
684  }
685  for (std::map<const std::string, int>::const_iterator iter = m_IntParMap.begin();
686  iter != m_IntParMap.end(); ++iter)
687  {
688  myparm->set_int_param(iter->first, iter->second);
689  }
690  for (std::map<const std::string, std::string>::const_iterator iter = m_StringParMap.begin();
691  iter != m_StringParMap.end(); ++iter)
692  {
693  myparm->set_string_param(iter->first, iter->second);
694  }
695 }
696 
697 unsigned int
699 {
700  unsigned int tics;
701  try
702  {
703  tics = boost::lexical_cast<unsigned int>(str);
704  }
705  catch (boost::bad_lexical_cast const &)
706  {
707  std::cout << "Cannot extract timestamp from " << str << std::endl;
708  gSystem->Exit(1);
709  exit(1);
710  }
711  return tics;
712 }