/data3/calcul/jacquem/working_dir/Micromegas/micromegasFrameWork/lcio/src/cpp/src/UTIL/LCStdHepRdr.cc

Go to the documentation of this file.
00001 #include "UTIL/LCStdHepRdr.h"
00002 #include "EVENT/MCParticle.h"
00003 #include "IMPL/MCParticleImpl.h"
00004 #include "IMPL/LCEventImpl.h"
00005 #include "lcio.h"
00006 #include "EVENT/LCIO.h"
00007 #include <sstream>
00008 //#include <stdlib.h>
00009 #include <cmath>        // for pow()
00010 #include "Exceptions.h"
00011 
00012 using namespace EVENT ;
00013 using namespace IMPL ;
00014 
00015 
00016 #define IDRUP_NAME "_idrup" 
00017 #define EVTWGT_NAME "_weight" 
00018 
00019 namespace UTIL{
00020 
00021   LCStdHepRdr::LCStdHepRdr(const char* evfile){
00022     //
00023     //   Use Willie's reader from LELAPS, and open the input file
00024     //
00025     _reader = new UTIL::lStdHep(evfile,false);
00026     if(_reader->getError()) {
00027       std::stringstream description ; 
00028       description << "LCStdHepRdr: no stdhep file: " << evfile << std::ends ;
00029       throw IO::IOException( description.str() );
00030     }
00031 
00032     //    _reader->printFileHeader() ;
00033 
00034   }
00035   LCStdHepRdr::~LCStdHepRdr(){
00036 
00037     delete _reader ;
00038   }
00039   
00040 
00041 
00042   void LCStdHepRdr::printHeader(std::ostream& os ) {
00043 
00044     if( os == std::cout ) {
00045 
00046       _reader->printFileHeader() ;
00047     }
00048 
00049   }
00050 
00051 
00052 
00053   void LCStdHepRdr::updateNextEvent( IMPL::LCEventImpl* evt , const char* colName ) {
00054 
00055     if( evt == 0 ) {
00056       throw EVENT::Exception( " LCStdHepRdr::updateEvent - null pointer for event "  );
00057     }
00058     
00059     IMPL::LCCollectionVec* mcpCol = readEvent() ;
00060     
00061     if( mcpCol == 0 ) {
00062 
00063       throw IO::EndOfDataException( " LCStdHepRdr::updateEvent: EOF " ) ;
00064     }
00065 
00066     // copy event parameters from the collection to the event:
00067     // FIXME: make this more efficient - not going through paramer map twice....
00068     
00069     int idrup = mcpCol->getParameters().getIntVal( IDRUP_NAME ) ;
00070     
00071     if( idrup !=0 ) {
00072       
00073       evt->parameters().setValue( IDRUP_NAME ,  idrup ) ;
00074     }
00075 
00076     double evtwgt = mcpCol->getParameters().getFloatVal( EVTWGT_NAME ) ;
00077 
00078     evt->setWeight( evtwgt ) ;
00079 
00080 
00081     // ---- end event parameters  ------------------
00082 
00083  
00084     evt->addCollection( mcpCol , colName ) ;
00085   }
00086 
00087 
00088   //
00089   // Read an event and return a LCCollectionVec of MCParticles
00090   //
00091   IMPL::LCCollectionVec * LCStdHepRdr::readEvent()
00092   {
00093     IMPL::LCCollectionVec * mcVec = 0;
00094     double c_light = 299.792;// mm/ns
00095     //
00096     //  Read the event, check for errors
00097     //
00098 //     if( _reader->more() ){
00099 
00100       int errorcode = _reader->readEvent() ;
00101 
00102       if( errorcode != LSH_SUCCESS ){
00103 
00104         if(  errorcode != LSH_ENDOFFILE ) {
00105           
00106           std::stringstream description ; 
00107           description << "LCStdHepRdr::readEvent: error when reading event: " << errorcode << std::ends ;
00108           
00109           throw IO::IOException( description.str() );
00110         }
00111         
00112         else {
00113           
00114           return 0 ;
00115           // throw IO::EndOfDataException( " LCStdHepRdr::readEvent EOF " ) ;
00116         }
00117       }
00118 
00119       
00120 //     } else {
00121 //       //
00122 //       // End of File :: ??? Exception ???
00123 //       //   -> FG:   EOF is not an exception as it happens for every file at the end !
00124 //       //
00125 //       return mcVec;  // == null !
00126 //     }
00127 
00128     //
00129     //  Create a Collection Vector
00130     //
00131     mcVec = new IMPL::LCCollectionVec(LCIO::MCPARTICLE);
00132     MCParticleImpl* p;
00133     MCParticleImpl* d;
00134     //
00135     //  Loop over particles
00136     //
00137     int NHEP = _reader->nTracks();
00138     
00139     // user defined process  id
00140     long idrup = _reader->idrup() ;  
00141     
00142 //     static int counter = 0 ;
00143 //     bool isCritical = false ;
00144 //     std::cout << " -----  readEvent  " << counter << " err: " <<   errorcode 
00145 //            << " nhep : " << NHEP 
00146 //            << std::endl ;
00147 //     if( counter++ == 3850 ) {
00148 //       std::cout << " - critical event read !!! " << std::endl ;
00149 //       isCritical = true ;
00150 //       _reader->printEvent() ;
00151 //       _reader->printEventHeader() ;
00152 //       for(int bla=0;bla<NHEP;bla++){
00153 //      _reader->printTrack( bla ) ;
00154 //       }
00155 //     }
00156 
00157 
00158     if( idrup != 0 ) {
00159       
00160       mcVec->parameters().setValue( IDRUP_NAME ,  (int) idrup ) ;
00161     }
00162     
00163     double evtWeight = _reader->eventweight() ;
00164     
00165     
00166     mcVec->parameters().setValue( EVTWGT_NAME ,  (float) evtWeight ) ;
00167 
00168 
00169     for( int IHEP=0; IHEP<NHEP; IHEP++ )
00170       {
00171         //
00172         //  Create a MCParticle and fill it from stdhep info
00173         //
00174         MCParticleImpl* mcp = new MCParticleImpl();
00175         //
00176         //  PDGID
00177         //
00178         mcp->setPDG(_reader->pid(IHEP));
00179 
00180 
00181         //
00182         //  charge
00183         // 
00184         mcp->setCharge( threeCharge( mcp->getPDG() ) / 3. ) ;
00185 
00186         //
00187         //  Momentum vector
00188         //
00189         float p0[3] = {_reader->Px(IHEP),_reader->Py(IHEP),_reader->Pz(IHEP)};
00190         mcp->setMomentum(p0);
00191         //
00192         //  Mass
00193         //
00194         mcp->setMass(_reader->M(IHEP));
00195         //
00196         //  Vertex
00197         //
00198         double v0[3] = {_reader->X(IHEP),_reader->Y(IHEP),_reader->Z(IHEP)};
00199         mcp->setVertex(v0);
00200         //
00201         //  Generator status
00202         //
00203         mcp->setGeneratorStatus(_reader->status(IHEP));
00204         //
00205         //  Simulator status 0 until simulator acts on it
00206         //
00207         mcp->setSimulatorStatus(0);
00208         //
00209         //  Creation time (note the units)
00210         //
00211         mcp->setTime(_reader->T(IHEP)/c_light);
00212         //
00213         //  Add the particle to the collection vector
00214         //
00215         mcVec->push_back(mcp);
00216 
00217 
00218 // ------
00219 // fg 20071120 - ignore mother relation ship altogether and use only daughter relationship
00220 //             - this is neede to avoid double counting in Mokka geant4 simulation
00221 //             - however some information might be lost here if encoded in inconsistent parent
00222 //               daughter relationships...
00223 
00224 //
00225 //
00226 //      //
00227 //      // Add the parent information. The implicit assumption here is that
00228 //      // no particle is read in before its parents.
00229 //      //
00230 //      int fp = _reader->mother1(IHEP) - 1;
00231 //      int lp = _reader->mother2(IHEP) - 1;
00232 
00233 // //   if( isCritical ) {
00234 // //     std::cout << " parents:  fp : " << fp  << " lp : " <<  lp << std::endl ;
00235 // //   }
00236 
00237 //      //
00238 //      //  If both first parent and second parent > 0, and second parent >
00239 //      //     first parent, assume a range
00240 //      //
00241 //      if( (fp > -1) && (lp > -1) )
00242 //        {
00243 //          if(lp >= fp)
00244 //            {
00245 //              for(int ip=fp;ip<lp+1;ip++)
00246 //                {
00247 //                  p = dynamic_cast<MCParticleImpl*>
00248 //                    (mcVec->getElementAt(ip));
00249 //                  mcp->addParent(p);
00250 //                }
00251 //            }
00252 //          //
00253 //          //  If first parent < second parent, assume 2 discreet parents
00254 //          //
00255 //          else
00256 //            {
00257 //              p = dynamic_cast<MCParticleImpl*>
00258 //                (mcVec->getElementAt(fp));
00259 //              mcp->addParent(p);
00260 //              p = dynamic_cast<MCParticleImpl*>
00261 //                (mcVec->getElementAt(lp));
00262 //              mcp->addParent(p);
00263 //            }
00264 //        }
00265 //      //
00266 //      //  Only 1 parent > 0, set it
00267 //      //
00268 //      else if(fp > -1)
00269 //        {
00270 //          p = dynamic_cast<MCParticleImpl*>
00271 //            (mcVec->getElementAt(fp));
00272 //          mcp->addParent(p);
00273 //        }
00274 //      else if(lp > -1)
00275 //        {
00276 //          p = dynamic_cast<MCParticleImpl*>
00277 //            (mcVec->getElementAt(lp));
00278 //          mcp->addParent(p);
00279 //        }
00280       }// End loop over particles
00281 
00282 
00283 // fg 20071120 - as we ignore mother relation ship altogether this loop now
00284 //      creates the parent-daughter
00285 
00286     //
00287     //  Now make a second loop over the particles, checking the daughter
00288     //  information. This is not always consistent with parent 
00289     //  information, and this utility assumes all parents listed are
00290     //  parents and all daughters listed are daughters
00291     //
00292     for( int IHEP=0; IHEP<NHEP; IHEP++ )
00293       {
00294         //
00295         //  Get the MCParticle
00296         //
00297         MCParticleImpl* mcp = 
00298           dynamic_cast<MCParticleImpl*>
00299           (mcVec->getElementAt(IHEP));
00300         //
00301         //  Get the daughter information, discarding extra information
00302         //  sometimes stored in daughter variables.
00303         //
00304         int fd = _reader->daughter1(IHEP)%10000 - 1;
00305         int ld = _reader->daughter2(IHEP)%10000 - 1;
00306 
00307 //      if( isCritical ) {
00308 //        std::cout << "daughters fd : " << fd  << " ld : " <<  ld << std::endl ;
00309 //      }
00310 
00311         //
00312         //  As with the parents, look for range, 2 discreet or 1 discreet 
00313         //  daughter.
00314         //
00315         if( (fd > -1) && (ld > -1) )
00316           {
00317             if(ld >= fd)
00318               {
00319                 for(int id=fd;id<ld+1;id++)
00320                   {
00321                     //
00322                     //  Get the daughter, and see if it already lists this particle as
00323                     //    a parent.
00324                     //
00325                     d = dynamic_cast<MCParticleImpl*>
00326                       (mcVec->getElementAt(id));
00327                     int np = d->getParents().size();
00328                     bool gotit = false;
00329                     for(int ip=0;ip < np;ip++)
00330                       {
00331                         p = dynamic_cast<MCParticleImpl*>
00332                           (d->getParents()[ip]);
00333                         if(p == mcp)gotit = true;
00334                       }
00335                     //
00336                     //  If not already listed, add this particle as a parent
00337                     //
00338                     if(!gotit)d->addParent(mcp);
00339                   }
00340               }
00341             //
00342             //  Same logic, discreet cases
00343             //
00344             else
00345               {
00346                 d = dynamic_cast<MCParticleImpl*>
00347                   (mcVec->getElementAt(fd));
00348                 int np = d->getParents().size();
00349                 bool gotit = false;
00350                 for(int ip=0;ip < np;ip++)
00351                   {
00352                     p = dynamic_cast<MCParticleImpl*>
00353                       (d->getParents()[ip]);
00354                     if(p == mcp)gotit = true;
00355                   }
00356                 if(!gotit)d->addParent(mcp);
00357                 d = dynamic_cast<MCParticleImpl*>
00358                   (mcVec->getElementAt(ld));
00359                 np = d->getParents().size();
00360                 gotit = false;
00361                 for(int ip=0;ip < np;ip++)
00362                   {
00363                     p = dynamic_cast<MCParticleImpl*>
00364                       (d->getParents()[ip]);
00365                     if(p == mcp)gotit = true;
00366                   }
00367                 if(!gotit)d->addParent(mcp);
00368               }
00369           }
00370         else if(fd > -1 ) 
00371           {
00372 
00373             if( fd < NHEP ) {
00374               d = dynamic_cast<MCParticleImpl*>
00375                 (mcVec->getElementAt(fd));
00376               int np = d->getParents().size();
00377               bool gotit = false;
00378               for(int ip=0;ip < np;ip++)
00379                 {
00380                   p = dynamic_cast<MCParticleImpl*>
00381                     (d->getParents()[ip]);
00382                   if(p == mcp)gotit = true;
00383                 }
00384               if(!gotit)d->addParent(mcp);
00385 
00386             } else { 
00387               //FIXME: whizdata has lots of of illegal daughter indices 21 < NHEP
00388 //            std::cout << " WARNING:  LCStdhepReader: invalid index in stdhep : " << fd 
00389 //                      << " NHEP = " << NHEP << " - ignored ! " << std::endl ;
00390             }
00391 
00392           }
00393 // --------- fg: ignore daughters if the first daughter index is illegal (0 in stdhep, -1 here)
00394 //      else if(ld > -1 )
00395 //        {
00396 //          std::cout << " WARNING: LCStdhepReader: illegal daughter index in stdhep : " << ld 
00397 //                    << " NHEP = " << NHEP << " - ignored ! " << std::endl ;
00398         //          if(  ld < NHEP ){
00399         //            d = dynamic_cast<MCParticleImpl*>
00400         //              (mcVec->getElementAt(ld));
00401         //            int np = d->getParents().size();
00402         //            bool gotit = false;
00403         //            for(int ip=0;ip < np;ip++)
00404         //              {
00405         //                p = dynamic_cast<MCParticleImpl*>
00406         //                  (d->getParents()[ip]);
00407         //                if(p == mcp)gotit = true;
00408         //              }
00409         //            if(!gotit)d->addParent(mcp);
00410         
00411         //          } else {
00412         //            //FIXME: whizdata has lots of of illegal daughter indices 21 < NHEP
00413         // //         std::cout << " WARNING: LCStdhepReader: invalid index in stdhep : " << ld 
00414         // //                   << " NHEP = " << NHEP << " - ignored ! " << std::endl ;
00415         
00416         //          }
00417         
00418         //        }
00419 
00420       }// End second loop over particles
00421     //
00422     //  Return the collection
00423     //
00424     return mcVec;    
00425   }
00426 
00427 
00428   int LCStdHepRdr::threeCharge( int pdgID ) const {
00429     //
00430     // code copied from HepPDT package, author L.Garren
00431     // modified to take pdg
00432     
00433     ///  PID digits (base 10) are: n nr nl nq1 nq2 nq3 nj
00434     ///  The location enum provides a convenient index into the PID.
00435     enum location { nj=1, nq3, nq2, nq1, nl, nr, n, n8, n9, n10 };
00436 
00437     int charge=0;
00438     int ida, sid;
00439     unsigned short q1, q2, q3;
00440     static int ch100[100] = { -1, 2,-1, 2,-1, 2,-1, 2, 0, 0,
00441                               -3, 0,-3, 0,-3, 0,-3, 0, 0, 0,
00442                               0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
00443                               0, 0, 0, 3, 0, 0, 3, 0, 0, 0,
00444                               0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
00445                               0, 6, 3, 6, 0, 0, 0, 0, 0, 0,
00446                               0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00447                               0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00448                               0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00449                               0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00450     
00451     ida = (pdgID < 0) ? -pdgID : pdgID ;
00452     
00453     //     q1 = digit(nq1);
00454     //     q2 = digit(nq2);
00455     //     q3 = digit(nq3);
00456 
00457     q1 =  ( ida / ( (int) std::pow( 10.0, (nq1 -1) ) )  ) % 10 ;
00458     q2 =  ( ida / ( (int) std::pow( 10.0, (nq2 -1) ) )  ) % 10 ;
00459     q3 =  ( ida / ( (int) std::pow( 10.0, (nq3 -1) ) )  ) % 10 ;
00460     
00461 //     sid = fundamentalID();
00462     //---- ParticleID::fundamentalID -------
00463     short dig_n9 =  ( ida / ( (int) std::pow( 10.0, (n9 -1) ) )  ) % 10 ;
00464     short dig_n10 =  ( ida / ( (int) std::pow( 10.0, (n10 -1) ) )  ) % 10 ;
00465     
00466     if( ( dig_n10 == 1 ) && ( dig_n9 == 0 ) ) {
00467       
00468       sid = 0 ;
00469     } 
00470     else if( q2 == 0 && q1 == 0) {
00471       
00472       sid = ida % 10000;
00473     } 
00474     else if( ida <= 102 ) {
00475       
00476       sid = ida ; 
00477     } 
00478     else {
00479 
00480       sid = 0;
00481     }
00482     //----------------
00483 
00484     int extraBits = ida / 10000000 ;
00485     // everything beyond the 7th digit (e.g. outside the numbering scheme)
00486 
00487     short dig_nj =  ( ida / ( (int) std::pow( 10.0, (nj -1) ) )  ) % 10 ;
00488 
00489     if( ida == 0 || extraBits > 0 ) {      // ion or illegal
00490       return 0;
00491     } else if( sid > 0 && sid <= 100 ) {        // use table
00492       charge = ch100[sid-1];
00493       if(ida==1000017 || ida==1000018) { charge = 0; }
00494       if(ida==1000034 || ida==1000052) { charge = 0; }
00495       if(ida==1000053 || ida==1000054) { charge = 0; }
00496       if(ida==5100061 || ida==5100062) { charge = 6; }
00497     } else if( dig_nj == 0 ) {          // KL, Ks, or undefined
00498       return 0;
00499     } else if( q1 == 0 ) {                      // mesons
00500       if( q2 == 3 || q2 == 5 ) {
00501         charge = ch100[q3-1] - ch100[q2-1];
00502       } else {
00503         charge = ch100[q2-1] - ch100[q3-1];
00504       }
00505     } else if( q3 == 0 ) {                      // diquarks
00506       charge = ch100[q2-1] + ch100[q1-1];
00507     } else {                                    // baryons
00508       charge = ch100[q3-1] + ch100[q2-1] + ch100[q1-1];
00509     }
00510     if( charge == 0 ) {
00511       return 0;
00512     } else if( pdgID < 0 ) {
00513       charge = -charge; 
00514     }
00515     return charge;
00516   }
00517 
00518 } // namespace UTIL
00519 

Generated on Mon Jan 7 13:15:21 2013 for MicromegasFramework by  doxygen 1.4.7