All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
photonCorrectionProcessor.cc
Go to the documentation of this file.
2 #include <iostream>
3 #include <marlin/Global.h>
4 #include "lcio.h"
5 
6 #include "IMPL/LCCollectionVec.h"
7 #include "IMPL/ReconstructedParticleImpl.h"
8 
9 #include "DD4hep/DD4hepUnits.h"
10 #include "DD4hep/DetType.h"
11 #include "DD4hep/DetectorSelector.h"
12 #include "DDRec/DetectorData.h"
13 
14 #ifdef MARLIN_USE_AIDA
15 #include <marlin/AIDAProcessor.h>
16 #include <AIDA/AIDA.h>
17 #endif
18 
19 
20 using namespace lcio ;
21 using namespace marlin ;
22 using std::cout;
23 using std::endl;
24 
26 
27 
28 photonCorrectionProcessor::photonCorrectionProcessor() : Processor("photonCorrectionProcessor") {
29  // processor description
30  _description = "photonCorrectionProcessor applies an energy correction to photon-like PFOs" ;
31 
32  registerProcessorParameter("inputCollection", "name of input PFO collection",
33  _inputCollection, std::string("PandoraPFOs") );
34 
35  registerProcessorParameter("modifyPFOenergies" , "apply the corrected energies to the PFOs", _modifyPFOenergies, true );
36  registerProcessorParameter("modifyPFOdirection", "apply the corrected direction to the PFOs", _modifyPFOdirections, true );
37 
38  std::vector <float> linearise;
39  linearise.push_back( 9.870e-01 );
40  linearise.push_back( 1.426e-02 );
41  registerProcessorParameter("energyCor_Linearise", "parameters to linearise overall energy response", _energyCorr_linearise, linearise );
42 
43  std::vector <float> eCorr_barPhi;
44  eCorr_barPhi.push_back(0.412249 );
45  eCorr_barPhi.push_back(0.0142289 );
46  eCorr_barPhi.push_back(-0.0933687 );
47  eCorr_barPhi.push_back( 0.01345 );
48  eCorr_barPhi.push_back(0.0408156 );
49  registerProcessorParameter("energyCorr_barrelPhi", "paramters to correct energy response vs. phi in barrel", _energyCorr_barrelPhi, eCorr_barPhi );
50 
51  std::vector <float> eCorr_costh;
52  eCorr_costh.push_back( -0.0900 );
53  eCorr_costh.push_back( 0. );
54  eCorr_costh.push_back( 0.235 );
55  eCorr_costh.push_back( 0.007256 );
56  eCorr_costh.push_back( -0.0369648 );
57  eCorr_costh.push_back( 0. );
58  eCorr_costh.push_back( 0.588 );
59  eCorr_costh.push_back( 0.0121604 );
60  eCorr_costh.push_back( -0.0422968 );
61  eCorr_costh.push_back( 0.774 );
62  eCorr_costh.push_back( 0.009 );
63  eCorr_costh.push_back( 1.002 );
64  registerProcessorParameter("energyCorr_costh", "paramters to correct energy response vs. cos(theta)", _energyCorr_costheta, eCorr_costh );
65 
66  std::vector <float> eCorr_endcap;
67  eCorr_endcap.push_back( -0.025 );
68  eCorr_endcap.push_back( 855. );
69  eCorr_endcap.push_back( 23. );
70  eCorr_endcap.push_back( -0.07 );
71  eCorr_endcap.push_back( 1489. );
72  eCorr_endcap.push_back( 18. );
73  registerProcessorParameter("energyCorr_endcap", "paramters to correct energy response vs. endcap cracks", _energyCorr_endcap, eCorr_endcap );
74 
75  std::vector <float> phiCorr_barrel;
76  phiCorr_barrel.push_back( 2.36517e-05 );
77  phiCorr_barrel.push_back( 1.32090e-04 );
78  phiCorr_barrel.push_back( -3.86883e+00 );
79  phiCorr_barrel.push_back( -1.67809e-01 );
80  phiCorr_barrel.push_back( 2.28614e-05 );
81  phiCorr_barrel.push_back( 6.03495e-05 );
82  phiCorr_barrel.push_back( 0.419 );
83  phiCorr_barrel.push_back( 0.00728 );
84  phiCorr_barrel.push_back( 0.025 );
85  phiCorr_barrel.push_back( 0.00 );
86  phiCorr_barrel.push_back( 2.86667e-05 );
87  phiCorr_barrel.push_back( 2.49371e-05 );
88  phiCorr_barrel.push_back( -7.71684e-06 );
89  phiCorr_barrel.push_back( -1.48118e-05 );
90  phiCorr_barrel.push_back( -5.63786e-06 );
91  phiCorr_barrel.push_back( -9.38376e-06 );
92  phiCorr_barrel.push_back( -4.96296e-06 );
93  phiCorr_barrel.push_back( 2.91262e-06 );
94  registerProcessorParameter("phiCorr_barrel", "paramters to correct phi bias in barrel", _phiCorr_barrel, phiCorr_barrel );
95 
96  std::vector <float> thetaCorr_barrel;
97  thetaCorr_barrel.push_back( -0.000166568);
98  thetaCorr_barrel.push_back( -7.119e-05 );
99  thetaCorr_barrel.push_back( 0.000223618 );
100  thetaCorr_barrel.push_back( -3.95915e-05);
101  registerProcessorParameter("thetaCorr_barrel", "paramters to correct theta bias in barrel", _thetaCorr_barrel, thetaCorr_barrel );
102 
103  std::vector <float> thetaCorr_endcap;
104  thetaCorr_endcap.push_back( 0.000129478 ) ;
105  thetaCorr_endcap.push_back( -3.73863e-05 );
106  thetaCorr_endcap.push_back( -0.000847783 );
107  thetaCorr_endcap.push_back( 0.000153646 ) ;
108  thetaCorr_endcap.push_back( 0.000806605 ) ;
109  thetaCorr_endcap.push_back( -0.000132608 );
110  registerProcessorParameter("thetaCorr_endcap", "paramters to correct theta bias in endcap", _thetaCorr_endcap, thetaCorr_endcap );
111 
112  registerProcessorParameter("validationPlots", "produce validation plots", _validationPlots, false );
113  registerProcessorParameter("nominalEnergy", "nominal photon energy (for validation plots)", _nominalEnergy, float(200) );
114 }
115 
116 
118  streamlog_out (MESSAGE) << "hello from photonCorrectionProcessor::init" << endl;
119 
120  printParameters();
121 
122  // first get some geometry information
123  dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance();
124  // endcap ecal
125  unsigned int includeFlag = ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ENDCAP | dd4hep::DetType::ELECTROMAGNETIC );
126  unsigned int excludeFlag = ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD );
127  const std::vector< dd4hep::DetElement>& endcapEcalDetectors = dd4hep::DetectorSelector(mainDetector).detectors( includeFlag, excludeFlag );
128  if ( endcapEcalDetectors.size() == 1 ) {
129  _assumed_boxsize = endcapEcalDetectors.at(0).extension<dd4hep::rec::LayeredCalorimeterData>()->extent[0]/dd4hep::mm; // r-min
130  _assumed_endZ = endcapEcalDetectors.at(0).extension<dd4hep::rec::LayeredCalorimeterData>()->extent[2]/dd4hep::mm; // z-min
131  } else {
132  streamlog_out (ERROR) << "did not find exactly one endcap ECAL! found " << endcapEcalDetectors.size() << "; refusing to continue!" << endl;
133  assert(0);
134  }
135 
136  // barrel ecal
137  includeFlag = ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::BARREL | dd4hep::DetType::ELECTROMAGNETIC );
138  excludeFlag = ( dd4hep::DetType::AUXILIARY | dd4hep::DetType::FORWARD );
139  const std::vector< dd4hep::DetElement>& barrelEcalDetectors = dd4hep::DetectorSelector(mainDetector).detectors( includeFlag, excludeFlag );
140  if ( barrelEcalDetectors.size() == 1 ) {
141  float barrelLength = barrelEcalDetectors.at(0).extension<dd4hep::rec::LayeredCalorimeterData>()->extent[3]/dd4hep::mm; // z-max
142  float barrelInRad = barrelEcalDetectors.at(0).extension<dd4hep::rec::LayeredCalorimeterData>()->extent[0]/dd4hep::mm; // r-min
143  _barrelendcap_limit_costh=barrelLength/sqrt( pow(barrelLength,2) + pow(barrelInRad,2) );
144  } else {
145  streamlog_out (ERROR) << "did not find exactly one barrel ECAL! found " << barrelEcalDetectors.size() << "; refusing to continue!" << endl;
146  assert(0);
147  }
148 
149  streamlog_out (MESSAGE) << "*** ECAL endcap dimensions: minZ, minR, barrel/endcap transition " <<
150  _assumed_endZ << " , " << _assumed_boxsize << " , " << _barrelendcap_limit_costh << endl;
151 
153 
157 
165 
166  return;
167 }
168 
169 void photonCorrectionProcessor::processRunHeader( LCRunHeader* /* run */ ) {
170  streamlog_out (MESSAGE) << "hello from photonCorrectionProcessor::processRunHeader" << endl;
171 }
172 
174  // adjust energy of all type==22 objects in the input collection
175 
176 
178  streamlog_out (DEBUG) << "not asked to modify any PFO properties: so doing nothing" << std::endl;
179  return;
180  }
181 
182  // for validation plots: sum the pfo energies before and after correction
183  float totPfoEn[2]={0};
184  float totPfoGammaEn[2]={0};
185  float totomom[3]={0};
186 
187  try {
188  LCCollectionVec* pfocol = dynamic_cast<LCCollectionVec*>(evt->getCollection( _inputCollection ) );
189  for (auto lcobj : (*pfocol) ) {
190  ReconstructedParticleImpl* pfo = dynamic_cast<ReconstructedParticleImpl*>(lcobj);
191 
192  if ( _validationPlots ) {
193  for (int j=0; j<3; j++) {
194  totomom[j]+=pfo->getMomentum()[j];
195  }
196  }
197 
198  if ( pfo->getType() == 22 ) {
199 
200  float origEn = pfo->getEnergy();
201  float origMom(0);
202  for (int i=0; i<3; i++) {
203  origMom+=pow(pfo->getMomentum()[i],2);
204  }
205  origMom=sqrt(origMom);
206  float origTheta = acos( pfo->getMomentum()[2]/origMom);
207  float origPhi = atan2( pfo->getMomentum()[1], pfo->getMomentum()[0] );
208 
209  float correctedEnergy = _photonCorrector->photonEnergyCorrection( pfo );
210 
211  float correctedMom = origMom*correctedEnergy/origEn; // just scale. in principle should be same as energy for massless photon PFO
212 
213  float correctedTheta, correctedPhi;
214  _photonCorrector->photonDirectionCorrection( pfo , correctedTheta, correctedPhi );
215 
216  // these are the properties we will set for the PFO
217  float newEnergy = _modifyPFOenergies ? correctedEnergy : origEn;
218  float newMom = _modifyPFOenergies ? correctedMom : origMom;
219  float newTheta = _modifyPFOdirections ? correctedTheta : origTheta;
220  float newPhi = _modifyPFOdirections ? correctedPhi : origPhi;
221 
222  float newMomentum[3];
223  newMomentum[0] = newMom*sin(newTheta)*cos(newPhi);
224  newMomentum[1] = newMom*sin(newTheta)*sin(newPhi);
225  newMomentum[2] = newMom*cos(newTheta);
226 
227  streamlog_out (DEBUG) << "updating energy/momentum from " <<
228  origEn << " / (" << pfo->getMomentum()[0] << " " << pfo->getMomentum()[1] << " " << pfo->getMomentum()[2] << ") to " <<
229  newEnergy << " / (" << newMomentum[0] << " " << newMomentum[1] << " " << newMomentum[2] << ")" << std::endl;
230 
231  pfo->setEnergy( newEnergy );
232  pfo->setMomentum( newMomentum );
233 
234  if ( _validationPlots ) {
235  totPfoEn [0]+=pfo->getEnergy();
236  totPfoGammaEn[0]+=pfo->getEnergy();
237  totPfoEn [1]+=correctedEnergy;
238  totPfoGammaEn[1]+=correctedEnergy;
239  }
240 
241  } else {
242  totPfoEn[0]+=pfo->getEnergy();
243  totPfoEn[1]+=pfo->getEnergy();
244  }
245  }
246  } catch(DataNotAvailableException &e) {};
247 
248 
249 #ifdef MARLIN_USE_AIDA
250 
251  if ( _validationPlots ) {
252  static AIDA::IHistogram2D* h_sumPfoE_orig ;
253  static AIDA::IHistogram2D* h_sumPfoE_corr ;
254  static AIDA::IHistogram2D* h_sumGamPfoE_orig ;
255  static AIDA::IHistogram2D* h_sumGamPfoE_corr ;
256  if ( isFirstEvent() ) {
257  h_sumPfoE_orig = AIDAProcessor::histogramFactory(this)->createHistogram2D( "sumPfoE_orig" , "energy [GeV]", 200, -1, 1, 100, 0., 1.5*_nominalEnergy );
258  h_sumPfoE_corr = AIDAProcessor::histogramFactory(this)->createHistogram2D( "sumPfoE_corr" , "energy [GeV]", 200, -1, 1, 100, 0., 1.5*_nominalEnergy );
259  h_sumGamPfoE_orig = AIDAProcessor::histogramFactory(this)->createHistogram2D( "sumGamPfoE_orig", "energy [GeV]", 200, -1, 1, 100, 0., 1.5*_nominalEnergy );
260  h_sumGamPfoE_corr = AIDAProcessor::histogramFactory(this)->createHistogram2D( "sumGamPfoE_corr", "energy [GeV]", 200, -1, 1, 100, 0., 1.5*_nominalEnergy );
261  }
262 
263  float costh = totomom[2]/sqrt( pow( totomom[0], 2 ) +
264  pow( totomom[1], 2 ) +
265  pow( totomom[2], 2 ) );
266 
267  h_sumPfoE_orig ->fill( costh, totPfoEn[0] );
268  h_sumPfoE_corr ->fill( costh, totPfoEn[1] );
269  h_sumGamPfoE_orig->fill( costh, totPfoGammaEn[0] );
270  h_sumGamPfoE_corr->fill( costh, totPfoGammaEn[1] );
271  }
272 
273 #endif
274 
275  return;
276 }
277 
278 void photonCorrectionProcessor::check( LCEvent * /* evt */ ) {
279  // nothing to check here - could be used to fill checkplots in reconstruction processor
280 }
281 
283  streamlog_out (MESSAGE) << "photonCorrectionProcessor::end() " << name() << std::endl ;
284 }
285 
static const float mm
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
virtual void end()
Called after data processing for clean up.
void set_energyCorr_costheta(std::vector< float > pars)
void set_energyCorr_linearise(std::vector< float > pars)
void set_phiCorr_barrel(std::vector< float > pars)
float photonEnergyCorrection(EVENT::ReconstructedParticle *rp)
std::vector< float > _phiCorr_barrel
virtual void processEvent(LCEvent *evt)
Called for every event - the working horse.
std::vector< float > _energyCorr_linearise
void photonDirectionCorrection(EVENT::ReconstructedParticle *rp, float &cor_theta, float &cor_phi)
virtual void init()
Called at the begin of the job before anything is read.
std::vector< float > _thetaCorr_endcap
void set_thetaCorr_barrel(std::vector< float > pars)
void set_thetaCorr_endcap(std::vector< float > pars)
static const float e
std::vector< float > _thetaCorr_barrel
std::vector< float > _energyCorr_endcap
std::vector< LCCollection * > LCCollectionVec
Definition: SiStripClus.h:55
virtual void check(LCEvent *evt)
photonCorrectionProcessor aphotonCorrectionProcessor
void set_barrelendcap_limit(float x)
void set_assumed_endZ(float x)
void set_energyCorr_endcap(std::vector< float > pars)
void set_assumed_boxsize(float x)
void set_energyCorr_barrelPhi(std::vector< float > pars)
std::vector< float > _energyCorr_costheta
std::vector< float > _energyCorr_barrelPhi