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