TauolaParticle.cxx

00001 #include "TauolaParticle.h"
00002 #include "Log.h"
00003 #include <stdexcept> 
00004 
00005 namespace Tauolapp
00006 {
00007 
00008 double TauolaParticle::getPolarimetricX(){
00009   return m_pol_x;
00010 }
00011 
00012 double TauolaParticle::getPolarimetricY(){
00013   return m_pol_y;
00014 }
00015 
00016 double TauolaParticle::getPolarimetricZ(){
00017   return m_pol_z;
00018 }
00019 
00020 
00021 TauolaParticle * TauolaParticle::clone(){
00022   
00023   return createNewParticle(getPdgID(),getStatus(),getMass(),
00024                            getPx(),getPy(),getPz(),getE());
00025 
00026 }
00027 
00028 // NOTE: Not executed by release examples
00029 double TauolaParticle::getAngle(TauolaParticle * other_particle){
00030 
00031   //use the dot product
00032   double x1 = getPx();
00033   double y1 = getPy();
00034   double z1 = getPz();
00035   double x2 = other_particle->getPx();
00036   double y2 = other_particle->getPy();
00037   double z2 = other_particle->getPz();
00038 
00039   return acos( (x1*x2+y1*y2+z1*z2) / sqrt((x1*x1+y1*y1+z1*z1)*(x2*x2+y2*y2+z2*z2)) );
00040 
00041 }
00042 
00043 // NOTE: Not executed by release examples
00044 void TauolaParticle::add(TauolaParticle * other_particle){
00045 
00046   setPx(getPx() + other_particle->getPx());
00047   setPy(getPy() + other_particle->getPy());
00048   setPz(getPz() + other_particle->getPz());
00049   setE(getE() + other_particle->getE());
00050   setMass( sqrt( getE()*getE()-getPx()*getPx()-getPy()*getPy()-getPz()*getPz() ));
00051 }
00052 
00053 void TauolaParticle::subtract(TauolaParticle * other_particle){
00054 
00055   setPx(getPx() - other_particle->getPx());
00056   setPy(getPy() - other_particle->getPy());
00057   setPz(getPz() - other_particle->getPz());
00058   setE(getE() - other_particle->getE());
00059   setMass( sqrt( getE()*getE()-getPx()*getPx()-getPy()*getPy()-getPz()*getPz() ));
00060 }
00061 
00062 int TauolaParticle::getSign(){
00063   if(getPdgID()== Tauola::getDecayingParticle())
00064     return SAME_SIGN;
00065   else if(getPdgID()== -1 * Tauola::getDecayingParticle())
00066     return OPPOSITE_SIGN;
00067   else
00068     return NA_SIGN;
00069 }
00070 
00071 bool TauolaParticle::hasDaughters(){
00072   if(getDaughters().size()==0)
00073     return 0;
00074   else
00075     return 1;
00076 }
00077 
00078 TauolaParticle * TauolaParticle::findLastSelf(){
00079   vector<TauolaParticle*> daughters = getDaughters();
00080   vector<TauolaParticle*>::iterator pcl_itr = daughters.begin();
00081   
00082   //get all daughters and look for stable with same pgd id
00083   for(;pcl_itr != daughters.end();pcl_itr++){
00084     if((*pcl_itr)->getPdgID()==this->getPdgID())
00085       return (*pcl_itr)->findLastSelf();
00086   }
00087 
00088   return this;
00089 }
00090 
00091 std::vector<TauolaParticle*> TauolaParticle::findProductionMothers(){
00092   vector<TauolaParticle*> mothers = getMothers();
00093   vector<TauolaParticle*>::iterator pcl_itr = mothers.begin();
00094   
00095     //get all mothers and check none have pdg id of this one
00096     for(;pcl_itr != mothers.end();pcl_itr++){
00097       if((*pcl_itr)->getPdgID()==this->getPdgID())
00098         return (*pcl_itr)->findProductionMothers();
00099     }
00100     return mothers;
00101 }
00102 
00103 void TauolaParticle::decay(){
00104 
00105   //Do the decay and set the polarimetric vectors
00106   TauolaDecay(getSign(),&m_pol_x, &m_pol_y, &m_pol_z, &m_pol_n);
00107 }
00108 
00109 void TauolaParticle::addDecayToEventRecord(){
00110 
00111   //Add to decay list used by f_filhep.c
00112   DecayList::addToEnd(this);
00113   TauolaWriteDecayToEventRecord(getSign());
00114 
00115   double xmom[4]={0};
00116   double *pp=xmom;
00117 
00118   if (Tauola::ion[2])
00119     for(int i=1;1;i++)
00120     {
00121       TauolaParticle *x;
00122       try{ x=DecayList::getParticle(i); }
00123       catch(std::out_of_range d) {break;}
00124       if(x->getPdgID()==221){ 
00125 
00126         // Fix 28.04.2011 The pp vector must have boost for eta undone
00127         TauolaParticle *x_copy = x->clone();
00128         if(getP(TauolaParticle::Z_AXIS)>0)
00129           x_copy->boostAlongZ(-getP(),getE());
00130         else
00131           x_copy->boostAlongZ(getP(),getE());
00132 
00133         pp[3]=x_copy->getE();
00134         pp[0]=x_copy->getPx();
00135         pp[1]=x_copy->getPy();
00136         pp[2]=x_copy->getPz();
00137         taueta_(pp,&i);
00138       } 
00139     }
00140 
00141   if (Tauola::ion[1])
00142     for(int i=1;1;i++)
00143     {
00144       TauolaParticle *x;
00145       try{ x=DecayList::getParticle(i); }
00146       catch(std::out_of_range d) {break;}
00147       if(x->getPdgID()==310){
00148 
00149         // Fix 28.04.2011 The pp vector must have boost for k0 undone
00150         TauolaParticle *x_copy = x->clone();
00151         if(getP(TauolaParticle::Z_AXIS)>0)
00152           x_copy->boostAlongZ(-getP(),getE());
00153         else
00154           x_copy->boostAlongZ(getP(),getE());
00155 
00156         pp[3]=x_copy->getE();
00157         pp[0]=x_copy->getPx();
00158         pp[1]=x_copy->getPy();
00159         pp[2]=x_copy->getPz();
00160         tauk0s_(pp,&i);
00161       } 
00162     }
00163 
00164   if (Tauola::ion[0])
00165     for(int i=1;1;i++)
00166     {
00167       TauolaParticle *x;
00168       try{ x=DecayList::getParticle(i); }
00169       catch(std::out_of_range d) {break;}
00170       if(x->getPdgID()==111){ 
00171 
00172         // Fix 28.04.2011 The pp vector must have boost for pi0 undone
00173         TauolaParticle *x_copy = x->clone();
00174         if(getP(TauolaParticle::Z_AXIS)>0)
00175           x_copy->boostAlongZ(-getP(),getE());
00176         else
00177           x_copy->boostAlongZ(getP(),getE());
00178 
00179         pp[3]=x_copy->getE();
00180         pp[0]=x_copy->getPx();
00181         pp[1]=x_copy->getPy();
00182         pp[2]=x_copy->getPz();
00183         taupi0_(pp,&i);
00184       } 
00185     }
00186   DecayList::clear();
00187 
00188   if(!hasDaughters())
00189     Log::Fatal("TAUOLA failed. No decay was created",5);
00190   //  checkMomentumConservation();
00191   //  decayEndgame(); // vertex shift was wrongly calculated, 
00192   //                     used 4-momenta should be in lab frame,
00193   //                     thanks to Sho Iwamoto for debug info.
00194 
00195 }
00196 
00197 
00198 void TauolaParticle::boostDaughtersFromRestFrame(TauolaParticle * tau_momentum){
00199 
00200   if(!hasDaughters()) //if there are no daughters
00201     return;
00202 
00203   vector<TauolaParticle*> daughters = getDaughters();
00204   vector<TauolaParticle*>::iterator pcl_itr = daughters.begin();
00205   
00206   //get all daughters then rotate and boost them.
00207   for(;pcl_itr != daughters.end();pcl_itr++){
00208  
00209     (*pcl_itr)->boostFromRestFrame(tau_momentum);
00210     (*pcl_itr)->boostDaughtersFromRestFrame(tau_momentum);
00211   }
00212   //checkMomentumConservation();
00213 }
00214 
00215 void TauolaParticle::boostDaughtersToRestFrame(TauolaParticle * tau_momentum){
00216 
00217   if(!hasDaughters()) //if there are no daughters
00218     return;
00219   // NOTE: Not executed by release examples
00220   //       because !hasDaughters() is always true
00221   vector<TauolaParticle*> daughters = getDaughters();
00222   vector<TauolaParticle*>::iterator pcl_itr = daughters.begin();
00223   
00224   //get all daughters then rotate and boost them.
00225   for(;pcl_itr != daughters.end();pcl_itr++){
00226  
00227     (*pcl_itr)->boostToRestFrame(tau_momentum);
00228     (*pcl_itr)->boostDaughtersToRestFrame(tau_momentum);
00229   }
00230   //checkMomentumConservation();
00231 }
00232 
00233 
00234 void TauolaParticle::boostToRestFrame(TauolaParticle * tau_momentum){
00235 
00236   double theta = tau_momentum->getRotationAngle(Y_AXIS);
00237   tau_momentum->rotate(Y_AXIS,theta);
00238   double phi = tau_momentum->getRotationAngle(X_AXIS);
00239   tau_momentum->rotate(Y_AXIS,-theta);
00240 
00241   //Now rotate coordinates to get boost in Z direction.
00242   rotate(Y_AXIS,theta);
00243   rotate(X_AXIS,phi);
00244   boostAlongZ(-1*tau_momentum->getP(),tau_momentum->getE());
00245   rotate(X_AXIS,-phi);
00246   rotate(Y_AXIS,-theta);
00247 
00248 }
00249 
00250 void TauolaParticle::boostFromRestFrame(TauolaParticle * tau_momentum){
00251   //get the rotation angles
00252   //and boost z
00253 
00254   double theta = tau_momentum->getRotationAngle(Y_AXIS);
00255   tau_momentum->rotate(Y_AXIS,theta);
00256   double phi = tau_momentum->getRotationAngle(X_AXIS);
00257   tau_momentum->rotate(Y_AXIS,-theta);
00258 
00259   //Now rotate coordinates to get boost in Z direction.
00260   rotate(Y_AXIS,theta);
00261   rotate(X_AXIS,phi);
00262   boostAlongZ(tau_momentum->getP(),tau_momentum->getE());
00263   rotate(X_AXIS,-phi);
00264   rotate(Y_AXIS,-theta);
00265 }
00266 
00267 /** Get the angle needed to rotate the 4 momentum vector so that
00268     the x (y) component disapears. (and the Z component is > 0) */
00269 double TauolaParticle::getRotationAngle(int axis, int second_axis){
00270 
00271   /**if(getP(axis)==0){
00272     if(getPz()>0)
00273       return 0; //no rotaion required
00274     else
00275       return M_PI;
00276       }**/
00277   if(getP(second_axis)==0){
00278     if(getP(axis)>0)
00279       return -M_PI/2.0;
00280     else
00281       return M_PI/2.0;
00282   }
00283   if(getP(second_axis)>0)
00284     return -atan(getP(axis)/getP(second_axis));
00285   else
00286     return M_PI-atan(getP(axis)/getP(second_axis));
00287 
00288 }
00289 
00290 /** Boost this vector along the Z direction.
00291     Assume no momentum components in the X or Y directions. */
00292 void TauolaParticle::boostAlongZ(double boost_pz, double boost_e){
00293 
00294   // Boost along the Z axis
00295   double m=sqrt(boost_e*boost_e-boost_pz*boost_pz);
00296 
00297   double p=getPz();
00298   double e=getE();
00299 
00300   setPz((boost_e*p + boost_pz*e)/m);
00301   setE((boost_pz*p + boost_e*e )/m);
00302 }
00303 
00304 /** Rotation around an axis X or Y */
00305 void TauolaParticle::rotate(int axis,double theta, int second_axis){
00306   
00307   double temp_px=getP(axis);
00308   double temp_pz=getP(second_axis);
00309   setP(axis,cos(theta)*temp_px + sin(theta)*temp_pz);
00310   setP(second_axis,-sin(theta)*temp_px + cos(theta)*temp_pz);
00311 }
00312 
00313 void TauolaParticle::rotateDaughters(int axis,double theta, int second_axis){
00314   if(!hasDaughters()) //if there are no daughters
00315     return;
00316 
00317   vector<TauolaParticle*> daughters = getDaughters();
00318   vector<TauolaParticle*>::iterator pcl_itr = daughters.begin();
00319   
00320   //get all daughters then rotate and boost them.
00321   for(;pcl_itr != daughters.end();pcl_itr++){
00322  
00323     (*pcl_itr)->rotate(axis,theta,second_axis);
00324     (*pcl_itr)->rotateDaughters(axis,theta,second_axis);
00325   }
00326   //checkMomentumConservation();
00327 }
00328 
00329 double TauolaParticle::getMass(){
00330   double e_sq=getE()*getE();
00331   double p_sq=getP()*getP();
00332 
00333   if(e_sq>p_sq)
00334     return sqrt(e_sq-p_sq);
00335   else
00336     return -1*sqrt(p_sq-e_sq); //if it's negative
00337 }
00338 
00339 double TauolaParticle::getP(){
00340   return sqrt(getPx()*getPx()+getPy()*getPy()+getPz()*getPz());
00341 }
00342 
00343 double TauolaParticle::getP(int axis){
00344   if(axis==X_AXIS)
00345     return getPx();
00346 
00347   if(axis==Y_AXIS)
00348     return getPy();
00349 
00350   if(axis==Z_AXIS)
00351     return getPz();
00352 
00353   return 0;
00354 }
00355 
00356 void TauolaParticle::setP(int axis, double p_component){
00357   if(axis==X_AXIS)
00358     setPx(p_component);
00359   if(axis==Y_AXIS)
00360     setPy(p_component);
00361   if(axis==Z_AXIS)
00362     setPz(p_component);
00363 }
00364 
00365 } // namespace Tauolapp
Generated on Sun Oct 20 20:24:11 2013 for C++InterfacetoTauola by  doxygen 1.6.3