The Gaudi Framework  v33r1 (b1225454)
PartPropSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #ifdef __ICC
12 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
13 // TODO: should be removed because come from HepPDT
14 # pragma warning( disable : 1572 )
15 #endif
16 
17 // Include files
19 #include "GaudiKernel/MsgStream.h"
21 
22 #include "PartPropSvc.h"
23 
24 #include "HepPDT/HeavyIonUnknownID.hh"
25 
26 #include <fstream>
27 
28 #include <boost/algorithm/string/case_conv.hpp>
29 #include <boost/tokenizer.hpp>
30 
31 //*************************************************************************//
33 
35 
36  if ( status.isFailure() ) {
37  error() << "Could not initialize main svc" << endmsg;
38  return StatusCode::FAILURE;
39  }
40 
41  std::string key = m_pdtFiles.value();
42 
43  typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
44  boost::char_separator<char> sep( ", " );
45  boost::char_separator<char> sep_eq( "=" );
46 
47  tokenizer tokens( key, sep );
48  for ( auto it = tokens.begin(); it != tokens.end(); ++it ) {
49 
50  tokenizer tok2( *it, sep_eq );
51  int nToks( std::distance( tok2.begin(), tok2.end() ) );
52 
53  auto it2 = tok2.begin();
54  const std::string fname = *it2;
55  std::string fmt;
56  if ( nToks == 1 ) {
57  info() << "No table format type specified for \"" << fname << "\". Assuming PDG" << endmsg;
58  fmt = "PDG";
59  } else {
60  ++it2;
61  fmt = *it2;
62  }
63 
64  // see if input file exists in $DATAPATH
65  std::string rfile = System::PathResolver::find_file( fname, "DATAPATH" );
66  if ( rfile.empty() ) {
67  error() << "Could not find PDT file: \"" << fname << "\" in $DATAPATH" << endmsg;
68  return StatusCode::FAILURE;
69  }
70 
71  // is the file readable?
72  std::ifstream pdfile{rfile};
73  if ( !pdfile ) {
74  error() << "Could not open PDT file: \"" << rfile << "\"" << endmsg;
75  return StatusCode::FAILURE;
76  }
77 
78  std::string FMT = boost::algorithm::to_upper_copy( fmt );
79 
80  inputFunPtr pF = nullptr;
81  try {
82  pF = parseTableType( FMT );
83  } catch ( ... ) {
84  error() << "Could not determine Particle Property table type: \"" << FMT << "\" for file \"" << fname << "\""
85  << endmsg;
86  return StatusCode::FAILURE;
87  }
88 
89  debug() << "Adding PDT file \"" << rfile << "\" type " << FMT << endmsg;
90 
91  m_inputs.emplace_back( rfile, pF );
92  }
93 
94  return status;
95 }
96 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
97 
99 
100  m_pdt.reset();
101 
102  if ( m_upid_local && m_upid ) {
103  m_upid_local = false;
104  // This will cause a memory leak, but we can't delete it as the
105  // destructor of HepPDT::processUnknownID is protected.
106  // We need this though to call reinitialize successfully.
107  m_upid = nullptr;
108  }
109 
110  StatusCode status = Service::finalize();
111 
112  if ( status.isSuccess() ) { debug() << "Service finalised successfully" << endmsg; }
113 
114  return status;
115 }
116 
117 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
118 
120  static const auto table = {
121  std::make_pair( "PDG", &HepPDT::addPDGParticles ), std::make_pair( "PYTHIA", &HepPDT::addPythiaParticles ),
122  std::make_pair( "EVTGEN", &HepPDT::addEvtGenParticles ), std::make_pair( "HERWIG", &HepPDT::addHerwigParticles ),
123  std::make_pair( "ISAJET", &HepPDT::addIsajetParticles ), std::make_pair( "QQ", &HepPDT::addQQParticles )};
124  auto i = std::find_if( std::begin( table ), std::end( table ),
125  [&]( const std::pair<const char*, inputFunPtr>& p ) { return typ == p.first; } );
126  if ( i == std::end( table ) ) {
127  error() << "Unknown Particle Data file type: \"" << typ << "\"" << endmsg;
128  throw std::runtime_error( "error parsing particle table type" );
129  }
130  return i->second;
131 }
132 
133 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
134 
136 
137  // use a handler for unknown heavy ions
138  if ( !m_upid ) {
139  setUnknownParticleHandler( new HepPDT::HeavyIonUnknownID, "Default Heavy Ion Handler" );
140  m_upid_local = true;
141  }
142 
143  m_pdt.emplace( m_upid_name, m_upid );
144 
145  HepPDT::TableBuilder tb( *m_pdt );
146 
147  for ( const auto& itr : m_inputs ) {
148  const auto& f = itr.first;
149  const auto& pF = itr.second;
150 
151  debug() << "Reading PDT file \"" << f << "\"" << endmsg;
152 
153  std::ifstream pdfile{f};
154  // build a table from the file
155  if ( !pF( pdfile, tb ) ) {
156  error() << "Error reading PDT file: \"" << f << "\"" << endmsg;
157  return StatusCode::FAILURE;
158  }
159  }
160 
161  return StatusCode::SUCCESS;
162 }
163 
164 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
165 
166 HepPDT::ParticleDataTable* PartPropSvc::PDT() {
167 
168  if ( !m_pdt ) {
169  debug() << "creating ParticleDataTable" << endmsg;
170  if ( createTable().isFailure() ) {
171  fatal() << "Could not create ParticleDataTable" << endmsg;
172  m_pdt.reset();
173  }
174  }
175 
176  return m_pdt ? &m_pdt.value() : nullptr;
177 }
178 
179 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
180 
181 void PartPropSvc::setUnknownParticleHandler( HepPDT::ProcessUnknownID* puid, const std::string& n ) {
182  if ( m_pdt ) {
183  error() << "not setting Unknown Particle Handler \"" << n << "\" as ParticleDataTable already instantiated"
184  << endmsg;
185  return;
186  }
187 
188  debug() << "setting Unknown Particle Handler \"" << n << "\" at " << puid << endmsg;
189 
190  if ( m_upid ) {
191  warning() << "overriding previously selected Unknown Particle Handler \"" << m_upid_name << "\" with \"" << n
192  << "\"" << endmsg;
193  }
194 
195  m_upid = puid;
196  m_upid_name = n;
197 }
198 
199 // Instantiation of a static factory class used by clients to create
200 // instances of this service
202 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
StatusCode initialize() override
Definition: Service.cpp:70
T empty(T... args)
StatusCode initialize() override
Definition: PartPropSvc.cpp:32
T distance(T... args)
StatusCode finalize() override
Definition: Service.cpp:174
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
inputFunPtr parseTableType(const std::string &)
bool(*)(std::istream &, HepPDT::TableBuilder &) inputFunPtr
Definition: PartPropSvc.h:51
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
T end(T... args)
Gaudi::Property< std::string > m_pdtFiles
Definition: PartPropSvc.h:56
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
std::vector< std::pair< std::string, inputFunPtr > > m_inputs
Definition: PartPropSvc.h:54
StatusCode finalize() override
Definition: PartPropSvc.cpp:98
HepPDT::ProcessUnknownID * m_upid
Definition: PartPropSvc.h:58
STL class.
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
bool m_upid_local
Definition: PartPropSvc.h:65
T make_pair(T... args)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
bool isSuccess() const
Definition: StatusCode.h:365
T find_if(T... args)
HepPDT::ParticleDataTable * PDT() override
T begin(T... args)
constexpr static const auto FAILURE
Definition: StatusCode.h:101
StatusCode createTable()
bool isFailure() const
Definition: StatusCode.h:145
std::optional< HepPDT::ParticleDataTable > m_pdt
Definition: PartPropSvc.h:61
void setUnknownParticleHandler(HepPDT::ProcessUnknownID *, const std::string &) override
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
STL class.
T emplace_back(T... args)
std::string m_upid_name
Definition: PartPropSvc.h:59