1 #include "TauolaHepMCParticle.h"
7 TauolaHepMCParticle::TauolaHepMCParticle(){
8 m_particle = new HepMC::GenParticle();
11 TauolaHepMCParticle::~TauolaHepMCParticle(){
13 //delete the mother and daughter pointers
14 while(m_mothers.size()!=0){
15 TauolaParticle * temp = m_mothers.back();
19 while(m_daughters.size()!=0){
20 TauolaParticle * temp = m_daughters.back();
21 m_daughters.pop_back();
25 while(m_created_particles.size()!=0){
26 TauolaHepMCParticle * temp = (TauolaHepMCParticle*) m_created_particles.back();
27 m_created_particles.pop_back();
28 if(temp->getHepMC()->barcode()==0) delete temp->getHepMC();
34 // NOTE: Not executed by release examples
35 TauolaHepMCParticle::TauolaHepMCParticle(int pdg_id, int status, double mass){
36 m_particle = new HepMC::GenParticle();
37 m_particle->set_pdg_id(pdg_id);
38 m_particle->set_status(status);
39 m_particle->set_generated_mass(mass);
42 TauolaHepMCParticle::TauolaHepMCParticle(HepMC::GenParticle * particle){
43 m_particle = particle;
46 HepMC::GenParticle * TauolaHepMCParticle::getHepMC(){
50 void TauolaHepMCParticle::undecay(){
51 std::vector<TauolaParticle*> daughters = getDaughters();
52 std::vector<TauolaParticle*>::iterator dIter = daughters.begin();
54 for(; dIter != daughters.end(); dIter++)
57 if(m_particle->end_vertex())
59 while(m_particle->end_vertex()->particles_out_size())
61 HepMC::GenParticle *p = m_particle->end_vertex()->remove_particle(*(m_particle->end_vertex()->particles_out_const_begin()));
64 delete m_particle->end_vertex();
68 m_particle->set_status(TauolaParticle::STABLE);
70 for(unsigned int i=0;i<daughters.size();i++)
74 void TauolaHepMCParticle::setMothers(vector<TauolaParticle*> mothers){
76 /******** Deal with mothers ***********/
78 //If there are mothers
81 HepMC::GenParticle * part;
82 part=dynamic_cast<TauolaHepMCParticle*>(mothers.at(0))->getHepMC();
84 //Use end vertex of first mother as production vertex for particle
85 HepMC::GenVertex * production_vertex = part->end_vertex();
86 HepMC::GenVertex * orig_production_vertex = production_vertex;
88 //If production_vertex does not exist - create it
89 //If it's tau decay - set the time and position including the tau lifetime correction
90 //otherwise - copy the time and position of decaying particle
91 if(!production_vertex){
92 production_vertex = new HepMC::GenVertex();
93 HepMC::FourVector point = part->production_vertex()->position();
94 production_vertex->set_position(point);
95 part->parent_event()->add_vertex(production_vertex);
98 //Loop over all mothers to check that the end points to the right place
99 vector<TauolaParticle*>::iterator mother_itr;
100 for(mother_itr = mothers.begin(); mother_itr != mothers.end();
103 HepMC::GenParticle * moth;
104 moth = dynamic_cast<TauolaHepMCParticle*>(*mother_itr)->getHepMC();
106 if(moth->end_vertex()!=orig_production_vertex)
107 Log::Fatal("Mother production_vertices point to difference places. Can not override. Please delete vertices first.",1);
109 production_vertex->add_particle_in(moth);
112 if(moth->status()==TauolaParticle::STABLE)
113 moth->set_status(TauolaParticle::DECAYED);
115 production_vertex->add_particle_out(m_particle);
119 void TauolaHepMCParticle::setDaughters(vector<TauolaParticle*> daughters){
121 if(!m_particle->parent_event())
122 Log::Fatal("New particle needs the event set before it's daughters can be added",2);
124 //If there are daughters
125 if(daughters.size()>0){
126 // NOTE: Not executed by release examples
127 // because daughters.size() is always 0
129 //Use production vertex of first daughter as end vertex for particle
130 HepMC::GenParticle * first_daughter;
131 first_daughter = (dynamic_cast<TauolaHepMCParticle*>(daughters.at(0)))->getHepMC();
133 HepMC::GenVertex * end_vertex;
134 end_vertex=first_daughter->production_vertex();
135 HepMC::GenVertex * orig_end_vertex = end_vertex;
137 if(!end_vertex){ //if it does not exist create it
138 end_vertex = new HepMC::GenVertex();
139 m_particle->parent_event()->add_vertex(end_vertex);
142 //Loop over all daughters to check that the end points to the right place
143 vector<TauolaParticle*>::iterator daughter_itr;
144 for(daughter_itr = daughters.begin(); daughter_itr != daughters.end();
147 HepMC::GenParticle * daug;
148 daug = dynamic_cast<TauolaHepMCParticle*>(*daughter_itr)->getHepMC();
151 if(daug->production_vertex()!=orig_end_vertex)
152 Log::Fatal("Daughter production_vertices point to difference places. Can not override. Please delete vertices first.",3);
154 end_vertex->add_particle_out(daug);
156 end_vertex->add_particle_in(m_particle);
160 std::vector<TauolaParticle*> TauolaHepMCParticle::getMothers(){
162 if(m_mothers.size()==0&&m_particle->production_vertex()){
163 HepMC::GenVertex::particles_in_const_iterator pcle_itr;
164 pcle_itr=m_particle->production_vertex()->particles_in_const_begin();
166 HepMC::GenVertex::particles_in_const_iterator pcle_itr_end;
167 pcle_itr_end=m_particle->production_vertex()->particles_in_const_end();
169 for(;pcle_itr != pcle_itr_end; pcle_itr++){
170 m_mothers.push_back(new TauolaHepMCParticle(*pcle_itr));
176 std::vector<TauolaParticle*> TauolaHepMCParticle::getDaughters(){
178 if(m_daughters.size()==0&&m_particle->end_vertex()){
179 HepMC::GenVertex::particles_out_const_iterator pcle_itr;
180 pcle_itr=m_particle->end_vertex()->particles_out_const_begin();
182 HepMC::GenVertex::particles_out_const_iterator pcle_itr_end;
183 pcle_itr_end=m_particle->end_vertex()->particles_out_const_end();
185 for(;pcle_itr != pcle_itr_end; pcle_itr++){
186 m_daughters.push_back(new TauolaHepMCParticle(*pcle_itr));
192 void TauolaHepMCParticle::checkMomentumConservation(){
194 if(!m_particle->end_vertex()) return;
196 // HepMC version of check_momentum_conservation
197 // with added energy check
199 double sumpx = 0, sumpy = 0, sumpz = 0, sume = 0;
200 for( HepMC::GenVertex::particles_in_const_iterator part1 = m_particle->end_vertex()->particles_in_const_begin();
201 part1 != m_particle->end_vertex()->particles_in_const_end(); part1++ ){
203 sumpx += (*part1)->momentum().px();
204 sumpy += (*part1)->momentum().py();
205 sumpz += (*part1)->momentum().pz();
206 sume += (*part1)->momentum().e();
209 for( HepMC::GenVertex::particles_out_const_iterator part2 = m_particle->end_vertex()->particles_out_const_begin();
210 part2 != m_particle->end_vertex()->particles_out_const_end(); part2++ ){
212 sumpx -= (*part2)->momentum().px();
213 sumpy -= (*part2)->momentum().py();
214 sumpz -= (*part2)->momentum().pz();
215 sume -= (*part2)->momentum().e();
218 if( sqrt( sumpx*sumpx + sumpy*sumpy + sumpz*sumpz + sume*sume) > Tauola::momentum_conservation_threshold ) {
219 Log::Warning()<<"Momentum not conserved in the vertex:"<<endl;
220 Log::RedirectOutput(Log::Warning(false));
221 m_particle->end_vertex()->print();
229 // NOTE: Not executed by release examples
230 void TauolaHepMCParticle::setPdgID(int pdg_id){
231 m_particle->set_pdg_id(pdg_id);
234 void TauolaHepMCParticle::setMass(double mass){
235 m_particle->set_generated_mass(mass);
238 // NOTE: Not executed by release examples
239 void TauolaHepMCParticle::setStatus(int status){
240 m_particle->set_status(status);
243 int TauolaHepMCParticle::getPdgID(){
244 return m_particle->pdg_id();
247 int TauolaHepMCParticle::getStatus(){
248 return m_particle->status();
251 int TauolaHepMCParticle::getBarcode(){
252 return m_particle->barcode();
255 // Set (X,T) Position of tau decay trees
256 void TauolaHepMCParticle::decayEndgame(){
258 double lifetime = Tauola::tau_lifetime * (-log( Tauola::randomDouble() ));
259 HepMC::FourVector tau_momentum = m_particle->momentum();
261 double mass = sqrt(abs( tau_momentum.e()*tau_momentum.e()
262 - tau_momentum.px()*tau_momentum.px()
263 - tau_momentum.py()*tau_momentum.py()
264 - tau_momentum.pz()*tau_momentum.pz()
267 // Get previous position
268 HepMC::FourVector previous_position = m_particle->production_vertex()->position();
270 // Calculate new position
271 HepMC::FourVector new_position(previous_position.x()+tau_momentum.px()/mass*lifetime,
272 previous_position.y()+tau_momentum.py()/mass*lifetime,
273 previous_position.z()+tau_momentum.pz()/mass*lifetime,
274 previous_position.t()+tau_momentum.e() /mass*lifetime);
277 m_particle->end_vertex()->set_position(new_position);
278 recursiveSetPosition(m_particle,new_position);
281 void TauolaHepMCParticle::recursiveSetPosition(HepMC::GenParticle *p, HepMC::FourVector pos){
283 if(!p->end_vertex()) return;
285 // Iterate over all outgoing particles
286 for(HepMC::GenVertex::particles_out_const_iterator pp = p->end_vertex()->particles_out_const_begin();
287 pp != p->end_vertex()->particles_out_const_end();
289 if( !(*pp)->end_vertex() ) continue;
292 (*pp)->end_vertex()->set_position(pos);
293 recursiveSetPosition(*pp,pos);
297 TauolaHepMCParticle * TauolaHepMCParticle::createNewParticle(
298 int pdg_id, int status, double mass,
299 double px, double py, double pz, double e){
301 TauolaHepMCParticle * new_particle = new TauolaHepMCParticle();
302 new_particle->getHepMC()->set_pdg_id(pdg_id);
303 new_particle->getHepMC()->set_status(status);
304 new_particle->getHepMC()->set_generated_mass(mass);
306 HepMC::FourVector momentum(px,py,pz,e);
307 new_particle->getHepMC()->set_momentum(momentum);
309 m_created_particles.push_back(new_particle);
314 void TauolaHepMCParticle::print(){
319 /******** Getter and Setter methods: ***********************/
321 inline double TauolaHepMCParticle::getPx(){
322 return m_particle->momentum().px();
325 inline double TauolaHepMCParticle::getPy(){
326 return m_particle->momentum().py();
329 double TauolaHepMCParticle::getPz(){
330 return m_particle->momentum().pz();
333 double TauolaHepMCParticle::getE(){
334 return m_particle->momentum().e();
337 void TauolaHepMCParticle::setPx(double px){
338 //make new momentum as something is wrong with
339 //the HepMC momentum setters
341 HepMC::FourVector momentum(m_particle->momentum());
343 m_particle->set_momentum(momentum);
346 void TauolaHepMCParticle::setPy(double py){
347 HepMC::FourVector momentum(m_particle->momentum());
349 m_particle->set_momentum(momentum);
353 void TauolaHepMCParticle::setPz(double pz){
354 HepMC::FourVector momentum(m_particle->momentum());
356 m_particle->set_momentum(momentum);
359 void TauolaHepMCParticle::setE(double e){
360 HepMC::FourVector momentum(m_particle->momentum());
362 m_particle->set_momentum(momentum);
365 } // namespace Tauolapp