00001
00002
00003
00004
00005
00006 #include <cstdlib>
00007 #include <cstring>
00008 #include <fstream>
00009
00010
00011
00012 #include "GaudiKernel/SvcFactory.h"
00013 #include "GaudiKernel/ISvcLocator.h"
00014 #include "GaudiKernel/MsgStream.h"
00015 #include "GaudiKernel/ParticleProperty.h"
00016 #include "GaudiKernel/PhysicalConstants.h"
00017 #include "GaudiKernel/IFileAccess.h"
00018 #include "GaudiKernel/System.h"
00019
00020
00021
00022
00023
00024 #include "ParticlePropertySvc.h"
00025
00026 namespace Gaudi {
00030 DECLARE_SERVICE_FACTORY(ParticlePropertySvc)
00031
00043
00044 ParticlePropertySvc::ParticlePropertySvc
00045 ( const std::string& name ,
00046 ISvcLocator* svc )
00047 : base_class( name, svc )
00048
00049 , m_filename ( "ParticleTable.txt" )
00050 , m_other ()
00051 , m_particles ()
00052
00053 , m_vectpp ()
00054 , m_idmap ()
00055 , m_namemap ()
00056 , m_stdhepidmap()
00057 , m_pythiaidmap()
00058
00059 , m_owned ()
00060 , m_replaced ()
00061 , m_fileAccess (0)
00062 {
00064
00065 if( System::getEnv("PARAMFILESROOT", m_filename) )
00066 {
00067 m_filename += "/data/ParticleTable.txt";
00068 }
00069
00070 declareProperty ( "ParticlePropertiesFile" , m_filename ) ;
00071 declareProperty ( "OtherFiles" , m_other ) ;
00072 declareProperty ( "Particles" , m_particles ) ;
00073 }
00074
00076
00077 ParticlePropertySvc::~ParticlePropertySvc()
00078 {
00079 for ( Set::iterator i = m_owned.begin(); i != m_owned.end() ; ++i )
00080 { if ( 0 != *i ) { delete *i ; } }
00081 }
00082
00084
00085 StatusCode ParticlePropertySvc::initialize()
00086 {
00087 StatusCode sc = Service::initialize();
00088 if ( sc.isFailure() ) { return sc ; }
00089
00090 MsgStream log( msgSvc() , name() ) ;
00091
00092 sc = setProperties();
00093 if ( sc.isFailure() )
00094 {
00095 log << MSG::ERROR << " Could not set the properties " << endmsg ;
00096 return sc ;
00097 }
00098
00099
00100 sc = service("VFSSvc",m_fileAccess);
00101 if ( sc.isFailure() )
00102 {
00103 log << MSG::ERROR << " Cannot retrieve the VFS service " << endmsg ;
00104 return sc ;
00105 }
00106
00107 sc = parse();
00108 if ( sc.isFailure() )
00109 {
00110 log << MSG::ERROR << " Could not parse the file " << endmsg ;
00111 return sc ;
00112 }
00113 if ( !m_particles.empty() )
00114 {
00115 sc = addParticles () ;
00116 if ( sc.isFailure() )
00117 {
00118 log << MSG::ERROR << " Could not treat particles! " << endmsg ;
00119 return sc ;
00120 }
00121 }
00122 log << MSG::DEBUG << "ParticleProperties parsed successfully" << endmsg;
00123
00124 log << MSG::DEBUG << "Access properties" << endmsg;
00125
00126
00127 log << MSG::DEBUG << "NameMap size =" << m_namemap.size() << endmsg;
00128
00129 log << MSG::DEBUG << "GeantID Map size =" << m_idmap.size() << endmsg;
00130
00131 log << MSG::DEBUG << "StdHepID Map size =" << m_stdhepidmap.size()
00132 << endmsg;
00133
00134 log << MSG::DEBUG << "PythiaID Map size =" << m_pythiaidmap.size()
00135 << endmsg;
00136
00137 if ( !m_replaced.empty() )
00138 {
00139 log << MSG::INFO
00140 << "Properties have been redefined for "
00141 << m_replaced.size() << " particles : "
00142 << Gaudi::Utils::toString( m_replaced )
00143 << endmsg ;
00144 }
00145
00146 return StatusCode::SUCCESS ;
00147 }
00148
00150
00151 StatusCode ParticlePropertySvc::finalize()
00152 {
00153 if ( !m_other.empty() )
00154 {
00155 MsgStream log( msgSvc() , name() ) ;
00156 log << MSG::INFO
00157 << "Additional Properties have been read from files: "
00158 << Gaudi::Utils::toString ( m_other )
00159 << endmsg ;
00160 }
00161
00162 if ( !m_replaced.empty() )
00163 {
00164 MsgStream log( msgSvc() , name() ) ;
00165 log << MSG::ALWAYS
00166 << "Properties have been redefined for "
00167 << m_replaced.size() << " particles : "
00168 << Gaudi::Utils::toString( m_replaced )
00169 << endmsg ;
00170 }
00171
00172 if (m_fileAccess) {
00173 m_fileAccess->release();
00174 m_fileAccess = 0;
00175 }
00176
00178 return Service::finalize () ;
00179 }
00180
00182
00183 StatusCode ParticlePropertySvc::push_back
00184 ( const std::string& particle ,
00185 int geantId ,
00186 int jetsetId ,
00187 double charge ,
00188 double mass ,
00189 double tlife ,
00190 const std::string& evtName ,
00191 int pythiaId ,
00192 double maxWidth )
00193 {
00194 ParticleProperty* pp = new ParticleProperty
00195 ( particle , geantId , jetsetId ,
00196 charge , mass , tlife ,
00197 evtName , pythiaId , maxWidth ) ;
00198
00199 m_owned.insert ( pp ) ;
00200
00201 return push_back( pp );
00202 }
00203
00205
00206 StatusCode ParticlePropertySvc::push_back ( ParticleProperty* pp )
00207 {
00208 if ( 0 == pp ) { return StatusCode::FAILURE ; }
00209
00210 {
00211 const int ID = pp->geantID() ;
00212
00213 MapID::const_iterator ifind = m_idmap.find( ID ) ;
00214 if ( m_idmap.end() != ifind && 0 != m_idmap[ ID ])
00215 {
00216 diff ( ifind->second , pp ) ;
00217 m_replaced.insert( m_idmap[ ID ]->particle() ) ;
00218 }
00219
00220 m_idmap[ ID ] = pp ;
00221 }
00222
00223 {
00224 const std::string& particle = pp->particle() ;
00225
00226 MapName::const_iterator ifind = m_namemap.find( particle ) ;
00227 if ( m_namemap.end() != ifind && 0 != m_namemap[ particle ] )
00228 {
00229 diff ( ifind->second , pp ) ;
00230 m_replaced.insert( m_namemap[ particle ]->particle() ) ;
00231 }
00232
00233 m_namemap[ particle ] = pp ;
00234 }
00235
00236
00237
00238 if ( 0 != pp->jetsetID() && "Tcherenkov" != pp->particle() )
00239 {
00240 const int ID = pp->jetsetID() ;
00241
00242 MapStdHepID::const_iterator ifind = m_stdhepidmap.find( ID ) ;
00243 if ( m_stdhepidmap.end() != ifind && 0 != m_stdhepidmap[ ID ])
00244 {
00245 diff ( ifind->second , pp ) ;
00246 m_replaced.insert( m_stdhepidmap[ ID ]->particle() ) ;
00247 }
00248
00249 m_stdhepidmap[ ID ] = pp ;
00250 }
00251
00252
00253
00254 if ( 0 != pp->pythiaID() &&
00255 0 != pp->jetsetID() &&
00256 "Tcherenkov" != pp->particle() )
00257 {
00258 const int ID = pp->pythiaID() ;
00259
00260 MapPythiaID::const_iterator ifind = m_pythiaidmap.find( ID ) ;
00261 if ( m_pythiaidmap.end() != ifind && 0 != m_pythiaidmap[ ID ])
00262 {
00263 diff ( ifind->second , pp ) ;
00264 m_replaced.insert( m_pythiaidmap[ ID ]->particle() ) ;
00265 }
00266
00267 m_pythiaidmap[ ID ] = pp ;
00268 }
00269
00270 return rebuild() ;
00271 }
00272
00274
00275 namespace
00276 {
00277 template <class MAP>
00278 void _remove_ ( MAP& m , const ParticleProperty* pp )
00279 {
00280 typename MAP::iterator i = m.begin() ;
00281 for ( ; m.end() != i ; ++i ) { if ( i->second == pp ) { break ; } }
00282 if ( m.end() != i ) { m.erase ( i ) ; }
00283 }
00284 }
00285
00286 StatusCode ParticlePropertySvc::erase( const ParticleProperty* pp )
00287 {
00288 if ( 0 == pp ) { return StatusCode::FAILURE ; }
00289
00290 _remove_ ( m_idmap , pp ) ;
00291 _remove_ ( m_namemap , pp ) ;
00292 _remove_ ( m_stdhepidmap , pp ) ;
00293 _remove_ ( m_pythiaidmap , pp ) ;
00294
00295 return rebuild() ;
00296 }
00297
00299
00300 StatusCode ParticlePropertySvc::parse()
00301 {
00302
00303
00304 StatusCode sc = parse ( m_filename ) ;
00305 if ( sc.isFailure() ) { return sc ; }
00306
00307
00308 for ( Files::const_iterator file = m_other.begin() ;
00309 m_other.end() != file ; ++file )
00310 {
00311 sc = parse ( *file ) ;
00312 if ( sc.isFailure() ) { return sc ; }
00313 }
00314
00315
00316
00317 if ( m_namemap.size() == 0 )
00318 {
00319 MsgStream log( msgSvc(), name() );
00320 log << MSG::ERROR
00321 << "Format of input file inconsistent with what expected"
00322 << " - Check you are using ParticleData.txt" << endmsg;
00323 return StatusCode::FAILURE;
00324 }
00325
00326 return sc;
00327 }
00328
00329 StatusCode ParticlePropertySvc::parse( const std::string& file )
00330 {
00331 StatusCode sc = StatusCode::FAILURE;
00332
00333 MsgStream log( msgSvc(), name() );
00334 char line[ 255 ];
00335
00336 std::auto_ptr<std::istream> infileptr;
00337 if (m_fileAccess) infileptr = m_fileAccess->open(file);
00338
00339 if ( infileptr.get() == 0 )
00340 {
00341 log << MSG::ERROR << "Unable to open properties file : " << file
00342 << endmsg;
00343 return StatusCode::FAILURE ;
00344 }
00345
00346 std::istream &infile = *infileptr;
00347 sc = StatusCode::SUCCESS;
00348 log << MSG::INFO
00349 << "Opened particle properties file : " << file << endmsg;
00350
00351 while( infile )
00352 {
00353
00354
00355 infile.getline( line, 255 );
00356
00357 if ( line[0] == '#' ) continue;
00358
00360 #ifdef WIN32
00361
00362
00363 #pragma warning(disable:4996)
00364 #endif
00365 std::string par, gid, jid, chg, mas, lif, evt, pyt, mwi ;
00366 char* token = strtok( line, " " );
00367 if ( token ) { par = token; token = strtok( NULL, " " );} else continue;
00368 if ( token ) { gid = token; token = strtok( NULL, " " );} else continue;
00369 if ( token ) { jid = token; token = strtok( NULL, " " );} else continue;
00370 if ( token ) { chg = token; token = strtok( NULL, " " );} else continue;
00371 if ( token ) { mas = token; token = strtok( NULL, " " );} else continue;
00372 if ( token ) { lif = token; token = strtok( NULL, " " );} else continue;
00373 if ( token ) { evt = token; token = strtok( NULL, " " );} else continue;
00374 if ( token ) { pyt = token; token = strtok( NULL, " " );} else continue;
00375 if ( token ) { mwi = token; token = strtok( NULL, " " );} else continue;
00376 if ( token != NULL ) continue;
00377
00378
00379
00380 double mass = atof( mas.c_str() ) * Gaudi::Units::GeV;
00381 double tlife = atof( lif.c_str() ) * Gaudi::Units::s;
00382 long ljid = atoi( jid.c_str() );
00383 long lgid = atoi( gid.c_str() );
00384 long lpyt = atoi( pyt.c_str() ) ;
00385 double mW = atof( mwi.c_str() ) * Gaudi::Units::GeV ;
00386
00387
00388 if ( ljid == 0 ) {
00389 ljid = 10000000*lgid;
00390 }
00391
00392
00393 sc = push_back( par, lgid, ljid,
00394 atof( chg.c_str() ), mass, tlife, evt, lpyt, mW ) ;
00395 if ( sc.isFailure() )
00396 {
00397 log << MSG::ERROR
00398 << "Error from ParticlePropertySvc::push_back for particle='"
00399 << par << "'" << endmsg ;
00400 }
00401
00402 }
00403
00404
00405
00406 return StatusCode::SUCCESS ;
00407 }
00408
00414
00415 const ParticleProperty*
00416 ParticlePropertySvc::anti ( const ParticleProperty* pp ) const
00417 {
00418 if ( 0 == pp ) { return 0 ; }
00419 const int ID = pp->pdgID() ;
00420 const int antiID = -1 * ID ;
00421 for ( const_iterator it = m_vectpp.begin() ; m_vectpp.end() != it ; ++it )
00422 {
00423 const ParticleProperty* ap = *it ;
00424 if ( 0 == ap ) { continue ; }
00425 if ( antiID == ap->pdgID() ) { return ap ; }
00426 };
00427
00428 return pp ;
00429 }
00430
00435
00436 StatusCode ParticlePropertySvc::setAntiParticles()
00437 {
00438
00439 for ( iterator ip = m_vectpp.begin() ; m_vectpp.end() != ip ; ++ip )
00440 {
00441 ParticleProperty* pp = *ip ;
00442 if ( 0 == pp ) { continue ; }
00443 const ParticleProperty* ap = anti ( pp ) ;
00444 if ( 0 != ap ) { pp->setAntiParticle( ap ) ; }
00445 }
00446 return StatusCode::SUCCESS ;
00447 }
00448
00450
00451 namespace
00452 {
00454 template <class MAP>
00455 void _load_ ( MAP& m , ParticlePropertySvc::Set& result )
00456 {
00457 for ( typename MAP::iterator i = m.begin() ; m.end() != i ; ++i )
00458 { result.insert ( i->second ); }
00459 }
00460 }
00461
00462 StatusCode ParticlePropertySvc::rebuild()
00463 {
00464 Set local ;
00465 m_vectpp.clear() ;
00466 m_vectpp.reserve ( m_idmap.size() + 100 ) ;
00467
00468 _load_ ( m_idmap , local ) ;
00469 _load_ ( m_namemap , local ) ;
00470 _load_ ( m_stdhepidmap , local ) ;
00471 _load_ ( m_pythiaidmap , local ) ;
00472
00473 for ( Set::iterator i = local.begin() ; local.end() != i ; ++i )
00474 { m_vectpp.push_back ( *i ) ; }
00475 return setAntiParticles() ;
00476 }
00477
00478
00479
00480 StatusCode ParticlePropertySvc::addParticles()
00481 {
00482
00483 MsgStream log ( msgSvc() , name() ) ;
00484
00485 for ( Particles::const_iterator ip = m_particles.begin() ;
00486 m_particles.end() != ip ; ++ip )
00487 {
00488 const std::string item = *ip ;
00489 std::istringstream input( item ) ;
00490
00491 std::string p_name ;
00492 int p_geant ;
00493 int p_jetset ;
00494 double p_charge ;
00495 double p_mass ;
00496 double p_ltime ;
00497 std::string p_evtgen ;
00498 int p_pythia ;
00499 double p_maxwid ;
00500 if ( input
00501 >> p_name
00502 >> p_geant
00503 >> p_jetset
00504 >> p_charge
00505 >> p_mass
00506 >> p_ltime
00507 >> p_evtgen
00508 >> p_pythia
00509 >> p_maxwid )
00510 {
00511 log << MSG::ALWAYS
00512 << " Add/Modify the particle: "
00513 << " name='" << p_name << "'"
00514 << " geant=" << p_geant
00515 << " jetset=" << p_jetset
00516 << " charge=" << p_charge
00517 << " mass=" << p_mass
00518 << " ltime=" << p_ltime
00519 << " evtgen='" << p_evtgen << "'"
00520 << " pythia=" << p_pythia
00521 << " maxwid=" << p_maxwid << endmsg ;
00522
00523 StatusCode sc = push_back
00524 ( p_name ,
00525 p_geant ,
00526 p_jetset ,
00527 p_charge ,
00528 p_mass * Gaudi::Units::GeV ,
00529 p_ltime * Gaudi::Units::s ,
00530 p_evtgen ,
00531 p_pythia ,
00532 p_maxwid * Gaudi::Units::GeV ) ;
00533 if ( sc.isFailure() ) { return sc ; }
00534 }
00535 else
00536 {
00537 log << MSG::ERROR
00538 << " could not parse '" << item << "'" << endmsg ;
00539 return StatusCode::FAILURE ;
00540 }
00541 }
00542
00543 return StatusCode::SUCCESS ;
00544 }
00545
00546 #ifdef __ICC
00547
00548
00549 #pragma warning(push)
00550 #pragma warning(disable:1572)
00551 #endif
00552 bool ParticlePropertySvc::diff
00553 ( const ParticleProperty* o ,
00554 const ParticleProperty* n ,
00555 const MSG::Level l ) const
00556 {
00557
00558 if ( o == n ) { return false ; }
00559
00560 MsgStream log ( msgSvc() , name() ) ;
00561 log << l ;
00562 if ( 0 == o || 0 == n )
00563 {
00564 log << MSG::WARNING << " ParticleProperty* point to NULL" << endmsg ;
00565 return true ;
00566 }
00567
00568 bool result = false ;
00569 if ( o -> particle () != n -> particle () )
00570 {
00571 result = true ;
00572 log << " Name:'" << o -> particle () << "'/'" << n -> particle () << "'" ;
00573 }
00574 if ( o -> geantID () != n -> geantID () )
00575 {
00576 result = true ;
00577 log << " G3ID:" << o -> geantID () << "/" << n -> geantID () << "'" ;
00578 }
00579 if ( o -> pdgID () != n -> pdgID () )
00580 {
00581 result = true ;
00582 log << " PDGID:" << o -> pdgID () << "/" << n -> pdgID () << "'" ;
00583 }
00584 if ( o -> pythiaID () != n -> pythiaID () )
00585 {
00586 result = true ;
00587 log << " PYID:" << o -> pythiaID () << "/" << n -> pythiaID () << "'" ;
00588 }
00589 if ( o -> charge () != n -> charge () )
00590 {
00591 result = true ;
00592 log << " Q:" << o -> charge () << "/" << n -> charge () << "'" ;
00593 }
00594 if ( o -> mass () != n -> mass () )
00595 {
00596 result = true ;
00597 log << " M:" << o -> mass () << "/" << n -> mass () << "'" ;
00598 }
00599 if ( o -> lifetime () != n -> lifetime () )
00600 {
00601 result = true ;
00602 log << " T:" << o -> lifetime () << "/" << n -> lifetime () << "'" ;
00603 }
00604 if ( o -> evtGenName () != n -> evtGenName () )
00605 {
00606 result = true ;
00607 log << " EvtGen:" << o -> evtGenName () << "/" << n -> evtGenName () << "'" ;
00608 }
00609 if ( o -> maxWidth () != n -> maxWidth () )
00610 {
00611 result = true ;
00612 log << " WMAX:" << o -> maxWidth () << "/" << n -> maxWidth () << "'" ;
00613 }
00614 if ( result ) { log << endmsg ; }
00615
00616 return result ;
00617 }
00618
00619 }
00620 #ifdef __ICC
00621
00622 #pragma warning(pop)
00623 #endif
00624
00625
00626
00627