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