C++InterfacetoTauola
TauolaParticlePair.cxx
1 #include "Tauola.h"
2 #include "TauolaParticlePair.h"
3 #include "Log.h"
4 #include <stdlib.h>
5 #include <math.h>
6 #include <iostream>
7 //static double transcosTheta;
8 
9 
10 namespace Tauolapp
11 {
12  extern "C" { double transcosTheta ; double transinvariant_mass;
13  int transincoming_pdg_id;
14  double transR11, transR22, transWT11, transWT22;
15  double trans_h_tau_minus[4]; double trans_h_tau_plus[4];}
16  //static double transcosTheta;
17 /** constructor. Get the mothers, grandmothers and siblings of the tau */
18 TauolaParticlePair::TauolaParticlePair(std::vector<TauolaParticle*> &particle_list){
19  TauolaParticle *particle=particle_list.back();
20  particle_list.pop_back();
21  setBornKinematics(0,0,-1.,0.); //set the default born variables
22 
23  // In case of decayOne() we need only the tau information
25  {
26  m_mother = 0;
27  m_mother_exists = false;
28  m_production_particles.push_back(particle);
29  m_final_particles.push_back(particle);
31  Log::AddDecay(0);
32  return;
33  }
34 
35  //See if there are any mothers
36  std::vector<TauolaParticle *> temp_mothers = particle->findProductionMothers();
37 
38  // Case that there are no mothers or grandmothers
39  if(temp_mothers.size()==0){
40  // NOTE: Not executed by release examples
41  // However, such cases were present if tests used older Pythia8.1 or so.
42  Log::Warning()<< "WARNING: Could not find taus mother or grandmothers. "
43  << "Ignoring spin effects" << std::endl;
44  m_mother = 0;
45  m_mother_exists = false;
46  m_production_particles.push_back(particle);
47  m_final_particles.push_back(particle->findLastSelf());
49  Log::AddDecay(1);
50  return;
51  }
52 
53  //fill the sibling pointers
54  std::vector<TauolaParticle*> temp_daughters;
55  temp_daughters = temp_mothers.at(0)->getDaughters();
56  if(temp_daughters.size()==0)
57  Log::Fatal("WARNING: Something wrong with event structure or there is a bug in the TAUOLA interface.",6);
58 
59  m_production_particles=temp_daughters;
60  m_final_particles.push_back(particle->findLastSelf());
61 
62  //Second tau-like particle selection should match properties of the hard (exotic) process. At present, solution
63  //match one of the possible diagrams contributing to SM process. Rare case like tau+ tau+ nutau nutau will not be treted
64  //accordingly to any diagram of SM
65  for(signed int i=0; i < (int) m_production_particles.size(); i++)
66  {
67  //check if it has opposite PDGID sign
68  if(m_final_particles.at(0)->getPdgID()*m_production_particles.at(i)->getPdgID()>=0) continue;
69 
70  if(m_production_particles.at(i)->getPdgID()==TauolaParticle::TAU_PLUS||
72  {
73  //tau+ or tau- - check if it's on the particle_list
74  int j=-1;
75  for(j=0;j<(int)particle_list.size();j++)
76  if(m_production_particles.at(i)->getBarcode()==particle_list.at(j)->getBarcode()) break;
77  if(j>=(int)particle_list.size()) continue;
78 
79  //exists on the list - add to m_final_particles and delete from particle_list
80  m_final_particles.push_back(m_production_particles.at(i)->findLastSelf());
81  particle_list.erase(particle_list.begin()+j);
82  }
83  else if(m_production_particles.at(i)->getPdgID()==TauolaParticle::TAU_NEUTRINO||
85  {
86  //neutrino - for now - just add to m_final_particles
87  m_final_particles.push_back(m_production_particles.at(i)->findLastSelf());
88  }
89  }
90 
91 
92  //fill the mother and grandmother pointers
93  if(temp_mothers.size()==1){ //one mother
94  m_mother_exists = true;
95  m_mother = temp_mothers.at(0);
97  Log::AddDecay(3);
98  }
99  else{ //no mother, but grandparents exist
100  m_mother_exists = false;
101  m_grandmothers = temp_mothers;
103  Log::AddDecay(2);
104  }
105 
107 
108  return;
109 }
110 
111 
112 /** The axis is defined by the boosting routine but our standard convention
113  is:
114  - Axis 3 is along the direction of the +ve tau,
115  - Axis 1 is perpendicular to the reaction plane (sign=??)
116  - Axis 2 is defined through the vector product so the system
117  is right handed (?? check). Axis 1,2 and 3 are parrellel for the 1st
118  and second tau. */
120  int incoming_pdg_id=0;
121  int outgoing_pdg_id=0;
122  double invariant_mass_squared=-5.0;
123  double cosTheta=3.0;
124 
125  //initialize all elements of the density matrix to zero
126  for(int x = 0; x < 4; x ++) {
127  for(int y = 0; y < 4; y ++)
128  m_R[x][y] = 0;
129  }
130 
131  m_R[0][0]=1;
132 
134  {
135  const double *pol = Tauola::getDecayOnePolarization();
136 
137  m_R[0][1]=pol[0];
138  m_R[0][2]=pol[1];
139  m_R[0][3]=pol[2];
140 
141  m_R[1][0]=pol[0];
142  m_R[2][0]=pol[1];
143  m_R[3][0]=pol[2];
144  }
145 
146  if(!m_mother) return;
147  // fill the matrix depending on mother
148 
149 
150  // do scalar-pseudoscalar mixed higgs case separately since
151  // switch doesn't allow non-constants in a case statement.
152  // very annoying!
153 
155  if(!Tauola::spin_correlation.HIGGS_H) return;
156 
157  double phi = Tauola::getHiggsScalarPseudoscalarMixingAngle();
158  double mass_ratio = Tauola::getTauMass()/m_mother->getMass();
159 
160  double beta = sqrt(1-4*mass_ratio*mass_ratio);
161  double denominator = pow(cos(phi)*beta,2)+pow(sin(phi),2);
162 
163  m_R[0][0]= 1;
164  m_R[1][1]= (pow(cos(phi)*beta,2)-pow(sin(phi),2))/denominator;
165  m_R[1][2]= 2*cos(phi)*sin(phi)*beta/denominator;
166  m_R[2][1]= -m_R[1][2];
167  m_R[2][2]= m_R[1][1];
168  m_R[3][3]= -1;
169  }
170  else {
171 
172  double pz = 0.0;
173 
174  switch(m_mother->getPdgID()){
175 
176  case TauolaParticle::Z0:
177  if(!Tauola::spin_correlation.Z0) break;
178  // Here we calculate SVAR and COSTHE as well as IDE and IDF
179  // ANGULU(&IDE,&IDF,&SVAR,&COSTHE);
180  // this is ++ configuration of Fig 5 from HEPPH0101311:
181  //pol_tau_minus[2]=-1; pol_tau_plus[2]=1;
182 
183  pz = getZPolarization(&incoming_pdg_id, &outgoing_pdg_id, &invariant_mass_squared, &cosTheta);
184  m_R[0][0]=1;
185  m_R[0][3]=2*pz-1;
186  m_R[3][0]=2*pz-1;
187  m_R[3][3]=1;
188  // alternatively this may be overwritten if better solution exist
189  recalculateRij(incoming_pdg_id, outgoing_pdg_id, invariant_mass_squared, cosTheta);
190  break;
191 
193  if(!Tauola::spin_correlation.GAMMA) break;
194  // Here we calculate SVAR and COSTHE as well as IDE and IDF
195  // ANGULU(&IDE,&IDF,&SVAR,&COSTHE);
196  // this is ++ configuration of Fig 5 from HEPPH0101311:
197  //pol_tau_minus[2]=-1; pol_tau_plus[2]=1;
198 
199  pz = getZPolarization(&incoming_pdg_id, &outgoing_pdg_id, &invariant_mass_squared, &cosTheta);
200  m_R[0][0]=1;
201  m_R[0][3]=2*pz-1;
202  m_R[3][0]=2*pz-1;
203  m_R[3][3]=1;
204  // alternatively this may be overwritten if better solution exist
205  recalculateRij(incoming_pdg_id, outgoing_pdg_id, invariant_mass_squared, cosTheta);
206  break;
207 
208  //scalar higgs
210  if(!Tauola::spin_correlation.HIGGS) break;
211  m_R[0][0]=1;
212  m_R[1][1]=1;
213  m_R[2][2]=1;
214  m_R[3][3]=-1;
215  break;
216 
217  //pseudoscalar higgs case
219  if(!Tauola::spin_correlation.HIGGS_A) break;
220  m_R[0][0]=1;
221  m_R[1][1]=-1;
222  m_R[2][2]=-1;
223  m_R[3][3]=-1;
224  break;
225 
227  if(!Tauola::spin_correlation.HIGGS_PLUS) break;
228  m_R[0][0]=1;
229  m_R[0][3]=-1;
230  m_R[3][0]=-1;
231  break;
232 
234  if(!Tauola::spin_correlation.HIGGS_MINUS) break;
235  m_R[0][0]=1;
236  m_R[0][3]=-1;
237  m_R[3][0]=-1;
238  break;
239 
241  if(!Tauola::spin_correlation.W_PLUS) break;
242  m_R[0][0]=1;
243  m_R[0][3]=1; //tau minus (tau minus is on the -ve Z axis)
244  m_R[3][0]=1; //tau plus
245  break;
246 
248  if(!Tauola::spin_correlation.W_MINUS) break;
249  m_R[0][0]=1;
250  m_R[0][3]=1; //tau minus (tau minus is on the -ve Z axis)
251  m_R[3][0]=1; //tau plus
252  break;
253 
254  //ignore spin effects when mother is unknown
255  default:
256  m_R[0][0]=1;
257  break;
258  }
259  }
260 
261 }
262 
263 /**************************************************************/
264 void TauolaParticlePair::setBornKinematics(int incoming_pdg_id, int outgoing_pdg_id, double invariant_mass_squared,double cosTheta){
265  Tauola::buf_incoming_pdg_id=incoming_pdg_id;
266  Tauola::buf_outgoing_pdg_id=outgoing_pdg_id;
267  Tauola::buf_invariant_mass_squared=invariant_mass_squared;
268  Tauola::buf_cosTheta=cosTheta;
269  //cout<<"(TauolaParticlePair::Just to be sure:) "<<buf_incoming_pdg_id<<" "<<buf_outgoing_pdg_id<<" "<<buf_invariant_mass_squared<<" "<<buf_cosTheta<<endl;
270  // m_R[0][0] to be added in next step;
271 }
272 
273 /**************************************************************/
274 double TauolaParticlePair::getZPolarization(int *incoming_pdg_id, int *outgoing_pdg_id, double *invariant_mass_squared,double *cosTheta){
275 
276  //defaults
277  *incoming_pdg_id = TauolaParticle::ELECTRON;
278  *cosTheta = 0 ;
279  *outgoing_pdg_id = TauolaParticle::TAU_PLUS;
280  *invariant_mass_squared = pow(m_mother->getMass(),2);
281  setBornKinematics(*incoming_pdg_id, *outgoing_pdg_id, *invariant_mass_squared, *cosTheta); // store for debugging
282 
283  //TRIVIAL CASE:
284  //if we don't know the incoming beams then
285  //return the average z polarisation
286  if(m_grandmothers.size()<2){
287  Log::Warning()<<"Not enough mothers of Z to "
288  <<"calculate cos(theta) between "
289  <<"incoming about outgoing beam"
290  << endl;
291  return 1-plzap0_(incoming_pdg_id,outgoing_pdg_id,
292  invariant_mass_squared, cosTheta);
293  }
294 
296  Log::Error()<<"tau+ or tau- not found in Z decay"<< endl;
297  return 0;
298  }
299 
300  //NOW CHECK FOR THE DIFFICULT EVENTS:
301  //case f1 + f2 + f3 -> Z -> tau tau
302  //case f1 + f2 -> Z + f3, Z-> tau tau or f1 + f2 -> tau tau f3
303  //case f1 + f2 -> Z -> tau tau gamma
304  if(m_grandmothers.size()>2 ||
305  (m_grandmothers.at(0)->getDaughters().size()>1 && m_mother_exists==true) ||
306  m_production_particles.size() > 2){
307 
308  //make a vector of the extra grandmother particles
309  vector<TauolaParticle*> extra_grandmothers;
310  for(int i=0; i<(int) m_grandmothers.size(); i++){
311  // temp_grandmothers.push_back(m_grandmothers.at(i));
314  extra_grandmothers.push_back(m_grandmothers.at(i));
315  }
316 
317  //make a vector of the tau siblings
318  //and copy all the production particle vector.
319  vector<TauolaParticle*> extra_tau_siblings;
320  vector<TauolaParticle*> temp_production_particles;
321  for(int i=0; i<(int) m_production_particles.size(); i++){
324  extra_tau_siblings.push_back(m_production_particles.at(i));
325  }
326 
327  //make a vector of the Z's sibling
328  vector<TauolaParticle*> extra_Z_siblings;
329  for(int i=0; m_mother_exists && i<(int) m_grandmothers.at(0)->getDaughters().size(); i++){
330  if(m_grandmothers.at(0)->getDaughters().at(i)->getPdgID()!=TauolaParticle::Z0)
331  extra_Z_siblings.push_back(m_grandmothers.at(0)->getDaughters().at(i));
332  }
333 
334  //make temporary particles for the effect beams
335  //and copy into a vector
336  std::vector<TauolaParticle*> effective_taus;
337  effective_taus.push_back(getTauPlus(m_production_particles)->clone());
338  effective_taus.push_back(getTauMinus(m_production_particles)->clone());
339 
340  //copy grandmothers into the m_grandmothers vector since we want this to be perminante.
343  m_grandmothers.clear();
344  m_grandmothers.push_back(g1);
345  m_grandmothers.push_back(g2);
346 
347  //loop over extra grandmothers
348  for(int i=0; i<(int) extra_grandmothers.size(); i++)
349  addToBeam(extra_grandmothers.at(i),&m_grandmothers,0);
350 
351  //loop over siblings to the Z
352  for(int i=0; i<(int) extra_Z_siblings.size(); i++)
353  addToBeam(extra_Z_siblings.at(i),0,&m_grandmothers);
354 
355  //loop over siblings of the taus
356  for(int i=0; i<(int) extra_tau_siblings.size() ; i++){
357  if(m_mother_exists)
358  addToBeam(extra_tau_siblings.at(i),&effective_taus,0);
359  else
360  addToBeam(extra_tau_siblings.at(i),&effective_taus,&m_grandmothers);
361  }
362  //And we are finish making the effective income and outgoing beams
363 
364  TauolaParticle * temp_mother = makeTemporaryMother(effective_taus);
365  *invariant_mass_squared = pow(temp_mother->getMass(),2);
366 
367  //now we are ready to do the boosting, calculate the angle
368  //between incoming and outgoing, and get the polarisation of the Z
369 
370  double angle1,angle2,angle3;
371  boostFromLabToTauPairFrame(&angle1, &angle2, &angle3, temp_mother,
372  m_grandmothers, effective_taus);
373 
374  /*double theta1 = -getGrandmotherPlus(m_grandmothers)->getRotationAngle(TauolaParticle::Y_AXIS);
375  double theta2 = -(M_PI+getGrandmotherMinus(m_grandmothers)->getRotationAngle(TauolaParticle::Y_AXIS));
376  *cosTheta = cos((theta1+theta2)/2.0); //just average the angles for now.*/
377 
378  TauolaParticle *tM=getTauPlus(effective_taus);
380 
381  double costheta1=(tM->getPx()*gM->getPx()+tM->getPy()*gM->getPy()+tM->getPz()*gM->getPz())/
382  sqrt(tM->getPx()*tM->getPx()+tM->getPy()*tM->getPy()+tM->getPz()*tM->getPz())/
383  sqrt(gM->getPx()*gM->getPx()+gM->getPy()*gM->getPy()+gM->getPz()*gM->getPz());
384  tM=getTauMinus(effective_taus);
386 
387  double costheta2=(tM->getPx()*gM->getPx()+tM->getPy()*gM->getPy()+tM->getPz()*gM->getPz())/
388  sqrt(tM->getPx()*tM->getPx()+tM->getPy()*tM->getPy()+tM->getPz()*tM->getPz())/
389  sqrt(gM->getPx()*gM->getPx()+gM->getPy()*gM->getPy()+gM->getPz()*gM->getPz());
390  double sintheta1 = sqrt(1-costheta1*costheta1);
391  double sintheta2 = sqrt(1-costheta2*costheta2);
392  double avg = (costheta1*sintheta2+costheta2*sintheta1)/(sintheta1+sintheta2);
393 
394  *cosTheta = avg;
395 
396  *incoming_pdg_id = getGrandmotherPlus(m_grandmothers)->getPdgID();
397 
398  if(abs(*incoming_pdg_id)==21 || abs(*incoming_pdg_id)==22)
399  {
400  *incoming_pdg_id = -getGrandmotherMinus(m_grandmothers)->getPdgID();
401  //cout<<"INFO:\tgluon pdg id changed!"<<endl;
402  }
403 
404  if( abs(*incoming_pdg_id)> 8 &&
405  abs(*incoming_pdg_id)!=11 &&
406  abs(*incoming_pdg_id)!=13 &&
407  abs(*incoming_pdg_id)!=15 )
408  {
409  Log::Error()<<"Second class disaster: incoming_pdg_id = "<<*incoming_pdg_id<<endl;
410 
411  // Return avarage Z polarization
412  *incoming_pdg_id = TauolaParticle::ELECTRON;
413  *cosTheta = 0 ;
414  *outgoing_pdg_id = TauolaParticle::TAU_PLUS;
415 
416  return 1-plzap0_(incoming_pdg_id,outgoing_pdg_id,
417  invariant_mass_squared, cosTheta);
418  }
419 
420  boostFromTauPairToLabFrame(angle1, angle2, angle3, temp_mother,
421  m_grandmothers, effective_taus);
422  setBornKinematics(*incoming_pdg_id, *outgoing_pdg_id, *invariant_mass_squared, *cosTheta); // store for debugging
423  return 1-plzap0_(incoming_pdg_id,outgoing_pdg_id, invariant_mass_squared, cosTheta);
424 
425  }
426  //REGULAR CASE:
427  //f1 + f2 -> Z -> tau+ tau - or f1 f2 -> tau+ tau-
428  //This includes Z -> tau tau, tau -> gamma tau?
429 
430  double angle1,angle2,angle3;
431  boostFromLabToTauPairFrame(&angle1, &angle2, &angle3,
433 
436  double costheta1=(tM->getPx()*gM->getPx()+tM->getPy()*gM->getPy()+tM->getPz()*gM->getPz())/
437  sqrt(tM->getPx()*tM->getPx()+tM->getPy()*tM->getPy()+tM->getPz()*tM->getPz())/
438  sqrt(gM->getPx()*gM->getPx()+gM->getPy()*gM->getPy()+gM->getPz()*gM->getPz());
439 
442 
443  double costheta2=(tM->getPx()*gM->getPx()+tM->getPy()*gM->getPy()+tM->getPz()*gM->getPz())/
444  sqrt(tM->getPx()*tM->getPx()+tM->getPy()*tM->getPy()+tM->getPz()*tM->getPz())/
445  sqrt(gM->getPx()*gM->getPx()+gM->getPy()*gM->getPy()+gM->getPz()*gM->getPz());
446 
447  double sintheta1 = sqrt(1-costheta1*costheta1);
448  double sintheta2 = sqrt(1-costheta2*costheta2);
449 
450  double avg = (costheta1*sintheta2+costheta2*sintheta1)/(sintheta1+sintheta2);
451 
452  *cosTheta = avg;
453 
454  *incoming_pdg_id = getGrandmotherPlus(m_grandmothers)->getPdgID();
455 
456  boostFromTauPairToLabFrame(angle1, angle2, angle3,
458 
459  setBornKinematics(*incoming_pdg_id, *outgoing_pdg_id, *invariant_mass_squared, *cosTheta); // store for debugging
460  return 1-plzap0_(incoming_pdg_id,outgoing_pdg_id, invariant_mass_squared, cosTheta);
461  // return 0.5 - (-0.12 + 0.12*cosTheta)/2;
462 }
463 
464 /** WHERE WE CALCULATE THE EFFECTIVE BEAMS **/
465 /** This is where we decide which particle should be added into which beam,
466  add it and change the flavour if necessary. candidates_same
467  are on the same side of the vertex as the particle. This is needed
468  for negative the particle 4-momentum. **/
470  std::vector<TauolaParticle*> *candidates_same,
471  std::vector<TauolaParticle*> *candidates_opp){
472 
473 
474  double s=0.,o=-10.;
475  TauolaParticle * s_beam = NULL;
476  TauolaParticle * o_beam = NULL;
477 
478  if(candidates_same){
479  double s0 =1.0/getVirtuality(pcle,candidates_same->at(0),false);
480  double s1 = 1.0/getVirtuality(pcle,candidates_same->at(1),false);
481  if(s0>s1){
482  s=s0;
483  s_beam = candidates_same->at(0);
484  }
485  else{
486  s=s1;
487  s_beam = candidates_same->at(1);
488  }
489  }
490  if(candidates_opp){
491 
492  double o0 =1.0/getVirtuality(pcle,candidates_opp->at(0),true);
493  double o1 = 1.0/getVirtuality(pcle,candidates_opp->at(1),true);
494  if(o0>o1){
495  o=o0;
496  o_beam = candidates_opp->at(0);
497  }
498  else{
499  o=o1;
500  o_beam = candidates_opp->at(1);
501  }
502  }
503 
504  if(s>o)
505  {
506  s_beam->add(pcle);
507  int pdg1 = pcle->getPdgID();
508  int pdg2 = s_beam->getPdgID();
509  if(abs(pdg2)==15) return;
510  if((abs(pdg2)==21 || abs(pdg2)==22) && abs(pdg1)<17 && abs(pdg1)!=10 && abs(pdg1)!=9) s_beam->setPdgID( pdg1);
511  }
512  else
513  {
514  o_beam->subtract(pcle);
515  int pdg1 = pcle->getPdgID();
516  int pdg2 = o_beam->getPdgID();
517  if((abs(pdg2)==21 || abs(pdg2)==22) && abs(pdg1)<17 && abs(pdg1)!=10 && abs(pdg1)!=9) o_beam->setPdgID(-pdg1);
518  }
519 
520  //should we also do something with the flavours??
521 
522 }
523 
525 
526  //if one particle in a gluon and the other a lepton
527  if((p1->getPdgID()==TauolaParticle::GLUON&&abs(p2->getPdgID())>10&&abs(p2->getPdgID())<20) ||
528  (p2->getPdgID()==TauolaParticle::GLUON&&abs(p1->getPdgID())>10&&abs(p1->getPdgID())<20))
529  return -1;
530 
531  //add some others...
532 
533  //otherwise we calculate the virtuality:
534  double kp = p1->getE()*p2->getE() - p1->getPx()*p2->getPx()
535  - p1->getPy()*p2->getPy() - p1->getPz()*p2->getPz();
536  if(flip) // Note that we have 1/(p1+p2)^2 or 1/(p1-p2)^2 and p2^2=0
537  kp = kp - p1->getMass()*p1->getMass();
538 
539  double q = 1;
540  if(p1->getPdgID()==TauolaParticle::GAMMA){
541  if(abs(p2->getPdgID())==TauolaParticle::UP ||
542  abs(p2->getPdgID())==TauolaParticle::CHARM ||
543  abs(p2->getPdgID())==TauolaParticle::TOP)
544  q=2.0/3.0;
545  if(abs(p2->getPdgID())==TauolaParticle::DOWN ||
546  abs(p2->getPdgID())==TauolaParticle::STRANGE ||
547  abs(p2->getPdgID())==TauolaParticle::BOTTOM)
548  q=1.0/3.0;
549  }
550  if(p2->getPdgID()==TauolaParticle::GAMMA){
551  if(abs(p1->getPdgID())==TauolaParticle::UP ||
552  abs(p1->getPdgID())==TauolaParticle::CHARM ||
553  abs(p1->getPdgID())==TauolaParticle::TOP)
554  q=2.0/3.0;
555  if(abs(p1->getPdgID())==TauolaParticle::DOWN ||
556  abs(p1->getPdgID())==TauolaParticle::STRANGE ||
557  abs(p1->getPdgID())==TauolaParticle::BOTTOM)
558  q=1.0/3.0;
559  }
560 
561  return fabs(2*kp)/q;
562 }
563 
564 /***********************************************************
565  ** TauolaParticlePair::decayTauPair().
566  ** Generate tau decay
567  ************************************************************/
569 
570  //initalize h vectors in case the partner is not a tau
571  double h_tau_minus[4]={2,0,0,0}; //2 used to compensate for maximum weight
572  double h_tau_plus[4]={2,0,0,0}; //in the case when there is only 1 tau
573 
576  // cout<<" wchodzim do decayTauPair()" <<endl;
577  //now calculate the spin weight
578  for(double weight=0; weight < Tauola::randomDouble();){
579  // cout<<" wchodzim do petli decayTauPair()" <<endl;
580  //call tauola decay and get polarimetric vectors
581  if(tau_minus){
582  Tauola::redefineTauMinusProperties(tau_minus);
583  tau_minus->decay();
584  h_tau_minus[0]=1;
585  h_tau_minus[1]=tau_minus->getPolarimetricX();
586  h_tau_minus[2]=tau_minus->getPolarimetricY();
587  h_tau_minus[3]=tau_minus->getPolarimetricZ();
588  }
589  if(tau_plus){
590  Tauola::redefineTauPlusProperties(tau_plus);
591  tau_plus->decay();
592  h_tau_plus[0]=1;
593  h_tau_plus[1]=tau_plus->getPolarimetricX();
594  h_tau_plus[2]=tau_plus->getPolarimetricY();
595  h_tau_plus[3]=tau_plus->getPolarimetricZ();
596  }
597  double sinv=sqrt((tau_minus->getE()+tau_plus->getE())*(tau_minus->getE()+tau_plus->getE())
598  -(tau_minus->getPx()+tau_plus->getPx())*(tau_minus->getPx()+tau_plus->getPx())
599  -(tau_minus->getPy()+tau_plus->getPy())*(tau_minus->getPy()+tau_plus->getPy())
600  -(tau_minus->getPz()+tau_plus->getPz())*(tau_minus->getPz()+tau_plus->getPz()) );
601  // cout<<" --------------------tauP tauM --------------------------------sqrt(s)="<<sinv<<" "<< tau_plus->getPdgID()<<" "<< tau_minus->getPdgID()<<endl;
602  // cout<<"taum -(E,x,y,z)=" << tau_minus->getE() <<" " << tau_minus->getPx() <<" " << tau_minus->getPy() <<" " << tau_minus->getPz() <<endl;
603  // cout<<"taup -(E,x,y,z)=" << tau_plus->getE() <<" " << tau_plus->getPx() <<" " << tau_plus->getPy() <<" " << tau_plus->getPz() <<endl;
604  double asymi=(tau_minus->getE()- tau_plus->getE())/( tau_minus->getE()+ tau_plus->getE());
605  // cout<<" longitudinal energy asymmetry for the event =" << asymi <<endl;
606  // cout<<" elementy Rij (0,0) (3,3) (0,3) (3,0) =" <<endl;
607  // cout<<" "<< m_R[0][0]<<" " <<m_R[3][3]<<" " << m_R[0][3]<<" " <<m_R[3][0] <<endl;
608  // cout<<" elementy Rij (1,1) (2,2) (1,2) (2,1) =";// <<endl;
609  // cout<<" "<< m_R[1][1]<<" " <<m_R[2][2]<<" " << m_R[1][2]<<" " <<m_R[2][1] <<endl;
610  // cout<<"h^-(0,1,2,3)=" << h_tau_minus[0] <<" " << h_tau_minus[1] <<" " << h_tau_minus[2] <<" " << h_tau_minus[3] <<endl;
611  // cout<<"h^+(0,1,2,3)=" << h_tau_plus[0] <<" " << h_tau_plus[1] <<" " << h_tau_plus[2] <<" " << h_tau_plus[3] <<endl;
612  // cout<<" ----------------------------------------------------------- " <<endl;
613  //calculate the weight
614  transR11=m_R[1][1];
615  transR22=m_R[2][2];
616  transWT11=m_R[1][1]* h_tau_minus[1]* h_tau_plus[1];
617  transWT22=m_R[2][2]* h_tau_minus[2]* h_tau_plus[2];
618  trans_h_tau_minus[3]= h_tau_minus[3];
619  trans_h_tau_minus[1]= h_tau_minus[1];
620  trans_h_tau_minus[2]= h_tau_minus[2];
621  trans_h_tau_plus[3]= h_tau_plus[3];
622  trans_h_tau_plus[1]= h_tau_plus[1];
623  trans_h_tau_plus[2]= h_tau_plus[2];
624  weight=0;
625  for(int i =0; i<4; i++){
626  for(int j=0; j<4; j++)
627  weight+=m_R[i][j]*h_tau_minus[i]*h_tau_plus[j];
628  }
629  weight = weight/4.0;
630  // cout<<"i z tego jest wt/4, weight= " << weight <<endl;
631  }
632  double wthel[4]={0};
633  wthel[0]=(h_tau_minus[0]+h_tau_minus[3])*(h_tau_plus[0]+h_tau_plus[3])*(m_R[0][0]+m_R[0][3]+m_R[3][0]+m_R[3][3]);
634  wthel[1]=(h_tau_minus[0]+h_tau_minus[3])*(h_tau_plus[0]-h_tau_plus[3])*(m_R[0][0]-m_R[0][3]+m_R[3][0]-m_R[3][3]);
635  wthel[2]=(h_tau_minus[0]-h_tau_minus[3])*(h_tau_plus[0]+h_tau_plus[3])*(m_R[0][0]+m_R[0][3]-m_R[3][0]-m_R[3][3]);
636  wthel[3]=(h_tau_minus[0]-h_tau_minus[3])*(h_tau_plus[0]-h_tau_plus[3])*(m_R[0][0]-m_R[0][3]-m_R[3][0]+m_R[3][3]);
637 
638  double rn=Tauola::randomDouble();
639  if (rn>(wthel[0]+wthel[1]+wthel[2])/(wthel[0]+wthel[1]+wthel[2]+wthel[3])) Tauola::setHelicities(-1,-1);
640  else if (rn>(wthel[0]+wthel[1]) /(wthel[0]+wthel[1]+wthel[2]+wthel[3])) Tauola::setHelicities(-1,+1);
641  else if (rn>(wthel[0]) /(wthel[0]+wthel[1]+wthel[2]+wthel[3])) Tauola::setHelicities( 1,-1);
642  else Tauola::setHelicities( 1, 1);
643 
644 
645 
646 
647  //boost into the frame used to define the density matrices
648  //and add the tau's new daughters.
649 
650  double angle1,angle2,angle3;
652 
654  boostFromLabToTauPairFrame(&angle1, &angle2, &angle3,
656 
657  //add the accepted decay into the event record
658  if(tau_plus)
659  tau_plus->addDecayToEventRecord();
660  if(tau_minus)
661  tau_minus->addDecayToEventRecord();
662 
664  boostFromTauPairToLabFrame(angle1,angle2,angle3,
666 
667  // Apply final decay modification, once taus are in lab frame.
668  // At present 28.02.11, vertex position shift (in HepMC) is implemented.
669  // Thanks Sho Iwamoto for feedback
670  if(tau_plus)
671  tau_plus->decayEndgame();
672  if(tau_minus)
673  tau_minus->decayEndgame();
674 // cout<<" koniec pracy dla decayTauPair" <<endl;
675 }
676 
677 /***********************************************************
678  ** Below are the methods used for boosting and rotating
679  ** into another reference frame.
680  ************************************************************/
681 
682 /** Step 1. (Transformation A). Any modification to this method also requires a modification
683  to the inverse method boostFromTauPairFrameToLab (transformation A^-1).*/
684 void TauolaParticlePair::boostFromLabToTauPairFrame(double * rotation_angle1,
685  double * rotation_angle2,
686  double * rotation_angle3,
687  TauolaParticle * mother,
688  vector<TauolaParticle *> grandmothers,
689  vector<TauolaParticle *> taus
690  ){ //in positive z axis (+1) //or negative z axis (-1)
691 
692  /** boost all gradmothers and daughters (taus, neutrinos, etc,)
693  to the mothers rest frame */
694 
695  for(int i=0; i< (int) grandmothers.size(); i++)
696  grandmothers.at(i)->boostToRestFrame(mother);
697  //If taus.size()==1 then taus[1] is the same as mum. Disaster to be avoided.
698  if(taus.size()!=1)
699  for(int i=0; i< (int) taus.size(); i++){
700  taus.at(i)->boostToRestFrame(mother);
701  // NOTE: Following line has no effect in release examples
702  // because taus don't have daughters at this step
703  taus.at(i)->boostDaughtersToRestFrame(mother);
704  }
705 
706  /** rotate all particles so taus are on the z axis */
707  if(getTauPlus(taus)){ //if there's a tau+ use this to get the rotation angle
708  *rotation_angle1 = getTauPlus(taus)->getRotationAngle(TauolaParticle::Y_AXIS);
709  rotateSystem(grandmothers,taus,*rotation_angle1,TauolaParticle::Y_AXIS);
710  *rotation_angle2 = getTauPlus(taus)->getRotationAngle(TauolaParticle::X_AXIS);
711  rotateSystem(grandmothers,taus,*rotation_angle2,TauolaParticle::X_AXIS);
712  }
713  else{ //otherwise use the tau-
714  *rotation_angle1 = M_PI+getTauMinus(taus)->getRotationAngle(TauolaParticle::Y_AXIS);
715  rotateSystem(grandmothers,taus,*rotation_angle1,TauolaParticle::Y_AXIS);
716  *rotation_angle2 = M_PI+getTauMinus(taus)->getRotationAngle(TauolaParticle::X_AXIS);
717  rotateSystem(grandmothers,taus,*rotation_angle2,TauolaParticle::X_AXIS);
718  }
719 
720  //now rotate incoming beams so they are aligned in the y-z plane
721  if(grandmothers.size()<1){ //if there are no grandmothers
722  *rotation_angle3 = 0;
723  return;
724  }
725 
726  //the first grandmother will have a positive y component
727  if(getGrandmotherPlus(grandmothers))
729  else
731 
732  rotateSystem(grandmothers,taus,*rotation_angle3,TauolaParticle::X_AXIS,TauolaParticle::Y_AXIS);
733 
734 }
735 
736 /** Reverses boostFromLabtoMotherFrame. The three rotation angle must be provided.
737  Any modification to this would require a modification to boostFromLabToTauPairFrame
738  since this is the inverse transformation (Step 2: A^-1). */
740  double rotation_angle2,
741  double rotation_angle3,
742  TauolaParticle * mother,
743  vector<TauolaParticle *> grandmothers,
744  vector<TauolaParticle *> taus){
745 
746 
747  if(mother==0) //if there are no mothers
748  return;
749 
750 
751  //rotate grand mothers back away from the y-z plane
752  rotateSystem(grandmothers,taus,-rotation_angle3, TauolaParticle::X_AXIS,TauolaParticle::Y_AXIS);
753 
754  //rotate all so that taus are no longer on the z axis
755  rotateSystem(grandmothers,taus,-rotation_angle2,TauolaParticle::X_AXIS);
756  rotateSystem(grandmothers,taus,-rotation_angle1,TauolaParticle::Y_AXIS);
757 
758 
759  /*** boost grandmothers and daughters (taus) back into the lab frame */
760  for(int i=0; i< (int) grandmothers.size(); i++)
761  grandmothers.at(i)->boostFromRestFrame(mother);
762  //If taus.size()==1 then taus[1] is the same as mum. Disaster to be avoided.
763  if(taus.size()!=1)
764  for(int i=0; i< (int) taus.size(); i++){
765  taus.at(i)->boostFromRestFrame(mother);
766  taus.at(i)->boostDaughtersFromRestFrame(mother);
767  }
768 }
769 
770 void TauolaParticlePair::rotateSystem(vector<TauolaParticle *> grandmothers,
771  vector<TauolaParticle *> taus,
772  double theta, int axis, int axis2){
773  for(int i=0; i< (int) grandmothers.size(); i++)
774  grandmothers.at(i)->rotate(axis,theta,axis2);
775  for(int i=0; i< (int) taus.size(); i++){
776  taus.at(i)->rotate(axis,theta,axis2);
777  taus.at(i)->rotateDaughters(axis,theta,axis2);
778  }
779 }
780 
781 
782 
783 /***********************************************************
784  Some extra useful methods
785 ************************************************************/
787 
788  //calculate mothers 4-momentum based on the daughters.
789  double e=0;
790  double px=0;
791  double py=0;
792  double pz=0;
793 
794  bool tau_plus = false;
795  bool tau_minus = false;
796  bool tau_neutrino = false;
797  bool tau_antineutrino = false;
798 
799  for(int d=0; d < (int) taus.size(); d++){
800  TauolaParticle * daughter = taus.at(d);
801  e+=daughter->getE();
802  px+=daughter->getPx();
803  py+=daughter->getPy();
804  pz+=daughter->getPz();
805  switch(daughter->getPdgID()){
807  tau_plus=true;
808  break;
810  tau_minus=true;
811  break;
813  tau_neutrino=true;
814  break;
816  tau_antineutrino=true;
817  break;
818  }
819  }
820  double m = e*e-px*px-py*py-pz*pz;
821  if(m<0)
822  m= -sqrt(-m);
823  else
824  m=sqrt(m);
825 
826  //look for mothers type:
827  int pdg=0;
828 
829  //Assume Z
830  if(tau_plus&&tau_minus)
831  pdg=TauolaParticle::Z0 ;
832 
833  //Assume W+
834  if(tau_plus&&tau_neutrino)
836 
837  //Assume W-
838  if(tau_minus&&tau_antineutrino)
840 
841  // now make the mother
842  return taus.at(0)->createNewParticle(pdg,2,m,px,py,pz,e);
843 }
844 
845 // see if "particle" is one of the final taus in this tau pair
846 // (based on particle barcode)
847 // NOTE: Not executed by release examples
849 
850  for(int i=0; i< (int) m_final_particles.size(); i++){
851  if(m_final_particles.at(i)->getBarcode()==particle->getBarcode())
852  return true;
853  }
854  return false;
855 }
856 
857 TauolaParticle * TauolaParticlePair::getTauMinus(vector<TauolaParticle*> taus){
858  for(int i=0; i< (int) taus.size(); i++){
859  if(taus.at(i)->getPdgID()==TauolaParticle::TAU_MINUS)
860  return taus.at(i);
861  }
862  return 0;
863 }
864 
865 TauolaParticle * TauolaParticlePair::getTauPlus(vector<TauolaParticle*> taus){
866  for(int i=0; i< (int) taus.size(); i++){
867  if(taus.at(i)->getPdgID()==TauolaParticle::TAU_PLUS)
868  return taus.at(i);
869  }
870  return 0;
871 }
872 
873 TauolaParticle * TauolaParticlePair::getGrandmotherPlus(vector<TauolaParticle*> grandmothers){
874  //choose based on energy if there are more than one??
875  double e = -1e30;
876  int index = -1;
877  for(int i=0; i< (int) grandmothers.size(); i++){
878  if( (grandmothers.at(i)->getPdgID()<0 && grandmothers.at(i)->getPdgID()>-9) ||
879  grandmothers.at(i)->getPdgID()== TauolaParticle::POSITRON||
880  grandmothers.at(i)->getPdgID()== TauolaParticle::MUON_PLUS){
881  if(e<grandmothers.at(i)->getE()){
882  e=grandmothers.at(i)->getE();
883  index=i;
884  }
885  }
886  }
887  if(index==-1)
888  {
889  for(int i=0; i< (int) grandmothers.size(); i++)
890  {
891  if(grandmothers.at(i)->getPdgID()==21 || grandmothers.at(i)->getPdgID()==22)
892  {
893  index=i;
894  e=grandmothers.at(i)->getE();
895  break;
896  }
897  }
898  }
899  if(index==-1) index=0;
900  if(e==0)
901  {
902  grandmothers.at(index)->print();
903  return 0;
904  }
905  else
906  return grandmothers.at(index);
907 }
908 
909 TauolaParticle * TauolaParticlePair::getGrandmotherMinus(vector<TauolaParticle*> grandmothers){
910  //choose based on energy if there are more than one??
911  double e = -1e30;
912  int index = -1;
913  for(int i=0; i< (int) grandmothers.size(); i++){
914  if( (grandmothers.at(i)->getPdgID()>0 && grandmothers.at(i)->getPdgID()<9) ||
915  grandmothers.at(i)->getPdgID()== TauolaParticle::ELECTRON||
916  grandmothers.at(i)->getPdgID()== TauolaParticle::MUON_MINUS){
917  if(e<grandmothers.at(i)->getE()){
918  e=grandmothers.at(i)->getE();
919  index=i;
920  }
921  }
922  }
923  if(index==-1)
924  {
925  for(int i=(int) grandmothers.size()-1; i>=0 ; i--)
926  {
927  if(grandmothers.at(i)->getPdgID()==21||grandmothers.at(i)->getPdgID()==22)
928  {
929  index=i;
930  e=grandmothers.at(i)->getE();
931  break;
932  }
933  }
934  }
935  if(index==-1) index=0;
936  if(e==0)
937  return 0;
938  else
939  return grandmothers.at(index);
940 }
941 
942 
943 
945 
946  Log::RedirectOutput(Log::Info());
947  std::cout << "Daughters final:" << std::endl;
948  for(int i=0; i< (int) m_final_particles.size(); i++)
949  m_final_particles.at(i)->print();
950 
951 
952  std::cout << "Daughters at production:" << std::endl;
953  for(int i=0; i< (int) m_production_particles.size(); i++)
954  m_production_particles.at(i)->print();
955 
956 
957  std::cout << "Mother particle: " << std::endl;
958  if(m_mother)
959  m_mother->print();
960 
961  std::cout << "Grandmother particles: " << std::endl;
962  for(int i=0; i< (int) m_grandmothers.size(); i++)
963  m_grandmothers.at(i)->print();
964 
966 }
967 
968 
970 
971  for(int i=0; i< (int) m_final_particles.size(); i++)
972  m_final_particles.at(i)->checkMomentumConservation();
973 
974  for(int i=0; i< (int) m_production_particles.size(); i++)
975  m_production_particles.at(i)->checkMomentumConservation();
976 
977  if(m_mother)
979 
980  for(int i=0; i< (int) m_grandmothers.size(); i++)
981  m_grandmothers.at(i)->checkMomentumConservation();
982 
983 }
984 
985 void TauolaParticlePair::recalculateRij(int incoming_pdg_id, int outgoing_pdg_id, double invariant_mass_squared, double cosTheta){
986 
987  if (abs(outgoing_pdg_id)!=15)
988  {
989  Log::Warning()<<"interface was not used for taus pdg id="<<outgoing_pdg_id<<endl;
990  return;
991  }
992 
993  double (*T) [Tauola::NCOS][4][4] = NULL;
994  double (*Tw) [Tauola::NCOS] = NULL;
995  double (*Tw0)[Tauola::NCOS] = NULL;
996  double smin = 0.0; // Tauola::sminA;
997  double smax = 0.0; // Tauola::smaxA;
998  double step = 0.0; // (smaxl-sminl)/(Tauola::NS1-1);
999 
1000  // Select table for appropriate incoming particles
1001  switch(abs(incoming_pdg_id)){
1002  case 11:
1003  if(invariant_mass_squared<Tauola::smaxB && invariant_mass_squared>Tauola::sminB)
1004  {
1005  T = Tauola::table11B;
1006  Tw = Tauola::wtable11B;
1007  Tw0 = Tauola::w0table11B;
1008  smin = Tauola::sminB;
1009  smax = Tauola::smaxB;
1010  step = (smax-smin)/(Tauola::NS2-1);
1011  }
1012  else if (invariant_mass_squared<Tauola::smaxC && invariant_mass_squared>Tauola::sminC)
1013  {
1014  T = Tauola::table11C;
1015  Tw = Tauola::wtable11C;
1016  Tw0 = Tauola::w0table11C;
1017  smin = Tauola::sminC;
1018  smax = Tauola::smaxC;
1019  step = (smax-smin)/(Tauola::NS3-1);
1020  }
1021  else
1022  {
1023  T = Tauola::table11A;
1024  Tw = Tauola::wtable11A;
1025  Tw0 = Tauola::w0table11A;
1026  smin = Tauola::sminA;
1027  smax = Tauola::smaxA;
1028  step = (smax-smin)/(Tauola::NS1-1);
1029  }
1030  break;
1031 
1032  // NOTE: Use the same tables for 1, 3 and 5
1033  case 1:
1034  case 3:
1035  case 5:
1036  if(invariant_mass_squared<Tauola::smaxB && invariant_mass_squared>Tauola::sminB)
1037  {
1038  T = Tauola::table1B;
1039  Tw = Tauola::wtable1B;
1040  Tw0 = Tauola::w0table1B;
1041  smin = Tauola::sminB;
1042  smax = Tauola::smaxB;
1043  step = (smax-smin)/(Tauola::NS2-1);
1044  }
1045  else if (invariant_mass_squared<Tauola::smaxC && invariant_mass_squared>Tauola::sminC)
1046  {
1047  T = Tauola::table1C;
1048  Tw = Tauola::wtable1C;
1049  Tw0 = Tauola::w0table1C;
1050  smin = Tauola::sminC;
1051  smax = Tauola::smaxC;
1052  step = (smax-smin)/(Tauola::NS3-1);
1053  }
1054  else
1055  {
1056  T = Tauola::table1A;
1057  Tw = Tauola::wtable1A;
1058  Tw0 = Tauola::w0table1A;
1059  smin = Tauola::sminA;
1060  smax = Tauola::smaxA;
1061  step = (smax-smin)/(Tauola::NS1-1);
1062  }
1063  break;
1064 
1065  // NOTE: Use the same tables for 2 and 4
1066  case 2:
1067  case 4:
1068  if(invariant_mass_squared<Tauola::smaxB && invariant_mass_squared>Tauola::sminB)
1069  {
1070  T = Tauola::table2B;
1071  Tw = Tauola::wtable2B;
1072  Tw0 = Tauola::w0table2B;
1073  smin = Tauola::sminB;
1074  smax = Tauola::smaxB;
1075  step = (smax-smin)/(Tauola::NS2-1);
1076  }
1077  else if (invariant_mass_squared<Tauola::smaxC && invariant_mass_squared>Tauola::sminC)
1078  {
1079  T = Tauola::table2C;
1080  Tw = Tauola::wtable2C;
1081  Tw0 = Tauola::w0table2C;
1082  smin = Tauola::sminC;
1083  smax = Tauola::smaxC;
1084  step = (smax-smin)/(Tauola::NS3-1);
1085  }
1086  else
1087  {
1088  T = Tauola::table2A;
1089  Tw = Tauola::wtable2A;
1090  Tw0 = Tauola::w0table2A;
1091  smin = Tauola::sminA;
1092  smax = Tauola::smaxA;
1093  step = (smax-smin)/(Tauola::NS1-1);
1094  }
1095  break;
1096 
1097  default:
1098  Log::Warning()<<"interface was not used for proper beams pdg id="<<incoming_pdg_id<<endl;
1099  return;
1100  }
1101 
1102  // Check if we have found a table for matrix recalculation
1103  if (T[0][0][0][0]<0.5) return;
1104 
1105  // If mass is too small
1106  if (invariant_mass_squared <= exp(Tauola::sminA)){
1107  double mta = 1.777;
1108  double cosf = cosTheta;
1109  double s = invariant_mass_squared;
1110  double sinf = sqrt(1-cosf*cosf);
1111  double MM = sqrt(4e0*mta*mta/s);
1112  double xnorm = 1+cosf*cosf + MM*MM*sinf*sinf;
1113 
1114  // Zero matrix
1115  for (int i=0;i<4;i++)
1116  for (int j=0;j<4;j++)
1117  m_R[i][j]=0.0;
1118 
1119  m_R[0][0] = (1+cosf*cosf + MM*MM*sinf*sinf)/xnorm;
1120  m_R[1][1] = (-(1- MM*MM)*sinf*sinf)/xnorm;
1121  m_R[2][2] = ( (1+ MM*MM)*sinf*sinf)/xnorm;
1122  m_R[3][3] = (1+cosf*cosf - MM*MM*sinf*sinf)/xnorm;
1123  m_R[2][3] = (2*MM*sinf*cosf)/xnorm;
1124  m_R[3][2] = (2*MM*sinf*cosf)/xnorm;
1125 
1126  // Get weights
1127  double w = 1.;
1128  double w0 = 1.;
1129 
1130  if (Tauola::wtable2A[0][0]>0 ) w=Tauola::wtable2A[0][0];
1131  else if(Tauola::wtable1A[0][0]>0 ) w=Tauola::wtable1A[0][0];
1132  else if(Tauola::wtable11A[0][0]>0) w=Tauola::wtable11A[0][0];
1133 
1134  if (Tauola::wtable2A[0][0]>0 ) w0=Tauola::w0table2A[0][0];
1135  else if(Tauola::wtable1A[0][0]>0 ) w0=Tauola::w0table1A[0][0];
1136  else if(Tauola::wtable11A[0][0]>0) w0=Tauola::w0table11A[0][0];
1137 
1138  // Tauola::setEWwt(w/w0);
1139  Tauola::setEWwt(w,w0);
1140  return;
1141  } // if(mass too small)
1142 
1143  int x = 0;
1144  double buf = smin;
1145  double remnant = 0.0;
1146 
1147  // Interpolate s
1148  if(T==Tauola::table11A || T==Tauola::table1A || T== Tauola::table2A)
1149  {
1150  while(log(invariant_mass_squared) > buf){
1151  x++;
1152  buf += (step);
1153  }
1154  remnant = (log(invariant_mass_squared)-(buf-step))/step;
1155  }
1156  else
1157  {
1158  while(invariant_mass_squared > buf){
1159  x++;
1160  buf += step;
1161  }
1162  remnant = (invariant_mass_squared-(buf-step))/step;
1163  }
1164 
1165  double cmin = -1.;
1166  int y = 0;
1167  double remnantc = 0.0;
1168 
1169  // Interpolate cosTheta
1170  buf = cmin+1./Tauola::NCOS;
1171  while(cosTheta > buf){
1172  y++;
1173  buf+=2./Tauola::NCOS;
1174  }
1175 
1176  remnantc = (cosTheta-(buf-2./Tauola::NCOS))/(2./Tauola::NCOS);
1177 
1178  // Special cases at edges - extrapolation
1179  bool isUsingExtrapolation = false;
1180  if(y >= Tauola::NCOS) { isUsingExtrapolation = true; y = Tauola::NCOS-1; }
1181  if(y == 0) { isUsingExtrapolation = true; y = 1; }
1182 
1183  // Bilinear interpolation
1184  double b11,b21,b12,b22;
1185 
1186  for (int i=0; i<4; i++){
1187  for (int j=0; j<4; j++){
1188  // std::cout << "---petla i,j---"<<i<<" "<<j<<std::endl;
1189  if(isUsingExtrapolation){
1190  if(y == 1){
1191  b11 = 2*T[x-1][0][i][j] - T[x-1][1][i][j];
1192  b21 = 2*T[x][0][i][j] - T[x][1][i][j];
1193  b12 = T[x-1][0][i][j];
1194  b22 = T[x][0][i][j];
1195  }
1196  else{
1197  b11 = T[x-1][y][i][j];
1198  b21 = T[x][y][i][j];
1199  b12 = 2*T[x-1][y][i][j] - T[x-1][y-1][i][j];
1200  b22 = 2*T[x][y][i][j] - T[x][y-1][i][j];
1201  }
1202  } // if(isUsingExtrapolation)
1203  else{
1204  b11 = T[x-1][y-1][i][j];
1205  b21 = T[x][y-1][i][j];
1206  b12 = T[x-1][y][i][j];
1207  b22 = T[x][y][i][j];
1208  }
1209  m_R[i][j] = b11*(1-remnant)*(1-remnantc) + b21*remnant*(1-remnantc)
1210  + b12*(1-remnant)*remnantc + b22*remnant*remnantc;
1211  //if(i==1&&j==1) { std::cout << "echh i,j=1 b11,b22,b21,b12= "<<b11<<" "<<b22<<" "<<b21<<" "<<b12<< std::endl;
1212  //}
1213  } // for(j)
1214  } // for(i)
1215  //std::cout << "---tutaaj---"<<std::endl;
1216 
1217  transcosTheta= cosTheta;
1218  transincoming_pdg_id=incoming_pdg_id;
1219  transinvariant_mass=sqrt(invariant_mass_squared);
1220  //std::cout << "transcosTheta= "<<transcosTheta<<std::endl;
1221  //std::cout << "uzywamy cosTheta, invariant_mass, incoming_pdg_id= "<< cosTheta<<" "<<sqrt(invariant_mass_squared)<<" "<< incoming_pdg_id<<std::endl;
1222  //std::cout << "testy m_R(1,1)(2,2)=: " << m_R[1][1]<<" "<<m_R[2][2]<<" refik= "<< (1-cosTheta*cosTheta)/(1+cosTheta*cosTheta+2*cosTheta)<<std::endl;
1223  // h1->Fill(cosTheta);
1224  // Calculate electroweak weights
1225  double w,w0;
1226 
1227  if(isUsingExtrapolation){
1228  if(y == 1){
1229  b11 = 2*Tw[x-1][0] - Tw[x-1][1];
1230  b21 = 2*Tw[x][0] - Tw[x][1];
1231  b12 = Tw[x-1][0];
1232  b22 = Tw[x][0];
1233  }
1234  else
1235  {
1236  b11 = Tw[x-1][y];
1237  b21 = Tw[x][y];
1238  b12 = 2*Tw[x-1][y] - Tw[x-1][y-1];
1239  b22 = 2*Tw[x][y] - Tw[x][y-1];
1240  }
1241  } // if(isUsingExtrapolation)
1242  else
1243  {
1244  b11 = Tw[x-1][y-1];
1245  b21 = Tw[x][y-1];
1246  b12 = Tw[x-1][y];
1247  b22 = Tw[x][y];
1248  }
1249 
1250  w = b11*(1-remnant)*(1-remnantc) + b21*remnant*(1-remnantc)
1251  + b12*(1-remnant)*remnantc + b22*remnant*remnantc;
1252 
1253  if(isUsingExtrapolation){
1254  if(y == 1){
1255  b11 = 2*Tw0[x-1][0] - Tw0[x-1][1];
1256  b21 = 2*Tw0[x][0] - Tw0[x][1];
1257  b12 = Tw0[x-1][0];
1258  b22 = Tw0[x][0];
1259  }
1260  else{
1261  b11 = Tw0[x-1][y];
1262  b21 = Tw0[x][y];
1263  b12 = 2*Tw0[x-1][y] - Tw0[x-1][y-1];
1264  b22 = 2*Tw0[x][y] - Tw0[x][y-1];
1265  }
1266  } // if (isUsingExtrapolation)
1267  else{
1268  b11 = Tw0[x-1][y-1];
1269  b21 = Tw0[x][y-1];
1270  b12 = Tw0[x-1][y];
1271  b22 = Tw0[x][y];
1272  }
1273 
1274  w0 = b11*(1-remnant)*(1-remnantc) + b21*remnant*(1-remnantc)
1275  + b12*(1-remnant)*remnantc + b22*remnant*remnantc;
1276  // std::cout << "---tutaaj setEW---"<<std::endl;
1277  Tauola::setEWwt(w,w0);
1278  //std::cout << "---tutaaj po setEW---"<<std::endl;
1279 }
1280 
1281 } // namespace Tauolapp
TauolaParticle * clone()
TauolaParticle * getTauMinus(std::vector< TauolaParticle * > particles)
virtual void setPdgID(int pdg_id)=0
static const double * getDecayOnePolarization()
Definition: Tauola.cxx:601
static void RedirectOutput(void(*func)(), ostream &where=*out)
Definition: Log.cxx:93
static double getTauMass()
Definition: Tauola.cxx:668
virtual void print()=0
std::vector< TauolaParticle * > findProductionMothers()
void addToBeam(TauolaParticle *pcle, std::vector< TauolaParticle * > *candidates_same, std::vector< TauolaParticle * > *candidates_opp)
TauolaParticle * getGrandmotherPlus(std::vector< TauolaParticle * > particles)
double getZPolarization(int *incoming_pdg_id, int *outgoing_pdg_id, double *invMass, double *cosTheta)
static void AddDecay(int type)
Definition: Log.cxx:25
void recalculateRij(int incoming_pdg_id, int outgoing_pdg_id, double invariant_mass_squared, double cosTheta)
static int getHiggsScalarPseudoscalarPDG()
Definition: Tauola.cxx:676
virtual double getPx()=0
virtual double getE()=0
virtual int getPdgID()=0
virtual double getPy()=0
void add(TauolaParticle *)
std::vector< TauolaParticle * > m_final_particles
bool contains(TauolaParticle *particle)
double getRotationAngle(int axis, int second_axis=Z_AXIS)
double getVirtuality(TauolaParticle *p1, TauolaParticle *p2, bool flip)
void rotateSystem(vector< TauolaParticle * > grandmothers, vector< TauolaParticle * > taus, double theta, int axis, int axis2=TauolaParticle::Z_AXIS)
static bool isUsingDecayOneBoost()
Definition: Tauola.cxx:586
std::vector< TauolaParticle * > m_grandmothers
static bool isUsingDecayOne()
Definition: Tauola.cxx:581
void boostFromTauPairToLabFrame(double rotation_angle1, double rotation_angle2, double rotation_angle3, TauolaParticle *mother, vector< TauolaParticle * > grandmothers, vector< TauolaParticle * > taus)
TauolaParticle * getTauPlus(std::vector< TauolaParticle * > particles)
std::vector< TauolaParticle * > m_production_particles
static void setBornKinematics(int incoming_pdg_id, int outgoing_pdg_id, double invariant_mass_squared, double cosTheta)
TauolaParticle * findLastSelf()
static void RevertOutput()
TauolaParticle * getGrandmotherMinus(std::vector< TauolaParticle * > particles)
void boostFromLabToTauPairFrame(double *rotation_angle1, double *rotation_angle2, double *rotation_angle3, TauolaParticle *mother, vector< TauolaParticle * > grandmothers, vector< TauolaParticle * > taus)
void subtract(TauolaParticle *)
virtual int getBarcode()=0
TauolaParticle * makeTemporaryMother(vector< TauolaParticle * > taus)
static void Fatal(string text, unsigned short int code=0)
virtual double getPz()=0