20#include "CLHEP/Units/SystemOfUnits.h"
24using namespace std::string_literals;
34 const std::string& name,
35 const IInterface* parent)
48 declareInterface<IClusterCellWeightTool>(
this);
83 msg(MSG::INFO) <<
"Interpolation is ON, dimensions: ";
85 msg(MSG::INFO) <<
" " << (*it).first <<
" (";
86 for(std::vector<std::string >::iterator it2 = (*it).second.begin(); it2!=(*it).second.end(); ++it2) {
87 msg() << (*it2) <<
" ";
93 std::vector<int > *vtmp=
nullptr;
94 if((*it).first ==
"AREA_DMFIT") {
96 }
else if((*it).first ==
"AREA_DMLOOKUP") {
98 }
else if((*it).first ==
"AREA_DMSMPW") {
101 msg(MSG::WARNING) <<
"Unkown dead material area type '" << (*it).first <<
"'" << std::endl;
104 for(std::vector<std::string >::iterator it2 = (*it).second.begin(); it2!=(*it).second.end(); ++it2) {
107 vtmp->push_back(
int(
id));
109 ATH_MSG_WARNING(
"Dimension '" << (*it2) <<
"' is invalid and will be excluded." );
120 return StatusCode::SUCCESS;
133 float wrong_dm_energy = 0.0;
134 float dm_total = 0.0;
137 double weightMom (1);
145 double eWeighted = theCluster->
e();
165 set_zero_moments(theCluster);
167 return StatusCode::SUCCESS;
173 ATH_MSG_ERROR(
"Cannot retrieve EM_PROBABILITY cluster moment, "
174 <<
" cluster energy " << theCluster->
e() <<
" remains the same." );
175 return StatusCode::FAILURE;
179 }
else if ( pi0Prob > 1 ) {
186 double center_lambda = 0;
188 ATH_MSG_ERROR(
"Cannot retrieve CENTER_LAMBDA cluster moment, "
189 <<
" cluster energy " << theCluster->
e() <<
" remains the same." );
190 return StatusCode::FAILURE;
198 return StatusCode::FAILURE;
201 ATH_MSG_DEBUG(
"Cluster is selected for local DM calibration."
202 <<
" Old cluster energy:" << theCluster->
e()
206 std::vector<Area> areas;
207 std::vector<Cell> cells;
208 float smp_energy[CaloSampling::Unknown];
209 float cls_unweighted_energy = 0;
211 smp_energy, cls_unweighted_energy,
data);
212 if ( !
sc.isSuccess() ) {
214 set_zero_moments(theCluster);
220 float cls_initial_energy = theCluster->
e();
221 float cls_side = (theCluster->
eta()<0?-1.0:1.0);
222 float cls_eta = fabs(theCluster->
eta());
223 float cls_phi = theCluster->
phi();
224 float log10ener = 0.0;
225 if(cls_unweighted_energy > 0.0) {
226 log10ener = log10(cls_unweighted_energy);
229 if(center_lambda > 0.0) {
230 log10lambda = log10(center_lambda);
231 if(log10lambda >=4.0) log10lambda = 3.9999;
236 std::cout <<
" cls_initial_energy: " << cls_initial_energy <<
" cls_eta: " << cls_eta << std::endl;
237 std::cout <<
" log10ener: " << log10ener <<
" log10lambda: " << log10lambda << std::endl;
238 for(
int i_smp=0; i_smp<CaloSampling::Unknown; i_smp++){
239 std::cout <<
" i_smp: " << i_smp <<
" smp_energy: " << smp_energy[i_smp] << std::endl;
243 std::vector<float > vars;
252 size_t n_dm =
data->getSizeAreaSet();
255 for(
int i_mix=0; i_mix<2; i_mix++){
256 float mixWeight = (i_mix==0?(1-pi0Prob):pi0Prob);
257 if(mixWeight == 0)
continue;
262 for(
size_t i_dm=0; i_dm < n_dm; i_dm++){
263 if(areas[i_dm].eprep <= 0.0)
continue;
267 if(log10ener > emax) log10ener = emax - 0.0001;
271 if( !pars )
continue;
293 const int nSmp=pars->size()-1;
295 double ecalonew = 0.0;
296 double ecaloold = 0.0;
297 for(
int i_smp=0; i_smp<nSmp; i_smp++){
298 ecaloold += smp_energy[i_smp];
299 ecalonew += smp_energy[i_smp] * (*pars)[i_smp];
301 ecalonew += (*pars)[nSmp];
302 edm = ecalonew - ecaloold;
319 std::cout <<
"CaloLCDeadMaterialTool -> Error! Unknown correction type " <<
area->getType()
320 <<
" with number of parameters " <<
area->getNpars() << std::endl;
322 wrong_dm_energy += areas[i_dm].edm_wrong;
325 std::cout <<
" result> edm: " << edm <<
" edm_wrong:" << edm_wrong << std::endl;
327 edm -= areas[i_dm].edm_wrong;
329 areas[i_dm].erec = areas[i_dm].erec + edm*mixWeight;
341 std::cout <<
"wc> calculation of weights" << std::endl;
347 theCluster->
setE(cls_initial_energy + dm_total - wrong_dm_energy);
352 float sub_ener_old = 0.0;
353 for(
size_t i_c = 0; i_c < cells.size(); i_c++)
355 const Cell& cell = cells[i_c];
357 sub_ener_old += cell.weight*cell.energy;
359 if(sub_ener_old > 0.0) {
360 float corr = (sub_ener_old + dm_total)/sub_ener_old;
361 for(
size_t i_c = 0; i_c < cells.size(); i_c++)
364 cells[i_c].weight *= corr;
372 for (
size_t cell_index = 0; cell_index < cells.size(); ++cell_index)
374 const Cell& cell = cells[cell_index];
376 float we = cell.weight * cell.energy;
378 areas[cell.dm].sub_ener_old += we;
384 for(
size_t i_dm=0; i_dm < areas.size(); i_dm++) {
385 Area& dma = areas[i_dm];
387 if (i_dm >= n_dm || dma.
eprep <= 0)
403 for (
size_t cell_index = 0; cell_index < cells.size(); ++cell_index)
405 Cell& cell = cells[cell_index];
408 cell.weight *= areas[cell.dm].corr;
409 cell.weight *= gblfac;
420 for (;itrCell!=itrCellEnd; ++itrCell) {
422 const float old_weight = itrCell.
weight();
423 float new_weight = cells[cell_index].weight;
427 new_weight = old_weight;
430 std::cout <<
" cells> " << cell_index <<
" ener: " << cells[cell_index].energy <<
" old_w: " << old_weight <<
" new_w:" << new_weight << std::endl;
431 if( new_weight > 100) std::cout <<
"DeadMaterialCorrectionTool2 -> Panic! Too large weight" << std::endl;
441 <<
" (contains wrongly estimated DM energy: " << wrong_dm_energy <<
")"
442 <<
" calculated DM energy (to be added):" << dm_total
443 <<
" new cluster energy:" << theCluster->
e());
455 x = (double)smp_energy[CaloSampling::PreSamplerB];
458 x = (double)smp_energy[CaloSampling::PreSamplerE];
461 x = (double)smp_energy[CaloSampling::TileGap3];
464 x = (double)(dm_total+wrong_dm_energy);
467 for(
size_t i_dm=0; i_dm < areas.size(); i_dm++) {
468 Area& dma = areas[i_dm];
470 x = (double)dma.
erec;
471 if(i_dm ==
sDM_EMB0_EMB1 && smp_energy[CaloSampling::PreSamplerB]>0.0)
x+= smp_energy[CaloSampling::PreSamplerB];
472 if(i_dm ==
sDM_EME0_EME12 && smp_energy[CaloSampling::PreSamplerE] > 0.0)
x+= smp_energy[CaloSampling::PreSamplerE];
473 if(i_dm ==
sDM_SCN && smp_energy[CaloSampling::TileGap3] > 0.0)
x+= smp_energy[CaloSampling::TileGap3];
485 if ( eWeighted > 0 || eWeighted < 0 ) {
486 weightMom *= theCluster->
e()/eWeighted;
490 return StatusCode::SUCCESS;
500 theCluster->
insertMoment(CaloCluster::ENG_RECO_EMB0, 0.0);
501 theCluster->
insertMoment(CaloCluster::ENG_RECO_EME0, 0.0);
502 theCluster->
insertMoment(CaloCluster::ENG_RECO_TILEG3, 0.0);
503 theCluster->
insertMoment(CaloCluster::ENG_RECO_DEAD_TOT, 0.0);
504 for(
size_t i_dm=0; i_dm < DeadMaterialCorrectionTool2::sDM; i_dm++) {
523 std::vector<Area>& areas,
524 std::vector<Cell>& cells,
528 areas.resize(
data->getSizeAreaSet());
529 cells.reserve (theCluster->size());
531 bzero(smp_energy, CaloSampling::Unknown*
sizeof(
float));
537 cls_unweighted_energy = 0;
538 for (;itrCell!=itrCellEnd; ++itrCell) {
540 const CaloCell* thisCell = *itrCell;
545 float energy = thisCell->
e();
547 cls_unweighted_energy += energy;
551 cell.energy = energy;
554 smp_energy[nsmp] += energy;
558 if ( nsmp == CaloSampling::PreSamplerB || nsmp == CaloSampling::EMB1) {
561 }
else if( nsmp == CaloSampling::TileGap3 ) {
564 }
else if ( nsmp == CaloSampling::PreSamplerE || nsmp == CaloSampling::EME1 ) {
567 }
else if (nsmp == CaloSampling::EME3) {
570 }
else if (nsmp == CaloSampling::HEC0) {
573 }
else if (nsmp == CaloSampling::EMB3) {
576 }
else if (nsmp == CaloSampling::TileBar0) {
581 cells.push_back (cell);
596 x = smp_energy[CaloSampling::PreSamplerB];
603 x = smp_energy[CaloSampling::EMB3];
604 y = smp_energy[CaloSampling::TileBar0];
608 x = smp_energy[CaloSampling::TileGap3];
615 x = smp_energy[CaloSampling::PreSamplerE];
622 x = smp_energy[CaloSampling::EME3];
623 y = smp_energy[CaloSampling::HEC0];
626 areas[
sDM_FCAL].eprep = cls_unweighted_energy;
630 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
char data[hepevt_bytes_allocation_ATLAS]
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Data object for each calorimeter readout cell.
virtual double e() const override final
get energy (data member) (synonym to method energy()
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
weight_t weight() const
Accessor for weight associated to this cell.
weight_t weight() const
Accessor for weight associated to this cell.
static void calculateKine(xAOD::CaloCluster *clu, const bool useweight=true, const bool updateLayers=true, const bool useGPUCriteria=false)
Helper class to calculate cluster kinematics based on cells.
defines enums and data types for different moments of CaloCluster
Principal data class for CaloCell clusters.
double eSample(sampling_type sampling) const
Retrieve energy in a given sampling.
bool retrieveMoment(const moment_type &momType, moment_value &momValue, bool useLink=true) const
Retrieve individual moment.
virtual double e() const
Retrieve energy independent of signal state.
void insertMoment(const moment_type &momType, const moment_value &momValue, bool useLink=true)
Set individual moment.
virtual double eta() const
Retrieve eta independent of signal state.
virtual double phi() const
Retrieve phi independent of signal state.
virtual void setE(double e)
Set energy.
cell_iterator cell_end() const
Retrieve a STL-type end() iterator for the cell store.
void reweightCell(const CaloCell *pCell, double weight)
Reweight a cell with kinematic update.
cell_iterator cell_begin() const
Retrieve a STL-type begin() iterator for the cell store.
CaloCell_ID::CaloSample getSampling() const
cell sampling
static bool Interpolate(const CaloLocalHadCoeff *m_data, const unsigned int n_area, std::vector< float > &x, CaloLocalHadCoeff::LocalHadCoeff &pars, const std::vector< int > &dim, double xfit=0.)
static CaloLocalHadDefs::LocalHadDimensionId getDimensionId(const std::string &dimensionName)
Definition of correction area.
Hold binned correction data for local hadronic calibration procedure.
std::vector< float > LocalHadCoeff
Correction parameters for one general bin.
reconstruction status indicator
CaloClusterCellLink::iterator cell_iterator
Iterator of the underlying CaloClusterCellLink (non-const version)
CaloClusterCellLink::const_iterator const_cell_iterator
Iterator of the underlying CaloClusterCellLink (explicitly const version)
MomentType
Enums to identify different moments.
@ EM_PROBABILITY
Classification probability to be em-like.
@ DM_WEIGHT
Dead-material weight (E_dm/E_ooc)
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
@ ENG_CALIB_DEAD_TOT
Attached Calibration Hit energy in dead material.
void prefetchNext(Iter iter, Iter endIter)
Prefetch next object in sequence.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Functions to prefetch blocks of memory.
LocalHadDimensionId
enums to identify user dimensions id number DIMC_* - classification, DIMW_*-weighting,...