PhotosHepMCParticle.cxx

00001 #include "HepMC/GenEvent.h"
00002 #include "PhotosHepMCParticle.h"
00003 #include "Log.h"
00004 #include "Photos.h"
00005 
00006 namespace Photospp
00007 {
00008 
00009 PhotosHepMCParticle::PhotosHepMCParticle(){
00010   m_particle = new HepMC::GenParticle();
00011 }
00012 
00013 PhotosHepMCParticle::PhotosHepMCParticle(int pdg_id, int status, double mass){
00014   m_particle = new HepMC::GenParticle();
00015   m_particle->set_pdg_id(pdg_id);
00016   m_particle->set_status(status);
00017   m_particle->set_generated_mass(mass);
00018 }
00019 
00020 PhotosHepMCParticle::PhotosHepMCParticle(HepMC::GenParticle * particle){
00021   m_particle = particle;
00022 }
00023 
00024 PhotosHepMCParticle::~PhotosHepMCParticle(){
00025   clear(m_mothers);
00026   clear(m_daughters);
00027   //  clear(m_created_particles);
00028 
00029   // Delete HepMC particle if it's not attached to any vertex or event
00030   if( m_particle &&
00031      !m_particle->parent_event() &&
00032      !m_particle->production_vertex() &&
00033      !m_particle->end_vertex()) delete m_particle;
00034 }
00035  
00036 
00037 //delete the TauolaHepMCParticle objects
00038 void PhotosHepMCParticle::clear(std::vector<PhotosParticle*> v){
00039   while(v.size()!=0){
00040     PhotosParticle * temp = v.back();
00041     v.pop_back();
00042     delete temp;
00043   }
00044 }
00045 
00046 HepMC::GenParticle * PhotosHepMCParticle::getHepMC(){
00047   return m_particle;
00048 }
00049 
00050 void PhotosHepMCParticle::setMothers(vector<PhotosParticle*> mothers){
00051 
00052   /******** Deal with mothers ***********/
00053 
00054   clear(m_mothers);
00055 
00056   //If there are mothers
00057   if(mothers.size()>0){
00058 
00059     HepMC::GenParticle * part;
00060     part=dynamic_cast<PhotosHepMCParticle*>(mothers.at(0))->getHepMC();
00061 
00062     //Use end vertex of first mother as production vertex for particle
00063     HepMC::GenVertex * production_vertex = part->end_vertex();
00064     HepMC::GenVertex * orig_production_vertex = production_vertex;
00065 
00066     if(!production_vertex){ //if it does not exist create it
00067       production_vertex = new HepMC::GenVertex();
00068       part->parent_event()->add_vertex(production_vertex);
00069     }
00070 
00071     //Loop over all mothers to check that the end points to the right place
00072     vector<PhotosParticle*>::iterator mother_itr;
00073     for(mother_itr = mothers.begin(); mother_itr != mothers.end();
00074         mother_itr++){
00075 
00076       HepMC::GenParticle * moth;
00077       moth = dynamic_cast<PhotosHepMCParticle*>(*mother_itr)->getHepMC();
00078 
00079       if(moth->end_vertex()!=orig_production_vertex)
00080         Log::Fatal("PhotosHepMCParticle::setMothers(): Mother production_vertices point to difference places. Can not override. Please delete vertices first.",1);
00081       else
00082         production_vertex->add_particle_in(moth);
00083 
00084       //update status info
00085       if(moth->status()==PhotosParticle::STABLE)
00086         moth->set_status(PhotosParticle::DECAYED);
00087     }
00088     production_vertex->add_particle_out(m_particle);
00089   }
00090 }
00091 
00092 
00093 
00094 void PhotosHepMCParticle::addDaughter(PhotosParticle* daughter){
00095 
00096   //add to this classes internal list as well.
00097   m_daughters.push_back(daughter);
00098 
00099   //this assumes there is already an end vertex for the particle
00100 
00101   if(!m_particle->end_vertex())
00102     Log::Fatal("PhotosHepMCParticle::addDaughter(): This method assumes an end_vertex exists. Maybe you really want to use setDaughters.",2);
00103 
00104   HepMC::GenParticle * daugh = (dynamic_cast<PhotosHepMCParticle*>(daughter))->getHepMC();
00105   m_particle->end_vertex()->add_particle_out(daugh);
00106   
00107 }
00108 
00109 void PhotosHepMCParticle::setDaughters(vector<PhotosParticle*> daughters){
00110 
00111   if(!m_particle->parent_event())
00112     Log::Fatal("PhotosHepMCParticle::setDaughters(): New particle needs the event set before it's daughters can be added",3);
00113 
00114   clear(m_daughters);
00115 
00116   //If there are daughters
00117   if(daughters.size()>0){
00118 
00119     //Use production vertex of first daughter as end vertex for particle
00120     HepMC::GenParticle * first_daughter;
00121     first_daughter = (dynamic_cast<PhotosHepMCParticle*>(daughters.at(0)))->getHepMC();
00122 
00123     HepMC::GenVertex * end_vertex;
00124     end_vertex=first_daughter->production_vertex();
00125     HepMC::GenVertex * orig_end_vertex = end_vertex;
00126 
00127     if(!end_vertex){ //if it does not exist create it
00128       end_vertex = new HepMC::GenVertex();
00129       m_particle->parent_event()->add_vertex(end_vertex);
00130     }
00131 
00132     //Loop over all daughters to check that the end points to the right place
00133     vector<PhotosParticle*>::iterator daughter_itr;
00134     for(daughter_itr = daughters.begin(); daughter_itr != daughters.end();
00135         daughter_itr++){
00136 
00137       HepMC::GenParticle * daug;
00138       daug = dynamic_cast<PhotosHepMCParticle*>(*daughter_itr)->getHepMC();
00139 
00140 
00141       if(daug->production_vertex()!=orig_end_vertex)
00142         Log::Fatal("PhotosHepMCParticle::setDaughters(): Daughter production_vertices point to difference places. Can not override. Please delete vertices first.",4);
00143       else
00144         end_vertex->add_particle_out(daug);
00145     }
00146     end_vertex->add_particle_in(m_particle);
00147   }
00148 
00149 }
00150 
00151 std::vector<PhotosParticle*> PhotosHepMCParticle::getMothers(){
00152 
00153   if(m_mothers.size()==0&&m_particle->production_vertex()){
00154 
00155     HepMC::GenVertex::particles_in_const_iterator pcle_itr;
00156     pcle_itr=m_particle->production_vertex()->particles_in_const_begin();
00157     
00158     HepMC::GenVertex::particles_in_const_iterator pcle_itr_end;
00159     pcle_itr_end=m_particle->production_vertex()->particles_in_const_end();
00160     
00161     for(;pcle_itr != pcle_itr_end; pcle_itr++){
00162       m_mothers.push_back(new PhotosHepMCParticle(*pcle_itr));
00163     }
00164   }
00165   return m_mothers;
00166 }
00167 
00168 std::vector<PhotosParticle*> PhotosHepMCParticle::getDaughters(){
00169 
00170   if(m_daughters.size()==0&&m_particle->end_vertex()){
00171     HepMC::GenVertex::particles_out_const_iterator pcle_itr;
00172     pcle_itr=m_particle->end_vertex()->particles_out_const_begin();
00173     
00174     HepMC::GenVertex::particles_out_const_iterator pcle_itr_end;
00175     pcle_itr_end=m_particle->end_vertex()->particles_out_const_end();
00176     
00177     for(;pcle_itr != pcle_itr_end; pcle_itr++){
00178 
00179       // ommit particles if their status code is ignored by Photos
00180       if( Photos::isStatusCodeIgnored( (*pcle_itr)->status() ) ) continue;
00181 
00182       m_daughters.push_back(new PhotosHepMCParticle(*pcle_itr));
00183     }
00184   }
00185   return m_daughters;
00186 
00187 }
00188 
00189 std::vector<PhotosParticle*> PhotosHepMCParticle::getAllDecayProducts(){
00190 
00191   m_decay_products.clear();
00192 
00193   if(!hasDaughters()) // if this particle has no daughters
00194     return m_decay_products;
00195 
00196   std::vector<PhotosParticle*> daughters = getDaughters();
00197   
00198   // copy daughters to list of all decay products
00199   m_decay_products.insert(m_decay_products.end(),daughters.begin(),daughters.end());
00200   
00201   // Now, get all daughters recursively, without duplicates.
00202   // That is, for each daughter:
00203   // 1)  get list of her daughters
00204   // 2)  for each particle on this list:
00205   //  a) check if it is already on the list
00206   //  b) if it's not, add her to the end of the list
00207   for(unsigned int i=0;i<m_decay_products.size();i++)
00208   {
00209     std::vector<PhotosParticle*> daughters2 = m_decay_products[i]->getDaughters();
00210 
00211     if(!m_decay_products[i]->hasDaughters()) continue;
00212     for(unsigned int j=0;j<daughters2.size();j++)
00213     {
00214       bool add=true;
00215       for(unsigned int k=0;k<m_decay_products.size();k++)
00216         if( daughters2[j]->getBarcode() == m_decay_products[k]->getBarcode() )
00217         {
00218           add=false;
00219           break;
00220         }
00221 
00222       if(add) m_decay_products.push_back(daughters2[j]);
00223     }
00224   }
00225 
00226   return m_decay_products;
00227 }
00228 
00229 bool PhotosHepMCParticle::checkMomentumConservation(){
00230 
00231   if(!m_particle->end_vertex()) return true;
00232   
00233   // HepMC version of check_momentum_conservation
00234   // Ommitting history entries (status == 3)
00235 
00236   double sumpx = 0, sumpy = 0, sumpz = 0, sume = 0;
00237   for( HepMC::GenVertex::particles_in_const_iterator part1 = m_particle->end_vertex()->particles_in_const_begin();
00238        part1 != m_particle->end_vertex()->particles_in_const_end(); part1++ ){
00239 
00240     if( Photos::isStatusCodeIgnored((*part1)->status()) ) continue;
00241 
00242     sumpx += (*part1)->momentum().px();
00243     sumpy += (*part1)->momentum().py();
00244     sumpz += (*part1)->momentum().pz();
00245     sume  += (*part1)->momentum().e();
00246   }
00247   
00248   for( HepMC::GenVertex::particles_out_const_iterator part2 = m_particle->end_vertex()->particles_out_const_begin();
00249        part2 != m_particle->end_vertex()->particles_out_const_end(); part2++ ){
00250 
00251     if( Photos::isStatusCodeIgnored((*part2)->status()) ) continue;
00252 
00253     sumpx -= (*part2)->momentum().px();
00254     sumpy -= (*part2)->momentum().py();
00255     sumpz -= (*part2)->momentum().pz();
00256     sume  -= (*part2)->momentum().e();
00257   }
00258 
00259   if( sqrt( sumpx*sumpx + sumpy*sumpy + sumpz*sumpz + sume*sume) > Photos::momentum_conservation_threshold ) {
00260     Log::Warning()<<"Momentum not conserved in the vertex:"<<endl;
00261     Log::RedirectOutput(Log::Warning(false));
00262     m_particle->end_vertex()->print();
00263     Log::RevertOutput();
00264     return false;
00265   }
00266   
00267   return true;
00268 }
00269 
00270 void PhotosHepMCParticle::setPdgID(int pdg_id){
00271   m_particle->set_pdg_id(pdg_id);
00272 }
00273 
00274 void PhotosHepMCParticle::setMass(double mass){
00275   m_particle->set_generated_mass(mass);
00276 }
00277 
00278 void PhotosHepMCParticle::setStatus(int status){
00279   m_particle->set_status(status);
00280 }
00281 
00282 int PhotosHepMCParticle::getPdgID(){
00283   return m_particle->pdg_id();
00284 }
00285 
00286 int PhotosHepMCParticle::getStatus(){
00287   return m_particle->status();
00288 }
00289 
00290 int PhotosHepMCParticle::getBarcode(){
00291   return m_particle->barcode();
00292 }
00293 
00294 
00295 PhotosHepMCParticle * PhotosHepMCParticle::createNewParticle(
00296                         int pdg_id, int status, double mass,
00297                         double px, double py, double pz, double e){
00298 
00299   PhotosHepMCParticle * new_particle = new PhotosHepMCParticle();
00300   new_particle->getHepMC()->set_pdg_id(pdg_id);
00301   new_particle->getHepMC()->set_status(status);
00302   new_particle->getHepMC()->set_generated_mass(mass);
00303 
00304   HepMC::FourVector momentum(px,py,pz,e);
00305   new_particle->getHepMC()->set_momentum(momentum);
00306 
00307   m_created_particles.push_back(new_particle);
00308   return new_particle;
00309 }
00310 
00311 void PhotosHepMCParticle::createHistoryEntry(){
00312 
00313   if(!m_particle->production_vertex())
00314   {
00315     Log::Warning()<<"PhotosHepMCParticle::createHistoryEntry(): particle without production vertex."<<endl;
00316     return;
00317   }
00318   
00319   HepMC::GenParticle *part = new HepMC::GenParticle(*m_particle);
00320   part->set_status(Photos::historyEntriesStatus);
00321   m_particle->production_vertex()->add_particle_out(part);
00322 }
00323 
00324 void PhotosHepMCParticle::createSelfDecayVertex(PhotosParticle *out)
00325 {
00326   if(m_particle->end_vertex())
00327   {
00328     Log::Error()<<"PhotosHepMCParticle::createSelfDecayVertex: particle already has end vertex!"<<endl;
00329     return;
00330   }
00331 
00332   if(getHepMC()->parent_event()==NULL)
00333   {
00334     Log::Error()<<"PhotosHepMCParticle::createSelfDecayVertex: particle not in the HepMC event!"<<endl;
00335     return;
00336   }
00337 
00338   // Add new vertex and new particle to HepMC
00339   HepMC::GenParticle *outgoing = new HepMC::GenParticle( *(dynamic_cast<PhotosHepMCParticle*>(out)->m_particle) );
00340   HepMC::GenVertex   *v        = new HepMC::GenVertex();
00341   
00342   // Copy vertex position from parent vertex
00343   v->set_position( m_particle->production_vertex()->position() );
00344   
00345   v->add_particle_in (m_particle);
00346   v->add_particle_out(outgoing);
00347   
00348   getHepMC()->parent_event()->add_vertex(v);
00349   
00350   // If this particle was stable, set its status to 2
00351   if(getStatus()==1) setStatus(2);
00352 }
00353 
00354 void PhotosHepMCParticle::print(){
00355   m_particle->print();
00356 }
00357 
00358 
00359 /******** Getter and Setter methods: ***********************/
00360 
00361 inline double PhotosHepMCParticle::getPx(){
00362   return m_particle->momentum().px();
00363 }
00364 
00365 inline double PhotosHepMCParticle::getPy(){
00366   return m_particle->momentum().py();
00367 }
00368 
00369 double PhotosHepMCParticle::getPz(){
00370   return m_particle->momentum().pz();
00371 }
00372 
00373 double PhotosHepMCParticle::getE(){
00374   return m_particle->momentum().e();
00375 }
00376 
00377 void PhotosHepMCParticle::setPx(double px){
00378   //make new momentum as something is wrong with
00379   //the HepMC momentum setters
00380 
00381   HepMC::FourVector momentum(m_particle->momentum());
00382   momentum.setPx(px);
00383   m_particle->set_momentum(momentum);
00384 }
00385 
00386 void PhotosHepMCParticle::setPy(double py){
00387   HepMC::FourVector momentum(m_particle->momentum());
00388   momentum.setPy(py);
00389   m_particle->set_momentum(momentum);
00390 }
00391 
00392 
00393 void PhotosHepMCParticle::setPz(double pz){
00394   HepMC::FourVector momentum(m_particle->momentum());
00395   momentum.setPz(pz);
00396   m_particle->set_momentum(momentum);
00397 }
00398 
00399 void PhotosHepMCParticle::setE(double e){
00400   HepMC::FourVector momentum(m_particle->momentum());
00401   momentum.setE(e);
00402   m_particle->set_momentum(momentum);
00403 }
00404 
00405 double PhotosHepMCParticle::getMass()
00406 {
00407         return m_particle->generated_mass();
00408 }
00409 
00410 } // namespace Photospp
Generated on Sun Oct 20 20:23:56 2013 for C++InterfacetoPHOTOS by  doxygen 1.6.3