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
00028
00029
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
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
00053
00054 clear(m_mothers);
00055
00056
00057 if(mothers.size()>0){
00058
00059 HepMC::GenParticle * part;
00060 part=dynamic_cast<PhotosHepMCParticle*>(mothers.at(0))->getHepMC();
00061
00062
00063 HepMC::GenVertex * production_vertex = part->end_vertex();
00064 HepMC::GenVertex * orig_production_vertex = production_vertex;
00065
00066 if(!production_vertex){
00067 production_vertex = new HepMC::GenVertex();
00068 part->parent_event()->add_vertex(production_vertex);
00069 }
00070
00071
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
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
00097 m_daughters.push_back(daughter);
00098
00099
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
00117 if(daughters.size()>0){
00118
00119
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){
00128 end_vertex = new HepMC::GenVertex();
00129 m_particle->parent_event()->add_vertex(end_vertex);
00130 }
00131
00132
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
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())
00194 return m_decay_products;
00195
00196 std::vector<PhotosParticle*> daughters = getDaughters();
00197
00198
00199 m_decay_products.insert(m_decay_products.end(),daughters.begin(),daughters.end());
00200
00201
00202
00203
00204
00205
00206
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
00234
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
00339 HepMC::GenParticle *outgoing = new HepMC::GenParticle( *(dynamic_cast<PhotosHepMCParticle*>(out)->m_particle) );
00340 HepMC::GenVertex *v = new HepMC::GenVertex();
00341
00342
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
00351 if(getStatus()==1) setStatus(2);
00352 }
00353
00354 void PhotosHepMCParticle::print(){
00355 m_particle->print();
00356 }
00357
00358
00359
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
00379
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 }