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
00029 double TauolaParticle::getAngle(TauolaParticle * other_particle){
00030
00031
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
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
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
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
00106 TauolaDecay(getSign(),&m_pol_x, &m_pol_y, &m_pol_z, &m_pol_n);
00107 }
00108
00109 void TauolaParticle::addDecayToEventRecord(){
00110
00111
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
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
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
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
00191
00192
00193
00194
00195 }
00196
00197
00198 void TauolaParticle::boostDaughtersFromRestFrame(TauolaParticle * tau_momentum){
00199
00200 if(!hasDaughters())
00201 return;
00202
00203 vector<TauolaParticle*> daughters = getDaughters();
00204 vector<TauolaParticle*>::iterator pcl_itr = daughters.begin();
00205
00206
00207 for(;pcl_itr != daughters.end();pcl_itr++){
00208
00209 (*pcl_itr)->boostFromRestFrame(tau_momentum);
00210 (*pcl_itr)->boostDaughtersFromRestFrame(tau_momentum);
00211 }
00212
00213 }
00214
00215 void TauolaParticle::boostDaughtersToRestFrame(TauolaParticle * tau_momentum){
00216
00217 if(!hasDaughters())
00218 return;
00219
00220
00221 vector<TauolaParticle*> daughters = getDaughters();
00222 vector<TauolaParticle*>::iterator pcl_itr = daughters.begin();
00223
00224
00225 for(;pcl_itr != daughters.end();pcl_itr++){
00226
00227 (*pcl_itr)->boostToRestFrame(tau_momentum);
00228 (*pcl_itr)->boostDaughtersToRestFrame(tau_momentum);
00229 }
00230
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
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
00252
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
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
00268
00269 double TauolaParticle::getRotationAngle(int axis, int second_axis){
00270
00271
00272
00273
00274
00275
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
00291
00292 void TauolaParticle::boostAlongZ(double boost_pz, double boost_e){
00293
00294
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
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())
00315 return;
00316
00317 vector<TauolaParticle*> daughters = getDaughters();
00318 vector<TauolaParticle*>::iterator pcl_itr = daughters.begin();
00319
00320
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
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);
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 }