ATLAS Offline Software
Loading...
Searching...
No Matches
GetLCDeadMaterialTree.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5//-----------------------------------------------------------------------
6// File and Version Information:
7// $Id: GetLCDeadMaterialTree.cxx,v 1.3 2009-05-18 20:31:52 pospelov Exp $
8//
9// Description: see GetLCDeadMaterialTree.h
10//
11// Environment:
12// Software developed for the ATLAS Detector at CERN LHC
13//
14// Author List:
15// Gennady Pospelov
16//
17//-----------------------------------------------------------------------
18
19//-----------------------
20// This Class's Header --
21//-----------------------
23
24//---------------
25// C++ Headers --
26//---------------
29#include "GaudiKernel/ISvcLocator.h"
30#include "GaudiKernel/StatusCode.h"
31
33#include "CaloEvent/CaloCell.h"
38#include <CLHEP/Units/SystemOfUnits.h>
46
47#include "TFile.h"
48#include "TTree.h"
49#include "TString.h"
50#include <iterator>
51#include <cmath>
52
53using CLHEP::MeV;
54using CLHEP::TeV;
55
56
57//###############################################################################
59 ISvcLocator* pSvcLocator)
60 : AthAlgorithm(name, pSvcLocator),
61 m_HadDMCoeffInitFile("CaloHadDMCoeff_init_v2.txt"),
62 m_outputTree(nullptr),
63 m_outputFileName("DeadMaterialTree.root"),
64 m_outputFile(nullptr),
65 m_clusterCollName("CaloTopoClusters"),
66 m_HadDMCoeff(nullptr),
67 m_data(nullptr),
69 m_energyMin(200*MeV),
70 m_calo_id(nullptr)
71{
72
73 // dead material zone description
74 declareProperty("HadDMCoeffInitFile",m_HadDMCoeffInitFile);
75
76 // Name of output file to save histograms in
77 declareProperty("OutputFileName",m_outputFileName);
78
79 // Name of ClusterContainer (uncalibrated) to use
80 declareProperty("ClusterCollectionName",m_clusterCollName);
81
82 // Name of ClusterContainer (calibrated) to use
83 declareProperty("ClusterCollectionNameCalib",m_clusterCollNameCalib);
84
85 // to save additional info from the collection with calibrated clusters
86 declareProperty("doSaveCalibClusInfo", m_doSaveCalibClusInfo);
87
88}
89
90
91
92/* ****************************************************************************
93
94***************************************************************************** */
99
100
101
102/* ****************************************************************************
103
104***************************************************************************** */
106{
107 ATH_CHECK(detStore()->retrieve(m_calo_id, "CaloCell_ID"));
108
109 /* ********************************************
110 set list of valid moments
111 ******************************************** */
112 moment_name_vector validNames;
113 validNames.push_back(moment_name_pair(std::string("ENG_CALIB_DEAD_EMB0"),xAOD::CaloCluster::ENG_CALIB_DEAD_EMB0));
114 validNames.push_back(moment_name_pair(std::string("ENG_CALIB_DEAD_TILE0"),xAOD::CaloCluster::ENG_CALIB_DEAD_TILE0));
115 validNames.push_back(moment_name_pair(std::string("ENG_CALIB_DEAD_TILEG3"),xAOD::CaloCluster::ENG_CALIB_DEAD_TILEG3));
116 validNames.push_back(moment_name_pair(std::string("ENG_CALIB_DEAD_EME0"),xAOD::CaloCluster::ENG_CALIB_DEAD_EME0));
117 validNames.push_back(moment_name_pair(std::string("ENG_CALIB_DEAD_HEC0"),xAOD::CaloCluster::ENG_CALIB_DEAD_HEC0));
118 validNames.push_back(moment_name_pair(std::string("ENG_CALIB_DEAD_FCAL"),xAOD::CaloCluster::ENG_CALIB_DEAD_FCAL));
119 validNames.push_back(moment_name_pair(std::string("ENG_CALIB_DEAD_LEAKAGE"),xAOD::CaloCluster::ENG_CALIB_DEAD_LEAKAGE));
120 validNames.push_back(moment_name_pair(std::string("ENG_CALIB_DEAD_UNCLASS"),xAOD::CaloCluster::ENG_CALIB_DEAD_UNCLASS));
121
122 /* ********************************************
123 initial coefficients
124 ******************************************** */
126 std::string fileName = PathResolver::find_file (m_HadDMCoeffInitFile, "DATAPATH");
127 m_HadDMCoeff = dmHelper.InitDataFromFile(fileName.c_str());
128 if( !m_HadDMCoeff ) {
129 ATH_MSG_FATAL( " Error while initializing default dead material coefficients " );
130 return StatusCode::FAILURE;
131 }
132 // how we have to set correspondance between dead material areas and calibration moments
133 m_momentForDMArea.resize( m_HadDMCoeff->getSizeAreaSet());
134 for(int i_dm=0; i_dm<m_HadDMCoeff->getSizeAreaSet(); i_dm++){
135 bool isValid(false);
136 for (const moment_name_pair& vname : validNames) {
137 if ( m_HadDMCoeff->getArea(i_dm)->getTitle() == vname.first ) {
138 m_momentForDMArea[i_dm] = vname.second;
139 isValid = true;
140 break;
141 }
142 }
143 if ( !isValid) {
144 ATH_MSG_FATAL( " Unknown moment name '" << m_HadDMCoeff->getArea(i_dm)->getTitle() << "' in the m_HadDMCoeff!" );
145 return StatusCode::FAILURE;
146 }
147 }
148
149 /* ********************************************
150 output file&tree
151 ******************************************** */
152 m_data = new CaloHadDMCoeffData(nullptr);
153
154 m_outputFile = new TFile(m_outputFileName.c_str(),"RECREATE");
155 m_outputFile->cd();
156
157 m_outputTree = m_data->MakeTree("DeadMaterialTree");
158
159 ATH_CHECK( m_clusterCollName.initialize() );
161 ATH_CHECK( m_clusterCollNameCalib.initialize() );
162 }
163 else {
165 }
166
167 return StatusCode::SUCCESS;
168}
169
170
171
172/* ****************************************************************************
173
174***************************************************************************** */
176{
177 ATH_MSG_INFO( "Writing out tree" );
178 m_outputFile->cd();
179 m_outputTree->Write();
180 m_outputFile->Close();
181
182 return StatusCode::SUCCESS;
183}
184
185
186
187/* ****************************************************************************
188
189***************************************************************************** */
191{
192 //bool useLink = true;
193
194 /* ********************************************
195 access to cluster container
196 ******************************************** */
198
199 /* ********************************************
200 reading primary particle
201 ******************************************** */
202 const McEventCollection* truthEvent=nullptr;
203 ATH_CHECK( evtStore()->retrieve(truthEvent, "TruthEvent") );
204#ifdef HEPMC3
205 const HepMC::ConstGenParticlePtr& gen = truthEvent->at(0)->particles().front();
206#else
207 HepMC::GenEvent::particle_const_iterator pit = truthEvent->at(0)->particles_begin();
208 const HepMC::GenParticle * gen = *pit;
209#endif
210
211 double mc_eta = gen->momentum().pseudoRapidity();
212 double mc_phi = gen->momentum().phi();
213
214 m_data->clear();
215
216 m_data->m_mc_pdg = gen->pdg_id();
217 m_data->m_mc_ener = gen->momentum().e();
218 m_data->m_mc_eta = mc_eta;
219 m_data->m_mc_phi = mc_phi;
220
221 int nClus = pClusColl->size();
222 m_data->m_ncls = nClus;
223 m_data->m_cls_ener->resize(nClus, 0.0);
224 m_data->m_cls_ener_unw->resize(nClus, 0.0);
225 m_data->m_cls_lambda->resize(nClus, 0.0);
226 m_data->m_cls_eta->resize(nClus, 0.0);
227 m_data->m_cls_phi->resize(nClus, 0.0);
228 //m_data->m_cls_emfrac->resize(nClus, 0.0);
229 m_data->m_cls_smpener->resize(nClus);
230 m_data->m_cls_smpener_unw->resize(nClus);
231 //m_data->m_cls_ibin->resize(nClus);
232 m_data->m_cls_eprep->resize(nClus);
233 m_data->m_cls_dmener->resize(nClus);
234 m_data->m_narea = m_HadDMCoeff->getSizeAreaSet();
235 for(int i_cls=0; i_cls<nClus; i_cls++){
236 //(*m_cls_ibin)[i_cls].resize(m_narea, -1);
237 (*m_data->m_cls_smpener)[i_cls].resize(CaloSampling::Unknown, 0.0);
238 (*m_data->m_cls_smpener_unw)[i_cls].resize(CaloSampling::Unknown, 0.0);
239 (*m_data->m_cls_eprep)[i_cls].resize(m_data->m_narea, 0.0);
240 (*m_data->m_cls_dmener)[i_cls].resize(m_data->m_narea, 0.0);
241 }
242 m_data->m_cls_engcalib->resize(nClus, 0.0);
243 m_data->m_cls_recostat->resize(nClus, 0);
244 m_data->m_cls_pi0prob->resize(nClus, 0.0);
245 m_data->m_cls_isol->resize(nClus, 0.0);
246 m_data->m_cls_oocener->resize(nClus, 0.0);
247 m_data->m_cls_calib_emfrac->resize(nClus, 0.0);
248 m_data->m_cls_engcalibpres->resize(nClus, 0.0);
249
250 xAOD::CaloClusterContainer::const_iterator clusIter = pClusColl->begin();
251 xAOD::CaloClusterContainer::const_iterator clusIterEnd = pClusColl->end();
252 unsigned int iClus = 0;
253 for( ;clusIter!=clusIterEnd;++clusIter,++iClus) {
254 const xAOD::CaloCluster * theCluster = (*clusIter);
255
256 (*m_data->m_cls_ener)[iClus] = theCluster->e();
257 // cluster energy in samplings
258 for(int i_smp=0; i_smp<(int)CaloSampling::Unknown; i_smp++){
259 (*m_data->m_cls_smpener)[iClus][i_smp] = theCluster->eSample((CaloSampling::CaloSample)i_smp);
260 }
261
262 // calibration energy of clusters
263 double mx_calib_tot=0;
264 if( !theCluster->retrieveMoment( xAOD::CaloCluster::ENG_CALIB_TOT, mx_calib_tot) ) {
265 ATH_MSG_ERROR( "Moment ENG_CALIB_TOT is absent" );
266 return StatusCode::FAILURE;
267 }
268 m_data->m_engClusSumCalib += mx_calib_tot;
269 (*m_data->m_cls_engcalib)[iClus] = mx_calib_tot;
270
271 double mx_calib_emb0=0, mx_calib_eme0=0, mx_calib_tileg3=0;
272 if( !theCluster->retrieveMoment(xAOD::CaloCluster::ENG_CALIB_EMB0, mx_calib_emb0)
273 || !theCluster->retrieveMoment(xAOD::CaloCluster::ENG_CALIB_EME0, mx_calib_eme0)
274 || !theCluster->retrieveMoment(xAOD::CaloCluster::ENG_CALIB_TILEG3, mx_calib_tileg3)){
275 ATH_MSG_ERROR( "One of the moment ENG_CALIB_EMB0, ENG_CALIB_EME0, ENG_CALIB_TILEG3 is absent" );
276 return StatusCode::FAILURE;
277 }else{
278 (*m_data->m_cls_engcalibpres)[iClus] = (mx_calib_emb0+mx_calib_eme0+mx_calib_tileg3);
279 }
280
283 if(pClusColl->size() != pClusCollCalib->size()) {
284 ATH_MSG_WARNING( "Different size of calibrated and uncalibrated cluster collection "
285 << pClusColl->size() << " " << pClusCollCalib->size() );
286 return StatusCode::SUCCESS;
287 }
288
289 const xAOD::CaloCluster * theClusterCalib = pClusCollCalib->at(iClus);
290
291 // reco status
292 const CaloRecoStatus& recoStatus = theClusterCalib->recoStatus();
293
294 (*m_data->m_cls_recostat)[iClus] = recoStatus.getStatusWord();
295
296 // classification pi0 probability (available on calibrated cluster)
297 double pi0Prob = 0;
298 if( !theClusterCalib->retrieveMoment( xAOD::CaloCluster::EM_PROBABILITY, pi0Prob) ) {
299 //ATH_MSG_ERROR( "Moment ENG_CALIB_TOT is absent" );
300 pi0Prob = -1.0;
301 } else {
302 if ( pi0Prob < 0 ) pi0Prob = 0;
303 if ( pi0Prob > 1 ) pi0Prob = 1;
304 }
305 (*m_data->m_cls_pi0prob)[iClus] = pi0Prob;
306 } // m_doSaveCalibClusInfo
307
308 // cluster isolation moment and out of cluster energy
309 double mx_isol;
310 if ( !theCluster->retrieveMoment(xAOD::CaloCluster::ISOLATION, mx_isol)) {
311 ATH_MSG_ERROR( "Moment ISOLATION is absent" );
312 return StatusCode::FAILURE;
313 }else{
314 (*m_data->m_cls_isol)[iClus] = mx_isol;
315 }
316
317 double mx_calib_oocL;
318 if ( !theCluster->retrieveMoment(xAOD::CaloCluster::ENG_CALIB_OUT_L, mx_calib_oocL)) {
319 ATH_MSG_ERROR( "Moment ENG_CALIB_OUT_L is absent" );
320 return StatusCode::FAILURE;
321 }else{
322 (*m_data->m_cls_oocener)[iClus] = mx_calib_oocL;
323 }
324
325 double mx_calib_emfrac;
326 if ( !theCluster->retrieveMoment(xAOD::CaloCluster::ENG_CALIB_FRAC_EM, mx_calib_emfrac)) {
327 ATH_MSG_WARNING( "Moment ENG_CALIB_FRAC_EM is absent" );
328 return StatusCode::FAILURE;
329 }else{
330 (*m_data->m_cls_calib_emfrac)[iClus] = mx_calib_emfrac;
331 }
332
333
334 // calculation of cluster energy and energy in samplings without accounting
335 // cells weights
336 xAOD::CaloCluster::const_cell_iterator cellIter = theCluster->cell_begin();
337 xAOD::CaloCluster::const_cell_iterator cellIterEnd = theCluster->cell_end();
338 for(; cellIter != cellIterEnd; cellIter++ ){
339 const CaloCell* pCell = (*cellIter);
340 Identifier myId = pCell->ID();
342 (*m_data->m_cls_ener_unw)[iClus] += pCell->e();
343 (*m_data->m_cls_smpener_unw)[iClus][(int)nsmp] += pCell->e();
344 }
345
346 double clusEner = (*m_data->m_cls_ener_unw)[iClus];
347 double clusLambda=0;
348 if (!theCluster->retrieveMoment(xAOD::CaloCluster::CENTER_LAMBDA,clusLambda)) {
349 ATH_MSG_WARNING( "Moment CENTER_LAMBDA is absent" );
350 return StatusCode::FAILURE;
351 }
352 (*m_data->m_cls_lambda)[iClus] = clusLambda;
353 (*m_data->m_cls_eta)[iClus] = theCluster->eta();
354 (*m_data->m_cls_phi)[iClus] = theCluster->phi();
355 if(clusEner > m_energyMin ) {
356 //clusEner = log10(clusEner);
357 //if(clusEner > 6.3) clusEner = 6.2999;
358 //clusLambda = log10(clusLambda);
359 //if(clusLambda > 4.0) clusLambda = 3.9999;
360 //double clusEta=fabs(theCluster->eta());
361
362 for(int i_dma=0; i_dma<m_data->m_narea; i_dma++){
363 //(*m_cls_ibin)[iClus][i_dma] = m_HadDMCoeff->getBin(i_dma, (float)clusEmFrac, (float)clusEner, (float)clusLambda, (float)clusEta);
364 double dmVal=0;
365 if (!theCluster->retrieveMoment( m_momentForDMArea[i_dma],dmVal)) {
366 ATH_MSG_WARNING( "Moment "<< m_momentForDMArea[i_dma] << " is absent" );
367 return StatusCode::FAILURE;
368 }
369 (*m_data->m_cls_dmener)[iClus][i_dma] = dmVal;
370
371 // now we have to calculate cluster quantities which we will use later for
372 // reconstruction of given dead material calibration moment
373 double eprep = 0.0;
374 double x(0), y(0);
375 switch ( m_momentForDMArea[i_dma] ) {
377 x = (*m_data->m_cls_smpener_unw)[iClus][CaloSampling::PreSamplerB];
378 if(x > 0.0) {
379 eprep = x;
380 }
381 break;
383 x = (*m_data->m_cls_smpener_unw)[iClus][CaloSampling::EMB3];
384 y = (*m_data->m_cls_smpener_unw)[iClus][CaloSampling::TileBar0];
385 if(x>0.0 && y>0.0) {
386 eprep = sqrt(x*y);
387 }
388 break;
390 x = (*m_data->m_cls_smpener_unw)[iClus][CaloSampling::TileGap3];
391 if(x > 0.0) {
392 eprep = x;
393 }
394 break;
396 x = (*m_data->m_cls_smpener_unw)[iClus][CaloSampling::PreSamplerE];
397 if( x > 0.0 ) {
398 eprep = x;
399 }
400 break;
402 x = (*m_data->m_cls_smpener_unw)[iClus][CaloSampling::EME3];
403 y = (*m_data->m_cls_smpener_unw)[iClus][CaloSampling::HEC0];
404 if(x>0.0 && y>0.0) {
405 eprep = sqrt(x*y);
406 }
407 break;
409 eprep = (*m_data->m_cls_ener_unw)[iClus];
410 break;
412 eprep = (*m_data->m_cls_ener_unw)[iClus];
413 break;
415 eprep = (*m_data->m_cls_ener_unw)[iClus];
416 break;
417 default:
418 ATH_MSG_ERROR( "No such moment registered " << m_momentForDMArea[i_dma] );
419 return StatusCode::FAILURE;
420 break;
421 }
422 (*m_data->m_cls_eprep)[iClus][i_dma] = eprep;
423
424 } // loop over dm areas
425
426 } // good cluster
427 } // loop over clusters
428
429 // now we have to process special case, when we have DM energy, say, in front of the
430 // calorimeter but there is no signal in presampler itself. When we have to add this
431 // DM energy into 'unclassified' area
432 for(int i_cls=0; i_cls<m_data->m_ncls; i_cls++){
433 double edm_uncorrected = 0.0;
434 for(int i_dma=0; i_dma<m_data->m_narea; i_dma++){
436 if( (*m_data->m_cls_eprep)[i_cls][i_dma] <= 0.0 &&
442 {
443 edm_uncorrected += (*m_data->m_cls_dmener)[i_cls][i_dma];
444 (*m_data->m_cls_dmener)[i_cls][i_dma] = 0.0;
445 }
446 } // i_dma
447 // now let's put this energy into unclassified area
448 for(int i_dma=0; i_dma<m_data->m_narea; i_dma++){
450 (*m_data->m_cls_dmener)[i_cls][i_dma] += edm_uncorrected;
451 }
452 } // i_dma
453 } // i_cls
454
455 m_outputTree->Fill();
456
457 return StatusCode::SUCCESS;
458}
459
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
Helpers for checking error return status codes and reporting errors.
Handle class for reading from StoreGate.
#define y
#define x
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
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
virtual double e() const override final
get energy (data member) (synonym to method energy()
Definition CaloCell.h:333
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition CaloCell.h:295
Data to read from special DeadMaterialTree.
CaloLocalHadCoeff * InitDataFromFile(const char *fname)
reconstruction status indicator
virtual const store_type & getStatusWord() const
retrieve the entire status word
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const T * at(size_type n) const
Access an element, as an rvalue.
CaloLocalHadCoeff * m_HadDMCoeff
Collection of dead material correction coeffitients.
std::string m_outputFileName
Name of the output file to save tree in.
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_clusterCollNameCalib
Name of the calibrated CaloClusterContainer to use.
virtual StatusCode initialize()
std::pair< std::string, xAOD::CaloCluster::MomentType > moment_name_pair
std::vector< moment_name_pair > moment_name_vector
const CaloCell_ID * m_calo_id
bool m_doSaveCalibClusInfo
save additional cluster info from calibrated collections
TTree * m_outputTree
Output tree.
std::string m_HadDMCoeffInitFile
Name of text file with initial parameters for coefficients calculation.
GetLCDeadMaterialTree(const std::string &name, ISvcLocator *pSvcLocator)
CaloHadDMCoeffData * m_data
data to save into the tree
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_clusterCollName
Name of the uncalibrated CaloClusterContainer to use.
std::vector< xAOD::CaloCluster::MomentType > m_momentForDMArea
virtual StatusCode finalize()
TFile * m_outputFile
Output file to save tree in.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
virtual double eta() const
The pseudorapidity ( ) of the particle.
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
float eSample(const CaloSample sampling) const
virtual double phi() const
The azimuthal angle ( ) of the particle.
MomentType
Enums to identify different moments.
@ ENG_CALIB_OUT_L
Attached Calibration Hit energy outside clusters but inside the calorimeter with loose matching (Angl...
@ EM_PROBABILITY
Classification probability to be em-like.
@ ENG_CALIB_DEAD_UNCLASS
Attached Calibration Hit energy in dead material in unclassified areas of the detector.
@ ENG_CALIB_DEAD_HEC0
Attached Calibration Hit energy in dead material between EME3 and HEC0.
@ ENG_CALIB_DEAD_TILEG3
Attached Calibration Hit energy in dead material before scintillator.
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
@ ENG_CALIB_DEAD_EME0
Attached Calibration Hit energy in dead material before EME0, between EME0 and EME1.
@ ENG_CALIB_DEAD_TILE0
Attached Calibration Hit energy in dead material between EMB3 and TILE0.
@ ENG_CALIB_FRAC_EM
Calibration Hit energy inside the cluster caused by e/gamma/pi0.
@ ENG_CALIB_DEAD_FCAL
Attached Calibration Hit energy in dead material before FCAL, between FCAL and HEC.
@ ENG_CALIB_TOT
Calibration Hit energy inside the cluster.
@ ENG_CALIB_DEAD_LEAKAGE
Attached Calibration Hit energy in dead material behind calorimeters.
@ ENG_CALIB_EMB0
Calibration Hit energy inside the cluster barrel presampler.
@ ENG_CALIB_EME0
Calibration Hit energy inside the cluster endcap presampler.
@ ENG_CALIB_DEAD_EMB0
Attached Calibration Hit energy in dead material before EMB0, between EMB0 and EMB1.
@ ISOLATION
Energy weighted fraction of non-clustered perimeter cells.
@ ENG_CALIB_TILEG3
Calibration Hit energy inside the cluster scintillator.
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version)
CaloRecoStatus & recoStatus()
Accesssor to CaloRecoStatus (non-const)
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.