Fork me on GitHub

Changeset 264 in svn for trunk/Delphes.cpp


Ignore:
Timestamp:
Feb 11, 2009, 10:22:30 AM (16 years ago)
Author:
Xavier Rouby
Message:

first test 2.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Delphes.cpp

    r260 r264  
    3131
    3232/// \file Delphes.cpp
    33 /// \brief executable for the Delphes
     33/// \brief Executable for Delphes
    3434
    3535#include "TChain.h"
     
    4141#include "ExRootTreeWriter.h"
    4242#include "ExRootTreeBranch.h"
     43#include "ExRootProgressBar.h"
    4344
    4445#include "DataConverter.h"
     
    4849
    4950#include "SmearUtil.h"
     51#include "CaloUtil.h"
    5052#include "BFieldProp.h"
    5153#include "TriggerUtil.h"
     
    5658#include <vector>
    5759#include <iostream>
    58 
    59 #include "Utilities/ExRootAnalysis/interface/ExRootProgressBar.h"
    6060
    6161using namespace std;
     
    7777int main(int argc, char *argv[])
    7878{
     79unsigned int nnnn=0, mmmm=0;
     80
    7981  int appargc = 2;
    8082  char *appName= new char[20];
     
    8688  delete [] appName;
    8789  delete [] appOpt;
    88 
    8990
    9091  if(argc != 3 && argc != 4 && argc != 5) {
     
    242243  //Propagation of tracks in the B field
    243244  TrackPropagation *TRACP = new TrackPropagation(DET);
    244   //TrackPropagation *TRACP = new TrackPropagation(DetDatacard);
    245245 
    246246  //Jet information
    247247  JetsUtil *JETRUN = new JetsUtil(DET);
    248   //JetsUtil *JETRUN = new JetsUtil(DetDatacard);
    249248 
    250249  //VFD information
    251250  VeryForward * VFD = new VeryForward(DET);
    252   //VeryForward * VFD = new VeryForward(DetDatacard);
    253251 
    254252  // data converters
     
    299297  ExRootTreeBranch *branchMuon = treeWriter->NewBranch("Muon", TRootMuon::Class());
    300298  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());
    302301  ExRootTreeBranch *branchETmis = treeWriter->NewBranch("ETmis", TRootETmis::Class());
    303302  ExRootTreeBranch *branchCalo = treeWriter->NewBranch("CaloTower", TRootCalo::Class());
     
    306305  ExRootTreeBranch *branchFP420 = treeWriter->NewBranch("FP420hits", TRootRomanPotHits::Class());
    307306 
    308   TRootGenParticle *particle;
    309307  TRootETmis *elementEtmis;
    310308  TRootElectron *elementElec;
    311309  TRootMuon *elementMu;
    312310  TRootPhoton *elementPhoton;
    313   TRootTracks *elementTracks;
     311  D_Track * elementTrack;
    314312  TRootCalo *elementCalo;
    315313 
     
    323321  vector<TLorentzVector> TrackCentral; 
    324322  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;
    328329
    329330  TSimpleArray<TRootGenParticle> NFCentralQ;
    330   float iPhi=0,iEta=0;
    331 
     331
     332D_CaloList list_of_calorimeters;
     333D_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);
     337D_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  );
     341D_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);
     346list_of_calorimeters.addElement(CentralCalo);
     347list_of_calorimeters.addElement(ForwardCalo);
     348list_of_calorimeters.addElement(BackwardCalo);
     349//list_of_calorimeters.addElement(CastorCalo);
     350list_of_calorimeters.sortElements();
    332351
    333352
     
    360379      towers.clear();
    361380      input_particles.clear();
    362      
     381
     382
     383/*
     384if(0) { // OLD SMEARING ALGORITHM without energy flow
    363385      // 2.1 Loop over all particles in event
    364386      itGen.Reset();
    365387      while( (particle = (TRootGenParticle*) itGen.Next()) ) {
    366388          int pid = abs(particle->PID);
     389          float iPhi=0,iEta=0;
    367390
    368391       
     
    381404          // the ordering of conditions have been optimised for speed : put first the STATUS condition
    382405          if( (particle->Status == 1)    &&
    383               ((pid != pNU1) && (pid != pNU2) && (pid != pNU3)) &&
     406              (pid != pNU1) && (pid != pNU2) && (pid != pNU3) &&
    384407              (fabs(particle->Eta) < DET->CEN_max_calo_fwd)
    385408              )
     
    431454              if(genMomentumBfield.E() !=0 && pid != pMU) {
    432455                // 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
    434457                else { // particles reach calos
    435458                  // applies the calo segmentation and returns iEta & iPhi
    436459                  DET->BinEtaPhi(genMomentumBfield.Phi(), genMomentumBfield.Eta(), iPhi, iEta);
    437                   if(iEta != -100 && iPhi != -100) {
     460                  if(iEta != UNDEFINED && iPhi != UNDEFINED) {
    438461                      momentumCaloSegmentation.SetPtEtaPhiE(genMomentumBfield.Pt(),iEta,iPhi,genMomentumBfield.E());
    439462                      elementCalo = (TRootCalo*) branchCalo->NewEntry();
     
    441464                      PhysicsTower Tower(LorentzVector(momentumCaloSegmentation.Px(),momentumCaloSegmentation.Py(),momentumCaloSegmentation.Pz(),momentumCaloSegmentation.E()));
    442465                      towers.push_back(Tower);
    443                   } // if iEta != -100
     466                  } // if iEta != UNDEFINED
    444467                } // else : when particles reach the calos
    445468              } // 2.1.2.3 calotowers
    446              
     469
    447470
    448471              // 2.1.2.4 ********************* central detector: tracks
     
    451474                 (genMomentumBfield.E()!=0) &&
    452475                 (fabs(genMomentumBfield.Eta()) < DET->CEN_max_tracker) &&
    453                  (DET->FLAG_bfield || ( !DET->FLAG_bfield && genMomentumBfield.Pt() > DET->TRACK_ptmin )) &&     
     476                 (DET->FLAG_bfield || ( !DET->FLAG_bfield && genMomentum.Pt() > DET->TRACK_ptmin )) &&     
    454477                        // if bfield not simulated, pt should be high enough to be taken into account
    455478                 ((rand()%100) < DET->TRACK_eff)  &&
     
    475498             VFD->RomanPots(treeWriter,branchRP220,branchFP420,particle);
    476499          }
    477          
    478        } // 2.1 while : loop on all particles of the event.
    479      
     500} // IF OLD ALGORITHM (= no energy flow )
     501
     502
     503
     504
     505else // 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
    480692
    481693
    482694      // 2.2 ********** Output preparation & complex objects  ***********
    483  
    484695      // 2.2.1 ********************* sorting collections by decreasing pt
    485696      DET->SortedVector(electron);
     
    487698        elementElec = (TRootElectron*) branchElectron->NewEntry();
    488699        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();
    489702        elementElec->Charge = sign(electron[i].PID());
    490703        elementElec->IsolFlag = DET->Isolation(electron[i].Phi(),electron[i].Eta(),TrackCentral,2.0);//isolation based on tracks
     
    495708        elementMu->Charge = sign(muon[i].PID());
    496709        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();
    497712        elementMu->IsolFlag = DET->Isolation(muon[i].Phi(),muon[i].Eta(),TrackCentral,2.0);
    498713      }
     
    501716        elementPhoton = (TRootPhoton*) branchPhoton->NewEntry();
    502717        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();
    503720      }
    504721     
     
    522739      elementEtmis->Py = (-PTmis).Py();
    523740     
    524       // 2.2.3 ************* B-tag, tau jets
     741      // 2.2.3 ************* jets, B-tag, tau jets
    525742      sorted_jets=JETRUN->RunJets(input_particles);
    526743      JETRUN->RunJetBtagging(treeWriter, branchJet,sorted_jets,NFCentralQ);
     
    529746      treeWriter->Fill();
    530747    } // 2. Loop over all events ('for' loop)
    531  
     748
     749
    532750  cout <<"**                                                                 **"<< endl;
    533751  cout <<"**                 Exiting detector simulation...                  **"<< endl;
     
    649867  delete treeReader;
    650868  delete DET;
    651 //  delete TRIGT;
     869  delete TRIGT;
    652870  delete TRACP;
    653871  delete JETRUN;
Note: See TracChangeset for help on using the changeset viewer.