Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

UtilHepevt.cxx

Go to the documentation of this file.
00001 #include "Util/UtilHepevt.h"
00002 #include "Util/UtilPDG.h"
00003 
00004 // for ::open, ::write, ::close
00005 #include <unistd.h>
00006 // for ssize_t
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 // for scanf
00010 #include <stdio.h>
00011 
00012 #include <iostream>
00013 #include <iomanip>
00014 #include <vector>
00015 
00016 #include "TMath.h"   // for units
00017 #include "TClonesArray.h"
00018 #include "TParticle.h"
00019 #include "TSystem.h"
00020 #include "TROOT.h"
00021 #include "TApplication.h"
00022 
00023 // Hepevt.h is in $ROOTSYS/eg
00024 #include "Hepevt.h"
00025 const int mxnhep = 4000;  // this should have been part of Hepevt.h
00026 
00027 int  UtilHepevt::getNHep() { return HEPEVT.nhep; }
00028 int  UtilHepevt::getNevHep() { return HEPEVT.nevhep; }
00029 void UtilHepevt::setNevHep(int evtnum) { HEPEVT.nevhep = evtnum; }
00030 
00031 void UtilHepevt::clearCommon(bool fast) 
00032 {
00033   HEPEVT.nevhep = 0;
00034   HEPEVT.nhep   = 0;
00035   if (fast) return;
00036   for (int i=0; i<mxnhep; ++i) {
00037     HEPEVT.isthep[i]     = 0;
00038     HEPEVT.idhep[i]      = 0;
00039     HEPEVT.jmohep[i][0]  = 0;
00040     HEPEVT.jmohep[i][1]  = 0;
00041     HEPEVT.jdahep[i][0]  = 0;
00042     HEPEVT.jdahep[i][1]  = 0;
00043     HEPEVT.phep[i][0]    = 0;
00044     HEPEVT.phep[i][1]    = 0;
00045     HEPEVT.phep[i][2]    = 0;
00046     HEPEVT.phep[i][3]    = 0;
00047     HEPEVT.phep[i][4]    = 0;
00048     HEPEVT.vhep[i][0]    = 0;
00049     HEPEVT.vhep[i][1]    = 0;
00050     HEPEVT.vhep[i][2]    = 0;
00051     HEPEVT.vhep[i][3]    = 0;
00052   }
00053 }
00054 
00055 TClonesArray* UtilHepevt::getEmptyStdHep(int dfltsiz)
00056 {
00057   if (dfltsiz<0) dfltsiz = mxnhep;
00058   TClonesArray* tc = new TClonesArray("TParticle",dfltsiz);
00059   tc->SetName("StdHep");
00060   return tc;
00061 }
00062 
00063 int UtilHepevt::unpackCommon(TClonesArray* stdhep_ptr,
00064                                cvu_t vtxCvu, cvu_t tCvu)
00065 { 
00066   // Copy info from /HEPEVT/ common block into the supplied
00067   // TClonesArray of TParticles.
00068 
00069   if (stdhep_ptr == 0) return -1;  // user failed to supply an array
00070   TClonesArray &stdhep = *stdhep_ptr;
00071 
00072   double vtxscale = unitScale(vtxCvu);
00073   double tscale   = unitScale(tCvu);
00074 
00075   stdhep.Clear();  // clear what's already there
00076 
00077   int numpart = HEPEVT.nhep;
00078   for (int i = 0; i<numpart; ++i) {
00079     // force PDG # for ions into chosen canonical form
00080     int ipdg = UtilPDG::stdIonNumber(HEPEVT.idhep[i]);
00081     new(stdhep[i]) 
00082       TParticle(
00083                 ipdg, // HEPEVT.idhep[i],   // pdg
00084                 HEPEVT.isthep[i],  // status
00085                 HEPEVT.jmohep[i][0]-1,   // FORTRAN to C index shift
00086                 HEPEVT.jmohep[i][1]-1,   // FORTRAN to C index shift
00087                 HEPEVT.jdahep[i][0]-1,   // FORTRAN to C index shift
00088                 HEPEVT.jdahep[i][1]-1,   // FORTRAN to C index shift
00089                 HEPEVT.phep[i][0],
00090                 HEPEVT.phep[i][1],
00091                 HEPEVT.phep[i][2],
00092                 HEPEVT.phep[i][3],
00093                 HEPEVT.vhep[i][0]*vtxscale,
00094                 HEPEVT.vhep[i][1]*vtxscale,
00095                 HEPEVT.vhep[i][2]*vtxscale,
00096                 HEPEVT.vhep[i][3]*tscale
00097                 );
00098     TParticle* apart = dynamic_cast<TParticle*>(stdhep[i]);
00099     apart->SetCalcMass(HEPEVT.phep[i][4]); // set the mass we found
00100   }
00101 
00102   return numpart;
00103 }
00104 
00105 int UtilHepevt::fillCommon(const TClonesArray* stdhep,
00106                            cvu_t vtxCvu, cvu_t tCvu)
00107 { 
00108   // Copy info from TClonesArray of TParticles into /HEPEVT/ common block.
00109 
00110   int numpart = stdhep->GetLast() + 1;  // count of entries in the array
00111   if (numpart > mxnhep) {
00112     std::cerr << "UtilHepevt::fillCommon() mxnhep=" << mxnhep 
00113               << " but StdHep has " << numpart << " entries," << std::endl
00114               << "  /HEPEVT/ copy will be incomplete." << std::endl;
00115     numpart = mxnhep;
00116   }
00117 
00118   double vtxscale = unitScale(vtxCvu);
00119   double tscale   = unitScale(tCvu);
00120 
00121   HEPEVT.nhep = numpart;
00122 
00123   for (int i=0; i<numpart; ++i) {
00124     TParticle* apart = dynamic_cast<TParticle*>(stdhep->At(i));
00125     if (!apart) {
00126       std::cerr << "UtilHepevt::fillCommon() "
00127                 << "index " << i << " in StdHep is not a TParticle!" << std::endl;
00128       continue;  // blank entry? 
00129     }
00130     HEPEVT.isthep[i]    = apart->GetStatusCode();
00131     // force PDG # for ions into chosen canonical form
00132     int ipdg = UtilPDG::stdIonNumber(apart->GetPdgCode());
00133     HEPEVT.idhep[i]     = ipdg;  // apart->GetPdgCode();
00134     HEPEVT.jmohep[i][0] = apart->GetMother(0)   + 1; // C to FORTRAN index shift
00135     HEPEVT.jmohep[i][1] = apart->GetMother(1)   + 1; // C to FORTRAN index shift
00136     HEPEVT.jdahep[i][0] = apart->GetDaughter(0) + 1; // C to FORTRAN index shift
00137     HEPEVT.jdahep[i][1] = apart->GetDaughter(1) + 1; // C to FORTRAN index shift
00138     HEPEVT.phep[i][0]   = apart->Px();
00139     HEPEVT.phep[i][1]   = apart->Py();
00140     HEPEVT.phep[i][2]   = apart->Pz();
00141     HEPEVT.phep[i][3]   = apart->Energy();
00142     HEPEVT.phep[i][4]   = apart->GetCalcMass(); // is this the right one?
00143     HEPEVT.vhep[i][0]   = apart->Vx() * vtxscale;
00144     HEPEVT.vhep[i][1]   = apart->Vy() * vtxscale;
00145     HEPEVT.vhep[i][2]   = apart->Vz() * vtxscale;
00146     HEPEVT.vhep[i][3]   = apart->T()  * tscale;
00147   }
00148   return numpart;
00149 }
00150 
00151 int  UtilHepevt::openBinary(std::string fname, bool write)
00152 {
00153   if (fname == "") {
00154     std::cout << "UtilHepevt::openBinary can't open nameless file " << std::endl;
00155     return -1;
00156   }
00157   std::cout << "UtilHepevt::openBinary file: " << fname << " for "
00158             << (write?"write":"read") << "." << std::endl;
00159 
00160   gSystem->ResetErrno();
00161 
00162   int flags =  O_RDWR | O_CREAT | O_TRUNC ;  // | O_BINARY;
00163   if (!write) flags = O_RDONLY;
00164 
00165   int mode  = S_IREAD | S_IWRITE;   // chmod bits
00166 
00167   int fd = ::open(fname.c_str(),flags,mode);
00168 
00169   if (fd < 0) {
00170     std::cerr << "Failed to open file: " << fname 
00171               << " Errno " << gSystem->GetErrno() << std::endl;
00172   }
00173   return fd;
00174 
00175 }
00176  
00177 void UtilHepevt::closeBinary(int& fd)
00178 {
00179   if ( fd < 0 ) return;  // nothing open
00180   ::close(fd);
00181   fd = -1;
00182 }
00183 
00184 int UtilHepevt::readBinary(int& fd)
00185 { 
00186   // Read FORTRAN compatible binary file of /HEPEVT/
00187   HEPEVT.nhep = 0;
00188   if ( fd < 0 ) return -1;
00189 
00190   const ssize_t szi4 = sizeof(Int_t);
00191   const ssize_t szd8 = sizeof(Double_t);
00192 
00193   ssize_t szrecmrk   = szi4;  // initial guess: record marker size is i4
00194 
00195   Int_t    ibufhead[6];     // recsiz [0] nevhep nhep recsiz [0]
00196   Int_t    ibufrowsz1[2];   // recsiz [0] 
00197   Int_t    ibufrowdata[6];  // ist id jmo1 jmo2 jda1 jda2
00198   Double_t dbufrowdata[9];  // px py pz e m vx vy vz t
00199   Int_t    ibufrowsz2[2];   // recsiz [0] 
00200 
00201   ssize_t rhead = ::read(fd,ibufhead,2*szi4+2*szrecmrk); // assume 4byte record markers
00202   // std::cout << "readBinary rhead=" << rhead << " errno " << gSystem->GetErrno() << std::endl;
00203   if (rhead == 0) {
00204     // saw EOF
00205     closeBinary(fd);
00206     return 0;
00207   }
00208   if (ibufhead[0] != 2*sizeof(Int_t)) {  // first record should just be two ints nevhep,nhep
00209     std::cerr << "UtilHepevt::readBinary on fd=" << fd
00210               << " failed first recsize test " << ibufhead[0] << std::endl;
00211     return -2;
00212   }
00213   if (ibufhead[0] == ibufhead[3]) {
00214     HEPEVT.nevhep = ibufhead[1];
00215     HEPEVT.nhep   = ibufhead[2];
00216   } else {
00217     // oops .. 8bytes record markers
00218     szrecmrk = 2*szi4;
00219     rhead += ::read(fd,ibufhead+4*szi4,2*szi4);  // read two more ints to flesh out the szrecmrk=8
00220     if (ibufhead[0] != ibufhead[5]) {
00221       std::cerr << "UtilHepevt::readBinary on fd=" << fd << " tried recmrksiz=8, "
00222                 << " failed 2nd recsize test " << ibufhead[0] 
00223                 << " " << ibufhead[5] << std::endl;
00224       return -3;
00225     }
00226     HEPEVT.nevhep = ibufhead[2];
00227     HEPEVT.nhep   = ibufhead[3];
00228   }
00229 
00230   // now read data rows
00231   int numpart   = HEPEVT.nhep;
00232   for (int i = 0; i < numpart; ++i) {
00233     ssize_t rsz1  = ::read(fd,ibufrowsz1,szrecmrk);
00234     ssize_t rirow = ::read(fd,ibufrowdata,6*szi4);
00235     ssize_t rdrow = ::read(fd,dbufrowdata,9*szd8);
00236     ssize_t rsz2  = ::read(fd,ibufrowsz2,szrecmrk);
00237     if (ibufrowsz1[0] != 6*szi4+9*szd8 || ibufrowsz1[0] != ibufrowsz2[0] ||
00238         rsz1 != szrecmrk || rirow != 6*szi4 || rdrow != 9*szd8 || rsz2 != szrecmrk) {
00239       std::cerr << "UtilHepevt::readBinary on fd=" << fd
00240                 << ", szrecmrk=" << szrecmrk << "failed.";
00241       std::cerr << " rsz1 " << rsz1 << " data: " << ibufrowsz1[0] << " " << ibufrowsz1[1] << std::endl;
00242       std::cerr << " rsz2 " << rsz2 << " data: " << ibufrowsz2[0] << " " << ibufrowsz2[1] << std::endl;
00243       std::cerr << " rirow " << rirow << " rdrow " << rdrow << std::endl;
00244       return -4;
00245     } // bad read of row due to rec marker problems or size problems
00246     HEPEVT.isthep[i]     = ibufrowdata[0];
00247     // force PDG # for ions into chosen canonical form
00248     int ipdg = UtilPDG::stdIonNumber(ibufrowdata[1]);
00249     HEPEVT.idhep[i]      = ipdg; // ibufrowdata[1];
00250     HEPEVT.jmohep[i][0]  = ibufrowdata[2];
00251     HEPEVT.jmohep[i][1]  = ibufrowdata[3];
00252     HEPEVT.jdahep[i][0]  = ibufrowdata[4];
00253     HEPEVT.jdahep[i][1]  = ibufrowdata[5];
00254     HEPEVT.phep[i][0]    = dbufrowdata[0];
00255     HEPEVT.phep[i][1]    = dbufrowdata[1];
00256     HEPEVT.phep[i][2]    = dbufrowdata[2];
00257     HEPEVT.phep[i][3]    = dbufrowdata[3];
00258     HEPEVT.phep[i][4]    = dbufrowdata[4];
00259     HEPEVT.vhep[i][0]    = dbufrowdata[5];
00260     HEPEVT.vhep[i][1]    = dbufrowdata[6];
00261     HEPEVT.vhep[i][2]    = dbufrowdata[7];
00262     HEPEVT.vhep[i][3]    = dbufrowdata[8];
00263   } // end of rows
00264 
00265   return numpart;  // success
00266 }
00267 
00268 bool UtilHepevt::writeBinary(int fd, int szrecmrk)
00269 { 
00270   // Write FORTRAN compatible binary file of /HEPEVT/
00271 
00272   const ssize_t szi4 = sizeof(Int_t);
00273   const ssize_t szd8 = sizeof(Double_t);
00274 
00275   if (szi4 != szrecmrk && 2*szi4 != szrecmrk) {
00276     std::cerr << "UtilHepevt::writeBinary of fd=" << fd
00277               << " was passed illegal szrecmrk=" << szrecmrk
00278               << " must be " << szi4 << " or "
00279               << 2*szi4 << "."  << std::endl;
00280     return false;
00281   }
00282 
00283   Int_t    ibufhead[6]    = { 0, 0, 0, 0, 0, 0 };  // recsiz [0] nevhep nhep recsiz [0]
00284   Int_t    ibufrowsz[2]   = { 0, 0 };              // recsiz [0] 
00285   Int_t    ibufrowdata[6] = { 0, 0, 0, 0, 0, 0 };  // ist id jmo1 jmo2 jda1 jda2
00286   Double_t dbufrowdata[9] = { 0 };                 // px py pz e m vx vy vz t
00287 
00288   int i = 0, sztowrite=2*szi4+2*szrecmrk;
00289   ssize_t whead, wsz1, wirow, wdrow, wsz2;
00290 
00291   // write the header record
00292   ibufhead[i] = 2*szi4;  // first record has only two ints
00293   if (szi4 != szrecmrk) i++;  // skip a word for 8 byte record markers
00294   ibufhead[i+1] = HEPEVT.nevhep;
00295   ibufhead[i+2] = HEPEVT.nhep;
00296   ibufhead[i+3] = 2*szi4;
00297   whead = ::write(fd,ibufhead,sztowrite);
00298   if (whead != sztowrite) {
00299     std::cerr << "UtilHepevt::writeBinary fd=" << fd << " failed first write of " 
00300               << sztowrite << ", just " << whead << "." << std::endl;
00301     return false;
00302   }
00303 
00304   // write individual rows
00305   const int recsiz = 6*szi4 + 9*szd8;
00306   int numpart = HEPEVT.nhep;
00307   for (int i=0; i<numpart; ++i) {
00308     ibufrowsz[0] = recsiz;
00309 
00310     ibufrowdata[0] = HEPEVT.isthep[i];
00311     // force PDG # for ions into chosen canonical form
00312     int ipdg = UtilPDG::stdIonNumber(HEPEVT.idhep[i]);
00313     ibufrowdata[1] = ipdg; // HEPEVT.idhep[i];
00314     ibufrowdata[2] = HEPEVT.jmohep[i][0];
00315     ibufrowdata[3] = HEPEVT.jmohep[i][1];
00316     ibufrowdata[4] = HEPEVT.jdahep[i][0];
00317     ibufrowdata[5] = HEPEVT.jdahep[i][1];
00318 
00319     dbufrowdata[0] = HEPEVT.phep[i][0];
00320     dbufrowdata[1] = HEPEVT.phep[i][1];
00321     dbufrowdata[2] = HEPEVT.phep[i][2];
00322     dbufrowdata[3] = HEPEVT.phep[i][3];
00323     dbufrowdata[4] = HEPEVT.phep[i][4];
00324     dbufrowdata[5] = HEPEVT.vhep[i][0];
00325     dbufrowdata[6] = HEPEVT.vhep[i][1];
00326     dbufrowdata[7] = HEPEVT.vhep[i][2];
00327     dbufrowdata[8] = HEPEVT.vhep[i][3];
00328 
00329     wsz1  = ::write(fd,ibufrowsz,szrecmrk);
00330     wirow = ::write(fd,ibufrowdata,6*szi4);
00331     wdrow = ::write(fd,dbufrowdata,9*szd8);
00332     wsz2  = ::write(fd,ibufrowsz,szrecmrk);
00333     //std::cout << " wsz " << wsz1 << " " << wsz2 << " " << szrecmrk << std::endl;
00334     if (wsz1 != szrecmrk || wsz2 != szrecmrk || wirow != 6*szi4 || wdrow != 9*szd8) {
00335       std::cerr << "UtilHepevt::writeBinary fd=" << fd << " failed sizerec write 1" << std::endl;
00336       std::cerr << " wsz1 " << wsz1 << " wsz2 " << wsz2 
00337                 << " wirow " << wirow << " wdrow " << wdrow << "." << std::endl;
00338       return false;
00339     }
00340 
00341   } // end of rows
00342   return true;
00343 }
00344 
00345 void UtilHepevt::dump(const TClonesArray* stdhep, int mode)
00346 { 
00347   // Formatted dump of StdHep array.
00348 
00349    // mode < 0 --> nothing
00350    // mode = 0 --> suppress vtx info
00351    // mode = 1 --> include vtx info
00352 
00353    if (mode < 0 ) return;
00354 
00355    bool dovtx = (mode > 0);
00356    bool doheader = true;
00357 
00358    // Loop over array ... print each element
00359    int n = stdhep->GetLast()+1;
00360    printf("StdHep:  %d entries\n",n);
00361    for (Int_t i=0; i<n; i++) {
00362      TParticle* apart = dynamic_cast<TParticle*>(stdhep->At(i));
00363      if (!apart) {
00364        std::cout << "dumpStdhep entry " << i << " is empty" << std::endl;
00365        continue;
00366      }
00367 
00368      //rwh: apart->Print() -- does a cruddy job, do it ourselves
00369      
00370      // header before the first entry
00371      if (doheader) {
00372        doheader = kFALSE;
00373        const char* head1 =
00374          "ihep stat  type   [parent][chldrn]         px          py          pz     energy\n";
00375        // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
00376        //                          1234123412341234 123456789A 123456789A  123456789A 12345678
00377        const char* head2 =
00378          "                                           vx          vy          vz      tprod\n";
00379        printf(head1);
00380        if (dovtx) printf(head2);
00381      }
00382      
00383      static Char_t alt[64];
00384      
00385      Int_t status = apart->GetStatusCode();
00386      // if there isn't a name construct one
00387      const Char_t* name = apart->GetName();
00388      if (name[0]=='X' && name[1]=='X' && name[2] == 'X') {
00389        sprintf(alt,"%d",apart->GetPdgCode());
00390        name = alt;
00391      }
00392      Int_t first_parent = apart->GetMother(0);
00393      //Int_t last_parent  = apart->GetMother(1);
00394      Int_t first_child  = apart->GetDaughter(0);
00395      Int_t last_child   = apart->GetDaughter(1);
00396      Double_t px = apart->Px();
00397      Double_t py = apart->Py();
00398      Double_t pz = apart->Pz();
00399      Double_t energy = apart->Energy();
00400      //Double_t calcmass = apart->GetCalcMass();
00401      //Double_t mass = (apart->GetPDG())?apart->GetMass():-99999.;
00402      Double_t vx = apart->Vx();
00403      Double_t vy = apart->Vy();
00404      Double_t vz = apart->Vz();
00405      Double_t tprod = apart->T();
00406      
00407      printf("%4d(%4d)%-10.10s %4d%4d%4d",
00408             i,status,name,first_parent,first_child,last_child);
00409      printf(" %11.4e %11.4e %11.4e%11.4e\n",px,py,pz,energy);
00410      if (dovtx) {
00411        printf("                                 ");
00412        printf(" %11.4e %11.4e %11.4e%11.4e\n",vx,vy,vz,tprod);
00413      }
00414    }  // loop over entries
00415 
00416 }
00417 
00418 double UtilHepevt::unitScale(UtilHepevt::cvu_t cvu)
00419 {
00420   switch (cvu) {
00421   case k_none:     return    1.0;
00422   case k_mmtosec:  return    0.001 / TMath::C();
00423   case k_sectomm:  return 1000.0   * TMath::C();
00424   case k_cmtom:    return    0.01;
00425   case k_mtocm:    return  100.0;
00426   case k_mmtom:    return    0.001;
00427   case k_mtomm:    return 1000.0;
00428   default:
00429       std::cerr << "UtilHepevt::unitScale() passed invalid enum "
00430                 << (int)cvu << "." << std::endl;
00431       return 1.0;
00432   }
00433 }
00434 
00435 int UtilHepevt::modStatusStdHep(TClonesArray* stdhep, std::string conditional,
00436                                  int istflag)
00437 {
00446 
00447   TApplication* app = gROOT->GetApplication();
00448   std::string tmp;
00449   int nflagged = 0;
00450   int nhep = stdhep->GetLast()+1;
00451   for (int i=0; i<nhep; ++i) {
00452     TParticle* apart = dynamic_cast<TParticle*>(stdhep->At(i));
00453     int ipdg = apart->GetPdgCode();
00454     bool ischarm = UtilPDG::isCharm(ipdg);
00455     bool istau   = UtilPDG::isTau(ipdg);
00456     int  mom0    = apart->GetMother(0);
00457     int  mom1    = apart->GetMother(1);
00458     bool fromcharm = false;
00459     bool fromtau   = false;
00460     if (mom0 >= 0 && mom1 >= mom0 ) {
00461       for (int k=mom0; k<=mom1; ++k) {
00462         TParticle* mompart = dynamic_cast<TParticle*>(stdhep->At(k));
00463         int ipdgmom = mompart->GetPdgCode();
00464         if (UtilPDG::isCharm(ipdgmom)) fromcharm = true;
00465         if (UtilPDG::isTau(ipdgmom)  ) fromtau   = true;
00466       }
00467     }
00468     std::string fmt = "";
00469     fmt += " const TParticle* p = (const TParticle*)0x%lx;";
00470     fmt += " int indx=%d, ist=%d, ipdg=%d, mo0=%d, mo1=%d, da0=%d, da1=%d;";
00471     fmt += " bool ischarm=%s, istau=%s, fromcharm=%s, fromtau=%s;";
00472     fmt += " return %s; ";
00473     tmp = Form(fmt.c_str(),
00474                reinterpret_cast<unsigned long>(apart),
00475                i,
00476                apart->GetStatusCode(),
00477                ipdg,
00478                mom0,
00479                mom1,
00480                apart->GetDaughter(0),
00481                apart->GetDaughter(1),
00482                (ischarm?"true":"false"),
00483                (istau?"true":"false"),
00484                (fromcharm?"true":"false"),
00485                (fromtau?"true":"false"),
00486                conditional.c_str());
00487     int pval = app->ProcessLine(tmp.c_str());
00488     //std::cout << "ProcessLine: " << tmp << " returned " << pval << std::endl;
00489     if (pval) { apart->SetStatusCode(istflag); ++nflagged; }
00490   }
00491   return nflagged;
00492 }
00493 
00494 int UtilHepevt::squeezeStdHep(TClonesArray* stdhep, int istrm)
00495 {
00500 
00501   int nhepold = stdhep->GetLast() + 1;  // count of entries
00502   int nhepnew = 0;
00503   std::vector<int> newindx(nhepold), ist(nhepold);
00504   std::vector<int> mo0(nhepold), mo1(nhepold), da0(nhepold), da1(nhepold);
00505   int i;
00506   int nremoved = 0;
00507   // first pass through decides who to keep and puts them in temporary
00508   for (i=0; i<nhepold; ++i) {
00509     TParticle* apart = dynamic_cast<TParticle*>(stdhep->At(i));
00510     ist[i]     = apart->GetStatusCode();
00511     mo0[i]     = apart->GetMother(0);
00512     mo1[i]     = apart->GetMother(1);
00513     da0[i]     = apart->GetDaughter(0);
00514     da1[i]     = apart->GetDaughter(1);
00515     newindx[i] = -1;
00516     if ( ist[i] != istrm ) { newindx[i] = nhepnew; ++nhepnew; }
00517   }
00518   
00519   // determine new mother/daughter indices
00520   for (i=nhepold-1; i>=0; --i) {
00521     if (newindx[i] < 0) {
00522       mo0[i] = -1;
00523       mo1[i] = -1;
00524       da0[i] = -1;
00525       da1[i] = -1;
00526       continue;  // not keeping it ...
00527     } else {
00528       if (mo0[i]>=0) mo0[i] = newindx[mo0[i]];
00529       if (mo1[i]>=0) mo1[i] = newindx[mo1[i]];
00530       if (da0[i]>=0) da0[i] = newindx[da0[i]];
00531       if (da1[i]>=0) da1[i] = newindx[da1[i]];
00532     }
00533     
00534   }
00535 
00536   // second pass through asks that the entry be removed, 
00537   // or fixes the mother/dauther indices
00538   for (i=nhepold-1; i>=0; --i) { 
00539     if ( newindx[i] < 0 ) {
00540       stdhep->RemoveAt(i); 
00541       ++nremoved;
00542     } else {
00543       TParticle* apart = dynamic_cast<TParticle*>(stdhep->At(i));
00544       apart->SetFirstMother(mo0[i]);
00545       apart->SetLastMother(mo1[i]);
00546       apart->SetFirstDaughter(da0[i]);
00547       apart->SetLastDaughter(da1[i]);
00548     }
00549   }
00550   if (nremoved>0) stdhep->Compress();
00551 
00552   return nremoved;
00553 }
00554 
00555 TClonesArray* UtilHepevt::readAscii(std::istream& istrm, 
00556                                     const TLorentzVector vtx_offset)
00557 {
00558   // read event record from ascii stream 
00559   // return null pointer if EOF or error
00560 
00561   const int LINEMX = 1024;
00562   char buffer[ LINEMX ];
00563   std::string line;
00564 
00565   enum Efilefmt { kUnknown, kHeplst4, kExodus, kdump, kArgoneut };
00566   const char* fmtname[] = 
00567     { "unknown", "Heplst4", "Exodus", "dump", "Argoneut" };
00568 
00569   bool isbad = false;
00570   Efilefmt thisfilefmt = kUnknown;
00571 
00572   if ( ! istrm.good() ) {
00573     // bad input return null pointer
00574     std::cerr << "UtilHepevt::readAscii input stream !good()" << std::endl;
00575     return 0;
00576   }
00577 
00578   int nhep = 0;
00579   while ( thisfilefmt == kUnknown ) {
00580     // for now only handle file layouts that explicitly give row counts
00581     istrm.getline(buffer,LINEMX);
00582     //std::cout << "HEY: read line \"" << buffer << "\"" << std::endl;
00583     if ( ! istrm.good() ) return 0; 
00584     line = buffer;
00585     if ( line.find("StdHep:") != std::string::npos ) {
00586       std::cout << buffer << std::endl;
00587       thisfilefmt = kdump;
00588       if ( line.find("entries") == std::string::npos ) 
00589         thisfilefmt = kArgoneut;
00590       sscanf(buffer,"StdHep:%d",&nhep);
00591       istrm.getline(buffer,LINEMX);  // header line
00592       istrm.getline(buffer,LINEMX);  // header line
00593     } else if ( line.find("nhep =") != std::string::npos ) {
00594         std::cout << "** Saw nhep=" << std::endl;
00595         std::cout << buffer << std::endl;
00596         thisfilefmt = kExodus;
00597         sscanf(buffer,"nhep =%d",&nhep);
00598         istrm.getline(buffer,LINEMX);  // header line
00599         istrm.getline(buffer,LINEMX);  // header line
00600     }
00601   }
00602   //std::cout << "HEY: saw file type " << (int)thisfilefmt 
00603   //          << " " << fmtname[thisfilefmt] << " nhep = " 
00604   //          << nhep << std::endl;
00605 
00606   // get an empty TClonesArray of TParticles, we know how many entries
00607   TClonesArray* stdhep_ptr =  getEmptyStdHep(nhep);
00608 
00609   // no-entries return an empty list
00610   if ( nhep <= 0 ) return stdhep_ptr;
00611 
00612   TClonesArray &stdhep = *stdhep_ptr;
00613 
00614   double vtxscale = 1.0, tscale = 1.0;
00615   int indx_offset = 0;  // mother+daughter index ajustment FORTRAN vs. C
00616   switch ( thisfilefmt ) {
00617   case kHeplst4:  indx_offset = 1; vtxscale = 1.000; tscale = 1.000;  break; 
00618   default:        indx_offset = 0; 
00619   }
00620 
00621   // read the entries for this record
00622   for (int irow = 0; irow < nhep; ++irow) {
00623     // read first of pair
00624     char pname[ LINEMX ];
00625     int irowx, nitems;
00626     int isthep = -999, ipdg = -999;
00627     int jmo1 = -999, jmo2 = -999, jda1 = -999, jda2 = -999;
00628     double phep[5] = { 0, 0, 0, 0, 0 };
00629     double vhep[4] = { 0, 0, 0, 0 };
00630 
00631 
00632     istrm.getline(buffer,LINEMX);  // status, particle, energy line
00633     if ( ! istrm.good() ) {
00634       std::cerr << " irow " << irow << " != good()" << std::endl;
00635       isbad = true;
00636       break;
00637     }
00638     // parse the line
00639     if ( thisfilefmt == kdump ) {
00640       nitems = sscanf(buffer,"%d(%d)%s %d %d %d %lf %lf %lf %lf",
00641                       &irowx,&isthep,pname,&jmo1,&jda1,&jda2,
00642                       &phep[0],&phep[1],&phep[2],&phep[3]);
00643       jmo2 = jmo1;
00644       // translate pname to ipdg here ...
00645       std::cerr << "pname: " << pname << std::endl;
00646     } else if ( thisfilefmt == kExodus ) {
00647       nitems = sscanf(buffer,"%d(%d)%s<%d %d> %lf %lf %lf %lf",
00648                       &irowx,&isthep,pname,&jmo1,&jmo2,
00649                       &phep[0],&phep[1],&phep[2],&phep[3]);
00650       if (nitems != 9) {
00651         std::cerr << "irow " << irow << " read only " << nitems 
00652                   << " of 9 elements" << std::endl;
00653         isbad = true;
00654         break;
00655       }
00656     } else if ( thisfilefmt == kArgoneut ) {
00657       nitems = sscanf(buffer,"%d(%d)%d %d %d %d %lf %lf %lf %lf",
00658                       &irowx,&isthep,&ipdg,&jmo1,&jda1,&jda2,
00659                       &phep[0],&phep[1],&phep[2],&phep[3]);
00660       jmo2 = jmo1;
00661     }
00662     // read second of pair
00663     istrm.getline(buffer,LINEMX);  // vertex info
00664     if ( thisfilefmt == kdump ) {
00665     } else if ( thisfilefmt == kExodus ) {
00666     } else if ( thisfilefmt == kArgoneut ) {
00667       nitems = sscanf(buffer,"%lf %lf %lf %lf",
00668                       &vhep[0],&vhep[1],&vhep[2],&vhep[3]);
00669     }
00670 
00671     if (irowx != irow ) {
00672       std::cerr << " irow " << irow << " != irowx " << irowx << std::endl;
00673       isbad = true;
00674       break;
00675     }
00676 
00677     if ( ipdg > UtilPDG::kIonBase )
00678       ipdg = UtilPDG::stdIonNumber(ipdg);  // cannonical form
00679     new(stdhep[irow]) 
00680       TParticle(ipdg, // HEPEVT.idhep[i],   // pdg
00681                 isthep,  // status
00682                 jmo1 - indx_offset, // FORTRAN to C index shift
00683                 jmo2 - indx_offset, // FORTRAN to C index shift
00684                 jda1 - indx_offset, // FORTRAN to C index shift
00685                 jda2 - indx_offset, // FORTRAN to C index shift
00686                 phep[0],
00687                 phep[1],
00688                 phep[2],
00689                 phep[3],
00690                 vhep[0]*vtxscale + vtx_offset[0],
00691                 vhep[1]*vtxscale + vtx_offset[1],
00692                 vhep[2]*vtxscale + vtx_offset[2],
00693                 vhep[3]*tscale   + vtx_offset[3]
00694                 );
00695 
00696   }
00697 
00698   return stdhep_ptr;
00699 }
00700 
00701 void UtilHepevt::AppendStdHep(TClonesArray* stdhep_ptr, const TClonesArray* addon,
00702                               const TLorentzVector vtx_offset)
00703 {
00706 
00707   if (stdhep_ptr == 0) return;  // user failed to supply an array
00708   TClonesArray &stdhep = *stdhep_ptr;
00709 
00710   int numpart = stdhep_ptr->GetLast() + 1; // count of entries in original list
00711   int nadd    = addon->GetLast() + 1;  // count of entries to add
00712 
00713   for (int i = 0; i<nadd; ++i) {
00714     TParticle* apart = dynamic_cast<TParticle*>(addon->At(i));
00715     if (!apart) {
00716       std::cerr << "UtilHepevt::AppendStdHep() "
00717                 << "index " << i << " in StdHep is not a TParticle!" << std::endl;
00718       continue;  // blank entry? 
00719     }
00720     Int_t indx = numpart + i;
00721     // extract the information from the entry in the old list
00722     Int_t isthep    = apart->GetStatusCode();
00723     // force PDG # for ions into chosen canonical form
00724     Int_t ipdg = UtilPDG::stdIonNumber(apart->GetPdgCode());
00725     Int_t jmohep[2], jdahep[2];
00726     jmohep[0] = apart->GetMother(0);
00727     jmohep[1] = apart->GetMother(1);
00728     jdahep[0] = apart->GetDaughter(0);
00729     jdahep[1] = apart->GetDaughter(1);
00730     if ( jmohep[0] >= 0 ) jmohep[0] += numpart; // shift index
00731     if ( jmohep[1] >= 0 ) jmohep[1] += numpart; // shift index
00732     if ( jdahep[0] >= 0 ) jdahep[0] += numpart; // shift index
00733     if ( jdahep[1] >= 0 ) jdahep[1] += numpart; // shift index
00734     Double_t phep[5], vhep[4];
00735     phep[0]   = apart->Px();
00736     phep[1]   = apart->Py();
00737     phep[2]   = apart->Pz();
00738     phep[3]   = apart->Energy();
00739     phep[4]   = apart->GetCalcMass(); // is this the right one?
00740     vhep[0]   = apart->Vx() + vtx_offset.X();
00741     vhep[1]   = apart->Vy() + vtx_offset.Y();
00742     vhep[2]   = apart->Vz() + vtx_offset.Z();
00743     vhep[3]   = apart->T()  + vtx_offset.T();
00744     // create the new entry
00745     new(stdhep[indx]) TParticle(ipdg,    // pdg
00746                                 isthep,  // status
00747                                 jmohep[0], jmohep[1],
00748                                 jdahep[0], jdahep[1],
00749                                 phep[0], phep[1], phep[2], phep[3],
00750                                 vhep[0], vhep[1], vhep[2], vhep[3]
00751                                 );
00752     TParticle* newpart = dynamic_cast<TParticle*>(stdhep[indx]);
00753     newpart->SetCalcMass(phep[4]); // set the mass we found
00754   }
00755 
00756 }

Generated on Wed Feb 18 00:07:36 2009 for loon by doxygen 1.3.5