PhotosHEPEVTParticle.cxx

00001 #include "PhotosHEPEVTParticle.h"
00002 #include "Log.h"
00003 
00004 namespace Photospp
00005 {
00006 
00007 PhotosHEPEVTParticle::~PhotosHEPEVTParticle()
00008 {
00009   // Cleanup particles that do not belong to event
00010   for(unsigned int i=0;i<cache.size();i++)
00011     if(cache[i]->m_barcode<0)
00012       delete cache[i];
00013 }
00014 
00015 PhotosHEPEVTParticle::PhotosHEPEVTParticle(int pdgid, int status, double px, double py, double pz, double e, double m, int ms, int me, int ds, int de){
00016   m_px = px;
00017   m_py = py;
00018   m_pz = pz;
00019   m_e  = e;
00020   m_generated_mass = m;
00021 
00022   m_pdgid  = pdgid;
00023   m_status = status;
00024 
00025   m_first_mother   = ms;
00026   m_second_mother  = me;
00027   m_daughter_start = ds;
00028   m_daughter_end   = de;
00029 
00030   m_barcode = -1;
00031   m_event = NULL;
00032 }
00033 
00034 /** Add a new daughter to this particle */
00035 void PhotosHEPEVTParticle::addDaughter(PhotosParticle* daughter)
00036 {
00037   if(!m_event) Log::Fatal("PhotosHEPEVTParticle::addDaughter - particle not in event record");
00038 
00039   std::vector<PhotosParticle*> mothers = daughter->getMothers();
00040   
00041   mothers.push_back( (PhotosParticle*)this );
00042 
00043   daughter->setMothers(mothers);
00044   
00045   int bc = daughter->getBarcode();
00046 
00047   if(m_daughter_end < 0)
00048   {
00049     m_daughter_start = bc;
00050     m_daughter_end   = bc;
00051   }
00052   // if it's in the middle of the event record
00053   else if(m_daughter_end != bc-1)
00054   {
00055     PhotosHEPEVTParticle *newPart = m_event->getParticle(bc);
00056     
00057     // Move all particles one spot down the list, to make place for new particle
00058     for(int i=bc-1;i>m_daughter_end;i--)
00059     {
00060       PhotosHEPEVTParticle *move = m_event->getParticle(i);
00061       move->setBarcode(i+1);
00062       m_event->setParticle(i+1,move);
00063     }
00064 
00065     m_daughter_end++;
00066     newPart->setBarcode(m_daughter_end);
00067     m_event->setParticle(m_daughter_end,newPart);
00068     
00069     // Now: correct all pointers before new particle
00070     for(int i=0;i<m_daughter_end;i++)
00071     {
00072       PhotosHEPEVTParticle *check = m_event->getParticle(i);
00073       int m = check->getDaughterRangeEnd();
00074       if(m!=-1 && m>m_daughter_end)
00075       {
00076         check->setDaughterRangeEnd(m+1);
00077         check->setDaughterRangeStart(check->getDaughterRangeStart()+1);
00078       }
00079     }
00080   }
00081   else m_daughter_end = bc;
00082 }
00083 
00084 void PhotosHEPEVTParticle::setMothers(vector<PhotosParticle*> mothers){
00085 
00086   // If this particle has not yet been added to the event record
00087   // then add it to the mothers' event record
00088   if(m_barcode<0 && mothers.size()>0)
00089   {
00090     PhotosHEPEVTEvent *evt = ((PhotosHEPEVTParticle*)mothers[0])->m_event;
00091     evt->addParticle(this);
00092   }
00093 
00094   if(mothers.size()>2) Log::Fatal("PhotosHEPEVTParticle::setMothers: HEPEVT does not allow more than two mothers!");
00095   
00096   if(mothers.size()>0) m_first_mother  = mothers[0]->getBarcode();
00097   if(mothers.size()>1) m_second_mother = mothers[1]->getBarcode();
00098 }
00099 
00100 void PhotosHEPEVTParticle::setDaughters(vector<PhotosParticle*> daughters){
00101 
00102   // This particle must be inside some event record to be able to add daughters
00103   if(m_event==NULL) Log::Fatal("PhotosHEPEVTParticle::setDaughters: particle not inside event record.");
00104 
00105   int beg = 65535, end = -1;
00106 
00107   for(unsigned int i=0;i<daughters.size();i++)
00108   {
00109     int bc = daughters[i]->getBarcode();
00110     if(bc<0) Log::Fatal("PhotosHEPEVTParticle::setDaughters: all daughters has to be in event record first");
00111     if(bc<beg) beg = bc;
00112     if(bc>end) end = bc;
00113   }
00114   if(end == -1) beg = -1;
00115 
00116   m_daughter_start = beg;
00117   m_daughter_end   = end;
00118 }
00119 
00120 std::vector<PhotosParticle*> PhotosHEPEVTParticle::getMothers(){
00121 
00122   std::vector<PhotosParticle*> mothers;
00123 
00124   PhotosParticle *p1 = NULL;
00125   PhotosParticle *p2 = NULL;
00126   
00127   if(m_first_mother>=0)  p1 = m_event->getParticle(m_first_mother);
00128   if(m_second_mother>=0) p2 = m_event->getParticle(m_second_mother);
00129 
00130   if(p1) mothers.push_back(p1);
00131   if(p2) mothers.push_back(p2);
00132 
00133   return mothers;
00134 }
00135 
00136 // WARNING: this method also corrects daughter indices 
00137 //          if such were not defined
00138 std::vector<PhotosParticle*> PhotosHEPEVTParticle::getDaughters(){
00139 
00140   std::vector<PhotosParticle*> daughters;
00141 
00142   if(!m_event) return daughters;
00143 
00144   // Check if m_daughter_start and m_daughter_end are set
00145   // If not - try to get list of daughters from event
00146   if(m_daughter_end<0)
00147   {
00148     int min_d=65535, max_d=-1;
00149     for(int i=0;i<m_event->getParticleCount();i++)
00150     {
00151       if(m_event->getParticle(i)->isDaughterOf(this))
00152       {
00153         if(i<min_d) min_d = i;
00154         if(i>max_d) max_d = i;
00155       }
00156     }
00157     if(max_d>=0)
00158     {
00159       m_daughter_start = min_d;
00160       m_daughter_end   = max_d;
00161       m_status         = 2;
00162     }
00163   }
00164 
00165   // If m_daughter_end is still not set - there are no daughters
00166   // Otherwsie - get daughters
00167   if(m_daughter_end>=0)
00168   {
00169     for(int i=m_daughter_start;i<=m_daughter_end;i++)
00170     {
00171       PhotosParticle *p = m_event->getParticle(i);
00172       if(p==NULL)
00173       {
00174         Log::Warning()<<"PhotosHEPEVTParticle::getDaughters(): No particle with index "<<i<<endl;
00175         return daughters;
00176       }
00177 
00178       daughters.push_back(p);
00179     }
00180   }
00181 
00182   return daughters;
00183 }
00184 
00185 std::vector<PhotosParticle*> PhotosHEPEVTParticle::getAllDecayProducts()
00186 {
00187   std::vector<PhotosParticle*> list;
00188 
00189   if(!hasDaughters()) // if this particle has no daughters
00190     return list;
00191 
00192   std::vector<PhotosParticle*> daughters = getDaughters();
00193   
00194   // copy daughters to list of all decay products
00195   list.insert(list.end(),daughters.begin(),daughters.end());
00196   
00197   // Now, get all daughters recursively, without duplicates.
00198   // That is, for each daughter:
00199   // 1)  get list of her daughters
00200   // 2)  for each particle on this list:
00201   //  a) check if it is already on the list
00202   //  b) if it's not, add her to the end of the list
00203   for(unsigned int i=0;i<list.size();i++)
00204   {
00205     std::vector<PhotosParticle*> daughters2 = list[i]->getDaughters();
00206 
00207     if(!list[i]->hasDaughters()) continue;
00208     for(unsigned int j=0;j<daughters2.size();j++)
00209     {
00210       bool add=true;
00211       for(unsigned int k=0;k<list.size();k++)
00212         if( daughters2[j]->getBarcode() == list[k]->getBarcode() )
00213         {
00214           add=false;
00215           break;
00216         }
00217 
00218       if(add) list.push_back(daughters2[j]);
00219     }
00220   }
00221 
00222   return list;
00223 }
00224 
00225 bool PhotosHEPEVTParticle::checkMomentumConservation(){
00226 
00227   if(!m_event)           return true;
00228   if(m_daughter_end < 0) return true;
00229 
00230   PhotosHEPEVTParticle *buf = m_event->getParticle(m_daughter_start);
00231 
00232   int first_mother_idx  = buf->getFirstMotherIndex();
00233   int second_mother_idx = buf->getSecondMotherIndex();
00234 
00235   double px =0.0, py =0.0, pz =0.0, e =0.0;
00236   double px2=0.0, py2=0.0, pz2=0.0, e2=0.0;
00237 
00238   for(int i=m_daughter_start;i<=m_daughter_end;i++)
00239   {
00240     buf = m_event->getParticle(i);
00241     px += buf->getPx();
00242     py += buf->getPy();
00243     pz += buf->getPz();
00244     e  += buf->getE ();
00245   }
00246 
00247   if(first_mother_idx>=0)
00248   {
00249     buf = m_event->getParticle(first_mother_idx);
00250     px2 += buf->getPx();
00251     py2 += buf->getPy();
00252     pz2 += buf->getPz();
00253     e2  += buf->getE();
00254   }
00255   
00256   if(second_mother_idx>=0)
00257   {
00258     buf = m_event->getParticle(second_mother_idx);
00259     px2 += buf->getPx();
00260     py2 += buf->getPy();
00261     pz2 += buf->getPz();
00262     e2  += buf->getE();
00263   }
00264   // 3-momentum  // test HepMC style
00265   double dp = sqrt( (px-px2)*(px-px2) + (py-py2)*(py-py2) + (pz-pz2)*(pz-pz2) );
00266   // virtuality test as well.
00267   double m1 = sqrt( fabs( e*e   - px*px   - py*py   - pz*pz   ) );
00268   double m2 = sqrt( fabs( e2*e2 - px2*px2 - py2*py2 - pz2*pz2 ) );
00269 
00270   if( fabs(m1-m2) > 0.0001 || dp > 0.0001*(e+e2))
00271   {
00272     Log::RedirectOutput( Log::Warning()<<"Momentum not conserved in vertex: " );
00273     if(first_mother_idx >=0) m_event->getParticle(first_mother_idx) ->print();
00274     if(second_mother_idx>=0) m_event->getParticle(second_mother_idx)->print();
00275     for(int i=m_daughter_start;i<=m_daughter_end;i++) m_event->getParticle(i)->print();
00276     Log::RevertOutput();
00277     return false;
00278   }
00279   
00280   return true;
00281 }
00282 
00283 PhotosHEPEVTParticle * PhotosHEPEVTParticle::createNewParticle(
00284                         int pdg_id, int status, double mass,
00285                         double px, double py, double pz, double e){
00286 
00287   // New particles created using this method are added to cache
00288   // They will be deleted when this particle will be deleted
00289 
00290   cache.push_back(new PhotosHEPEVTParticle(pdg_id,status,px,py,pz,e,mass,-1,-1,-1,-1));
00291   return cache.back();
00292 }
00293 
00294 void PhotosHEPEVTParticle::createHistoryEntry()
00295 {
00296   Log::Warning()<<"PhotosParticle::createHistoryEntry() not implemented for HEPEVT."<<endl;
00297 }
00298 
00299 void PhotosHEPEVTParticle::createSelfDecayVertex(PhotosParticle *out)
00300 {
00301   Log::Warning()<<"PhotosHEPEVTParticle::createSelfDecayVertex() not implemented for HEPEVT."<<endl;
00302 }
00303 
00304 bool PhotosHEPEVTParticle::isDaughterOf(PhotosHEPEVTParticle *p)
00305 {
00306   int bc = p->getBarcode();
00307   if(bc==m_first_mother || bc==m_second_mother) return true;
00308 
00309   return false;
00310 }
00311 
00312 bool PhotosHEPEVTParticle::isMotherOf  (PhotosHEPEVTParticle *p)
00313 {
00314   int bc = p->getBarcode();
00315   if(bc>=m_daughter_start && bc<=m_daughter_end) return true;
00316 
00317   return false;
00318 }
00319 
00320 void PhotosHEPEVTParticle::print(){
00321   char buf[256];
00322   sprintf(buf,"P: (%2i) %6i %2i | %11.4e %11.4e %11.4e %11.4e | %11.4e | M: %2i %2i | D: %2i %2i\n",
00323           m_barcode, m_pdgid, m_status, m_px, m_py, m_pz, m_e, m_generated_mass,
00324           m_first_mother, m_second_mother,   m_daughter_start, m_daughter_end);
00325 
00326   cout<<buf;
00327 }
00328 
00329 /******** Getter and Setter methods: ***********************/
00330 
00331 void PhotosHEPEVTParticle::setPdgID(int pdg_id){
00332   m_pdgid = pdg_id;
00333 }
00334 
00335 void PhotosHEPEVTParticle::setStatus(int status){
00336   m_status = status;
00337 }
00338 
00339 void PhotosHEPEVTParticle::setMass(double mass){
00340   m_generated_mass = mass;
00341 }
00342 
00343 int PhotosHEPEVTParticle::getPdgID(){
00344   return m_pdgid;
00345 }
00346 
00347 int PhotosHEPEVTParticle::getStatus(){
00348   return m_status;
00349 }
00350 
00351 double PhotosHEPEVTParticle::getMass(){
00352   return m_generated_mass;
00353 }
00354 
00355 inline double PhotosHEPEVTParticle::getPx(){
00356   return m_px;
00357 }
00358 
00359 inline double PhotosHEPEVTParticle::getPy(){
00360   return m_py;
00361 }
00362 
00363 double PhotosHEPEVTParticle::getPz(){
00364   return m_pz;
00365 }
00366 
00367 double PhotosHEPEVTParticle::getE(){
00368   return m_e;
00369 }
00370 
00371 void PhotosHEPEVTParticle::setPx(double px){
00372   m_px = px;
00373 }
00374 
00375 void PhotosHEPEVTParticle::setPy(double py){
00376   m_py = py;
00377 }
00378 
00379 
00380 void PhotosHEPEVTParticle::setPz(double pz){
00381   m_pz = pz;
00382 }
00383 
00384 void PhotosHEPEVTParticle::setE(double e){
00385   m_e = e;
00386 }
00387 
00388 int PhotosHEPEVTParticle::getBarcode(){
00389   return m_barcode;
00390 }
00391 
00392 void PhotosHEPEVTParticle::setBarcode(int barcode){
00393   m_barcode = barcode;
00394 }
00395 
00396 void PhotosHEPEVTParticle::setEvent(PhotosHEPEVTEvent *event){
00397   m_event = event;
00398 }
00399 
00400 int PhotosHEPEVTParticle::getFirstMotherIndex(){
00401   return m_first_mother;
00402 }
00403 
00404 int PhotosHEPEVTParticle::getSecondMotherIndex(){
00405   return m_second_mother;
00406 }
00407 
00408 int PhotosHEPEVTParticle::getDaughterRangeStart(){
00409   return m_daughter_start;
00410 }
00411 
00412 int PhotosHEPEVTParticle::getDaughterRangeEnd(){
00413   return m_daughter_end;
00414 }
00415 
00416 } // namespace Photospp
Generated on Sun Oct 20 20:23:56 2013 for C++InterfacetoPHOTOS by  doxygen 1.6.3