00001 #include <vector>
00002 #include <cmath>
00003 #include "PhotosBranch.h"
00004 #include "PhotosParticle.h"
00005 #include "PH_HEPEVT_Interface.h"
00006 #include "Log.h"
00007 using namespace std;
00008
00009 namespace Photospp
00010 {
00011
00012 vector<PhotosParticle*> PH_HEPEVT_Interface::m_particle_list;
00013 int PH_HEPEVT_Interface::ME_channel=0;
00014 int PH_HEPEVT_Interface::decay_idx=0;
00015
00016 void PH_HEPEVT_Interface::clear(){
00017
00018 m_particle_list.clear();
00019
00020 ph_hepevt_.nevhep=0;
00021 ph_hepevt_.nhep=0;
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 }
00044
00045 void PH_HEPEVT_Interface::add_particle(int i,PhotosParticle * particle,
00046 int first_mother, int last_mother,
00047 int first_daughter, int last_daughter){
00048
00049 if(i>0)
00050 i--;
00051 else
00052 Log::Warning()<<"Index given to PH_HEPEVT_Interface::add_particle "
00053 <<"is too low (it must be > 0)."<<endl;
00054
00055
00056 m_particle_list.push_back(particle);
00057
00058
00059 ph_hepevt_.nevhep=0;
00060 ph_hepevt_.nhep=ph_hepevt_.nhep++;
00061 ph_hepevt_.isthep[i]=particle->getStatus();
00062 ph_hepevt_.idhep[i]=particle->getPdgID();
00063
00064 ph_hepevt_.jmohep[i][0]=first_mother;
00065 ph_hepevt_.jmohep[i][1]=last_mother;
00066
00067 ph_hepevt_.jdahep[i][0]=first_daughter;
00068 ph_hepevt_.jdahep[i][1]=last_daughter;
00069
00070 ph_hepevt_.phep[i][0]=particle->getPx();
00071 ph_hepevt_.phep[i][1]=particle->getPy();
00072 ph_hepevt_.phep[i][2]=particle->getPz();
00073 ph_hepevt_.phep[i][3]=particle->getE();
00074
00075
00076
00077 if(!Photos::massFrom4Vector) ph_hepevt_.phep[i][4]=particle->getMass();
00078 else ph_hepevt_.phep[i][4]=particle->getVirtuality();
00079
00080 int pdgid = abs(particle->getPdgID());
00081
00082
00083 if(Photos::forceMassList)
00084 {
00085 for(unsigned int j=0;j<Photos::forceMassList->size();j++)
00086 {
00087 if(pdgid == abs(Photos::forceMassList->at(j)->first))
00088 {
00089 double mass = Photos::forceMassList->at(j)->second;
00090
00091
00092
00093
00094 if(mass<0.0) mass = particle->getMass();
00095 ph_hepevt_.phep[i][4] = mass;
00096 }
00097 }
00098 }
00099
00100 ph_hepevt_.vhep[i][0]=0;
00101 ph_hepevt_.vhep[i][1]=0;
00102 ph_hepevt_.vhep[i][2]=0;
00103 ph_hepevt_.vhep[i][3]=0;
00104
00105 ph_phoqed_.qedrad[i]=1;
00106
00107 }
00108
00109 int PH_HEPEVT_Interface::set(PhotosBranch *branch)
00110 {
00111 PH_HEPEVT_Interface::clear();
00112 int idx=1;
00113
00114
00115 vector<PhotosParticle *> mothers = branch->getMothers();
00116 int nmothers=mothers.size();
00117
00118
00119 decay_idx=0;
00120 PhotosParticle *decay_particle = branch->getDecayingParticle();
00121 if(decay_particle) decay_idx=nmothers+1;
00122
00123
00124 vector<PhotosParticle *> daughters = branch->getDaughters();
00125 int ndaughters=daughters.size();
00126
00127 for(int i=0;i<nmothers;i++)
00128 {
00129 if(decay_idx)
00130 add_particle(idx++,mothers.at(i),
00131 0,0,
00132 decay_idx,decay_idx);
00133 else
00134 add_particle(idx++,mothers.at(i),
00135 0,0,
00136 nmothers+1,nmothers+ndaughters);
00137 }
00138
00139 if(decay_particle)
00140 add_particle(idx++,decay_particle,
00141 1,nmothers,
00142 nmothers+2,nmothers+1+ndaughters);
00143
00144 for(int i=0;i<ndaughters;i++)
00145 {
00146 if(decay_idx)
00147 add_particle(idx++,daughters.at(i),
00148 decay_idx,decay_idx,
00149 0,0);
00150 else
00151 add_particle(idx++,daughters.at(i),
00152 1,nmothers,
00153 0,0);
00154 }
00155
00156 Log::Debug(1000,false)<<"PH_HEPEVT returning: "<<( (decay_idx) ? decay_idx : 1 )<<" from "<<idx-1<<" particles."<<endl;
00157 return (decay_idx) ? decay_idx : 1;
00158 }
00159
00160 void PH_HEPEVT_Interface::get(){
00161
00162 int index = 0;
00163
00164
00165 if(ph_hepevt_.nhep == (int) m_particle_list.size())
00166 return;
00167
00168
00169
00170 int particle_count = m_particle_list.size();
00171 int daughters_start = ph_hepevt_.jmohep[ph_hepevt_.nhep-1][0];
00172 int photons = ph_hepevt_.nhep - m_particle_list.size();
00173 bool isPhotonCreated = (photons>0);
00174
00175 std::vector<PhotosParticle*> photon_list;
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 if(ph_hepevt_.jmohep[ph_hepevt_.nhep-1][1]>0)
00187 daughters_start = ph_hepevt_.jmohep[ph_hepevt_.nhep-1][1];
00188
00189 index = particle_count;
00190
00191
00192 for(;photons>0; photons--, index++){
00193
00194 if(ph_hepevt_.idhep[index]!=PhotosParticle::GAMMA)
00195 Log::Fatal("PH_HEPEVT_Interface::get(): Extra particle added to the PH_HEPEVT common block in not a photon!",6);
00196
00197
00198 PhotosParticle * new_photon;
00199 new_photon = m_particle_list.at(0)->createNewParticle(ph_hepevt_.idhep[index],
00200 ph_hepevt_.isthep[index],
00201 ph_hepevt_.phep[index][4],
00202 ph_hepevt_.phep[index][0],
00203 ph_hepevt_.phep[index][1],
00204 ph_hepevt_.phep[index][2],
00205 ph_hepevt_.phep[index][3]);
00206
00207
00208
00209 PhotosParticle * mother = m_particle_list.at(ph_hepevt_.jmohep[index][0]-1);
00210 mother->addDaughter(new_photon);
00211
00212
00213 photon_list.push_back(new_photon);
00214 }
00215
00216
00217
00218
00219 bool special=false;
00220 PhotosParticle *p1 = NULL;
00221 PhotosParticle *p2 = NULL;
00222
00223 if( isPhotonCreated )
00224 {
00225 std::vector<PhotosParticle*> daughters;
00226
00227
00228
00229
00230
00231
00232
00233 for(int i=daughters_start;i<particle_count;i++)
00234 {
00235 PhotosParticle *p = m_particle_list.at(i);
00236
00237 daughters.push_back(p);
00238 }
00239
00240
00241 special = true;
00242
00243 if(daughters.size()==0) special = false;
00244
00245
00246
00247 for(unsigned int i=0;i<daughters.size();i++)
00248 {
00249 if(daughters[i]->getStatus()==1)
00250 {
00251 special = false;
00252 break;
00253 }
00254
00255
00256
00257
00258 std::vector<PhotosParticle*> daughters2 = daughters[i]->getDaughters();
00259
00260 if(daughters2.size()!=1 ||
00261 daughters2[0]->getPdgID() != daughters[i]->getPdgID() )
00262 {
00263 special = false;
00264 break;
00265 }
00266 }
00267
00268 if( special )
00269 {
00270 double px1=0.0, py1=0.0, pz1=0.0, e1=0.0;
00271 double px2=0.0, py2=0.0, pz2=0.0, e2=0.0;
00272
00273
00274 for(unsigned int i=0;i<daughters.size();i++)
00275 {
00276
00277 if(daughters[i]->getPdgID()==22) continue;
00278
00279 px1+=daughters[i]->getPx();
00280 py1+=daughters[i]->getPy();
00281 pz1+=daughters[i]->getPz();
00282 e1 +=daughters[i]->getE();
00283 }
00284
00285
00286 for(unsigned int i=0;i<daughters.size();i++)
00287 {
00288
00289 if(daughters[i]->getPdgID()==22) continue;
00290
00291
00292
00293 px2 += daughters[i]->getDaughters().at(0)->getPx();
00294 py2 += daughters[i]->getDaughters().at(0)->getPy();
00295 pz2 += daughters[i]->getDaughters().at(0)->getPz();
00296 e2 += daughters[i]->getDaughters().at(0)->getE();
00297 }
00298
00299
00300
00301
00302 p1 = m_particle_list.at(0)->createNewParticle(0,-1,0.0,px1,py1,pz1,e1);
00303 p2 = m_particle_list.at(0)->createNewParticle(0,-2,0.0,px2,py2,pz2,e2);
00304
00305
00306 for(unsigned int i=0;i<photon_list.size();i++)
00307 {
00308 PhotosParticle *boosted = photon_list[i]->createNewParticle( 22, 1,
00309 0.0,
00310 photon_list[i]->getPx(),
00311 photon_list[i]->getPy(),
00312 photon_list[i]->getPz(),
00313 photon_list[i]->getE() );
00314
00315 boosted->boostToRestFrame(p1);
00316 boosted->boostFromRestFrame(p2);
00317
00318 photon_list[i]->createSelfDecayVertex(boosted);
00319
00320 delete boosted;
00321 }
00322
00323 Log::Warning()<<"Hidden interaction, all daughters self decay."
00324 <<"Potentially over simplified solution applied."<<endl;
00325 }
00326 }
00327
00328
00329
00330
00331
00332 for(index=daughters_start; index < particle_count && index < (int) m_particle_list.size(); index++){
00333
00334 PhotosParticle * particle = m_particle_list.at(index);
00335
00336 if(ph_hepevt_.idhep[index]!=particle->getPdgID())
00337 Log::Fatal("PH_HEPEVT_Interface::get(): Something is wrong with the PH_HEPEVT common block",5);
00338
00339
00340 if(isPhotonCreated && Photos::isCreateHistoryEntries)
00341 {
00342 particle->createHistoryEntry();
00343 }
00344
00345
00346 bool update=false;
00347
00348
00349 double threshold = NO_BOOST_THRESHOLD*ph_hepevt_.phep[index][3];
00350 if( fabs(ph_hepevt_.phep[index][0]-particle->getPx()) > threshold ||
00351 fabs(ph_hepevt_.phep[index][1]-particle->getPy()) > threshold ||
00352 fabs(ph_hepevt_.phep[index][2]-particle->getPz()) > threshold ||
00353 fabs(ph_hepevt_.phep[index][3]-particle->getE()) > threshold ) update=true;
00354
00355 if(update)
00356 {
00357
00358
00359
00360
00361
00362 particle->boostDaughtersToRestFrame(particle);
00363
00364
00365 particle->setPx(ph_hepevt_.phep[index][0]);
00366 particle->setPy(ph_hepevt_.phep[index][1]);
00367 particle->setPz(ph_hepevt_.phep[index][2]);
00368 particle->setE(ph_hepevt_.phep[index][3]);
00369
00370
00371 particle->boostDaughtersFromRestFrame(particle);
00372
00373 if(special && particle->getDaughters().size()>0){
00374
00375
00376
00377 PhotosParticle *particled = particle->getDaughters().at(0);
00378
00379
00380 particled->boostDaughtersToRestFrame(particled);
00381
00382
00383
00384
00385 particled->setPx( particle->getPx() );
00386 particled->setPy( particle->getPy() );
00387 particled->setPz( particle->getPz() );
00388 particled->setE ( particle->getE() );
00389
00390
00391
00392
00393 particled->boostToRestFrame(p1);
00394 particled->boostFromRestFrame(p2);
00395
00396
00397 particled->boostDaughtersFromRestFrame(particled);
00398 }
00399
00400 }
00401 }
00402
00403
00404 if(p1) delete p1;
00405 if(p2) delete p2;
00406 }
00407
00408 void PH_HEPEVT_Interface::prepare()
00409 {
00410 check_ME_channel();
00411 }
00412
00413 void PH_HEPEVT_Interface::complete()
00414 {
00415
00416 }
00417
00418 void PH_HEPEVT_Interface::check_ME_channel()
00419 {
00420 ME_channel=0;
00421
00422
00423
00424 if(decay_idx==2) return;
00425 if(ph_hepevt_.idhep[0]*ph_hepevt_.idhep[1]>0) return;
00426
00427 Log::Debug(900)<<"ME_channel: Mothers PDG: "<<ph_hepevt_.idhep[0]<<" "<<ph_hepevt_.idhep[1]<<endl;
00428 if(decay_idx)
00429 Log::Debug(900,false)<<" Intermediate: "<<ph_hepevt_.idhep[decay_idx-1]<<endl;
00430
00431 int firstDaughter=3;
00432 if(decay_idx==0) firstDaughter=2;
00433
00434
00435 int mother1 = abs(ph_hepevt_.idhep[0]);
00436 int mother2 = abs(ph_hepevt_.idhep[1]);
00437 if( mother1<1 || (mother1>6 && mother1<11) || mother1>16 ) return;
00438 if( mother2<1 || (mother2>6 && mother2<11) || mother2>16 ) return;
00439
00440
00441
00442
00443
00444 int firstPDG =0;
00445 int secondPDG=0;
00446 for(int i=firstDaughter; i<ph_hepevt_.nhep;i++)
00447 {
00448 int pdg = abs(ph_hepevt_.idhep[i]);
00449 if(pdg==11 || pdg==13 || pdg==15)
00450 {
00451 if(firstPDG==0) firstPDG=ph_hepevt_.idhep[i];
00452 else
00453 {
00454 secondPDG=ph_hepevt_.idhep[i];
00455
00456 if(firstPDG*secondPDG>0) secondPDG=0;
00457 break;
00458 }
00459 }
00460 }
00461
00462 if( ME_channel==0 && firstPDG!=0 && secondPDG!=0 &&
00463 firstPDG==-secondPDG ) ME_channel=1;
00464
00465
00466
00467 firstPDG =0;
00468 secondPDG=0;
00469 for(int i=firstDaughter; i<ph_hepevt_.nhep;i++)
00470 {
00471 int pdg = abs(ph_hepevt_.idhep[i]);
00472 if(pdg>=11 && pdg<=16)
00473 {
00474 if(firstPDG==0) firstPDG=ph_hepevt_.idhep[i];
00475 else
00476 {
00477 secondPDG=ph_hepevt_.idhep[i];
00478
00479 if(firstPDG*secondPDG>0) secondPDG=0;
00480 break;
00481 }
00482 }
00483 }
00484
00485 firstPDG =abs(firstPDG);
00486 secondPDG=abs(secondPDG);
00487
00488 if( ME_channel==0 && firstPDG!=0 && secondPDG!=0 &&
00489 ( ( firstPDG==11 && secondPDG==12 ) || (firstPDG == 12 && secondPDG == 11) ||
00490 ( firstPDG==13 && secondPDG==14 ) || (firstPDG == 14 && secondPDG == 13) ||
00491 ( firstPDG==15 && secondPDG==16 ) || (firstPDG == 16 && secondPDG == 15)
00492 )
00493 ) ME_channel=2;
00494
00495 Log::Debug(901)<<"ME_channel: Found ME_channel: "<<ME_channel<<endl;
00496
00497
00498
00499
00500 if(ME_channel>0 && decay_idx)
00501 {
00502 int pdg=ph_hepevt_.idhep[decay_idx-1];
00503
00504 if(ME_channel==1 && !(pdg==22 || pdg==23) ) ME_channel=0;
00505 if(ME_channel==2 && !(pdg==24 || pdg==-24)) ME_channel=0;
00506
00507 if(ME_channel==0)
00508 Log::Debug(901,false)<<" but set to 0: wrong intermediate particle: "<<pdg<<endl;
00509 }
00510
00511
00512
00513 switch(ME_channel)
00514 {
00515 case 0: break;
00516 case 1: if(!Photos::meCorrectionWtForZ) ME_channel=0; break;
00517 case 2: if(!Photos::meCorrectionWtForW) ME_channel=0; break;
00518 default: Log::Error()<<"Unimplemented ME channel: "<<ME_channel<<endl; break;
00519 }
00520 Log::Debug(902)<<"ME_channel: Finally, after flag check, ME_channel is: "<<ME_channel<<endl;
00521 }
00522
00523
00524 extern "C" void me_channel_(int *x)
00525 {
00526 *x=PH_HEPEVT_Interface::ME_channel;
00527 }
00528
00529
00530 extern "C" void me_scalar_(int *x)
00531 {
00532 *x=(int) Photos::meCorrectionWtForScalar;
00533 }
00534
00535 }