Fork me on GitHub

Changeset a1b19ea in git for modules


Ignore:
Timestamp:
Jan 11, 2019, 4:39:56 PM (6 years ago)
Author:
Michele Selvaggi <michele.selvaggi@…>
Branches:
ImprovedOutputFile, Timing, dual_readout, master
Children:
e39abb4
Parents:
ef8a06d
Message:

first attempt at energy flow with Dual Readout

Location:
modules
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • modules/DualReadoutCalorimeter.cc

    ref8a06d ra1b19ea  
    2020/** \class DualReadoutCalorimeter
    2121 *
    22  *  Fills DualReadoutCalorimeter towers, performs DualReadoutCalorimeter resolution smearing,
    23  *  and creates energy flow objects (tracks, photons, and neutral hadrons).
     22
     23  // ============  TODO  =========================================================
     24  // This implementation of dual calorimetry relies on several approximations:
     25  // - If hadronic energy is found in the tower the energy resolution then the full tower enrgy is smeared according to hadronic resolution (pessimistic for (e,n) or (pi+,gamma))
     26  // - While e+ vs pi+ (or gamma vs n) separation is in principle possible for single particles (using C/S, PMT timing, lateral shower profile) it is not obvious it can be done overlapping particles.
     27  //   Now we assume that regarless of the number of particle hits per tower we can always distinguish e+ vs pi+, which is probably not true in the case (e+,n) vs (pi+,gamma) without longitudinal segmentation.
     28
    2429 *
    25  *  \author P. Demin - UCL, Louvain-la-Neuve
     30 *  \author M. Selvaggi - CERN
    2631 *
    2732 */
     
    6772  fHCalTowerTrackArray = new TObjArray;
    6873  fItHCalTowerTrackArray = fHCalTowerTrackArray->MakeIterator();
     74
     75  fTowerTrackArray = new TObjArray;
     76  fItTowerTrackArray = fTowerTrackArray->MakeIterator();
    6977 
    7078}
     
    8391  if(fHCalTowerTrackArray) delete fHCalTowerTrackArray;
    8492  if(fItHCalTowerTrackArray) delete fItHCalTowerTrackArray;
     93
     94  if(fTowerTrackArray) delete fTowerTrackArray;
     95  if(fItTowerTrackArray) delete fItTowerTrackArray;
    8596 
    8697}
     
    212223  Double_t ecalFraction, hcalFraction;
    213224  Double_t ecalEnergy, hcalEnergy;
    214   Double_t ecalSigma, hcalSigma;
    215   Double_t energyGuess;
     225  Double_t ecalSigma, hcalSigma, sigma;
     226  Double_t energyGuess, energy;
    216227  Int_t pdgCode;
    217228
     
    365376      fECalTrackEnergy = 0.0;
    366377      fHCalTrackEnergy = 0.0;
     378      fTrackEnergy = 0.0;
    367379     
    368380      fECalTrackSigma = 0.0;
    369381      fHCalTrackSigma = 0.0;
     382      fTrackSigma = 0.0;
    370383     
    371384      fTowerTrackHits = 0;
     
    374387      fECalTowerTrackArray->Clear();
    375388      fHCalTowerTrackArray->Clear();
     389      fTowerTrackArray->Clear();
    376390   
    377391    }
     
    388402      ecalEnergy = momentum.E() * fECalTrackFractions[number];
    389403      hcalEnergy = momentum.E() * fHCalTrackFractions[number];
     404      energy = ecalEnergy + hcalEnergy;
    390405
    391406      if(ecalEnergy > fTimingEnergyMin && fTower)
     
    397412      }
    398413
     414     
     415      /*
    399416      if(fECalTrackFractions[number] > 1.0E-9 && fHCalTrackFractions[number] < 1.0E-9)
    400417      {
     
    419436      }
    420437     
     438      // muons
    421439      else if(fECalTrackFractions[number] < 1.0E-9 && fHCalTrackFractions[number] < 1.0E-9)
    422440      {
    423441        fEFlowTrackOutputArray->Add(track);
    424442      }
     443      */
     444     
     445      // in Dual Readout we do not care if tracks are ECAL of HCAL
     446      if(fECalTrackFractions[number] > 1.0E-9 || fHCalTrackFractions[number] > 1.0E-9)
     447      {
     448        fTrackEnergy += energy;
     449        // this sigma will be used to determine whether neutral excess is significant. We choose the resolution according to bthe higest deposited fraction (in practice had for charged hadrons and em for electrons)     
     450        sigma = 0.0;
     451        if(fHCalTrackFractions[number] > 0)
     452          sigma = fHCalResolutionFormula->Eval(0.0, fTowerEta, 0.0, momentum.E());
     453        else
     454          sigma = fECalResolutionFormula->Eval(0.0, fTowerEta, 0.0, momentum.E());
     455         
     456        if(sigma/momentum.E() < track->TrackResolution)
     457          energyGuess = ecalEnergy + hcalEnergy;     
     458        else
     459          energyGuess = momentum.E();
     460             
     461        fTrackSigma += (track->TrackResolution)*energyGuess*(track->TrackResolution)*energyGuess;
     462        fTowerTrackArray->Add(track);
     463     
     464      }
     465      else
     466      {
     467        fEFlowTrackOutputArray->Add(track);
     468      }
    425469
    426470      continue;
     
    461505{
    462506
    463 
    464 
    465 
    466507  Candidate *track, *tower, *mother;
    467508  Double_t energy, pt, eta, phi;
    468509  Double_t ecalEnergy, hcalEnergy;
    469   Double_t ecalNeutralEnergy, hcalNeutralEnergy;
     510  Double_t ecalNeutralEnergy, hcalNeutralEnergy, neutralEnergy;
    470511 
    471512  Double_t ecalSigma, hcalSigma, sigma;
    472   Double_t ecalNeutralSigma, hcalNeutralSigma;
     513  Double_t ecalNeutralSigma, hcalNeutralSigma, neutralSigma;
    473514
    474515  Double_t weightTrack, weightCalo, bestEnergyEstimate, rescaleFactor;
     
    491532  // if no hadronic fraction at all, then use ECAL resolution
    492533
    493   //cout<<"fECalTowerEnergy: "<<fECalTowerEnergy<<", fHCalTowerEnergy: "<<fHCalTowerEnergy<<endl;
    494 
     534  //cout<<"fECalTowerEnergy: "<<fECalTowerEnergy<<", fHCalTowerEnergy: "<<fHCalTowerEnergy<<", Eta: "<<fTowerEta<<endl;
     535
     536  // if no hadronic energy, use ECAL resolution
    495537  if (fHCalTowerEnergy <= fHCalEnergyMin)
    496538  {
    497539    energy = fECalTowerEnergy;
    498540    sigma  = fECalResolutionFormula->Eval(0.0, fTowerEta, 0.0, energy);
    499     //cout<<"em: "<<energy<<","<<sigma<<endl;
     541    //cout<<"em energy"<<energy<<", sigma: "<<sigma<<endl;
    500542  }
    501543
     
    505547    energy = fECalTowerEnergy + fHCalTowerEnergy;
    506548    sigma  = fHCalResolutionFormula->Eval(0.0, fTowerEta, 0.0, energy);
    507     //cout<<"had: "<<energy<<","<<sigma<<endl;
     549    //cout<<"had energy: "<<energy<<", sigma: "<<sigma<<endl;
    508550  }
    509551
     
    525567  if(ecalEnergy < fECalEnergyMin || ecalEnergy < fECalEnergySignificanceMin*ecalSigma) ecalEnergy = 0.0;
    526568  if(hcalEnergy < fHCalEnergyMin || hcalEnergy < fHCalEnergySignificanceMin*hcalSigma) hcalEnergy = 0.0;
    527   //cout<<energy<<","<<ecalEnergy<<","<<hcalEnergy<<endl;
    528 
     569
     570  //cout<<"Measured energy: "<<energy<<endl;
    529571
    530572  if(fSmearTowerCenter)
     
    563605  }
    564606
    565 
    566607  fTower->Momentum.SetPtEtaPhiE(pt, eta, phi, energy);
    567608  fTower->Eem = ecalEnergy;
     
    579620      fPhotonOutputArray->Add(fTower);
    580621    }
    581 
    582622    fTowerOutputArray->Add(fTower);
    583623  }
    584  
     624
     625  // fill energy flow candidates
     626 
     627  fTrackSigma = TMath::Sqrt(fTrackSigma);
     628  neutralEnergy = max( (energy - fTrackEnergy) , 0.0);
     629  neutralSigma = neutralEnergy / TMath::Sqrt(fTrackSigma*fTrackSigma + sigma*sigma);
     630
     631  //cout<<"trackEnergy: "<<fTrackEnergy<<", trackSigma: "<<fTrackSigma<<", Ntracks: "<<fTowerTrackArray->GetEntries()<<endl;
     632
     633  //cout<<"neutralEnergy: "<<neutralEnergy<<", neutralSigma: "<<neutralSigma<<endl;
     634
     635   // For now, if neutral excess is significant, simply create neutral EflowPhoton tower and clone each track into eflowtrack !!! -> Creating only photons !! EFlowNeutralHadron collection will be empy!!! TO BE FIXED
     636  if(neutralEnergy > fEnergyMin && neutralSigma > fEnergySignificanceMin)
     637  {
     638   
     639    //cout<<"significant neutral excess found:"<<endl;
     640    // create new photon tower
     641    tower = static_cast<Candidate*>(fTower->Clone());
     642    pt =  neutralEnergy / TMath::CosH(eta);
     643    //cout<<"Creating tower with Pt, Eta, Phi, Energy: "<<pt<<","<<eta<<","<<phi<<","<<neutralEnergy<<endl;
     644    tower->Momentum.SetPtEtaPhiE(pt, eta, phi, neutralEnergy);
     645    tower->Eem = neutralEnergy;
     646    tower->Ehad = 0.0;
     647    tower->PID = 22;
     648
     649    fEFlowPhotonOutputArray->Add(tower);
     650
     651
     652    //clone tracks
     653    fItTowerTrackArray->Reset();
     654    while((track = static_cast<Candidate*>(fItTowerTrackArray->Next())))
     655    {
     656      //cout<<"looping over tracks"<<endl;
     657      mother = track;
     658      track = static_cast<Candidate*>(track->Clone());
     659      track->AddCandidate(mother);
     660      fEFlowTrackOutputArray->Add(track);
     661    }
     662  }
     663
     664 
     665  // if neutral excess is not significant, rescale eflow tracks, such that the total charged equals the best measurement given by the DualReadoutCalorimeter and tracking
     666  else if(fTrackEnergy > 0.0)
     667  {
     668    //cout<<"no significant neutral excess found:"<<endl;
     669    weightTrack = (fTrackSigma > 0.0) ? 1 / (fTrackSigma*fTrackSigma) : 0.0;
     670    weightCalo  = (sigma > 0.0) ? 1 / (sigma*sigma) : 0.0;
     671
     672    bestEnergyEstimate = (weightTrack*fTrackEnergy + weightCalo*energy) / (weightTrack + weightCalo);
     673    rescaleFactor = bestEnergyEstimate/fTrackEnergy;
     674
     675    //rescale tracks
     676    fItTowerTrackArray->Reset();
     677    while((track = static_cast<Candidate*>(fItTowerTrackArray->Next())))
     678    { 
     679      mother = track;
     680      track = static_cast<Candidate*>(track->Clone());
     681      track->AddCandidate(mother);
     682
     683      track->Momentum *= rescaleFactor;
     684
     685      fEFlowTrackOutputArray->Add(track);
     686    }
     687  }
     688 
     689
     690  /*
    585691  // fill energy flow candidates
    586692  fECalTrackSigma = TMath::Sqrt(fECalTrackSigma);
     
    693799    }
    694800  }
    695  
    696  
     801
     802  */
    697803}
    698804
  • modules/DualReadoutCalorimeter.h

    ref8a06d ra1b19ea  
    2525 *  and creates energy flow objects (tracks, photons, and neutral hadrons).
    2626 *
    27  *  \author P. Demin - UCL, Louvain-la-Neuve
     27 *  \author M. Selvaggi - CERN
    2828 *
    2929 */
     
    5959  Double_t fECalTowerEnergy, fHCalTowerEnergy;
    6060  Double_t fECalTrackEnergy, fHCalTrackEnergy;
     61  Double_t fTrackEnergy;
    6162
    6263  Double_t fTimingEnergyMin;
     
    7576  Double_t fECalTrackSigma;
    7677  Double_t fHCalTrackSigma;
     78  Double_t fTrackSigma;
    7779
    7880  Bool_t fSmearTowerCenter;
     
    114116  TIterator *fItHCalTowerTrackArray; //!
    115117
     118  TObjArray *fTowerTrackArray; //!
     119  TIterator *fItTowerTrackArray; //!
     120
    116121  void FinalizeTower();
    117122  Double_t LogNormal(Double_t mean, Double_t sigma);
Note: See TracChangeset for help on using the changeset viewer.