The Gaudi Framework  master (37c0b60a)
PartPropSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 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 // Include files
13 #include <GaudiKernel/MsgStream.h>
15 
16 #include "PartPropSvc.h"
17 
18 #include <HepPDT/HeavyIonUnknownID.hh>
19 
20 #include <fstream>
21 
22 #include <boost/algorithm/string/case_conv.hpp>
23 #include <boost/tokenizer.hpp>
24 
25 //*************************************************************************//
27 
29 
30  if ( status.isFailure() ) {
31  error() << "Could not initialize main svc" << endmsg;
32  return StatusCode::FAILURE;
33  }
34 
36 
37  typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
38  boost::char_separator<char> sep( ", " );
39  boost::char_separator<char> sep_eq( "=" );
40 
41  tokenizer tokens( key, sep );
42  for ( auto it = tokens.begin(); it != tokens.end(); ++it ) {
43 
44  tokenizer tok2( *it, sep_eq );
45  int nToks( std::distance( tok2.begin(), tok2.end() ) );
46 
47  auto it2 = tok2.begin();
48  const std::string fname = *it2;
50  if ( nToks == 1 ) {
51  info() << "No table format type specified for \"" << fname << "\". Assuming PDG" << endmsg;
52  fmt = "PDG";
53  } else {
54  ++it2;
55  fmt = *it2;
56  }
57 
58  // see if input file exists in $DATAPATH
59  std::string rfile = System::PathResolver::find_file( fname, "DATAPATH" );
60  if ( rfile.empty() ) {
61  error() << "Could not find PDT file: \"" << fname << "\" in $DATAPATH" << endmsg;
62  return StatusCode::FAILURE;
63  }
64 
65  // is the file readable?
66  std::ifstream pdfile{ rfile };
67  if ( !pdfile ) {
68  error() << "Could not open PDT file: \"" << rfile << "\"" << endmsg;
69  return StatusCode::FAILURE;
70  }
71 
72  std::string FMT = boost::algorithm::to_upper_copy( fmt );
73 
74  inputFunPtr pF = nullptr;
75  try {
76  pF = parseTableType( FMT );
77  } catch ( ... ) {
78  error() << "Could not determine Particle Property table type: \"" << FMT << "\" for file \"" << fname << "\""
79  << endmsg;
80  return StatusCode::FAILURE;
81  }
82 
83  debug() << "Adding PDT file \"" << rfile << "\" type " << FMT << endmsg;
84 
85  m_inputs.emplace_back( rfile, pF );
86  }
87 
88  return status;
89 }
90 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
91 
93 
94  m_pdt.reset();
95 
96  if ( m_upid_local && m_upid ) {
97  m_upid_local = false;
98  // This will cause a memory leak, but we can't delete it as the
99  // destructor of HepPDT::processUnknownID is protected.
100  // We need this though to call reinitialize successfully.
101  m_upid = nullptr;
102  }
103 
104  StatusCode status = Service::finalize();
105 
106  if ( status.isSuccess() ) { debug() << "Service finalised successfully" << endmsg; }
107 
108  return status;
109 }
110 
111 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
112 
114  static const auto table = {
115  std::make_pair( "PDG", &HepPDT::addPDGParticles ), std::make_pair( "PYTHIA", &HepPDT::addPythiaParticles ),
116  std::make_pair( "EVTGEN", &HepPDT::addEvtGenParticles ), std::make_pair( "HERWIG", &HepPDT::addHerwigParticles ),
117  std::make_pair( "ISAJET", &HepPDT::addIsajetParticles ), std::make_pair( "QQ", &HepPDT::addQQParticles ) };
118  auto i = std::find_if( std::begin( table ), std::end( table ),
119  [&]( const std::pair<const char*, inputFunPtr>& p ) { return typ == p.first; } );
120  if ( i == std::end( table ) ) {
121  error() << "Unknown Particle Data file type: \"" << typ << "\"" << endmsg;
122  throw std::runtime_error( "error parsing particle table type" );
123  }
124  return i->second;
125 }
126 
127 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
128 
130 
131  // use a handler for unknown heavy ions
132  if ( !m_upid ) {
133  setUnknownParticleHandler( new HepPDT::HeavyIonUnknownID, "Default Heavy Ion Handler" );
134  m_upid_local = true;
135  }
136 
137  m_pdt.emplace( m_upid_name, m_upid );
138 
139  HepPDT::TableBuilder tb( *m_pdt );
140 
141  for ( const auto& itr : m_inputs ) {
142  const auto& f = itr.first;
143  const auto& pF = itr.second;
144 
145  debug() << "Reading PDT file \"" << f << "\"" << endmsg;
146 
147  std::ifstream pdfile{ f };
148  // build a table from the file
149  if ( !pF( pdfile, tb ) ) {
150  error() << "Error reading PDT file: \"" << f << "\"" << endmsg;
151  return StatusCode::FAILURE;
152  }
153  }
154 
155  return StatusCode::SUCCESS;
156 }
157 
158 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
159 
160 HepPDT::ParticleDataTable* PartPropSvc::PDT() {
161 
162  if ( !m_pdt ) {
163  debug() << "creating ParticleDataTable" << endmsg;
164  if ( createTable().isFailure() ) {
165  fatal() << "Could not create ParticleDataTable" << endmsg;
166  m_pdt.reset();
167  }
168  }
169 
170  return m_pdt ? &m_pdt.value() : nullptr;
171 }
172 
173 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
174 
175 void PartPropSvc::setUnknownParticleHandler( HepPDT::ProcessUnknownID* puid, const std::string& n ) {
176  if ( m_pdt ) {
177  error() << "not setting Unknown Particle Handler \"" << n << "\" as ParticleDataTable already instantiated"
178  << endmsg;
179  return;
180  }
181 
182  debug() << "setting Unknown Particle Handler \"" << n << "\" at " << puid << endmsg;
183 
184  if ( m_upid ) {
185  warning() << "overriding previously selected Unknown Particle Handler \"" << m_upid_name << "\" with \"" << n
186  << "\"" << endmsg;
187  }
188 
189  m_upid = puid;
190  m_upid_name = n;
191 }
192 
193 // Instantiation of a static factory class used by clients to create
194 // instances of this service
196 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:118
std::string
STL class.
PartPropSvc::parseTableType
inputFunPtr parseTableType(const std::string &)
Definition: PartPropSvc.cpp:113
PartPropSvc::initialize
StatusCode initialize() override
Definition: PartPropSvc.cpp:26
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:314
std::pair
PartPropSvc::m_inputs
std::vector< std::pair< std::string, inputFunPtr > > m_inputs
Definition: PartPropSvc.h:54
PartPropSvc::m_upid_name
std::string m_upid_name
Definition: PartPropSvc.h:59
std::find_if
T find_if(T... args)
std::distance
T distance(T... args)
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:222
PartPropSvc::m_upid
HepPDT::ProcessUnknownID * m_upid
Definition: PartPropSvc.h:58
PartPropSvc::PDT
HepPDT::ParticleDataTable * PDT() override
Definition: PartPropSvc.cpp:160
StatusCode
Definition: StatusCode.h:65
PartPropSvc
Definition: PartPropSvc.py:1
Gaudi::Property::value
const ValueType & value() const
Definition: Property.h:237
PartPropSvc::m_pdtFiles
Gaudi::Property< std::string > m_pdtFiles
Definition: PartPropSvc.h:56
std::runtime_error
STL class.
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
cpluginsvc.n
n
Definition: cpluginsvc.py:234
PartPropSvc::createTable
StatusCode createTable()
Definition: PartPropSvc.cpp:129
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
PartPropSvc.h
std::vector::emplace_back
T emplace_back(T... args)
PartPropSvc::finalize
StatusCode finalize() override
Definition: PartPropSvc.cpp:92
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
System::PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cpp:118
std::begin
T begin(T... args)
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
PartPropSvc::setUnknownParticleHandler
void setUnknownParticleHandler(HepPDT::ProcessUnknownID *, const std::string &) override
Definition: PartPropSvc.cpp:175
fmt
PartPropSvc::m_upid_local
bool m_upid_local
Definition: PartPropSvc.h:65
std::string::empty
T empty(T... args)
PartPropSvc::inputFunPtr
bool(*)(std::istream &, HepPDT::TableBuilder &) inputFunPtr
Definition: PartPropSvc.h:51
std::make_pair
T make_pair(T... args)
std::end
T end(T... args)
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
PathResolver.h
ISvcLocator.h
PartPropSvc::m_pdt
std::optional< HepPDT::ParticleDataTable > m_pdt
Definition: PartPropSvc.h:61
ProduceConsume.key
key
Definition: ProduceConsume.py:84
MsgStream.h
std::ifstream
STL class.