39#include "TProfile2D.h"
46 ISvcLocator* pSvcLocator)
57 std::vector<Gaudi::Histo1DDef> dims(7);
58 dims[1] = Gaudi::Histo1DDef(
"side",-1.5,1.5,1);
59 dims[2] = Gaudi::Histo1DDef(
"|eta|",0.,1.6,16);
60 dims[3] = Gaudi::Histo1DDef(
"phi",-
M_PI,
M_PI,1);
61 dims[4] = Gaudi::Histo1DDef(
"log10(E_clus (MeV))",log10(200),log10(1e6),14);
62 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.6,1.1,14);
63 dims[6] = Gaudi::Histo1DDef(
"weight",-2,3,1);
65 dims[0] = Gaudi::Histo1DDef(
"EMB1",0.5,1.5,1);
67 dims[0] = Gaudi::Histo1DDef(
"EMB2",1.5,2.5,1);
68 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.8,0.5,14);
70 dims[0] = Gaudi::Histo1DDef(
"EMB3",2.5,3.5,1);
71 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.9,0.6,14);
73 dims[0] = Gaudi::Histo1DDef(
"EME1",4.5,5.5,1);
74 dims[2] = Gaudi::Histo1DDef(
"|eta|",1.2,3.2,20);
75 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.5,1.7,14);
77 dims[0] = Gaudi::Histo1DDef(
"EME2",5.5,6.5,1);
78 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.8,1.2,14);
80 dims[0] = Gaudi::Histo1DDef(
"EME3",6.5,7.5,1);
81 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.5,1.0,14);
83 dims[0] = Gaudi::Histo1DDef(
"HEC0",7.5,8.5,1);
84 dims[2] = Gaudi::Histo1DDef(
"|eta|",1.4,3.4,20);
85 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.8,0.6,14);
87 dims[0] = Gaudi::Histo1DDef(
"HEC1",8.5,9.5,1);
88 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.9,-0.2,14);
90 dims[0] = Gaudi::Histo1DDef(
"HEC2",9.5,10.5,1);
91 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.8,-0.2,14);
93 dims[0] = Gaudi::Histo1DDef(
"HEC3",10.5,11.5,1);
94 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-4.7,-0.2,14);
96 dims[0] = Gaudi::Histo1DDef(
"TileBar0",11.5,12.5,1);
97 dims[2] = Gaudi::Histo1DDef(
"|eta|",0.,1.2,12);
98 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-6,-1,14);
100 dims[0] = Gaudi::Histo1DDef(
"TileBar1",12.5,13.5,1);
101 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-6.7,-1.2,14);
103 dims[0] = Gaudi::Histo1DDef(
"TileBar2",13.5,14.5,1);
104 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-7,-1.9,14);
106 dims[0] = Gaudi::Histo1DDef(
"TileGap1",14.5,15.5,1);
107 dims[2] = Gaudi::Histo1DDef(
"|eta|",0.8,1.8,10);
108 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-6,-1,14);
110 dims[0] = Gaudi::Histo1DDef(
"TileGap2",15.5,16.5,1);
111 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-6.5,-1.5,14);
113 dims[0] = Gaudi::Histo1DDef(
"TileExt0",17.5,18.5,1);
114 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-6.5,-1,14);
116 dims[0] = Gaudi::Histo1DDef(
"TileExt1",18.5,19.5,1);
117 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-6.6,-1.5,14);
119 dims[0] = Gaudi::Histo1DDef(
"TileExt2",19.5,20.5,1);
120 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-7.2,-2.4,14);
122 dims[0] = Gaudi::Histo1DDef(
"FCal1",20.5,21.5,1);
123 dims[2] = Gaudi::Histo1DDef(
"|eta|",2.8,5.0,22);
124 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-3.5,2,14);
126 dims[0] = Gaudi::Histo1DDef(
"FCal2",21.5,22.5,1);
127 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-3.5,1.5,14);
129 dims[0] = Gaudi::Histo1DDef(
"FCal3",22.5,23.5,1);
130 dims[5] = Gaudi::Histo1DDef(
"log10(rho_cell (MeV/mm^3))",-3.8,1,14);
167 m_weight.resize(CaloSampling::Unknown);
173 ATH_MSG_INFO(
"Using weighting proportional to E_calib" );
177 ATH_MSG_INFO(
"Using weighting proportional to log(E_calib)" );
181 ATH_MSG_INFO(
"Using weighting proportional to 1/N_Clus_E_calib>0" );
194 ATH_MSG_INFO(
"Expecting ParticleID simulation as input -- use EM type clusters only" );
198 ATH_MSG_INFO(
"Expecting ParticleID simulation as input -- use HAD type clusters only" );
206 for(
unsigned int isamp=0;isamp<
m_dimensions.size();isamp++) {
207 int theSampling(CaloSampling::Unknown);
208 for (
unsigned int jsamp = 0;jsamp< CaloSampling::Unknown; jsamp++) {
214 if ( theSampling == CaloSampling::Unknown ) {
217 <<
" is not a valid Calorimeter sampling name and will be ignored! "
218 <<
"Valid names are: ";
219 for (
unsigned int jsamp = 0;jsamp< CaloSampling::Unknown; jsamp++) {
221 if ( jsamp < CaloSampling::Unknown-1)
238 for(
unsigned int idim=1;idim<
m_dimensions[isamp].size();idim++) {
243 else if (
m_dimensions[isamp][idim].title() ==
"|eta|" ) {
247 else if (
m_dimensions[isamp][idim].title() ==
"phi" ) {
251 else if (
m_dimensions[isamp][idim].title() ==
"log10(E_clus (MeV))" )
253 else if (
m_dimensions[isamp][idim].title() ==
"log10(rho_cell (MeV/mm^3))" )
255 else if (
m_dimensions[isamp][idim].title() ==
"weight" )
258 if ( ilogE < 0 || ilogrho < 0 || iweight < 0 ) {
259 ATH_MSG_FATAL(
" Mandatory dimension log10E, log10rho or weight missing ..." );
260 return StatusCode::FAILURE;
262 int nside = (iside>=0?
m_dimensions[isamp][iside].bins():1);
263 int neta = (ieta>=0?
m_dimensions[isamp][ieta].bins():1);
264 int nphi = (iphi>=0?
m_dimensions[isamp][iphi].bins():1);
265 m_weight[theSampling].resize(nside*neta*nphi,
nullptr);
266 for (
int jside=0;jside<nside;jside++) {
267 for (
int jeta=0;jeta<neta;jeta++) {
268 for (
int jphi=0;jphi<nphi;jphi++) {
271 wname +=
"inv_weight";
275 wname += theSampling;
279 wname += (iside>=0?
m_dimensions[isamp][iside].lowEdge():-1);
281 wname += (iside>=0?
m_dimensions[isamp][iside].highEdge():-1);
288 wname += (ieta>=0?
m_dimensions[isamp][ieta].lowEdge():-1);
290 wname += (ieta>=0?
m_dimensions[isamp][ieta].highEdge():-1);
297 wname += (iphi>=0?
m_dimensions[isamp][iphi].lowEdge():-1);
299 wname += (iphi>=0?
m_dimensions[isamp][iphi].highEdge():-1);
303 int iW = jphi*neta*nside+jeta*nside+jside;
305 new TProfile2D(wname,wname,
316 m_weight[theSampling][iW]->SetYTitle(
"log10(#rho_{cell}^{true} (MeV/mm^{3}))");
317 m_weight[theSampling][iW]->SetZTitle(
"E_{reco}/E_{tot}");
320 m_weight[theSampling][iW]->SetYTitle(
"log10(#rho_{cell} (MeV/mm^{3}))");
321 m_weight[theSampling][iW]->SetZTitle(
"E_{tot}/E_{reco}");
323 m_weight[theSampling][iW]->SetXTitle(
"log10(E_{clus} (MeV))");
333 return StatusCode::SUCCESS;
342 for(
unsigned int i=0;i<
m_weight.size();i++) {
343 for(
unsigned int j=0;j<
m_weight[i].size();j++) {
350 return StatusCode::SUCCESS;
357 const EventContext& ctx = getContext();
360 std::vector<const CaloCalibrationHitContainer *> v_cchc;
363 v_cchc.push_back(cchc.
cptr());
372 unsigned int maxHashSize(0);
375 maxHashSize = myHashMax-myHashMin;
376 cellVector[ic].resize(maxHashSize,
nullptr);
383 double eCalibTot(0.);
385 unsigned int iClus = 0;
386 double nClusECalibGt0 = 0.0;
390 ATH_MSG_ERROR(
"Failed to retrieve cluster moment ENG_CALIB_TOT");
391 return StatusCode::FAILURE;
396 ATH_MSG_ERROR(
"Failed to retrieve cluster moment ENG_CALIB_FAC_EM");
397 return StatusCode::FAILURE;
410 for(; cellIter != cellIterEnd; cellIter++ ){
411 const CaloCell* pCell = (*cellIter);
417 myClus->
iClus = iClus;
419 myClus->
next =
nullptr;
421 ClusWeight * theList = cellVector[otherSubDet][(
unsigned int)myHashId];
423 while ( theList->
next )
424 theList = theList->
next;
425 theList->
next = myClus;
428 cellVector[otherSubDet][(
unsigned int)myHashId] = myClus;
441 ClusWeight * theList = cellVector[otherSubDet][(
unsigned int)myHashId];
443 theList->
eCalibTot += hit->energyTotal();
444 theList = theList->
next;
456 if ( eCalibTot > 0 && nClusECalibGt0 > 0 ) {
457 const double inv_eCalibTot = 1. / eCalibTot;
458 const double inv_nClusECalibGt0 = 1. / nClusECalibGt0;
459 for (
unsigned int j=0;j<cc->size();j++) {
461 double eng = pClus->
e();
464 ATH_MSG_ERROR(
"Failed to retrieve cluster moment ENG_CALIB_TOT");
465 return StatusCode::FAILURE;
467 if ( eng > 0 && eCalib > 0 ) {
471 ATH_MSG_ERROR(
"Failed to retrieve cluster moment ENG_CALIB_FAC_EM");
472 return StatusCode::FAILURE;
481 for(; cellIter != cellIterEnd; cellIter++ ){
482 const CaloCell* pCell = (*cellIter);
497 isideCell = (int)(nside*(((pCell->
eta()<0?-1.0:1.0) - hd.lowEdge())
498 /(hd.highEdge()-hd.lowEdge())));
499 if ( isideCell < 0 || isideCell > nside-1 ) {
501 isideCell <<
" not in [0," << nside-1 <<
"] for "
502 <<
"Sampl=" << caloSample );
509 ietaCell = (int)(neta*((fabs(pCell->
eta()) - hd.lowEdge())
510 /(hd.highEdge()-hd.lowEdge())));
511 if ( ietaCell < 0 || ietaCell > neta-1 ) {
513 ietaCell <<
" not in [0," << neta-1 <<
"] for "
514 <<
"Sampl=" << caloSample );
521 iphiCell = (int)(nphi*((pCell->
phi() - hd.lowEdge())
522 /(hd.highEdge()-hd.lowEdge())));
523 if ( iphiCell < 0 || iphiCell > nphi-1 ) {
525 iphiCell <<
" not in [0," << nphi-1 <<
"] for "
526 <<
"Sampl=" << caloSample );
530 if ( isideCell >=0 && ietaCell >=0 && iphiCell >= 0 ) {
531 if ( myCDDE->
volume() > 0 ) {
535 unsigned int iW = iphiCell*neta*nside+ietaCell*nside+isideCell;
536 if ( iW >=
m_weight[caloSample].size() ) {
538 iW <<
" > " <<
m_weight[caloSample].size()-1 <<
" for "
539 <<
"Sampl=" << caloSample
540 <<
", iphi=" << iphiCell
541 <<
", ieta=" << ietaCell
542 <<
", iside=" << isideCell );
545 ClusWeight * theList = cellVector[otherSubDet][(
unsigned int)myHashId];
546 while ( theList && theList->
iClus != j )
547 theList = theList->
next;
549 if (
m_weight[caloSample][iW] && theList && eCalibTot > 0) {
552 norm = eCalib * inv_eCalibTot;
557 norm = log10(eCalib * inv_eCalibTot)+2.0;
562 norm = inv_nClusECalibGt0;
570 m_weight[caloSample][iW]->Fill(log10(eng),
571 log10(pCell->
e()/myCDDE->
volume()),
576 m_weight[caloSample][iW]->Fill(log10(eng),
593 for (
unsigned int ii = 0;ii<cellVector[ic].size();ii++ ) {
597 while ( theList->
next ) {
599 theList = theList->
next;
603 prev->
next =
nullptr;
605 cellVector[ic][ii] =
nullptr;
606 theList = cellVector[ic][ii];
612 return StatusCode::SUCCESS;
616 for (
unsigned int i=0;i<dims.size();i++) {
623 std::vector<int> theUsedSamplings(CaloSampling::Unknown,-1);
627 for (
const std::pair<const std::string, Gaudi::Histo1DDef>& p :
m_dimensionsmap) {
628 std::string_view dimname = std::string_view(p.first).substr(0,p.first.find(
':'));
629 int theSampling(CaloSampling::Unknown);
630 for (
unsigned int jsamp = 0;jsamp< CaloSampling::Unknown; jsamp++) {
636 if ( theSampling == CaloSampling::Unknown ) {
637 msg(MSG::ERROR) <<
"Calorimeter sampling " << dimname
638 <<
" is not a valid Calorimeter sampling name and will be ignored! "
639 <<
"Valid names are: ";
640 for (
unsigned int jsamp = 0;jsamp< CaloSampling::Unknown; jsamp++) {
642 if ( jsamp < CaloSampling::Unknown-1)
650 if ( theUsedSamplings[theSampling] == -1 ) {
652 theUsedSamplings[theSampling] = nsamp;
656 m_dimensions[theUsedSamplings[theSampling]].push_back(p.second);
658 << p.second.title() <<
", [" << p.second.lowEdge()
659 <<
", " << p.second.highEdge()
660 <<
", " << p.second.bins()
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Helpers for checking error return status codes and reporting errors.
static const std::vector< std::string > bins
Handle class for reading from StoreGate.
static const Attributes_t empty
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
Class to store calorimeter calibration hit.
void calo_cell_hash_range(const Identifier id, IdentifierHash &caloCellMin, IdentifierHash &caloCellMax) const
to loop on 'global' cell hashes of one sub-calorimeter alone
IdentifierHash subcalo_cell_hash(const Identifier cellId, int &subCalo) const
create hash id from 'global' cell id
Helper class for offline cell identifiers.
Data object for each calorimeter readout cell.
virtual double e() const override final
get energy (data member) (synonym to method energy()
virtual double phi() const override final
get phi (through CaloDetDescrElement)
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
virtual double eta() const override final
get eta (through CaloDetDescrElement)
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
weight_t weight() const
Accessor for weight associated to this cell.
This class groups all DetDescr information related to a CaloCell.
CaloCell_ID::CaloSample getSampling() const
cell sampling
float volume() const
cell volume
static const std::string & getSamplingName(const CaloSampling::CaloSample theSample)
Returns a string (name) for each CaloSampling.
std::string m_NormalizationType
string to choose different normalization types
std::vector< std::vector< Gaudi::Histo1DDef > > m_dimensions
definition of all dimensions used for each sampling
bool m_useInversionMethod
flag to switch on/off the use of the inversion method
void mapinsert(const std::vector< Gaudi::Histo1DDef > &dims)
std::unique_ptr< TFile > m_outputFile
Output file to save histograms in.
std::map< std::string, Gaudi::Histo1DDef > m_dimensionsmap
property to set all dimensions introduced above
virtual StatusCode execute()
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_clusterCollName
Name of the CaloClusterContainer to use.
GetLCWeights(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode initialize()
virtual StatusCode finalize()
int m_NormalizationTypeNumber
int m_ClassificationTypeNumber
std::vector< std::vector< int > > m_isampmap
Vector of indices in m_dimensions for each sampling.
std::string m_ClassificationType
string to choose different classification types
std::string m_outputFileName
Name of the output file to save histograms in.
std::vector< std::vector< TProfile2D * > > m_weight
Vector of vector of actual histograms.
SG::ReadHandleKeyArray< CaloCalibrationHitContainer > m_CalibrationHitContainerNames
vector of calibration hit container names to use.
This is a "hash" representation of an Identifier.
Property holding a SG store/key/clid from which a ReadHandle is made.
const_pointer_type cptr()
Dereference the pointer.
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
virtual double e() const
The total energy of the particle.
CaloClusterCellLink::const_iterator const_cell_iterator
Iterator of the underlying CaloClusterCellLink (explicitly const version)
const_cell_iterator cell_end() const
@ ENG_CALIB_FRAC_EM
Calibration Hit energy inside the cluster caused by e/gamma/pi0.
@ ENG_CALIB_TOT
Calibration Hit energy inside the cluster.
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version)
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.