Changeset 264 in svn for trunk/Delphes.cpp
- Timestamp:
- Feb 11, 2009, 10:22:30 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Delphes.cpp
r260 r264 31 31 32 32 /// \file Delphes.cpp 33 /// \brief executable for theDelphes33 /// \brief Executable for Delphes 34 34 35 35 #include "TChain.h" … … 41 41 #include "ExRootTreeWriter.h" 42 42 #include "ExRootTreeBranch.h" 43 #include "ExRootProgressBar.h" 43 44 44 45 #include "DataConverter.h" … … 48 49 49 50 #include "SmearUtil.h" 51 #include "CaloUtil.h" 50 52 #include "BFieldProp.h" 51 53 #include "TriggerUtil.h" … … 56 58 #include <vector> 57 59 #include <iostream> 58 59 #include "Utilities/ExRootAnalysis/interface/ExRootProgressBar.h"60 60 61 61 using namespace std; … … 77 77 int main(int argc, char *argv[]) 78 78 { 79 unsigned int nnnn=0, mmmm=0; 80 79 81 int appargc = 2; 80 82 char *appName= new char[20]; … … 86 88 delete [] appName; 87 89 delete [] appOpt; 88 89 90 90 91 if(argc != 3 && argc != 4 && argc != 5) { … … 242 243 //Propagation of tracks in the B field 243 244 TrackPropagation *TRACP = new TrackPropagation(DET); 244 //TrackPropagation *TRACP = new TrackPropagation(DetDatacard);245 245 246 246 //Jet information 247 247 JetsUtil *JETRUN = new JetsUtil(DET); 248 //JetsUtil *JETRUN = new JetsUtil(DetDatacard);249 248 250 249 //VFD information 251 250 VeryForward * VFD = new VeryForward(DET); 252 //VeryForward * VFD = new VeryForward(DetDatacard);253 251 254 252 // data converters … … 299 297 ExRootTreeBranch *branchMuon = treeWriter->NewBranch("Muon", TRootMuon::Class()); 300 298 ExRootTreeBranch *branchPhoton = treeWriter->NewBranch("Photon", TRootPhoton::Class()); 301 ExRootTreeBranch *branchTracks = treeWriter->NewBranch("Tracks", TRootTracks::Class()); 299 //ExRootTreeBranch *branchTracks = treeWriter->NewBranch("Tracks", TRootTracks::Class()); 300 ExRootTreeBranch *branchTrack = treeWriter->NewBranch("Tracks", D_Track::Class()); 302 301 ExRootTreeBranch *branchETmis = treeWriter->NewBranch("ETmis", TRootETmis::Class()); 303 302 ExRootTreeBranch *branchCalo = treeWriter->NewBranch("CaloTower", TRootCalo::Class()); … … 306 305 ExRootTreeBranch *branchFP420 = treeWriter->NewBranch("FP420hits", TRootRomanPotHits::Class()); 307 306 308 TRootGenParticle *particle;309 307 TRootETmis *elementEtmis; 310 308 TRootElectron *elementElec; 311 309 TRootMuon *elementMu; 312 310 TRootPhoton *elementPhoton; 313 TRootTracks *elementTracks;311 D_Track * elementTrack; 314 312 TRootCalo *elementCalo; 315 313 … … 323 321 vector<TLorentzVector> TrackCentral; 324 322 vector<PhysicsTower> towers; 325 vector<ParticleUtil> electron; 326 vector<ParticleUtil> muon; 327 vector<ParticleUtil> gamma; 323 //vector<ParticleUtil> electron; 324 vector<D_Particle> electron; 325 //vector<ParticleUtil> muon; 326 vector<D_Particle> muon; 327 //vector<ParticleUtil> gamma; 328 vector<D_Particle> gamma; 328 329 329 330 TSimpleArray<TRootGenParticle> NFCentralQ; 330 float iPhi=0,iEta=0; 331 331 332 D_CaloList list_of_calorimeters; 333 D_CaloElement CentralCalo("centralcalo", 334 -DET->CEN_max_calo_cen, DET->CEN_max_calo_cen, 335 DET->ELG_Ccen, DET->ELG_Ncen, DET->ELG_Scen, 336 DET->HAD_Chcal, DET->HAD_Nhcal, DET->HAD_Shcal); 337 D_CaloElement ForwardCalo("forwardcalo", 338 DET->CEN_max_calo_cen, DET->CEN_max_calo_fwd, 339 DET->ELG_Cfwd, DET->ELG_Nfwd, DET->ELG_Sfwd, 340 DET->HAD_Chf, DET->HAD_Nhf, DET->HAD_Shf ); 341 D_CaloElement BackwardCalo("backwardcalo", 342 -DET->CEN_max_calo_fwd, -DET->CEN_max_calo_cen, 343 DET->ELG_Cfwd, DET->ELG_Nfwd, DET->ELG_Sfwd, 344 DET->HAD_Chf, DET->HAD_Nhf, DET->HAD_Shf ); 345 //D_CaloElement CastorCalo("castor",5.5,6.6,1,0,0,1,0,0); 346 list_of_calorimeters.addElement(CentralCalo); 347 list_of_calorimeters.addElement(ForwardCalo); 348 list_of_calorimeters.addElement(BackwardCalo); 349 //list_of_calorimeters.addElement(CastorCalo); 350 list_of_calorimeters.sortElements(); 332 351 333 352 … … 360 379 towers.clear(); 361 380 input_particles.clear(); 362 381 382 383 /* 384 if(0) { // OLD SMEARING ALGORITHM without energy flow 363 385 // 2.1 Loop over all particles in event 364 386 itGen.Reset(); 365 387 while( (particle = (TRootGenParticle*) itGen.Next()) ) { 366 388 int pid = abs(particle->PID); 389 float iPhi=0,iEta=0; 367 390 368 391 … … 381 404 // the ordering of conditions have been optimised for speed : put first the STATUS condition 382 405 if( (particle->Status == 1) && 383 ( (pid != pNU1) && (pid != pNU2) && (pid != pNU3)) &&406 (pid != pNU1) && (pid != pNU2) && (pid != pNU3) && 384 407 (fabs(particle->Eta) < DET->CEN_max_calo_fwd) 385 408 ) … … 431 454 if(genMomentumBfield.E() !=0 && pid != pMU) { 432 455 // in case the Bfield is not simulated, checks that charged particles have enough pt to reach the calos 433 if ( !DET->FLAG_bfield && charge!=0 && genMomentumBfield.Pt() <= DET->TRACK_ptmin ) { /* particules do not reach calos */ }456 if ( !DET->FLAG_bfield && charge!=0 && genMomentumBfield.Pt() <= DET->TRACK_ptmin ) {}// particules do not reach calos 434 457 else { // particles reach calos 435 458 // applies the calo segmentation and returns iEta & iPhi 436 459 DET->BinEtaPhi(genMomentumBfield.Phi(), genMomentumBfield.Eta(), iPhi, iEta); 437 if(iEta != -100 && iPhi != -100) {460 if(iEta != UNDEFINED && iPhi != UNDEFINED) { 438 461 momentumCaloSegmentation.SetPtEtaPhiE(genMomentumBfield.Pt(),iEta,iPhi,genMomentumBfield.E()); 439 462 elementCalo = (TRootCalo*) branchCalo->NewEntry(); … … 441 464 PhysicsTower Tower(LorentzVector(momentumCaloSegmentation.Px(),momentumCaloSegmentation.Py(),momentumCaloSegmentation.Pz(),momentumCaloSegmentation.E())); 442 465 towers.push_back(Tower); 443 } // if iEta != -100466 } // if iEta != UNDEFINED 444 467 } // else : when particles reach the calos 445 468 } // 2.1.2.3 calotowers 446 469 447 470 448 471 // 2.1.2.4 ********************* central detector: tracks … … 451 474 (genMomentumBfield.E()!=0) && 452 475 (fabs(genMomentumBfield.Eta()) < DET->CEN_max_tracker) && 453 (DET->FLAG_bfield || ( !DET->FLAG_bfield && genMomentum Bfield.Pt() > DET->TRACK_ptmin )) &&476 (DET->FLAG_bfield || ( !DET->FLAG_bfield && genMomentum.Pt() > DET->TRACK_ptmin )) && 454 477 // if bfield not simulated, pt should be high enough to be taken into account 455 478 ((rand()%100) < DET->TRACK_eff) && … … 475 498 VFD->RomanPots(treeWriter,branchRP220,branchFP420,particle); 476 499 } 477 478 } // 2.1 while : loop on all particles of the event. 479 500 } // IF OLD ALGORITHM (= no energy flow ) 501 502 503 504 505 else // IF NEW ALGORITHM with energy flow 506 */ 507 { 508 D_CaloTowerList list_of_active_towers; 509 D_CaloTowerList list_of_towers_with_photon; // to speed up the code: will only look in interesting towers for gamma candidates 510 511 // 2.1a Loop over all particles in event, to fill the towers 512 itGen.Reset(); 513 TRootGenParticle *particle; 514 while( (particle = (TRootGenParticle*) itGen.Next()) ) { 515 int pid = abs(particle->PID); 516 particle->Charge=Charge(pid); 517 particle->setFractions(); // init 518 519 520 // 2.1a.1********************* preparation for the b-tagging 521 //// This subarray is needed for the B-jet algorithm 522 // optimization for speed : put first PID condition, then ETA condition, then either pt or status 523 if( (pid <= pB || pid == pGLUON) &&// is it a light quark or a gluon, i.e. is it one of these : u,d,c,s,b,g ? 524 fabs(particle->Eta) < DET->CEN_max_tracker && 525 particle->Status != 1 && 526 particle->PT > DET->PT_QUARKS_MIN ) { 527 NFCentralQ.Add(particle); 528 } 529 530 // 2.1a.2********************* visible particles only 531 if( (particle->Status == 1) && (pid != pNU1) && (pid != pNU2) && (pid != pNU3) ){ 532 533 // 2.1a.2.1 Central solenoidal magnetic field 534 TRACP->bfield(particle); // fills in particle->EtaCalo et particle->PhiCalo 535 particle->SetEtaPhi(particle->EtaCalo,particle->PhiCalo); // ???? check this line 536 537 // 2.1a.2.2 Filling the calorimetric towers -- includes also forward detectors ? 538 // first checks if the charged particles reach the calo! 539 if( DET->FLAG_bfield || 540 particle->getCharge()==0 || 541 (!DET->FLAG_bfield && particle->getCharge()!=0 && particle->PT > DET->TRACK_ptmin)) 542 if( 543 (particle->EtaCalo > list_of_calorimeters.getEtamin() ) && 544 (particle->EtaCalo < list_of_calorimeters.getEtamax() ) 545 ) { 546 float iEta=UNDEFINED, iPhi=UNDEFINED; 547 DET->BinEtaPhi(particle->PhiCalo,particle->EtaCalo,iPhi,iEta); // fills in iPhi and iEta 548 if (iEta != UNDEFINED && iPhi != UNDEFINED) 549 { 550 D_CaloTower tower(iEta,iPhi); // new tower 551 tower.Set_Eem_Ehad_E_ET(particle->E*particle->getFem() , particle->E*particle->getFhad() ); 552 553 list_of_active_towers.addTower(tower); 554 // this list may contain several times the same calotower, as several particles 555 // may leave some energy in the same calotower 556 // After the loop on particles, identical cells in the list should be merged 557 } // iEta and iPhi must be defined 558 } 559 560 // 2.1a.2.3 charged particles in tracker: energy flow 561 // if bfield not simulated, pt should be high enough to be taken into account 562 // it is supposed here that DET->MAX_calo > DET->CEN_max_tracker > DET->CEN_max_mu > 0 563 if( particle->getCharge() !=0 && 564 fabs(particle->EtaCalo)< DET->CEN_max_tracker && // stays in the tracker -> track available 565 ( DET->FLAG_bfield || 566 (!DET->FLAG_bfield && particle->PT > DET->TRACK_ptmin) 567 ) 568 ) { 569 // 2.1a.2.3.1 Filling the particle properties + smearing 570 // Hypothesis: the final eta/phi are the ones from the generator, thanks to the track reconstruction 571 // This is the EnergyFlow hypothesis 572 particle->SetEtaPhi(particle->Eta,particle->Phi); 573 float sET=UNDEFINED; // smeared ET, computed from the smeared E -> needed for the tracks 574 575 // 2.1a.2.3.2 Muons 576 if (pid == pMU && fabs(particle->EtaCalo)< DET->CEN_max_mu && particle->PT > DET->PTCUT_muon ) { 577 TLorentzVector p; 578 float sPT = gRandom->Gaus(particle->PT, DET->MU_SmearPt*particle->PT ); 579 if (sPT > 0 && sPT > DET->PTCUT_muon) { 580 p.SetPtEtaPhiE(sPT,particle->Eta,particle->Phi,sPT*cosh(particle->Eta)); 581 muon.push_back(D_Particle(p,pMU,particle->EtaCalo,particle->PhiCalo)); 582 } 583 sET = (sPT >0)? sPT : 0; 584 } 585 // 2.1a.2.3.3 Electrons 586 else if (pid == pE) { 587 // Finds in which calorimeter the particle has gone, to know its resolution 588 589 D_CaloElement currentCalo = list_of_calorimeters.getElement(particle->EtaCalo); 590 if(currentCalo.getName() == dummyCalo.getName()) { 591 cout << "** Warning: the calo coverage behind the tracker is not complete! **" << endl; } 592 593 // final smeared EM energy // electromagnetic fraction F_em =1 for electrons; 594 float sE = currentCalo.getElectromagneticResolution().Smear(particle->E); 595 if (sE>0) { 596 sET = sE/cosh(particle->Eta); 597 // NB: ET is found via the calorimetry and not via the track curvature 598 599 TLorentzVector p; 600 p.SetPtEtaPhiE(sET,particle->Eta,particle->Phi,sE); 601 if (sET > DET->PTCUT_elec) 602 electron.push_back(D_Particle(p,particle->PID,particle->EtaCalo,particle->PhiCalo)); 603 } else { sET=0;} // if negative smeared energy -- needed for the tracks 604 } 605 // 2.1a.2.3.4 Other charged particles : smear them for the tracks! 606 else { //other particles 607 D_CaloElement currentCalo = list_of_calorimeters.getElement(particle->EtaCalo); 608 float sEem = currentCalo.getElectromagneticResolution().Smear(particle->E * particle->getFem()); 609 float sEhad = currentCalo.getHadronicResolution().Smear(particle->E * particle->getFhad()); 610 float sE = ( (sEem>0)? sEem : 0 ) + ( (sEhad>0)? sEhad : 0 ); 611 sET = sE/cosh(particle->EtaCalo); 612 } 613 614 // 2.1a.2.3.5 Tracks 615 if( (rand()%100) < DET->TRACK_eff && sET!=0) { 616 elementTrack = (D_Track*) branchTrack->NewEntry(); 617 elementTrack->Set(particle->Eta, particle->Phi, particle->EtaCalo, particle->PhiCalo, sET); 618 TrackCentral.push_back(elementTrack->GetFourVector()); // tracks at vertex! 619 // TODO!!! associates the tracks to the calo where it points to 620 // TODO!!! apply a smearing on the position of the origin of the track 621 // TODO!!! elementTracks->SetPositionOut(Xout,Yout,Zout); 622 } 623 } // 2.1a.2.3 : if tracker/energy-flow 624 // 2.1a.2.4 Photons 625 // stays in the tracker -> track available -> gamma ID 626 else if( (pid == pGAMMA) && fabs(particle->EtaCalo)< DET->CEN_max_tracker ) { 627 float iEta=UNDEFINED, iPhi=UNDEFINED; 628 DET->BinEtaPhi(particle->PhiCalo,particle->EtaCalo,iPhi,iEta); // fills in iPhi and iEta 629 D_CaloTower tower(iEta,iPhi); 630 // stores the list of towers where to apply the photon ID algorithm. Just a trick for a faster search 631 list_of_towers_with_photon.addTower(tower); 632 } 633 // 2.1a.2.5 : very forward detectors 634 else if (DET->FLAG_vfd==1) { 635 // for the moment, only protons are transported 636 // BUT !!! could be a beam of other particles! (heavy ions?) 637 // BUT ALSO !!! if very forward muons, or others! 638 VFD->RomanPots(treeWriter,branchRP220,branchFP420,particle); 639 VFD->ZDC(treeWriter,branchZDC,particle); 640 } 641 // 2.1a.2.6: Zero degree calorimeter 642 //else if(DET->FLAG_zdc==1) { 643 //VFD->ZDC(treeWriter,branchZDC,particle); 644 //} 645 646 } // 2.1a.2 : if visible particle 647 } // loop on all particles 2.1a 648 649 650 // 2.1b loop on all (activated) towers 651 // at this stage, list_of_active_towers may contain several times the same tower 652 // first step is to merge identical towers, by matching their (iEta,iPhi) 653 list_of_active_towers.mergeDuplicates(); 654 // Calotower smearing 655 list_of_active_towers.smearTowers(list_of_calorimeters); 656 657 for(unsigned int i=0; i<list_of_active_towers.size(); i++) { 658 float iEta = list_of_active_towers[i].getEta(); 659 float iPhi = list_of_active_towers[i].getPhi(); 660 float e = list_of_active_towers[i].getE(); 661 if(iEta != UNDEFINED && iPhi != UNDEFINED && e!=0) { 662 elementCalo = (TRootCalo*) branchCalo->NewEntry(); 663 elementCalo->set(list_of_active_towers[i]); 664 // not beautiful : should be improved! 665 TLorentzVector p; 666 p.SetPtEtaPhiE(list_of_active_towers[i].getET(), iEta, iPhi, e ); 667 PhysicsTower Tower(LorentzVector(p.Px(),p.Py(),p.Pz(),p.E())); 668 towers.push_back(Tower); 669 } 670 } // loop on towers 671 672 // 2.1c photon ID 673 // list_of_towers_with_photon is the list of towers with photon candidates 674 // already smeared ! 675 // sorts the vector and smears duplicates 676 list_of_towers_with_photon.mergeDuplicates(); 677 678 for(unsigned int i=0; i<list_of_towers_with_photon.size(); i++) { 679 float eta = list_of_towers_with_photon[i].getEta(); 680 float phi = list_of_towers_with_photon[i].getPhi(); 681 D_CaloTower cal(list_of_active_towers.getElement(eta,phi)); 682 if(cal.getEta() != UNDEFINED && cal.getPhi() != UNDEFINED && cal.getE() > 0) { 683 TLorentzVector p; 684 p.SetPtEtaPhiE(cal.getET(), eta,phi,cal.getE() ); 685 if (cal.getET() > DET->PTCUT_gamma) { gamma.push_back(D_Particle(p,pGAMMA,p.Eta(),p.Phi())); } 686 } 687 } // for -- list of photons 688 689 } // IF NEW ALGORITHM with energy flow 690 691 480 692 481 693 482 694 // 2.2 ********** Output preparation & complex objects *********** 483 484 695 // 2.2.1 ********************* sorting collections by decreasing pt 485 696 DET->SortedVector(electron); … … 487 698 elementElec = (TRootElectron*) branchElectron->NewEntry(); 488 699 elementElec->Set(electron[i].Px(),electron[i].Py(),electron[i].Pz(),electron[i].E()); 700 elementElec->EtaCalo = electron[i].EtaCalo(); 701 elementElec->PhiCalo = electron[i].PhiCalo(); 489 702 elementElec->Charge = sign(electron[i].PID()); 490 703 elementElec->IsolFlag = DET->Isolation(electron[i].Phi(),electron[i].Eta(),TrackCentral,2.0);//isolation based on tracks … … 495 708 elementMu->Charge = sign(muon[i].PID()); 496 709 elementMu->Set(muon[i].Px(),muon[i].Py(),muon[i].Pz(),muon[i].E()); 710 elementMu->EtaCalo = muon[i].EtaCalo(); 711 elementMu->PhiCalo = muon[i].PhiCalo(); 497 712 elementMu->IsolFlag = DET->Isolation(muon[i].Phi(),muon[i].Eta(),TrackCentral,2.0); 498 713 } … … 501 716 elementPhoton = (TRootPhoton*) branchPhoton->NewEntry(); 502 717 elementPhoton->Set(gamma[i].Px(),gamma[i].Py(),gamma[i].Pz(),gamma[i].E()); 718 elementPhoton->EtaCalo = gamma[i].EtaCalo(); 719 elementPhoton->PhiCalo = gamma[i].PhiCalo(); 503 720 } 504 721 … … 522 739 elementEtmis->Py = (-PTmis).Py(); 523 740 524 // 2.2.3 ************* B-tag, tau jets741 // 2.2.3 ************* jets, B-tag, tau jets 525 742 sorted_jets=JETRUN->RunJets(input_particles); 526 743 JETRUN->RunJetBtagging(treeWriter, branchJet,sorted_jets,NFCentralQ); … … 529 746 treeWriter->Fill(); 530 747 } // 2. Loop over all events ('for' loop) 531 748 749 532 750 cout <<"** **"<< endl; 533 751 cout <<"** Exiting detector simulation... **"<< endl; … … 649 867 delete treeReader; 650 868 delete DET; 651 //delete TRIGT;869 delete TRIGT; 652 870 delete TRACP; 653 871 delete JETRUN;
Note:
See TracChangeset
for help on using the changeset viewer.