ATLAS Offline Software
Loading...
Searching...
No Matches
TBXMLCaloCellWriterTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7#include "TBXMLWriter.h"
8
9#include "GaudiKernel/MsgStream.h"
10
11#include "CLHEP/Units/SystemOfUnits.h"
12
13#include "Identifier/Identifier.h"
15
17#include "CaloDetDescr/CaloDetDescrElement.h"
18
20
21#include "CaloGeoHelpers/CaloSampling.h"
22#include "CaloEvent/CaloCell.h"
24
25#include <iostream>
26#include <fstream>
27#include <format>
28#include <iomanip>
29
30#include <vector>
31#include <sstream>
32#include <map>
33
34#include <cmath>
35
36
37using CLHEP::deg;
38
39
40const unsigned int TBXMLCaloCellWriterTool::m_nCols = 2;
41
43 const std::string& name,
44 const IInterface* parent)
45 : TBXMLWriterToolBase(type,name,parent)
46 , m_etaMin(-5.0)
47 , m_etaMax(5.0)
48 , m_phiMin(0.*deg)
49 , m_phiMax(360.*deg)
50 , m_firstEvent(true)
51 , m_idHelper(0)
52{
53 declareProperty("InputCellContainer", m_cellContainer);
54 declareProperty("IncludedCalos", m_includedCalos);
55 declareProperty("IncludedSamplings", m_includedSamplings);
56 declareProperty("EtaMin", m_etaMin);
57 declareProperty("EtaMax", m_etaMax);
58 declareProperty("PhiMin", m_phiMin);
59 declareProperty("PhiMax", m_phiMax);
60 // save pointer to algorithm
61 m_mother = dynamic_cast<const TBXMLWriter*>(parent);
62}
63
66
68{
70 ATH_CHECK(m_caloMgrKey.initialize());
71 return StatusCode::SUCCESS;
72}
73
75// Event Writer //
77
78StatusCode
80 std::string_view /* entryTag */)
81{
82 // messaging
83 MsgStream log(msgSvc(),name());
84
86 // On the Fly Initialization //
88
89 if ( m_firstEvent )
90 {
91 // check pointer
92 if ( m_mother == 0 )
93 {
94 log << MSG::ERROR
95 << "tool does not hang off the TBXMLWriter algorithm."
96 << endmsg;
97 return StatusCode::FAILURE;
98 }
99
100 // convert poperties
101 StatusCode checkOut = this->convertProperties();
102 if ( checkOut.isFailure() )
103 {
104 log << MSG::ERROR
105 << "cannot convert properties correctly!"
106 << endmsg;
107 return StatusCode::FAILURE;
108 }
109 m_firstEvent = false;
110
111 // print out configuration
112 log << MSG::INFO
113 << "list of included calo samplings:"
114 << endmsg;
115 for ( unsigned int i=0; i<m_caloSamplings.size(); i++ )
116 {
117 log << MSG::INFO
118 << "Sampling \042"
120 << "\042 with SubCalo index "
121 << (int)m_caloSamplings[i]
122 << endmsg;
123 }
124 }
125
127 // Check On Begin Run //
129
130 const EventContext& ctx = Gaudi::Hive::currentContext();
131 EventIDBase::number_type run_number = ctx.eventID().run_number();
132 if (m_runNumbers.insert (run_number).second) {
133 StatusCode checkOut = this->writeRunFiles(m_mother->getFileDir(),
134 run_number);
135 if ( checkOut.isFailure() )
136 {
137 log << MSG::ERROR
138 << "cannot produce run XML files."
139 << endmsg;
140 return StatusCode::FAILURE;
141 }
142 }
143
144
146 // Retrieve Data from StoreGate //
148
149 const CaloCellContainer* theContainer = 0;
150 ATH_CHECK( evtStore()->retrieve(theContainer,m_cellContainer) );
151
153 // Loop Individual Calorimeters //
155
156 for ( unsigned int i=0; i<m_caloIndices.size(); i++ )
157 {
158 // write container tag
159 outStream << "<!-- TBXMLCaloCellWriterTool: begin write cell container "
160 << m_includedCalos[i] << " -->" << '\n';
161
162 std::vector<std::string> theCellAttrNames;
163 theCellAttrNames.push_back("name");
164 theCellAttrNames.push_back("ncols");
165 theCellAttrNames.push_back("nrows");
166 theCellAttrNames.push_back("idtype");
167 theCellAttrNames.push_back("etype");
168 std::vector<std::string> theCellAttrValues;
169 theCellAttrValues.push_back(m_includedCalos[i]);
170
171 // get data size
172 unsigned int dataSize = theContainer->nCellsCalo(m_caloIndices[i]);
173 unsigned int nRows =
174 (unsigned int)ceil( (double)dataSize / (double)m_nCols );
175 theCellAttrValues.push_back(std::to_string(m_nCols));
176 theCellAttrValues.push_back(std::to_string(nRows));
177 theCellAttrValues.push_back("uint");
178 theCellAttrValues.push_back("double");
179 this->openElement(outStream,"CaloCellContainer",
180 theCellAttrNames,theCellAttrValues);
181
182 // loop on cells
184 theContainer->beginConstCalo(m_caloIndices[i]);
186 theContainer->endConstCalo(m_caloIndices[i]);
187
188 // baseline index
189 IdentifierHash baseIndex, lastIndex;
190 m_idHelper->calo_cell_hash_range((int)m_caloIndices[i],
191 baseIndex, lastIndex);
192
193 unsigned int theCtr = 0;
194 bool isTerminated = false;
195 for ( ; firstCell != lastCell; ++firstCell )
196 {
197 // check if cell in requested layer and range
198 double eta = (*firstCell)->eta();
199 double phi = (*firstCell)->phi();
200 const CaloDetDescrElement * theCaloDDE= (*firstCell)->caloDDE();
202 if (theCaloDDE) {
203 theLayer = (CaloSampling::CaloSample) theCaloDDE->getSampling();
204 }else{
205 theLayer = CaloSampling::Unknown;
206 }
207 if ( ( std::find(m_caloSamplings.begin(),
208 m_caloSamplings.end(),
209 theLayer) != m_caloSamplings.end() ) &&
210 ( ( eta > m_etaMin && eta < m_etaMax ) &&
211 ( phi > m_phiMin && phi < m_phiMax ) )
212 )
213 {
214 // get calorimeter hash index
215 IdentifierHash theIndex =
216 (*firstCell)->caloDDE()->calo_hash();
217 // get eta, phi, region
218 int etaIndex = m_idHelper->eta((*firstCell)->ID());
219 int phiIndex = m_idHelper->phi((*firstCell)->ID());
220 int regIndex = m_idHelper->region((*firstCell)->ID());
221 // int subIndex = m_idHelper->sub_calo((*firstCell)->ID());
222 int lyrIndex = m_idHelper->sampling((*firstCell)->ID());
223 int subIndex = -1;
224 // get subIndex
225 if ( m_idHelper->is_em_barrel((*firstCell)->ID()) )
226 {
227 subIndex = 0;
228 }
229 else if ( m_idHelper->is_em_endcap((*firstCell)->ID()) )
230 {
231 subIndex = 1;
232 }
233 else if ( m_idHelper->is_tile_barrel((*firstCell)->ID()) )
234 {
235 subIndex = 2;
236 }
237 else if ( m_idHelper->is_tile_extbarrel((*firstCell)->ID()) )
238 {
239 subIndex = 3;
240 }
241 else if ( m_idHelper->is_hec((*firstCell)->ID()) )
242 {
243 subIndex = 4;
244 }
245 else if ( m_idHelper->is_fcal((*firstCell)->ID()) )
246 {
247 subIndex = 5;
248 }
249 // get signal
250 double theEnergy = (*firstCell)->e();
251 if ( theCtr == 0 || ( theCtr % m_nCols ) == 0 )
252 {
253 outStream << " ";
254 }
255 theIndex -= (int)baseIndex;
256 //coverity[RW.CONSTEVAL_CALL_NONCONSTANT:FALSE]
257 outStream << std::format("{:>10} {:>3} {:>3} {:>3} {:>3} {:>3} {:>10.5g}",
258 theIndex.value(),
259 subIndex,
260 lyrIndex,
261 regIndex,
262 etaIndex,
263 phiIndex,
264 theEnergy);
265 theCtr++;
266 if ( (isTerminated = ( theCtr % m_nCols )) == 0 )
267 {
268 outStream << '\n';
269 }
270 }
271 }
272 if ( ! isTerminated ) outStream << '\n';
273 this->closeElement(outStream);
274 // write container tag
275 outStream << "<!-- TBXMLCaloCellWriterTool: end write cell container "
276 << m_includedCalos[i] << " -->" << '\n';
277 }
278
279 return StatusCode::SUCCESS;
280}
281
283// Run File Writer //
285
286StatusCode
287TBXMLCaloCellWriterTool::writeRunFiles(const std::string& fileDir,
288 unsigned int runNumber)
289{
290
292 // Write Dictionary //
294
295 std::ofstream thisFileStream(std::format("{}/geom.{:06}.xml", fileDir, runNumber));
296
297 // Document type
298 std::vector<std::string> theRunElements;
299 theRunElements.push_back("FCalGeomTable*");
300 this->openDictionary(thisFileStream,"FCalGeomTable",theRunElements);
301 std::vector<std::string> theRunAttr;
302 theRunAttr.push_back("name CDATA #REQUIRED");
303 this->addAttributes(thisFileStream,"FCalGeomTable",theRunAttr);
304
305 // FCal geometry table
306 std::vector<std::string> anyData;
307 anyData.push_back("ANY");
308 this->addDictElement(thisFileStream,"FCalGeomTable",anyData);
309 std::vector<std::string> theGeomAttr;
310 theGeomAttr.push_back("name CDATA #REQUIRED");
311 this->addAttributes(thisFileStream,"FCalGeomTable",theGeomAttr);
312
313 // close dictionary
314 this->closeDictionary(thisFileStream);
315
317 // Write Run Geometry //
319
321 const CaloDetDescrManager* caloDetMgr = *caloMgrHandle;
322 ATH_CHECK( detStore()->retrieve (caloDetMgr, "CaloMgr") );
323
324 IdentifierHash firstIndex, lastIndex, safeIndex;
325 m_idHelper->calo_cell_hash_range((int)CaloCell_ID::LARFCAL,
326 firstIndex, lastIndex);
327 safeIndex = firstIndex;
328
329 // open element
330 std::vector<std::string> theRunValues(theRunAttr.size());
331 for ( unsigned int i=0; i<theRunAttr.size(); i++ )
332 {
333 if ( (theRunAttr[i]).find("name") != std::string::npos )
334 {
335 theRunValues[i] = "FCalMod0";
336 theRunAttr[i] =
337 theRunAttr[i].substr(0,theRunAttr[i].find_first_of(' '));
338 }
339 }
340 this->openElement(thisFileStream,"FCalGeomTable",theRunAttr,theRunValues);
341 theRunValues[0] = "FCalCells";
342 this->openElement(thisFileStream,"FCalGeomTable",theRunAttr,theRunValues);
343 thisFileStream << "<!-- 32-bit Id"
344 << " Module# "
345 << " EtaIndex "
346 << " PhiIndex "
347 << " X [cm] "
348 << " Y [cm] "
349 << " Z [cm] "
350 << " TileSize "
351 << "-->\n";
352
353 // find big/small tile indicator -> to be replaced
354 std::unordered_map<int, double> smallestDx;
355 smallestDx.reserve(8); // usually only 3-4 sub-calos
356
357 for (unsigned int iCtr = safeIndex; iCtr <= lastIndex; ++iCtr)
358 {
359 const Identifier theId = m_idHelper->cell_id(IdentifierHash(iCtr));
360 const int theCalo = m_idHelper->sub_calo(theId);
361
362 const CaloDetDescrElement* theElement = caloDetMgr->get_element(IdentifierHash(iCtr));
363 const double dx = theElement->dx();
364
365 // One-lookup minimum update (very fast)
366 auto [it, inserted] = smallestDx.try_emplace(theCalo, dx);
367 if (!inserted && dx < it->second)
368 it->second = dx;
369 }
370
371 // get geometry
372 for (unsigned int iCtr=(unsigned int)firstIndex;
373 iCtr<=(unsigned int)lastIndex; iCtr++ )
374 {
375 IdentifierHash theIndex(iCtr);
376 // get identifiers
377 Identifier theId = m_idHelper->cell_id(theIndex);
378 int theModule = m_idHelper->sampling(theId);
379 int theEta = m_idHelper->eta(theId);
380 int thePhi = m_idHelper->phi(theId);
381 int theCalo = m_idHelper->sub_calo(theId);
382 // get geometry
383 const CaloDetDescrElement* theElement =
384 caloDetMgr->get_element(theIndex);
385 double theX = theElement->x();
386 double theY = theElement->y();
387 double theZ = theElement->z();
388 // check tile size
389 double dx = theElement->dx();
390 int tileSize = dx > 1.1*smallestDx[theCalo] ? 1 : 0;
391
392 // write out
393 thisFileStream << " "
394 << std::setw(10)
395 << std::setfill(' ') << iCtr-(unsigned int)firstIndex
396 << " "
397 << std::setw(2) << std::setfill(' ') << theModule
398 << " "
399 << std::setw(2) << std::setfill(' ') << theEta
400 << " "
401 << std::setw(2) << std::setfill(' ') << thePhi
402 << " "
403 << std::setw(10) << std::setprecision(5) << theX << " "
404 << std::setw(10) << std::setprecision(5) << theY << " "
405 << std::setw(10) << std::setprecision(5) << theZ << " "
406 << " "
407 << std::setw(2) << std::setfill(' ') << tileSize
408 << '\n';
409 }
410 ATH_CHECK(this->finalize(thisFileStream));
411 thisFileStream.close();
412
413 return StatusCode::SUCCESS;
414}
415
416StatusCode
418{
419 // messaging
420 MsgStream log(msgSvc(),name());
421
422 // get calo id helper
423 ATH_CHECK( detStore()->retrieve (m_idHelper, "CaloCell_ID") );
424
426 // Get Calo Indices //
428
429 std::vector<std::string>::iterator firstCalo = m_includedCalos.begin();
430 std::vector<std::string>::iterator lastCalo = m_includedCalos.end();
431 while ( firstCalo != lastCalo )
432 {
433 if ( *firstCalo == "LAREM" )
434 {
436 ++firstCalo;
437 }
438 else if ( *firstCalo == "LARHEC" )
439 {
441 ++firstCalo;
442 }
443 else if ( *firstCalo == "LARFCAL" )
444 {
446 ++firstCalo;
447 }
448 else if ( *firstCalo == "TILE" )
449 {
451 ++firstCalo;
452 }
453 else
454 {
455 firstCalo = m_includedCalos.erase(firstCalo);
456 }
457 }
458
460 // Get CaloSamplings //
462
463 // nasty (no switch on string types...)
464 for (const std::string& sample : m_includedSamplings)
465 {
466 // H8 calos
467 if ( sample == "PreSamplerB" )
468 m_caloSamplings.push_back(CaloSampling::PreSamplerB);
469 if ( sample == "EMB0" )
470 m_caloSamplings.push_back(CaloSampling::EMB1);
471 if ( sample == "EMB1" )
472 m_caloSamplings.push_back(CaloSampling::EMB2);
473 if ( sample == "EMB2" )
474 m_caloSamplings.push_back(CaloSampling::EMB3);
475 if ( sample == "TileBar0" )
476 m_caloSamplings.push_back(CaloSampling::TileBar0);
477 if ( sample == "TileBar1" )
478 m_caloSamplings.push_back(CaloSampling::TileBar0);
479 if ( sample == "TileBar2" )
480 m_caloSamplings.push_back(CaloSampling::TileBar0);
481 if ( sample == "TileExt0" )
482 m_caloSamplings.push_back(CaloSampling::TileExt0);
483 if ( sample == "TileExt1" )
484 m_caloSamplings.push_back(CaloSampling::TileExt1);
485 if ( sample == "TileExt2" )
486 m_caloSamplings.push_back(CaloSampling::TileExt2);
487
488 // H6 calos
489 if ( sample == "EME1" )
490 m_caloSamplings.push_back(CaloSampling::EME1);
491 if ( sample == "EME2" )
492 m_caloSamplings.push_back(CaloSampling::EME2);
493 if ( sample == "HEC0" )
494 m_caloSamplings.push_back(CaloSampling::HEC0);
495 if ( sample == "HEC1" )
496 m_caloSamplings.push_back(CaloSampling::HEC1);
497 if ( sample == "HEC2" )
498 m_caloSamplings.push_back(CaloSampling::HEC2);
499 if ( sample == "HEC3" )
500 m_caloSamplings.push_back(CaloSampling::HEC3);
501 if ( sample == "FCAL0" )
502 m_caloSamplings.push_back(CaloSampling::FCAL0);
503 if ( sample == "FCAL1" )
504 m_caloSamplings.push_back(CaloSampling::FCAL1);
505 if ( sample == "FCAL2" )
506 m_caloSamplings.push_back(CaloSampling::FCAL2);
507 }
508
509 return m_caloSamplings.size() == 0 && m_caloIndices.size() == 0
510 ? StatusCode::FAILURE
511 : StatusCode::SUCCESS;
512}
513
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
Definition of CaloDetDescrManager.
#define deg
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
const ServiceHandle< StoreGateSvc > & detStore() const
Container class for CaloCell.
CaloCellContainer::const_iterator beginConstCalo(CaloCell_ID::SUBCALO caloNum) const
get const iterators on cell of just one calo
CaloCellContainer::const_iterator endConstCalo(CaloCell_ID::SUBCALO caloNum) const
int nCellsCalo(const CaloCell_ID::SUBCALO caloNum) const
get number of cels of given calorimeter
This class groups all DetDescr information related to a CaloCell.
CaloCell_ID::CaloSample getSampling() const
cell sampling
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
This class provides the client interface for accessing the detector description information common to...
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
This is a "hash" representation of an Identifier.
constexpr value_type value() const
std::vector< std::string > m_includedSamplings
virtual StatusCode writeRunFiles(const std::string &fileDir, unsigned int runNumber) override
TBXMLCaloCellWriterTool(const std::string &type, const std::string &name, const IInterface *parent)
tool constructor
virtual StatusCode initialize() override
static const unsigned int m_nCols
std::unordered_set< EventIDBase::number_type > m_runNumbers
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
std::vector< std::string > m_includedCalos
virtual StatusCode writeEvent(std::ostream &outFile, std::string_view) override
virtual StatusCode convertProperties()
std::vector< CaloCell_ID::SUBCALO > m_caloIndices
std::vector< CaloSampling::CaloSample > m_caloSamplings
virtual void openDictionary(std::ostream &outStream, const std::string &dictName, const std::vector< std::string > &listOfElements)
TBXMLWriterToolBase(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode finalize() override
virtual void closeElement(std::ostream &outStream, const std::string &theElement)
virtual void addDictElement(std::ostream &outStream, const std::string &theElement, const std::vector< std::string > &listOfElements)
virtual void closeDictionary(std::ostream &outStream)
virtual void openElement(std::ostream &outStream, std::string_view theElement, const std::vector< std::string > &listOfAttr, const std::vector< std::string > &listOfValues)
virtual void addAttributes(std::ostream &outStream, const std::string &theElement, const std::vector< std::string > &listOfAttributes)
virtual StatusCode initialize() override
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140