LCOV - code coverage report
Current view: top level - TEvtGen/Tauola - TauolaParticlePair.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 615 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 20 0.0 %

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

Generated by: LCOV version 1.11