3 #include <marlin/Global.h> 
    6 #include "IMPL/LCCollectionVec.h" 
    7 #include "IMPL/ReconstructedParticleImpl.h" 
    9 #include "DD4hep/DD4hepUnits.h"  
   10 #include "DD4hep/DetType.h" 
   11 #include "DD4hep/DetectorSelector.h" 
   12 #include "DDRec/DetectorData.h" 
   14 #ifdef MARLIN_USE_AIDA 
   15 #include <marlin/AIDAProcessor.h> 
   16 #include <AIDA/AIDA.h> 
   20 using namespace lcio ;
 
   21 using namespace marlin ;
 
   30   _description = 
"photonCorrectionProcessor applies an energy correction to photon-like PFOs" ;
 
   32   registerProcessorParameter(
"inputCollection", 
"name of input PFO collection",
 
   35   registerProcessorParameter(
"modifyPFOenergies" , 
"apply the corrected energies to the PFOs", 
_modifyPFOenergies, 
true );
 
   36   registerProcessorParameter(
"modifyPFOdirection", 
"apply the corrected direction to the PFOs", 
_modifyPFOdirections, 
true );
 
   38   std::vector <float> linearise;
 
   39   linearise.push_back( 9.870
e-01 );
 
   40   linearise.push_back( 1.426
e-02 );
 
   41   registerProcessorParameter(
"energyCor_Linearise", 
"parameters to linearise overall energy response", 
_energyCorr_linearise, linearise );
 
   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 );
 
   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 );
 
   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 );
 
   75   std::vector <float> phiCorr_barrel;
 
   76   phiCorr_barrel.push_back(  2.36517
e-05  );
 
   77   phiCorr_barrel.push_back(   1.32090
e-04 );
 
   78   phiCorr_barrel.push_back(  -3.86883
e+00 );
 
   79   phiCorr_barrel.push_back(  -1.67809
e-01 );
 
   80   phiCorr_barrel.push_back(  2.28614
e-05 );
 
   81   phiCorr_barrel.push_back(  6.03495
e-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.86667
e-05 );
 
   87   phiCorr_barrel.push_back(  2.49371
e-05 );
 
   88   phiCorr_barrel.push_back(  -7.71684
e-06 );
 
   89   phiCorr_barrel.push_back(  -1.48118
e-05 );
 
   90   phiCorr_barrel.push_back(  -5.63786
e-06 );
 
   91   phiCorr_barrel.push_back(  -9.38376
e-06 );
 
   92   phiCorr_barrel.push_back(  -4.96296
e-06 );
 
   93   phiCorr_barrel.push_back(  2.91262
e-06 );
 
   94   registerProcessorParameter(
"phiCorr_barrel", 
"paramters to correct phi bias in barrel", 
_phiCorr_barrel, phiCorr_barrel );
 
   96   std::vector <float> thetaCorr_barrel;
 
   97   thetaCorr_barrel.push_back( -0.000166568);
 
   98   thetaCorr_barrel.push_back( -7.119
e-05  );
 
   99   thetaCorr_barrel.push_back( 0.000223618 );
 
  100   thetaCorr_barrel.push_back( -3.95915
e-05);
 
  101   registerProcessorParameter(
"thetaCorr_barrel", 
"paramters to correct theta bias in barrel", 
_thetaCorr_barrel, thetaCorr_barrel );
 
  103   std::vector <float> thetaCorr_endcap;
 
  104   thetaCorr_endcap.push_back( 0.000129478 ) ;
 
  105   thetaCorr_endcap.push_back( -3.73863
e-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 );
 
  112   registerProcessorParameter(
"validationPlots", 
"produce validation plots", 
_validationPlots, 
false );
 
  113   registerProcessorParameter(
"nominalEnergy", 
"nominal photon energy (for validation plots)", 
_nominalEnergy, 
float(200) );
 
  118   streamlog_out (MESSAGE) << 
