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 #include "GaudiKernel/System.h"
00022
00023
00024
00025
00026
00027 #include "ParticlePropertySvc.h"
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 {
00066
00067 if( System::getEnv("PARAMFILESROOT", m_filename) )
00068 {
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
00362 #ifdef WIN32
00363
00364
00365 #pragma warning(disable:4996)
00366 #endif
00367 std::string par, gid, jid, chg, mas, lif, evt, pyt, mwi ;
00368 char* token = strtok( line, " " );
00369 if ( token ) { par = token; token = strtok( NULL, " " );} else continue;
00370 if ( token ) { gid = token; token = strtok( NULL, " " );} else continue;
00371 if ( token ) { jid = token; token = strtok( NULL, " " );} else continue;
00372 if ( token ) { chg = token; token = strtok( NULL, " " );} else continue;
00373 if ( token ) { mas = token; token = strtok( NULL, " " );} else continue;
00374 if ( token ) { lif = token; token = strtok( NULL, " " );} else continue;
00375 if ( token ) { evt = token; token = strtok( NULL, " " );} else continue;
00376 if ( token ) { pyt = token; token = strtok( NULL, " " );} else continue;
00377 if ( token ) { mwi = token; token = strtok( NULL, " " );} else continue;
00378 if ( token != NULL ) continue;
00379
00380
00381
00382 double mass = atof( mas.c_str() ) * Gaudi::Units::GeV;
00383 double tlife = atof( lif.c_str() ) * Gaudi::Units::s;
00384 long ljid = atoi( jid.c_str() );
00385 long lgid = atoi( gid.c_str() );
00386 long lpyt = atoi( pyt.c_str() ) ;
00387 double mW = atof( mwi.c_str() ) * Gaudi::Units::GeV ;
00388
00389
00390 if ( ljid == 0 ) {
00391 ljid = 10000000*lgid;
00392 }
00393
00394
00395 sc = push_back( par, lgid, ljid,
00396 atof( chg.c_str() ), mass, tlife, evt, lpyt, mW ) ;
00397 if ( sc.isFailure() )
00398 {
00399 log << MSG::ERROR
00400 << "Error from ParticlePropertySvc::push_back for particle='"
00401 << par << "'" << endmsg ;
00402 }
00403
00404 }
00405
00406
00407
00408 return StatusCode::SUCCESS ;
00409 }
00410
00416
00417 const ParticleProperty*
00418 ParticlePropertySvc::anti ( const ParticleProperty* pp ) const
00419 {
00420 if ( 0 == pp ) { return 0 ; }
00421 const int ID = pp->pdgID() ;
00422 const int antiID = -1 * ID ;
00423 for ( const_iterator it = m_vectpp.begin() ; m_vectpp.end() != it ; ++it )
00424 {
00425 const ParticleProperty* ap = *it ;
00426 if ( 0 == ap ) { continue ; }
00427 if ( antiID == ap->pdgID() ) { return ap ; }
00428 };
00429
00430 return pp ;
00431 }
00432
00437
00438 StatusCode ParticlePropertySvc::setAntiParticles()
00439 {
00440
00441 for ( iterator ip = m_vectpp.begin() ; m_vectpp.end() != ip ; ++ip )
00442 {
00443 ParticleProperty* pp = *ip ;
00444 if ( 0 == pp ) { continue ; }
00445 const ParticleProperty* ap = anti ( pp ) ;
00446 if ( 0 != ap ) { pp->setAntiParticle( ap ) ; }
00447 }
00448 return StatusCode::SUCCESS ;
00449 }
00450
00452
00453 namespace
00454 {
00456 template <class MAP>
00457 void _load_ ( MAP& m , ParticlePropertySvc::Set& result )
00458 {
00459 for ( typename MAP::iterator i = m.begin() ; m.end() != i ; ++i )
00460 { result.insert ( i->second ); }
00461 }
00462 }
00463
00464 StatusCode ParticlePropertySvc::rebuild()
00465 {
00466 Set local ;
00467 m_vectpp.clear() ;
00468 m_vectpp.reserve ( m_idmap.size() + 100 ) ;
00469
00470 _load_ ( m_idmap , local ) ;
00471 _load_ ( m_namemap , local ) ;
00472 _load_ ( m_stdhepidmap , local ) ;
00473 _load_ ( m_pythiaidmap , local ) ;
00474
00475 for ( Set::iterator i = local.begin() ; local.end() != i ; ++i )
00476 { m_vectpp.push_back ( *i ) ; }
00477 return setAntiParticles() ;
00478 }
00479
00480
00481
00482 StatusCode ParticlePropertySvc::addParticles()
00483 {
00484
00485 MsgStream log ( msgSvc() , name() ) ;
00486
00487 for ( Particles::const_iterator ip = m_particles.begin() ;
00488 m_particles.end() != ip ; ++ip )
00489 {
00490 const std::string item = *ip ;
00491 std::istringstream input( item ) ;
00492
00493 std::string p_name ;
00494 int p_geant ;
00495 int p_jetset ;
00496 double p_charge ;
00497 double p_mass ;
00498 double p_ltime ;
00499 std::string p_evtgen ;
00500 int p_pythia ;
00501 double p_maxwid ;
00502 if ( input
00503 >> p_name
00504 >> p_geant
00505 >> p_jetset
00506 >> p_charge
00507 >> p_mass
00508 >> p_ltime
00509 >> p_evtgen
00510 >> p_pythia
00511 >> p_maxwid )
00512 {
00513 log << MSG::ALWAYS
00514 << " Add/Modify the particle: "
00515 << " name='" << p_name << "'"
00516 << " geant=" << p_geant
00517 << " jetset=" << p_jetset
00518 << " charge=" << p_charge
00519 << " mass=" << p_mass
00520 << " ltime=" << p_ltime
00521 << " evtgen='" << p_evtgen << "'"
00522 << " pythia=" << p_pythia
00523 << " maxwid=" << p_maxwid << endmsg ;
00524
00525 StatusCode sc = push_back
00526 ( p_name ,
00527 p_geant ,
00528 p_jetset ,
00529 p_charge ,
00530 p_mass * Gaudi::Units::GeV ,
00531 p_ltime * Gaudi::Units::s ,
00532 p_evtgen ,
00533 p_pythia ,
00534 p_maxwid * Gaudi::Units::GeV ) ;
00535 if ( sc.isFailure() ) { return sc ; }
00536 }
00537 else
00538 {
00539 log << MSG::ERROR
00540 << " could not parse '" << item << "'" << endmsg ;
00541 return StatusCode::FAILURE ;
00542 }
00543 }
00544
00545 return StatusCode::SUCCESS ;
00546 }
00547
00548 #ifdef __ICC
00549
00550
00551 #pragma warning(push)
00552 #pragma warning(disable:1572)
00553 #endif
00554 bool ParticlePropertySvc::diff
00555 ( const ParticleProperty* o ,
00556 const ParticleProperty* n ,
00557 const MSG::Level l ) const
00558 {
00559
00560 if ( o == n ) { return false ; }
00561
00562 MsgStream log ( msgSvc() , name() ) ;
00563 log << l ;
00564 if ( 0 == o || 0 == n )
00565 {
00566 log << MSG::WARNING << " ParticleProperty* point to NULL" << endmsg ;
00567 return true ;
00568 }
00569
00570 bool result = false ;
00571 if ( o -> particle () != n -> particle () )
00572 {
00573 result = true ;
00574 log << " Name:'" << o -> particle () << "'/'" << n -> particle () << "'" ;
00575 }
00576 if ( o -> geantID () != n -> geantID () )
00577 {
00578 result = true ;
00579 log << " G3ID:" << o -> geantID () << "/" << n -> geantID () << "'" ;
00580 }
00581 if ( o -> pdgID () != n -> pdgID () )
00582 {
00583 result = true ;
00584 log << " PDGID:" << o -> pdgID () << "/" << n -> pdgID () << "'" ;
00585 }
00586 if ( o -> pythiaID () != n -> pythiaID () )
00587 {
00588 result = true ;
00589 log << " PYID:" << o -> pythiaID () << "/" << n -> pythiaID () << "'" ;
00590 }
00591 if ( o -> charge () != n -> charge () )
00592 {
00593 result = true ;
00594 log << " Q:" << o -> charge () << "/" << n -> charge () << "'" ;
00595 }
00596 if ( o -> mass () != n -> mass () )
00597 {
00598 result = true ;
00599 log << " M:" << o -> mass () << "/" << n -> mass () << "'" ;
00600 }
00601 if ( o -> lifetime () != n -> lifetime () )
00602 {
00603 result = true ;
00604 log << " T:" << o -> lifetime () << "/" << n -> lifetime () << "'" ;
00605 }
00606 if ( o -> evtGenName () != n -> evtGenName () )
00607 {
00608 result = true ;
00609 log << " EvtGen:" << o -> evtGenName () << "/" << n -> evtGenName () << "'" ;
00610 }
00611 if ( o -> maxWidth () != n -> maxWidth () )
00612 {
00613 result = true ;
00614 log << " WMAX:" << o -> maxWidth () << "/" << n -> maxWidth () << "'" ;
00615 }
00616 if ( result ) { log << endmsg ; }
00617
00618 return result ;
00619 }
00620 #ifdef __ICC
00621
00622 #pragma warning(pop)
00623 #endif
00624
00625
00626
00627