LCIO  02.17
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LCStdHepRdr.cc
Go to the documentation of this file.
1 #include "UTIL/LCStdHepRdr.h"
2 #include "EVENT/MCParticle.h"
3 #include "IMPL/MCParticleImpl.h"
4 #include "IMPL/LCEventImpl.h"
5 #include "lcio.h"
6 #include "EVENT/LCIO.h"
7 #include <sstream>
8 //#include <stdlib.h>
9 #include <cmath> // for pow()
10 #include "Exceptions.h"
11 
12 using namespace EVENT ;
13 using namespace IMPL ;
14 
15 
16 #define IDRUP_NAME "_idrup"
17 #define EVTWGT_NAME "_weight"
18 
19 namespace UTIL{
20 
21  LCStdHepRdr::LCStdHepRdr(const char* evfile){
22  //
23  // Use Willie's reader from LELAPS, and open the input file
24  //
25  _reader = new UTIL::lStdHep(evfile,false);
26  if(_reader->getError()) {
27  std::stringstream description ;
28  description << "LCStdHepRdr: no stdhep file: " << evfile << std::ends ;
29  throw IO::IOException( description.str() );
30  }
31 
32  // _reader->printFileHeader() ;
33 
34  }
35  LCStdHepRdr::~LCStdHepRdr(){
36 
37  delete _reader ;
38  }
39 
40 
41 
42  void LCStdHepRdr::printHeader(std::ostream& os ) {
43 
44  if( &os == &std::cout ) {
45  _reader->printFileHeader() ;
46  }
47 
48  }
49 
50 
51 
52  void LCStdHepRdr::updateNextEvent( IMPL::LCEventImpl* evt , const char* colName ) {
53 
54  if( evt == 0 ) {
55  throw EVENT::Exception( " LCStdHepRdr::updateEvent - null pointer for event " );
56  }
57 
58  IMPL::LCCollectionVec* mcpCol = readEvent() ;
59 
60  if( mcpCol == 0 ) {
61 
62  throw IO::EndOfDataException( " LCStdHepRdr::updateEvent: EOF " ) ;
63  }
64 
65  // copy event parameters from the collection to the event:
66  // FIXME: make this more efficient - not going through paramer map twice....
67 
68  int idrup = mcpCol->getParameters().getIntVal( IDRUP_NAME ) ;
69 
70  evt->parameters().setValue( IDRUP_NAME , idrup ) ;
71 
72  double evtwgt = mcpCol->getParameters().getFloatVal( EVTWGT_NAME ) ;
73 
74  evt->setWeight( evtwgt ) ;
75 
76 
77  // ---- end event parameters ------------------
78 
79 
80  evt->addCollection( mcpCol , colName ) ;
81  }
82 
83 
84  //
85  // Read an event and return a LCCollectionVec of MCParticles
86  //
87  IMPL::LCCollectionVec * LCStdHepRdr::readEvent()
88  {
89  IMPL::LCCollectionVec * mcVec = 0;
90  double c_light = 299.792;// mm/ns
91  //
92  // Read the event, check for errors
93  //
94 // if( _reader->more() ){
95 
96  int errorcode = _reader->readEvent() ;
97 
98  if( errorcode != LSH_SUCCESS ){
99 
100  if( errorcode != LSH_ENDOFFILE ) {
101 
102  std::stringstream description ;
103  description << "LCStdHepRdr::readEvent: error when reading event: " << errorcode << std::ends ;
104 
105  throw IO::IOException( description.str() );
106  }
107 
108  else {
109 
110  return 0 ;
111  // throw IO::EndOfDataException( " LCStdHepRdr::readEvent EOF " ) ;
112  }
113  }
114 
115 
116 // } else {
117 // //
118 // // End of File :: ??? Exception ???
119 // // -> FG: EOF is not an exception as it happens for every file at the end !
120 // //
121 // return mcVec; // == null !
122 // }
123 
124  //
125  // Create a Collection Vector
126  //
127  mcVec = new IMPL::LCCollectionVec(LCIO::MCPARTICLE);
128  MCParticleImpl* p;
129  MCParticleImpl* d;
130  //
131  // Loop over particles
132  //
133  int NHEP = _reader->nTracks();
134 
135  // user defined process id
136  long idrup = _reader->idrup() ;
137 
138 // static int counter = 0 ;
139 // bool isCritical = false ;
140 // std::cout << " ----- readEvent " << counter << " err: " << errorcode
141 // << " nhep : " << NHEP
142 // << std::endl ;
143 // if( counter++ == 3850 ) {
144 // std::cout << " - critical event read !!! " << std::endl ;
145 // isCritical = true ;
146 // _reader->printEvent() ;
147 // _reader->printEventHeader() ;
148 // for(int bla=0;bla<NHEP;bla++){
149 // _reader->printTrack( bla ) ;
150 // }
151 // }
152 
153 
154  if( idrup != 0 ) {
155 
156  mcVec->parameters().setValue( IDRUP_NAME , (int) idrup ) ;
157  }
158 
159  double evtWeight = _reader->eventweight() ;
160 
161 
162  mcVec->parameters().setValue( EVTWGT_NAME , (float) evtWeight ) ;
163 
164  mcVec->resize( NHEP ) ;
165 
166  for( int IHEP=0; IHEP<NHEP; IHEP++ )
167  {
168  //
169  // Create a MCParticle and fill it from stdhep info
170  //
171  MCParticleImpl* mcp = new MCParticleImpl();
172 
173  // and add it to the collection (preserving the order of the hepevt block)
174  mcVec->at(IHEP) = mcp ;
175 
176  //
177  // PDGID
178  //
179  mcp->setPDG(_reader->pid(IHEP));
180 
181 
182  //
183  // charge
184  //
185  mcp->setCharge( threeCharge( mcp->getPDG() ) / 3. ) ;
186 
187  //
188  // Momentum vector
189  //
190  float p0[3] = {(float)_reader->Px(IHEP),(float)_reader->Py(IHEP),(float)_reader->Pz(IHEP)};
191  mcp->setMomentum(p0);
192  //
193  // Mass
194  //
195  mcp->setMass(_reader->M(IHEP));
196  //
197  // Vertex
198  //
199  double v0[3] = {_reader->X(IHEP),_reader->Y(IHEP),_reader->Z(IHEP)};
200  mcp->setVertex(v0);
201  //
202  // Generator status
203  //
204  mcp->setGeneratorStatus(_reader->status(IHEP));
205  //
206  // Simulator status 0 until simulator acts on it
207  //
208  mcp->setSimulatorStatus(0);
209  //
210  // Creation time (note the units)
211  //
212  mcp->setTime(_reader->T(IHEP)/c_light);
213 
214 
215  // add spin and color flow information if available
216  if( _reader->isStdHepEv4() ){
217 
218  float spin[3] = {(float) _reader->spinX( IHEP ) ,(float) _reader->spinY( IHEP ) , (float) _reader->spinZ( IHEP ) } ;
219  mcp->setSpin( spin ) ;
220 
221  int colorFlow[2] = { (int)_reader->colorflow( IHEP , 0 ) , (int)_reader->colorflow( IHEP , 1 ) } ;
222  mcp->setColorFlow( colorFlow ) ;
223 
224  }
225 
226 
227 
228 // ------
229 // fg 20071120 - ignore mother relation ship altogether and use only daughter relationship
230 // - this is neede to avoid double counting in Mokka geant4 simulation
231 // - however some information might be lost here if encoded in inconsistent parent
232 // daughter relationships...
233 
234 //
235 //
236 // //
237 // // Add the parent information. The implicit assumption here is that
238 // // no particle is read in before its parents.
239 // //
240 // int fp = _reader->mother1(IHEP) - 1;
241 // int lp = _reader->mother2(IHEP) - 1;
242 
243 // // if( isCritical ) {
244 // // std::cout << " parents: fp : " << fp << " lp : " << lp << std::endl ;
245 // // }
246 
247 // //
248 // // If both first parent and second parent > 0, and second parent >
249 // // first parent, assume a range
250 // //
251 // if( (fp > -1) && (lp > -1) )
252 // {
253 // if(lp >= fp)
254 // {
255 // for(int ip=fp;ip<lp+1;ip++)
256 // {
257 // p = dynamic_cast<MCParticleImpl*>
258 // (mcVec->getElementAt(ip));
259 // mcp->addParent(p);
260 // }
261 // }
262 // //
263 // // If first parent < second parent, assume 2 discreet parents
264 // //
265 // else
266 // {
267 // p = dynamic_cast<MCParticleImpl*>
268 // (mcVec->getElementAt(fp));
269 // mcp->addParent(p);
270 // p = dynamic_cast<MCParticleImpl*>
271 // (mcVec->getElementAt(lp));
272 // mcp->addParent(p);
273 // }
274 // }
275 // //
276 // // Only 1 parent > 0, set it
277 // //
278 // else if(fp > -1)
279 // {
280 // p = dynamic_cast<MCParticleImpl*>
281 // (mcVec->getElementAt(fp));
282 // mcp->addParent(p);
283 // }
284 // else if(lp > -1)
285 // {
286 // p = dynamic_cast<MCParticleImpl*>
287 // (mcVec->getElementAt(lp));
288 // mcp->addParent(p);
289 // }
290 
291 
292  }// End loop over particles
293 
294 
295 // fg 20071120 - as we ignore mother relation ship altogether this loop now
296 // creates the parent-daughter
297 
298  //
299  // Now make a second loop over the particles, checking the daughter
300  // information. This is not always consistent with parent
301  // information, and this utility assumes all parents listed are
302  // parents and all daughters listed are daughters
303  //
304  for( int IHEP=0; IHEP<NHEP; IHEP++ )
305  {
306  //
307  // Get the MCParticle
308  //
309  MCParticleImpl* mcp =
310  dynamic_cast<MCParticleImpl*>
311  (mcVec->getElementAt(IHEP));
312  //
313  // Get the daughter information, discarding extra information
314  // sometimes stored in daughter variables.
315  //
316  int fd = _reader->daughter1(IHEP)%10000 - 1;
317  int ld = _reader->daughter2(IHEP)%10000 - 1;
318 
319 // if( isCritical ) {
320 // std::cout << "daughters fd : " << fd << " ld : " << ld << std::endl ;
321 // }
322 
323  //
324  // As with the parents, look for range, 2 discreet or 1 discreet
325  // daughter.
326  //
327  if( (fd > -1) && (ld > -1) )
328  {
329  if(ld >= fd)
330  {
331  for(int id=fd;id<ld+1;id++)
332  {
333  //
334  // Get the daughter, and see if it already lists this particle as
335  // a parent.
336  //
337  d = dynamic_cast<MCParticleImpl*>
338  (mcVec->getElementAt(id));
339  int np = d->getParents().size();
340  bool gotit = false;
341  for(int ip=0;ip < np;ip++)
342  {
343  p = dynamic_cast<MCParticleImpl*>
344  (d->getParents()[ip]);
345  if(p == mcp)gotit = true;
346  }
347  //
348  // If not already listed, add this particle as a parent
349  //
350  if(!gotit)d->addParent(mcp);
351  }
352  }
353  //
354  // Same logic, discreet cases
355  //
356  else
357  {
358  d = dynamic_cast<MCParticleImpl*>
359  (mcVec->getElementAt(fd));
360  int np = d->getParents().size();
361  bool gotit = false;
362  for(int ip=0;ip < np;ip++)
363  {
364  p = dynamic_cast<MCParticleImpl*>
365  (d->getParents()[ip]);
366  if(p == mcp)gotit = true;
367  }
368  if(!gotit)d->addParent(mcp);
369  d = dynamic_cast<MCParticleImpl*>
370  (mcVec->getElementAt(ld));
371  np = d->getParents().size();
372  gotit = false;
373  for(int ip=0;ip < np;ip++)
374  {
375  p = dynamic_cast<MCParticleImpl*>
376  (d->getParents()[ip]);
377  if(p == mcp)gotit = true;
378  }
379  if(!gotit)d->addParent(mcp);
380  }
381  }
382  else if(fd > -1 )
383  {
384 
385  if( fd < NHEP ) {
386  d = dynamic_cast<MCParticleImpl*>
387  (mcVec->getElementAt(fd));
388  int np = d->getParents().size();
389  bool gotit = false;
390  for(int ip=0;ip < np;ip++)
391  {
392  p = dynamic_cast<MCParticleImpl*>
393  (d->getParents()[ip]);
394  if(p == mcp)gotit = true;
395  }
396  if(!gotit)d->addParent(mcp);
397 
398  } else {
399  //FIXME: whizdata has lots of of illegal daughter indices 21 < NHEP
400 // std::cout << " WARNING: LCStdhepReader: invalid index in stdhep : " << fd
401 // << " NHEP = " << NHEP << " - ignored ! " << std::endl ;
402  }
403 
404  }
405 // --------- fg: ignore daughters if the first daughter index is illegal (0 in stdhep, -1 here)
406 // else if(ld > -1 )
407 // {
408 // std::cout << " WARNING: LCStdhepReader: illegal daughter index in stdhep : " << ld
409 // << " NHEP = " << NHEP << " - ignored ! " << std::endl ;
410  // if( ld < NHEP ){
411  // d = dynamic_cast<MCParticleImpl*>
412  // (mcVec->getElementAt(ld));
413  // int np = d->getParents().size();
414  // bool gotit = false;
415  // for(int ip=0;ip < np;ip++)
416  // {
417  // p = dynamic_cast<MCParticleImpl*>
418  // (d->getParents()[ip]);
419  // if(p == mcp)gotit = true;
420  // }
421  // if(!gotit)d->addParent(mcp);
422 
423  // } else {
424  // //FIXME: whizdata has lots of of illegal daughter indices 21 < NHEP
425  // // std::cout << " WARNING: LCStdhepReader: invalid index in stdhep : " << ld
426  // // << " NHEP = " << NHEP << " - ignored ! " << std::endl ;
427 
428  // }
429 
430  // }
431 
432  }// End second loop over particles
433 
434  // ==========================================================================
435  // This code looks for entries with generator status 2, which do not have daughters assigned and tests if
436  // these inconsistencies are repairable with following 94 state. (B. Vormwald)
437  int nic = 0;
438  for( int IHEP=0; IHEP<NHEP; IHEP++ ){
439 
440  MCParticleImpl* mcp = dynamic_cast<MCParticleImpl*>(mcVec->getElementAt(IHEP));
441 
442  // find inconsistencies
443  if ((mcp->getGeneratorStatus()==2)&&(mcp->getDaughters().size()==0)){
444  //printf("inconsistency found in line %i (nic: %i->%i)\n", IHEP,nic,nic+1);
445  nic++;
446  }
447 
448  //try to repair inconsistencies when a 94 is present!
449  if ((nic>0) && (mcp->getPDG()==94)) {
450  //printf("generator status 94 found in line %i\n",IHEP);
451 
452  int parentid = _reader->mother1(IHEP)%10000 - 1;
453  int firstdau = _reader->daughter1(IHEP)%10000 - 1;
454  int lastdau = _reader->daughter2(IHEP)%10000 - 1;
455  unsigned outn = ( ( lastdau-firstdau +1 ) > 0 ? lastdau-firstdau +1 : 0 ) ;
456  //printf("found first parent in line %i\n",parentid);
457  MCParticleImpl* parent;
458 
459  //check if inconsistency appeared within lines [firstparent -> (IHEP-1)]
460  //if yes, fix relation!
461  for (unsigned int nextparentid = parentid; IHEP-nextparentid>0; nextparentid++){
462  //printf(" check line %i ", nextparentid);
463  parent = dynamic_cast<MCParticleImpl*>(mcVec->getElementAt(nextparentid));
464  if(( parent->getGeneratorStatus()==2) &&
465  (parent->getDaughters().size()==0) &&
466  mcp->getParents().size()<outn){
467  mcp->addParent(parent);
468  //printf(" -> relation fixed\n");
469  nic--;
470  }
471  //else {
472  // if (parent->getDaughters()[0]==mcp){
473  // printf(" -> relation checked\n");
474  // }
475  // else {
476  // printf(" -> other relation\n");
477  // }
478  //}
479  }
480  }
481  }
482  //if (nic>0) printf("WARNING: %i inconsistencies in event\n", nic);
483  // ==========================================================================
484 
485 
486  //
487  // Return the collection
488  //
489  return mcVec;
490  }
491 
492 
493  int LCStdHepRdr::threeCharge( int pdgID ) const {
494  //
495  // code copied from HepPDT package, author L.Garren
496  // modified to take pdg
497 
500  enum location { nj=1, nq3, nq2, nq1, nl, nr, n, n8, n9, n10 };
501 
502  int charge=0;
503  int ida, sid;
504  unsigned short q1, q2, q3;
505  static const int ch100[100] = { -1, 2,-1, 2,-1, 2,-1, 2, 0, 0,
506  -3, 0,-3, 0,-3, 0,-3, 0, 0, 0,
507  0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
508  0, 0, 0, 3, 0, 0, 3, 0, 0, 0,
509  0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
510  0, 6, 3, 6, 0, 0, 0, 0, 0, 0,
511  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
512  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
513  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
514  0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
515 
516  ida = (pdgID < 0) ? -pdgID : pdgID ;
517 
518  // q1 = digit(nq1);
519  // q2 = digit(nq2);
520  // q3 = digit(nq3);
521 
522  q1 = ( ida / ( (int) std::pow( 10.0, (nq1 -1) ) ) ) % 10 ;
523  q2 = ( ida / ( (int) std::pow( 10.0, (nq2 -1) ) ) ) % 10 ;
524  q3 = ( ida / ( (int) std::pow( 10.0, (nq3 -1) ) ) ) % 10 ;
525 
526 // sid = fundamentalID();
527  //---- ParticleID::fundamentalID -------
528  short dig_n9 = ( ida / ( (int) std::pow( 10.0, (n9 -1) ) ) ) % 10 ;
529  short dig_n10 = ( ida / ( (int) std::pow( 10.0, (n10 -1) ) ) ) % 10 ;
530 
531  if( ( dig_n10 == 1 ) && ( dig_n9 == 0 ) ) {
532 
533  sid = 0 ;
534  }
535  else if( q2 == 0 && q1 == 0) {
536 
537  sid = ida % 10000;
538  }
539  else if( ida <= 102 ) {
540 
541  sid = ida ;
542  }
543  else {
544 
545  sid = 0;
546  }
547  //----------------
548 
549  int extraBits = ida / 10000000 ;
550  // everything beyond the 7th digit (e.g. outside the numbering scheme)
551 
552  short dig_nj = ( ida / ( (int) std::pow( 10.0, (nj -1) ) ) ) % 10 ;
553 
554  if( ida == 0 || extraBits > 0 ) { // ion or illegal
555  return 0;
556  } else if( sid > 0 && sid <= 100 ) { // use table
557  charge = ch100[sid-1];
558  if(ida==1000017 || ida==1000018) { charge = 0; }
559  if(ida==1000034 || ida==1000052) { charge = 0; }
560  if(ida==1000053 || ida==1000054) { charge = 0; }
561  if(ida==5100061 || ida==5100062) { charge = 6; }
562  } else if( dig_nj == 0 ) { // KL, Ks, or undefined
563  return 0;
564  } else if( q1 == 0 ) { // mesons
565  if( q2 == 3 || q2 == 5 ) {
566  charge = ch100[q3-1] - ch100[q2-1];
567  } else {
568  charge = ch100[q2-1] - ch100[q3-1];
569  }
570  } else if( q3 == 0 ) { // diquarks
571  charge = ch100[q2-1] + ch100[q1-1];
572  } else { // baryons
573  charge = ch100[q3-1] + ch100[q2-1] + ch100[q1-1];
574  }
575  if( charge == 0 ) {
576  return 0;
577  } else if( pdgID < 0 ) {
578  charge = -charge;
579  }
580  return charge;
581  }
582 
583 } // namespace UTIL
584 
Base exception class for LCIO - all other exceptions extend this.
Definition: Exceptions.h:21
virtual EVENT::LCParameters & parameters()
Parameters defined for this run.
virtual EVENT::LCObject * getElementAt(int index) const
Returns pointer to element at index - no range check !.
void setWeight(double w)
Set the event weight.
Definition: LCEventImpl.cc:168
void setTime(float time)
Sets the createion time.
#define IDRUP_NAME
Definition: LCStdHepRdr.cc:16
Implementation of the LCCollection using (inheriting from) an STL vector of LCObjects.
Implementation of the main event class.
Definition: LCEventImpl.h:31
virtual const EVENT::LCParameters & getParameters() const
Parameters defined for this run.
virtual const EVENT::MCParticleVec & getParents() const
Returns the parents of this particle.
virtual int getGeneratorStatus() const
Returns the status for particles from the generator 0 empty line 1 undecayed particle, stable in the generator 2 particle decayed in the generator 3 documentation line.
void setGeneratorStatus(int status)
Sets the Generator status.
void addParent(EVENT::MCParticle *mom)
Adds a parent particle.
T resize(T...args)
virtual void addCollection(EVENT::LCCollection *col, const std::string &name)
Adds a collection with the given name (has to be a valid C/C++ variable name).
Definition: LCEventImpl.cc:107
T at(T...args)
void setColorFlow(const int cflow[2])
Sets the color flow.
void setSimulatorStatus(int status)
Sets the Simulator status.
#define LSH_ENDOFFILE
Definition: lStdHep.hh:60
void setMass(float m)
Sets the mass.
void setMomentum(const float p[3])
Sets the momentum.
T str(T...args)
IOException used for reading/writing errors.
Definition: Exceptions.h:92
void setVertex(const double vtx[3])
Sets the production vertex.
virtual void setValue(const std::string &key, int value)=0
Set integer value for the given key.
virtual float getFloatVal(const std::string &key) const =0
Returns the first float value for the given key.
void setCharge(float c)
Sets the charge.
virtual const EVENT::MCParticleVec & getDaughters() const
Returns the daughters of this particle.
#define EVTWGT_NAME
Definition: LCStdHepRdr.cc:17
virtual EVENT::LCParameters & parameters()
Parameters defined for this run.
Definition: LCEventImpl.h:135
void setPDG(int pdg)
Sets the parent.
T size(T...args)
T ends(T...args)
T pow(T...args)
virtual int getIntVal(const std::string &key) const =0
Returns the first integer value for the given key.
EndOfDataException for signaling the end of a data stream.
Definition: Exceptions.h:108
#define LSH_SUCCESS
Definition: lStdHep.hh:54
void setSpin(const float spin[3])
Sets the spin.
virtual int getPDG() const
Returns the number of daughters of this particle.
STL class.
Implementation of MCParticle.