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