| The Gaudi Framework v28r2p1 (f1a77ff4)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

ParticlePropertySvc.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // STD&STL
5 // ============================================================================
6 #include <cctype>
7 #include <fstream>
8 #include "boost/algorithm/string/split.hpp"
9 #include "boost/algorithm/string/trim.hpp"
10 #include "boost/algorithm/string/classification.hpp"
11 namespace ba = boost::algorithm;
12 // ============================================================================
13 // GaudiKernel
14 // ============================================================================
15 #include "GaudiKernel/ISvcLocator.h"
16 #include "GaudiKernel/MsgStream.h"
17 #include "GaudiKernel/ParticleProperty.h"
18 #include "GaudiKernel/PhysicalConstants.h"
19 #include "GaudiKernel/IFileAccess.h"
20 #include "GaudiKernel/System.h"
21 // ============================================================================
22 //#include "GaudiKernel/ToStream.h"
23 // ============================================================================
24 // Local
25 // ============================================================================
26 #include "ParticlePropertySvc.h"
27 // ============================================================================
28 namespace {
29 //@FIXME/@TODO remove once we can assume C++14...
30 template <typename T, class... Args>
31 std::unique_ptr<T> make_unique_(Args&&... args) {
32 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
33 }
34 }
35 namespace Gaudi {
39 DECLARE_COMPONENT(ParticlePropertySvc)
40 // ============================================================================
52 // ============================================================================
53 ParticlePropertySvc::ParticlePropertySvc
54 ( const std::string& name ,
55 ISvcLocator* svc )
56 : base_class( name, svc )
57 {
59 // Redefine the default name:
60 if( System::getEnv("PARAMFILESROOT", m_filename.value()) )
61 {
62 m_filename.value() += "/data/ParticleTable.txt";
63 }
64 }
65 // ============================================================================
67 // ============================================================================
68 StatusCode ParticlePropertySvc::initialize()
69 {
70 StatusCode sc = Service::initialize();
71 if ( sc.isFailure() ) { return sc ; }
72
73
74 sc = setProperties();
75 if ( sc.isFailure() )
76 {
77 error() << " Could not set the properties " << endmsg ;
78 return sc ;
79 }
80
81 m_fileAccess = service("VFSSvc");
82 if ( !m_fileAccess )
83 {
84 error() << " Cannot retrieve the VFS service " << endmsg ;
85 return StatusCode::FAILURE ;
86 }
87
88 sc = parse();
89 if ( sc.isFailure() )
90 {
91 error() << " Could not parse the file " << endmsg ;
92 return sc ;
93 }
94 if ( !m_particles.empty() )
95 {
96 sc = addParticles () ;
97 if ( sc.isFailure() )
98 {
99 error() << " Could not treat particles! " << endmsg ;
100 return sc ;
101 }
102 }
103 debug() << "ParticleProperties parsed successfully" << endmsg;
104
105 debug() << "Access properties" << endmsg;
106 // For debugging purposes print out the size of the internal maps
107 // particle name as key: all particles in database are present here
108 debug() << "NameMap size =" << m_namemap.size() << endmsg;
109 // Geant3 ID as key: all particles in database are present here
110 debug() << "GeantID Map size =" << m_idmap.size() << endmsg;
111 // StdHep ID as key: some particles have no valid StdHep ID
112 debug() << "StdHepID Map size =" << m_stdhepidmap.size()
113 << endmsg;
114 // Pythia ID as key: some particles are not defined in Pythia
115 debug() << "PythiaID Map size =" << m_pythiaidmap.size()
116 << endmsg;
117
118 if ( !m_replaced.empty() )
119 {
120 info()
121 << "Properties have been redefined for "
122 << m_replaced.size() << " particles : "
123 << Gaudi::Utils::toString( m_replaced )
124 << endmsg ;
125 }
126
127 return StatusCode::SUCCESS ;
128 }
129 // =============================================================================
131 // =============================================================================
132 StatusCode ParticlePropertySvc::finalize()
133 {
134 if ( !m_other.empty() )
135 {
136 info() << "Additional Properties have been read from files: "
137 << Gaudi::Utils::toString ( m_other )
138 << endmsg ;
139 }
140
141 if ( !m_replaced.empty() )
142 {
143 always() << "Properties have been redefined for "
144 << m_replaced.size() << " particles : "
145 << Gaudi::Utils::toString( m_replaced )
146 << endmsg ;
147 }
148
149 m_fileAccess.reset();
150
152 return Service::finalize () ;
153 }
154 // =============================================================================
156 // =============================================================================
157 StatusCode ParticlePropertySvc::push_back
158 ( const std::string& particle ,
159 int geantId ,
160 int jetsetId ,
161 double charge ,
162 double mass ,
163 double tlife ,
164 const std::string& evtName ,
165 int pythiaId ,
166 double maxWidth )
167 {
168 //
169 auto i = m_owned.insert(
170 make_unique_<ParticleProperty>( particle , geantId , jetsetId ,
171 charge , mass , tlife ,
172 evtName , pythiaId , maxWidth )
173 ) ;
174 //
175 return i.second ? push_back( i.first->get() ) : StatusCode::FAILURE;
176 }
177 // =============================================================================
179 // =============================================================================
180 StatusCode ParticlePropertySvc::push_back ( ParticleProperty* pp )
181 {
182 if ( !pp ) { return StatusCode::FAILURE ; }
183 //
184 { // try to add into Geant(3)ID map
185 const int ID = pp->geantID() ;
186 // is this already in the map?
187 auto ifind = m_idmap.find( ID ) ;
188 if ( m_idmap.end() != ifind && 0 != m_idmap[ ID ])
189 {
190 diff ( ifind->second , pp ) ;
191 m_replaced.insert( m_idmap[ ID ]->particle() ) ;
192 }
193 // put it into the map
194 m_idmap[ ID ] = pp ;
195 }
196 //
197 { // try to add into Name map
198 const std::string& particle = pp->particle() ;
199 // is this already in the map?
200 auto ifind = m_namemap.find( particle ) ;
201 if ( ifind != m_namemap.end() && ifind->second )
202 {
203 diff ( ifind->second , pp ) ;
204 m_replaced.insert( ifind->second->particle() ) ;
205 }
206 // put it into the map
207 m_namemap[ particle ] = pp ;
208 }
209 //
210 // add to StdHep map only if StdHep ID different from zero and if
211 // not Cerenkov (StdHep ID = gamma)
212 if ( 0 != pp->jetsetID() && "Tcherenkov" != pp->particle() )
213 { // try to add into StdHepID map
214 const int ID = pp->jetsetID() ;
215 // is this already in the map?
216 auto ifind = m_stdhepidmap.find( ID ) ;
217 if ( m_stdhepidmap.end() != ifind && ifind->second )
218 {
219 diff ( ifind->second , pp ) ;
220 m_replaced.insert( ifind->second->particle() ) ;
221 }
222 // put it into the map
223 m_stdhepidmap[ ID ] = pp ;
224 }
225 //
226 // add to Pythia map only if Pythia ID is different from
227 // zero ( StdHep id is always different from zero in this case )
228 if ( 0 != pp->pythiaID() &&
229 0 != pp->jetsetID() &&
230 "Tcherenkov" != pp->particle() )
231 { // try to add into PythiaID map
232 const int ID = pp->pythiaID() ;
233 // is this already in the map?
234 auto ifind = m_pythiaidmap.find( ID ) ;
235 if ( m_pythiaidmap.end() != ifind && ifind->second )
236 {
237 diff ( ifind->second , pp ) ;
238 m_replaced.insert( ifind->second ->particle() ) ;
239 }
240 // put it into the map
241 m_pythiaidmap[ ID ] = pp ;
242 }
243 //
244 return rebuild() ;
245 }
246 // =============================================================================
248 // =============================================================================
249 namespace
250 {
251 template <class MAP>
252 void _remove_ ( MAP& m , const ParticleProperty* pp )
253 {
254 auto i = std::find_if( m.begin(), m.end(),
255 [&](typename MAP::const_reference i) { return i.second == pp; } );
256 if ( i != m.end() ) { m.erase ( i ) ; }
257 }
258 }
259 // ============================================================================
260 StatusCode ParticlePropertySvc::erase( const ParticleProperty* pp )
261 {
262 if ( !pp ) { return StatusCode::FAILURE ; }
263
264 _remove_ ( m_idmap , pp ) ;
265 _remove_ ( m_namemap , pp ) ;
266 _remove_ ( m_stdhepidmap , pp ) ;
267 _remove_ ( m_pythiaidmap , pp ) ;
268 //
269 return rebuild() ;
270 }
271 // ============================================================================
273 // ============================================================================
274 StatusCode ParticlePropertySvc::parse()
275 {
276
277 // parse "the main" file
278 StatusCode sc = parse ( m_filename ) ;
279 if ( sc.isFailure() ) { return sc ; }
280
281 // parse "other" files
282 for ( auto& file : m_other )
283 {
284 sc = parse ( file ) ;
285 if ( sc.isFailure() ) { return sc ; }
286 }
287
288 // Now check that the file format was consistent with what parser
289 // expected
290 if ( m_namemap.empty() )
291 {
292 error()
293 << "Format of input file inconsistent with what expected"
294 << " - Check you are using ParticleData.txt" << endmsg;
295 return StatusCode::FAILURE;
296 }
297
298 return sc;
299 }
300 // ============================================================================
301 StatusCode ParticlePropertySvc::parse( const std::string& file )
302 {
303 auto infile = ( m_fileAccess ? m_fileAccess->open(file) : nullptr );
304 if ( !infile )
305 {
306 error() << "Unable to open properties file : " << file
307 << endmsg;
308 return StatusCode::FAILURE ;
309 }
310
311 StatusCode sc = StatusCode::SUCCESS;
312 info() << "Opened particle properties file : " << file << endmsg;
313
314 std::vector<std::string> tokens; tokens.reserve(9);
315 std::string line;
316 while( std::getline( *infile, line ) )
317 {
318 // parse each line of the file (comment lines begin with # in the cdf
319 // file,
320 if ( line.front() == '#' ) continue;
321
322 tokens.clear();
323 ba::trim_left_if( line, ba::is_space() );
324 ba::split( tokens, line, ba::is_space() , boost::token_compress_on );
325 if (tokens.size()!=9) continue;
326
327 auto gid = std::stoi( tokens[1] );
328 auto jid = std::stoi( tokens[2] );
329 // Change the particles that do not correspond to a pdg number
330 if ( jid == 0 ) jid = 10000000*gid;
331
332 // add a particle property
333 sc = push_back( tokens[0], gid, jid,
334 std::stod( tokens[3] ),
335 std::stod( tokens[4] ) * Gaudi::Units::GeV,
336 std::stod( tokens[5] ) * Gaudi::Units::s,
337 tokens[6],
338 std::stoi( tokens[7] ),
339 std::stod( tokens[8] ) * Gaudi::Units::GeV ) ;
340
341 if ( sc.isFailure() )
342 {
343 error()
344 << "Error from ParticlePropertySvc::push_back for particle='"
345 << tokens[0] << "'" << endmsg ;
346 }
347 }
348 return StatusCode::SUCCESS ;
349 }
350 // ============================================================================
356 // ============================================================================
357 const ParticleProperty*
358 ParticlePropertySvc::anti ( const ParticleProperty* pp ) const
359 {
360 if ( !pp ) { return nullptr ; }
361 const int ID = pp->pdgID() ;
362 const int antiID = -1 * ID ;
363 for ( const auto& ap : m_vectpp )
364 {
365 if ( ap && antiID == ap->pdgID() ) { return ap ; } // RETURN
366 };
367 //
368 return pp ; // RETURN
369 }
370 // ============================================================================
375 // ============================================================================
376 StatusCode ParticlePropertySvc::setAntiParticles()
377 {
378 // initialize particle<-->antiParticle relations
379 for ( auto& pp : m_vectpp )
380 {
381 if ( !pp ) { continue ; } // CONTINUE
382 const ParticleProperty* ap = anti ( pp ) ;
383 if ( ap ) { pp->setAntiParticle( ap ) ; }
384 }
385 return StatusCode::SUCCESS ;
386 }
387 // ============================================================================
389 // ============================================================================
390 namespace
391 {
393 template <typename MAP, typename SET>
394 void _load_ ( MAP& m , SET& result )
395 {
396 for ( auto i = m.begin() ; m.end() != i ; ++i )
397 { result.insert ( i->second ); }
398 }
399 }
400 // ============================================================================
401 StatusCode ParticlePropertySvc::rebuild()
402 {
403 std::set<mapped_type> local ;
404 m_vectpp.clear() ;
405 m_vectpp.reserve ( m_idmap.size() + 100 ) ;
406 // load information from maps into the set
407 _load_ ( m_idmap , local ) ;
408 _load_ ( m_namemap , local ) ;
409 _load_ ( m_stdhepidmap , local ) ;
410 _load_ ( m_pythiaidmap , local ) ;
411 // load information from set to the linear container vector
412 std::copy( std::begin(local), std::end(local), std::back_inserter(m_vectpp) );
413 return setAntiParticles() ;
414 }
415 // ============================================================================
416 // treat additional particles
417 // ============================================================================
418 StatusCode ParticlePropertySvc::addParticles()
419 {
420 // loop over all "explicit" particles
421 for ( const auto& item : m_particles )
422 {
423 std::istringstream input( item ) ;
424 // get the name
425 std::string p_name ;
426 int p_geant ;
427 int p_jetset ;
428 double p_charge ;
429 double p_mass ;
430 double p_ltime ;
431 std::string p_evtgen ;
432 int p_pythia ;
433 double p_maxwid ;
434 if ( input
435 >> p_name
436 >> p_geant
437 >> p_jetset
438 >> p_charge
439 >> p_mass
440 >> p_ltime
441 >> p_evtgen
442 >> p_pythia
443 >> p_maxwid )
444 {
445 always()
446 << " Add/Modify the particle: "
447 << " name='" << p_name << "'"
448 << " geant=" << p_geant
449 << " jetset=" << p_jetset
450 << " charge=" << p_charge
451 << " mass=" << p_mass
452 << " ltime=" << p_ltime
453 << " evtgen='" << p_evtgen << "'"
454 << " pythia=" << p_pythia
455 << " maxwid=" << p_maxwid << endmsg ;
456 //
457 StatusCode sc = push_back
458 ( p_name ,
459 p_geant ,
460 p_jetset ,
461 p_charge ,
462 p_mass * Gaudi::Units::GeV ,
463 p_ltime * Gaudi::Units::s ,
464 p_evtgen ,
465 p_pythia ,
466 p_maxwid * Gaudi::Units::GeV ) ;
467 if ( sc.isFailure() ) { return sc ; } // RETURN
468 }
469 else
470 {
471 error()
472 << " could not parse '" << item << "'" << endmsg ;
473 return StatusCode::FAILURE ; // RETURN
474 }
475 }
476 //
477 return StatusCode::SUCCESS ;
478 }
479 // ============================================================================
480 #ifdef __ICC
481 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
482 // The comparison are meant
483 #pragma warning(push)
484 #pragma warning(disable:1572)
485 #endif
486 bool ParticlePropertySvc::diff
487 ( const ParticleProperty* o ,
488 const ParticleProperty* n ,
489 const MSG::Level l ) const
490 {
491 //
492 if ( o == n ) { return false ; }
493 //
494 auto& log = msgStream();
495 log << l ;
496 if ( !o || !n )
497 {
498 log << MSG::WARNING << " ParticleProperty* point to NULL" << endmsg ;
499 return true ; // RETURN
500 }
501 //
502 bool result = false ;
503 if ( o -> particle () != n -> particle () )
504 {
505 result = true ;
506 log << " Name:'" << o -> particle () << "'/'" << n -> particle () << "'" ;
507 }
508 if ( o -> geantID () != n -> geantID () )
509 {
510 result = true ;
511 log << " G3ID:" << o -> geantID () << "/" << n -> geantID () << "'" ;
512 }
513 if ( o -> pdgID () != n -> pdgID () )
514 {
515 result = true ;
516 log << " PDGID:" << o -> pdgID () << "/" << n -> pdgID () << "'" ;
517 }
518 if ( o -> pythiaID () != n -> pythiaID () )
519 {
520 result = true ;
521 log << " PYID:" << o -> pythiaID () << "/" << n -> pythiaID () << "'" ;
522 }
523 if ( o -> charge () != n -> charge () )
524 {
525 result = true ;
526 log << " Q:" << o -> charge () << "/" << n -> charge () << "'" ;
527 }
528 if ( o -> mass () != n -> mass () )
529 {
530 result = true ;
531 log << " M:" << o -> mass () << "/" << n -> mass () << "'" ;
532 }
533 if ( o -> lifetime () != n -> lifetime () )
534 {
535 result = true ;
536 log << " T:" << o -> lifetime () << "/" << n -> lifetime () << "'" ;
537 }
538 if ( o -> evtGenName () != n -> evtGenName () )
539 {
540 result = true ;
541 log << " EvtGen:" << o -> evtGenName () << "/" << n -> evtGenName () << "'" ;
542 }
543 if ( o -> maxWidth () != n -> maxWidth () )
544 {
545 result = true ;
546 log << " WMAX:" << o -> maxWidth () << "/" << n -> maxWidth () << "'" ;
547 }
548 if ( result ) { log << endmsg ; }
549 //
550 return result ;
551 }
552
553 }
554 #ifdef __ICC
555 // re-enable icc remark #1572
556 #pragma warning(pop)
557 #endif
558 // ============================================================================
559 // The END
560 // ============================================================================
ParticleProperty::pdgID
int pdgID() const
Get the PDG (= JETSET) ID.
Definition: ParticleProperty.h:60
System::getEnv
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
Definition: System.cpp:550
System.h
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:64
StatusCode::SUCCESS
Definition: StatusCode.h:30
std::copy
T copy(T...args)
ISvcLocator
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
Gaudi::Units::s
constexpr double s
Definition: SystemOfUnits.h:134
std::istringstream
STL class.
ParticleProperty::geantID
int geantID() const
Get the GEANT3 ID.
Definition: ParticleProperty.h:54
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:28
StatusCode::FAILURE
Definition: StatusCode.h:29
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:174
MsgStream.h
gaudirun.args
args
Definition: gaudirun.py:236
std::string::front
T front(T...args)
ParticleProperty
A trivial class to hold information about a single particle properties.
Definition: ParticleProperty.h:18
ParticlePropertySvc.h
Gaudi::Utils::toString
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:367
std::stod
T stod(T...args)
std::getline
T getline(T...args)
std
STL namespace.
Gaudi::Parsers::parse
StatusCode parse(GaudiUtils::HashMap< K, V > &result, const std::string &input)
Basic parser for the types of HashMap used in DODBasicMapper.
Definition: DODBasicMapper.cpp:11
std::end
T end(T...args)
IFileAccess.h
Gaudi::Functional::details::details2::push_back
void push_back(Container &c, const Value &v, std::true_type)
Definition: FunctionalDetails.h:154
SET
#define SET(x)
StatusCode::isFailure
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:84
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
std::string
STL class.
ParticleProperty.h
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:217
MSG::Level
Level
Definition: IMessageSvc.h:15
ParticleProperty::jetsetID
int jetsetID() const
Get the JETSET(StdHep) ID.
Definition: ParticleProperty.h:66
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:93
PhysicalConstants.h
std::vector::clear
T clear(T...args)
gaudirun.l
dictionary l
Definition: gaudirun.py:421
std::string::find
T find(T...args)
std::vector::size
T size(T...args)
std::set
STL class.
std::vector< std::string >
std::unique_ptr
STL class.
std::begin
T begin(T...args)
std::back_inserter
T back_inserter(T...args)
compareOutputFiles.pp
pp
Definition: compareOutputFiles.py:417
CommonMessaging
Definition: CommonMessaging.h:55
Gaudi::Units::GeV
constexpr double GeV
Definition: SystemOfUnits.h:160
MSG::WARNING
Definition: IMessageSvc.h:20
ParticleProperty::particle
const std::string & particle() const
Get the particle name.
Definition: ParticleProperty.h:48
ParticleProperty::pythiaID
int pythiaID() const
Get the Pythia ID.
Definition: ParticleProperty.h:96
std::stoi
T stoi(T...args)
ISvcLocator.h
Gaudi
Helper functions to set/get the application return code.
Definition: __init__.py:1
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
plotSpeedupsPyRoot.line
line
Definition: plotSpeedupsPyRoot.py:164
std::vector::reserve
T reserve(T...args)
Gaudi.Configuration.log
log
Definition: Configuration.py:13