"hello from photonCorrectionProcessor::init" << endl;
 
  123   dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance();
 
  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 ) {
 
  130     _assumed_endZ     = endcapEcalDetectors.at(0).extension<dd4hep::rec::LayeredCalorimeterData>()->extent[2]/
dd4hep::mm; 
 
  132     streamlog_out (ERROR) << 
"did not find exactly one endcap ECAL! found " << endcapEcalDetectors.size() << 
"; refusing to continue!" << endl;
 
  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; 
 
  142     float barrelInRad  = barrelEcalDetectors.at(0).extension<dd4hep::rec::LayeredCalorimeterData>()->extent[0]/
dd4hep::mm; 
 
  145     streamlog_out (ERROR) << 
"did not find exactly one barrel ECAL! found " << barrelEcalDetectors.size() << 
"; refusing to continue!" << endl;
 
  149   streamlog_out (MESSAGE) << 
"*** ECAL endcap dimensions: minZ, minR, barrel/endcap transition " << 
 
  170   streamlog_out (MESSAGE) << 
"hello from photonCorrectionProcessor::processRunHeader" << endl;
 
  178     streamlog_out (DEBUG) << 
"not asked to modify any PFO properties: so doing nothing" << std::endl; 
 
  183   float totPfoEn[2]={0};
 
  184   float totPfoGammaEn[2]={0};
 
  185   float totomom[3]={0};
 
  189     for (
auto lcobj : (*pfocol) ) {
 
  190       ReconstructedParticleImpl* pfo = 
dynamic_cast<ReconstructedParticleImpl*
>(lcobj);
 
  193     for (
int j=0; j<3; j++) {
 
  194       totomom[j]+=pfo->getMomentum()[j];
 
  198       if ( pfo->getType() == 22 ) {
 
  200     float origEn = pfo->getEnergy();
 
  202     for (
int i=0; i<3; i++) {
 
  203       origMom+=pow(pfo->getMomentum()[i],2);
 
  205     origMom=sqrt(origMom);
 
  206     float origTheta = acos( pfo->getMomentum()[2]/origMom);
 
  207     float origPhi = atan2( pfo->getMomentum()[1], pfo->getMomentum()[0] );
 
  211     float correctedMom = origMom*correctedEnergy/origEn; 
 
  213     float correctedTheta, correctedPhi;
 
  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);
 
  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;
 
  231     pfo->setEnergy( newEnergy );
 
  232     pfo->setMomentum( newMomentum );
 
  235       totPfoEn     [0]+=pfo->getEnergy();
 
  236       totPfoGammaEn[0]+=pfo->getEnergy();
 
  237       totPfoEn     [1]+=correctedEnergy;
 
  238       totPfoGammaEn[1]+=correctedEnergy;
 
  242     totPfoEn[0]+=pfo->getEnergy();
 
  243     totPfoEn[1]+=pfo->getEnergy();
 
  246   } 
catch(DataNotAvailableException &
e) {};
 
  249 #ifdef MARLIN_USE_AIDA 
  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 );
 
  263     float costh = totomom[2]/sqrt( pow( totomom[0], 2 ) +
 
  264                    pow( totomom[1], 2 ) +
 
  265                    pow( totomom[2], 2 ) );
 
  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] );
 
  283   streamlog_out (MESSAGE) << 
"photonCorrectionProcessor::end()  " << name() << std::endl ;
 
bool _modifyPFOdirections
 
virtual void processRunHeader(LCRunHeader *run)
Called for every run. 
 
virtual void end()
Called after data processing for clean up. 
 
photonCorrectionProcessor()
 
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
 
std::string _inputCollection
 
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)
 
std::vector< float > _thetaCorr_barrel
 
std::vector< float > _energyCorr_endcap
 
photonCorrector * _photonCorrector
 
std::vector< LCCollection * > LCCollectionVec
 
virtual void check(LCEvent *evt)
 
photonCorrectionProcessor aphotonCorrectionProcessor
 
float _barrelendcap_limit_costh
 
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