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