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