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;
359 std::vector<const CaloCalibrationHitContainer *> v_cchc;
362 v_cchc.push_back(cchc.
cptr());
371 unsigned int maxHashSize(0);
374 maxHashSize = myHashMax-myHashMin;
375 cellVector[ic].resize(maxHashSize,
nullptr);
382 double eCalibTot(0.);
384 unsigned int iClus = 0;
385 double nClusECalibGt0 = 0.0;
389 ATH_MSG_ERROR(
"Failed to retrieve cluster moment ENG_CALIB_TOT");
390 return StatusCode::FAILURE;
395 ATH_MSG_ERROR(
"Failed to retrieve cluster moment ENG_CALIB_FAC_EM");
396 return StatusCode::FAILURE;
409 for(; cellIter != cellIterEnd; cellIter++ ){
410 const CaloCell* pCell = (*cellIter);
416 myClus->
iClus = iClus;
418 myClus->
next =
nullptr;
420 ClusWeight * theList = cellVector[otherSubDet][(
unsigned int)myHashId];
422 while ( theList->
next )
423 theList = theList->
next;
424 theList->
next = myClus;
427 cellVector[otherSubDet][(
unsigned int)myHashId] = myClus;
440 ClusWeight * theList = cellVector[otherSubDet][(
unsigned int)myHashId];
442 theList->
eCalibTot += hit->energyTotal();
443 theList = theList->
next;
455 if ( eCalibTot > 0 && nClusECalibGt0 > 0 ) {
456 const double inv_eCalibTot = 1. / eCalibTot;
457 const double inv_nClusECalibGt0 = 1. / nClusECalibGt0;
458 for (
unsigned int j=0;j<cc->size();j++) {
460 double eng = pClus->
e();
463 ATH_MSG_ERROR(
"Failed to retrieve cluster moment ENG_CALIB_TOT");
464 return StatusCode::FAILURE;
466 if ( eng > 0 && eCalib > 0 ) {
470 ATH_MSG_ERROR(
"Failed to retrieve cluster moment ENG_CALIB_FAC_EM");
471 return StatusCode::FAILURE;
480 for(; cellIter != cellIterEnd; cellIter++ ){
481 const CaloCell* pCell = (*cellIter);
496 isideCell = (int)(nside*(((pCell->
eta()<0?-1.0:1.0) - hd.lowEdge())
497 /(hd.highEdge()-hd.lowEdge())));
498 if ( isideCell < 0 || isideCell > nside-1 ) {
500 isideCell <<
" not in [0," << nside-1 <<
"] for "
501 <<
"Sampl=" << caloSample );
508 ietaCell = (int)(neta*((fabs(pCell->
eta()) - hd.lowEdge())
509 /(hd.highEdge()-hd.lowEdge())));
510 if ( ietaCell < 0 || ietaCell > neta-1 ) {
512 ietaCell <<
" not in [0," << neta-1 <<
"] for "
513 <<
"Sampl=" << caloSample );
520 iphiCell = (int)(nphi*((pCell->
phi() - hd.lowEdge())
521 /(hd.highEdge()-hd.lowEdge())));
522 if ( iphiCell < 0 || iphiCell > nphi-1 ) {
524 iphiCell <<
" not in [0," << nphi-1 <<
"] for "
525 <<
"Sampl=" << caloSample );
529 if ( isideCell >=0 && ietaCell >=0 && iphiCell >= 0 ) {
530 if ( myCDDE->
volume() > 0 ) {
534 unsigned int iW = iphiCell*neta*nside+ietaCell*nside+isideCell;
538 <<
"Sampl=" << caloSample
539 <<
", iphi=" << iphiCell
540 <<
", ieta=" << ietaCell
541 <<
", iside=" << isideCell );
544 ClusWeight * theList = cellVector[otherSubDet][(
unsigned int)myHashId];
545 while ( theList && theList->
iClus != j )
546 theList = theList->
next;
548 if (
m_weight[caloSample][iW] && theList && eCalibTot > 0) {
551 norm = eCalib * inv_eCalibTot;
556 norm = log10(eCalib * inv_eCalibTot)+2.0;
561 norm = inv_nClusECalibGt0;
569 m_weight[caloSample][iW]->Fill(log10(eng),
570 log10(pCell->
e()/myCDDE->
volume()),
575 m_weight[caloSample][iW]->Fill(log10(eng),
592 for (
unsigned int ii = 0;ii<cellVector[ic].size();ii++ ) {
596 while ( theList->
next ) {
598 theList = theList->
next;
602 prev->
next =
nullptr;
604 cellVector[ic][ii] =
nullptr;
605 theList = cellVector[ic][ii];
611 return StatusCode::SUCCESS;
615 for (
unsigned int i=0;i<dims.size();i++) {
622 std::vector<int> theUsedSamplings(CaloSampling::Unknown,-1);
626 for (
const std::pair<const std::string, Gaudi::Histo1DDef>& p :
m_dimensionsmap) {
627 std::string_view dimname = std::string_view(p.first).substr(0,p.first.find(
':'));
628 int theSampling(CaloSampling::Unknown);
629 for (
unsigned int jsamp = 0;jsamp< CaloSampling::Unknown; jsamp++) {
635 if ( theSampling == CaloSampling::Unknown ) {
636 msg(MSG::ERROR) <<
"Calorimeter sampling " << dimname
637 <<
" is not a valid Calorimeter sampling name and will be ignored! "
638 <<
"Valid names are: ";
639 for (
unsigned int jsamp = 0;jsamp< CaloSampling::Unknown; jsamp++) {
641 if ( jsamp < CaloSampling::Unknown-1)
649 if ( theUsedSamplings[theSampling] == -1 ) {
651 theUsedSamplings[theSampling] = nsamp;
655 m_dimensions[theUsedSamplings[theSampling]].push_back(p.second);
657 << p.second.title() <<
", [" << p.second.lowEdge()
658 <<
", " << p.second.highEdge()
659 <<
", " << 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.
size_t size() const
Number of registered mappings.
static const Attributes_t empty
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
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
virtual StatusCode execute(const EventContext &ctx)
Execute 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
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.