Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ParticlePropertySvc.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // STD&STL
5 // ============================================================================
6 #include <cstdlib>
7 #include <cstring>
8 #include <fstream>
9 // ============================================================================
10 // GaudiKernel
11 // ============================================================================
12 #include "GaudiKernel/SvcFactory.h"
14 #include "GaudiKernel/MsgStream.h"
18 #include "GaudiKernel/System.h"
19 // ============================================================================
20 //#include "GaudiKernel/ToStream.h"
21 // ============================================================================
22 // Local
23 // ============================================================================
24 #include "ParticlePropertySvc.h"
25 // ============================================================================
26 namespace Gaudi {
30 DECLARE_SERVICE_FACTORY(ParticlePropertySvc)
31 // ============================================================================
43 // ============================================================================
44 ParticlePropertySvc::ParticlePropertySvc
45 ( const std::string& name ,
46  ISvcLocator* svc )
47  : base_class( name, svc )
48  // the default name of input data file
49  , m_filename ( "ParticleTable.txt" )
50  , m_other ()
51  , m_particles ()
52  // storages :
53  , m_vectpp ()
54  , m_idmap ()
55  , m_namemap ()
56  , m_stdhepidmap()
57  , m_pythiaidmap()
58  //
59  , m_owned ()
60  , m_replaced ()
61  , m_fileAccess (0)
62 {
64  // Redefine the default name:
65  if( System::getEnv("PARAMFILESROOT", m_filename) )
66  {
67  m_filename += "/data/ParticleTable.txt";
68  }
69  //
70  declareProperty ( "ParticlePropertiesFile" , m_filename ) ;
71  declareProperty ( "OtherFiles" , m_other ) ;
72  declareProperty ( "Particles" , m_particles ) ;
73 }
74 // ============================================================================
76 // ============================================================================
77 ParticlePropertySvc::~ParticlePropertySvc()
78 {
79  for ( Set::iterator i = m_owned.begin(); i != m_owned.end() ; ++i )
80  { if ( 0 != *i ) { delete *i ; } }
81 }
82 // ============================================================================
84 // ============================================================================
86 {
88  if ( sc.isFailure() ) { return sc ; }
89 
90  MsgStream log( msgSvc() , name() ) ;
91 
92  sc = setProperties();
93  if ( sc.isFailure() )
94  {
95  log << MSG::ERROR << " Could not set the properties " << endmsg ;
96  return sc ;
97  }
98 
99 
100  sc = service("VFSSvc",m_fileAccess);
101  if ( sc.isFailure() )
102  {
103  log << MSG::ERROR << " Cannot retrieve the VFS service " << endmsg ;
104  return sc ;
105  }
106 
107  sc = parse();
108  if ( sc.isFailure() )
109  {
110  log << MSG::ERROR << " Could not parse the file " << endmsg ;
111  return sc ;
112  }
113  if ( !m_particles.empty() )
114  {
115  sc = addParticles () ;
116  if ( sc.isFailure() )
117  {
118  log << MSG::ERROR << " Could not treat particles! " << endmsg ;
119  return sc ;
120  }
121  }
122  log << MSG::DEBUG << "ParticleProperties parsed successfully" << endmsg;
123 
124  log << MSG::DEBUG << "Access properties" << endmsg;
125  // For debugging purposes print out the size of the internal maps
126  // particle name as key: all particles in database are present here
127  log << MSG::DEBUG << "NameMap size =" << m_namemap.size() << endmsg;
128  // Geant3 ID as key: all particles in database are present here
129  log << MSG::DEBUG << "GeantID Map size =" << m_idmap.size() << endmsg;
130  // StdHep ID as key: some particles have no valid StdHep ID
131  log << MSG::DEBUG << "StdHepID Map size =" << m_stdhepidmap.size()
132  << endmsg;
133  // Pythia ID as key: some particles are not defined in Pythia
134  log << MSG::DEBUG << "PythiaID Map size =" << m_pythiaidmap.size()
135  << endmsg;
136 
137  if ( !m_replaced.empty() )
138  {
139  log << MSG::INFO
140  << "Properties have been redefined for "
141  << m_replaced.size() << " particles : "
142  << Gaudi::Utils::toString( m_replaced )
143  << endmsg ;
144  }
145 
146  return StatusCode::SUCCESS ;
147 }
148 // =============================================================================
150 // =============================================================================
151 StatusCode ParticlePropertySvc::finalize()
152 {
153  if ( !m_other.empty() )
154  {
155  MsgStream log( msgSvc() , name() ) ;
156  log << MSG::INFO
157  << "Additional Properties have been read from files: "
158  << Gaudi::Utils::toString ( m_other )
159  << endmsg ;
160  }
161 
162  if ( !m_replaced.empty() )
163  {
164  MsgStream log( msgSvc() , name() ) ;
165  log << MSG::ALWAYS
166  << "Properties have been redefined for "
167  << m_replaced.size() << " particles : "
168  << Gaudi::Utils::toString( m_replaced )
169  << endmsg ;
170  }
171 
172  if (m_fileAccess) {
173  m_fileAccess->release();
174  m_fileAccess = 0;
175  }
176 
178  return Service::finalize () ;
179 }
180 // =============================================================================
182 // =============================================================================
183 StatusCode ParticlePropertySvc::push_back
184 ( const std::string& particle ,
185  int geantId ,
186  int jetsetId ,
187  double charge ,
188  double mass ,
189  double tlife ,
190  const std::string& evtName ,
191  int pythiaId ,
192  double maxWidth )
193 {
195  ( particle , geantId , jetsetId ,
196  charge , mass , tlife ,
197  evtName , pythiaId , maxWidth ) ;
198  //
199  m_owned.insert ( pp ) ;
200  //
201  return push_back( pp );
202 }
203 // =============================================================================
205 // =============================================================================
206 StatusCode ParticlePropertySvc::push_back ( ParticleProperty* pp )
207 {
208  if ( 0 == pp ) { return StatusCode::FAILURE ; }
209  //
210  { // try to add into Geant(3)ID map
211  const int ID = pp->geantID() ;
212  // is this already in the map?
213  MapID::const_iterator ifind = m_idmap.find( ID ) ;
214  if ( m_idmap.end() != ifind && 0 != m_idmap[ ID ])
215  {
216  diff ( ifind->second , pp ) ;
217  m_replaced.insert( m_idmap[ ID ]->particle() ) ;
218  }
219  // put it into the map
220  m_idmap[ ID ] = pp ;
221  }
222  //
223  { // try to add into Name map
224  const std::string& particle = pp->particle() ;
225  // is this already in the map?
226  MapName::const_iterator ifind = m_namemap.find( particle ) ;
227  if ( m_namemap.end() != ifind && 0 != m_namemap[ particle ] )
228  {
229  diff ( ifind->second , pp ) ;
230  m_replaced.insert( m_namemap[ particle ]->particle() ) ;
231  }
232  // put it into the map
233  m_namemap[ particle ] = pp ;
234  }
235  //
236  // add to StdHep map only if StdHep ID different from zero and if
237  // not Cerenkov (StdHep ID = gamma)
238  if ( 0 != pp->jetsetID() && "Tcherenkov" != pp->particle() )
239  { // try to add into StdHepID map
240  const int ID = pp->jetsetID() ;
241  // is this already in the map?
242  MapStdHepID::const_iterator ifind = m_stdhepidmap.find( ID ) ;
243  if ( m_stdhepidmap.end() != ifind && 0 != m_stdhepidmap[ ID ])
244  {
245  diff ( ifind->second , pp ) ;
246  m_replaced.insert( m_stdhepidmap[ ID ]->particle() ) ;
247  }
248  // put it into the map
249  m_stdhepidmap[ ID ] = pp ;
250  }
251  //
252  // add to Pythia map only if Pythia ID is different from
253  // zero ( StdHep id is always different from zero in this case )
254  if ( 0 != pp->pythiaID() &&
255  0 != pp->jetsetID() &&
256  "Tcherenkov" != pp->particle() )
257  { // try to add into PythiaID map
258  const int ID = pp->pythiaID() ;
259  // is this already in the map?
260  MapPythiaID::const_iterator ifind = m_pythiaidmap.find( ID ) ;
261  if ( m_pythiaidmap.end() != ifind && 0 != m_pythiaidmap[ ID ])
262  {
263  diff ( ifind->second , pp ) ;
264  m_replaced.insert( m_pythiaidmap[ ID ]->particle() ) ;
265  }
266  // put it into the map
267  m_pythiaidmap[ ID ] = pp ;
268  }
269  //
270  return rebuild() ;
271 }
272 // =============================================================================
274 // =============================================================================
275 namespace
276 {
277  template <class MAP>
278  void _remove_ ( MAP& m , const ParticleProperty* pp )
279  {
280  typename MAP::iterator i = m.begin() ;
281  for ( ; m.end() != i ; ++i ) { if ( i->second == pp ) { break ; } }
282  if ( m.end() != i ) { m.erase ( i ) ; }
283  }
284 }
285 // ============================================================================
286 StatusCode ParticlePropertySvc::erase( const ParticleProperty* pp )
287 {
288  if ( 0 == pp ) { return StatusCode::FAILURE ; }
289 
290  _remove_ ( m_idmap , pp ) ;
291  _remove_ ( m_namemap , pp ) ;
292  _remove_ ( m_stdhepidmap , pp ) ;
293  _remove_ ( m_pythiaidmap , pp ) ;
294  //
295  return rebuild() ;
296 }
297 // ============================================================================
299 // ============================================================================
301 {
302 
303  // parse "the main" file
304  StatusCode sc = parse ( m_filename ) ;
305  if ( sc.isFailure() ) { return sc ; }
306 
307  // parse "other" files
308  for ( Files::const_iterator file = m_other.begin() ;
309  m_other.end() != file ; ++file )
310  {
311  sc = parse ( *file ) ;
312  if ( sc.isFailure() ) { return sc ; }
313  }
314 
315  // Now check that the file format was consistent with what parser
316  // expected
317  if ( m_namemap.size() == 0 )
318  {
319  MsgStream log( msgSvc(), name() );
320  log << MSG::ERROR
321  << "Format of input file inconsistent with what expected"
322  << " - Check you are using ParticleData.txt" << endmsg;
323  return StatusCode::FAILURE;
324  }
325 
326  return sc;
327 }
328 // ============================================================================
330 {
332 
333  MsgStream log( msgSvc(), name() );
334  char line[ 255 ];
335 
336  std::auto_ptr<std::istream> infileptr;
337  if (m_fileAccess) infileptr = m_fileAccess->open(file);
338 
339  if ( infileptr.get() == 0 )
340  {
341  log << MSG::ERROR << "Unable to open properties file : " << file
342  << endmsg;
343  return StatusCode::FAILURE ;
344  }
345 
346  std::istream &infile = *infileptr;
347  sc = StatusCode::SUCCESS;
348  log << MSG::INFO
349  << "Opened particle properties file : " << file << endmsg;
350 
351  while( infile )
352  {
353  // parse each line of the file (comment lines begin with # in the cdf
354  // file,
355  infile.getline( line, 255 );
356 
357  if ( line[0] == '#' ) continue;
358 
360 #ifdef WIN32
361 // Disable warning
362 // C4996: 'strtok': This function or variable may be unsafe.
363 #pragma warning(disable:4996)
364 #endif
365  std::string par, gid, jid, chg, mas, lif, evt, pyt, mwi ;
366  char* token = strtok( line, " " );
367  if ( token ) { par = token; token = strtok( NULL, " " );} else continue;
368  if ( token ) { gid = token; token = strtok( NULL, " " );} else continue;
369  if ( token ) { jid = token; token = strtok( NULL, " " );} else continue;
370  if ( token ) { chg = token; token = strtok( NULL, " " );} else continue;
371  if ( token ) { mas = token; token = strtok( NULL, " " );} else continue;
372  if ( token ) { lif = token; token = strtok( NULL, " " );} else continue;
373  if ( token ) { evt = token; token = strtok( NULL, " " );} else continue;
374  if ( token ) { pyt = token; token = strtok( NULL, " " );} else continue;
375  if ( token ) { mwi = token; token = strtok( NULL, " " );} else continue;
376  if ( token != NULL ) continue;
377 
378  // In SICb cdf file mass and lifetime units are GeV and sec, specify it so
379  // that they are converted to Gaudi units (MeV and ns)
380  double mass = atof( mas.c_str() ) * Gaudi::Units::GeV;
381  double tlife = atof( lif.c_str() ) * Gaudi::Units::s;
382  long ljid = atoi( jid.c_str() );
383  long lgid = atoi( gid.c_str() );
384  long lpyt = atoi( pyt.c_str() ) ;
385  double mW = atof( mwi.c_str() ) * Gaudi::Units::GeV ;
386 
387  // Change the particles that do not correspond to a pdg number
388  if ( ljid == 0 ) {
389  ljid = 10000000*lgid;
390  }
391 
392  // add a particle property
393  sc = push_back( par, lgid, ljid,
394  atof( chg.c_str() ), mass, tlife, evt, lpyt, mW ) ;
395  if ( sc.isFailure() )
396  {
397  log << MSG::ERROR
398  << "Error from ParticlePropertySvc::push_back for particle='"
399  << par << "'" << endmsg ;
400  }
401 
402  }
403 
404  //infile.close();
405 
406  return StatusCode::SUCCESS ;
407 }
408 // ============================================================================
414 // ============================================================================
415 const ParticleProperty*
416 ParticlePropertySvc::anti ( const ParticleProperty* pp ) const
417 {
418  if ( 0 == pp ) { return 0 ; }
419  const int ID = pp->pdgID() ;
420  const int antiID = -1 * ID ;
421  for ( const_iterator it = m_vectpp.begin() ; m_vectpp.end() != it ; ++it )
422  {
423  const ParticleProperty* ap = *it ;
424  if ( 0 == ap ) { continue ; } // CONTINUE
425  if ( antiID == ap->pdgID() ) { return ap ; } // RETURN
426  };
427  //
428  return pp ; // RETURN
429 }
430 // ============================================================================
435 // ============================================================================
436 StatusCode ParticlePropertySvc::setAntiParticles()
437 {
438  // initialize particle<-->antiParticle relations
439  for ( iterator ip = m_vectpp.begin() ; m_vectpp.end() != ip ; ++ip )
440  {
441  ParticleProperty* pp = *ip ;
442  if ( 0 == pp ) { continue ; } // CONTINUE
443  const ParticleProperty* ap = anti ( pp ) ;
444  if ( 0 != ap ) { pp->setAntiParticle( ap ) ; }
445  }
446  return StatusCode::SUCCESS ;
447 }
448 // ============================================================================
450 // ============================================================================
451 namespace
452 {
454  template <class MAP>
455  void _load_ ( MAP& m , ParticlePropertySvc::Set& result )
456  {
457  for ( typename MAP::iterator i = m.begin() ; m.end() != i ; ++i )
458  { result.insert ( i->second ); }
459  }
460 }
461 // ============================================================================
462 StatusCode ParticlePropertySvc::rebuild()
463 {
464  Set local ;
465  m_vectpp.clear() ;
466  m_vectpp.reserve ( m_idmap.size() + 100 ) ;
467  // load information from maps into the set
468  _load_ ( m_idmap , local ) ;
469  _load_ ( m_namemap , local ) ;
470  _load_ ( m_stdhepidmap , local ) ;
471  _load_ ( m_pythiaidmap , local ) ;
472  // load information from set to the linear container vector
473  for ( Set::iterator i = local.begin() ; local.end() != i ; ++i )
474  { m_vectpp.push_back ( *i ) ; }
475  return setAntiParticles() ;
476 }
477 // ============================================================================
478 // treat additional particles
479 // ============================================================================
480 StatusCode ParticlePropertySvc::addParticles()
481 {
482 
483  MsgStream log ( msgSvc() , name() ) ;
484  // loop over all "explicit" particles
485  for ( Particles::const_iterator ip = m_particles.begin() ;
486  m_particles.end() != ip ; ++ip )
487  {
488  const std::string item = *ip ;
489  std::istringstream input( item ) ;
490  // get the name
491  std::string p_name ;
492  int p_geant ;
493  int p_jetset ;
494  double p_charge ;
495  double p_mass ;
496  double p_ltime ;
497  std::string p_evtgen ;
498  int p_pythia ;
499  double p_maxwid ;
500  if ( input
501  >> p_name
502  >> p_geant
503  >> p_jetset
504  >> p_charge
505  >> p_mass
506  >> p_ltime
507  >> p_evtgen
508  >> p_pythia
509  >> p_maxwid )
510  {
511  log << MSG::ALWAYS
512  << " Add/Modify the particle: "
513  << " name='" << p_name << "'"
514  << " geant=" << p_geant
515  << " jetset=" << p_jetset
516  << " charge=" << p_charge
517  << " mass=" << p_mass
518  << " ltime=" << p_ltime
519  << " evtgen='" << p_evtgen << "'"
520  << " pythia=" << p_pythia
521  << " maxwid=" << p_maxwid << endmsg ;
522  //
523  StatusCode sc = push_back
524  ( p_name ,
525  p_geant ,
526  p_jetset ,
527  p_charge ,
528  p_mass * Gaudi::Units::GeV ,
529  p_ltime * Gaudi::Units::s ,
530  p_evtgen ,
531  p_pythia ,
532  p_maxwid * Gaudi::Units::GeV ) ;
533  if ( sc.isFailure() ) { return sc ; } // RETURN
534  }
535  else
536  {
537  log << MSG::ERROR
538  << " could not parse '" << item << "'" << endmsg ;
539  return StatusCode::FAILURE ; // RETURN
540  }
541  }
542  //
543  return StatusCode::SUCCESS ;
544 }
545 // ============================================================================
546 #ifdef __ICC
547 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
548 // The comparison are meant
549 #pragma warning(push)
550 #pragma warning(disable:1572)
551 #endif
552 bool ParticlePropertySvc::diff
553 ( const ParticleProperty* o ,
554  const ParticleProperty* n ,
555  const MSG::Level l ) const
556 {
557  //
558  if ( o == n ) { return false ; }
559  //
560  MsgStream log ( msgSvc() , name() ) ;
561  log << l ;
562  if ( 0 == o || 0 == n )
563  {
564  log << MSG::WARNING << " ParticleProperty* point to NULL" << endmsg ;
565  return true ; // RETURN
566  }
567  //
568  bool result = false ;
569  if ( o -> particle () != n -> particle () )
570  {
571  result = true ;
572  log << " Name:'" << o -> particle () << "'/'" << n -> particle () << "'" ;
573  }
574  if ( o -> geantID () != n -> geantID () )
575  {
576  result = true ;
577  log << " G3ID:" << o -> geantID () << "/" << n -> geantID () << "'" ;
578  }
579  if ( o -> pdgID () != n -> pdgID () )
580  {
581  result = true ;
582  log << " PDGID:" << o -> pdgID () << "/" << n -> pdgID () << "'" ;
583  }
584  if ( o -> pythiaID () != n -> pythiaID () )
585  {
586  result = true ;
587  log << " PYID:" << o -> pythiaID () << "/" << n -> pythiaID () << "'" ;
588  }
589  if ( o -> charge () != n -> charge () )
590  {
591  result = true ;
592  log << " Q:" << o -> charge () << "/" << n -> charge () << "'" ;
593  }
594  if ( o -> mass () != n -> mass () )
595  {
596  result = true ;
597  log << " M:" << o -> mass () << "/" << n -> mass () << "'" ;
598  }
599  if ( o -> lifetime () != n -> lifetime () )
600  {
601  result = true ;
602  log << " T:" << o -> lifetime () << "/" << n -> lifetime () << "'" ;
603  }
604  if ( o -> evtGenName () != n -> evtGenName () )
605  {
606  result = true ;
607  log << " EvtGen:" << o -> evtGenName () << "/" << n -> evtGenName () << "'" ;
608  }
609  if ( o -> maxWidth () != n -> maxWidth () )
610  {
611  result = true ;
612  log << " WMAX:" << o -> maxWidth () << "/" << n -> maxWidth () << "'" ;
613  }
614  if ( result ) { log << endmsg ; }
615  //
616  return result ;
617 }
618 
619 }
620 #ifdef __ICC
621 // re-enable icc remark #1572
622 #pragma warning(pop)
623 #endif
624 // ============================================================================
625 // The END
626 // ============================================================================
627 

Generated at Wed Dec 4 2013 14:33:10 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004