ATLAS Offline Software
gFexTower2SCellDecorator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //***************************************************************************
6 // gFexTower2SCellDecorator - description
7 // -------------------
8 // This reentrant algorithm is meant to decorate the gFEX Towers (input data and simulation) with the corresponding matching set of SuperCell from LAr
9 // Information about SCellContainer objetcs are in:
10 // - https://gitlab.cern.ch/atlas/athena/-/blob/22.0/Calorimeter/CaloEvent/CaloEvent/CaloCell.h
11 //
12 // begin : 27 01 2023
13 // email : cecilia.tosciri@cern.ch
14 //***************************************************************************/
15 
16 
19 
20 #include <iostream>
21 #include <fstream>
22 #include <sstream>
23 #include <algorithm>
24 #include <stdio.h>
25 
26 namespace LVL1 {
27 
29 
31  ATH_MSG_INFO( "L1CaloFEXTools/gFexTower2SCellDecorator::initialize()");
33  ATH_CHECK( m_triggerTowerKey.initialize() );
34  ATH_CHECK( m_gTowersReadKey.initialize() );
35  ATH_CHECK( m_gSCellEtdecorKey.initialize() );
36  ATH_CHECK( m_gSCellEtadecorKey.initialize() );
37  ATH_CHECK( m_gSCellPhidecorKey.initialize() );
38  ATH_CHECK( m_gSCellIDdecorKey.initialize() );
39  ATH_CHECK( m_gSCellSampledecorKey.initialize() );
40  ATH_CHECK( m_gtowerEtMeVdecorKey.initialize() );
41  ATH_CHECK( m_gTowerEtdecorKey.initialize() );
42  ATH_CHECK( m_gTileEtMeVdecorKey.initialize() );
43  ATH_CHECK( m_gTileEtadecorKey.initialize() );
44  ATH_CHECK( m_gTilePhidecorKey.initialize() );
45  ATH_CHECK( m_gTileIDdecorKey.initialize() );
46 
47 
48  //Reading from CVMFS Trigger Tower and their corresponding SCell ID
51 
52  return StatusCode::SUCCESS;
53 }
54 
55 StatusCode gFexTower2SCellDecorator::execute(const EventContext& ctx) const {
56 
57  //Reading the Scell container
58  SG::ReadHandle<CaloCellContainer> ScellContainer(m_SCellKey, ctx);
59  if(!ScellContainer.isValid()) {
60  ATH_MSG_FATAL("Could not retrieve collection " << ScellContainer.key() );
61  return StatusCode::FAILURE;
62  }
63 
64  // Reading the TriggerTower container
66  if(!triggerTowerContainer.isValid()) {
67  ATH_MSG_FATAL("Could not retrieve collection " << triggerTowerContainer.key() );
68  return StatusCode::FAILURE;
69  }
70 
71  //Reading the gTower container
73  if(!gTowerContainer.isValid()) {
74  ATH_MSG_FATAL("Could not retrieve collection " << gTowerContainer.key() );
75  return StatusCode::FAILURE;
76  }
77 
78  if(ScellContainer->empty() || triggerTowerContainer->empty() || gTowerContainer->empty() ){
79  ATH_MSG_WARNING("Nothing to decorate here, at least one container is empty. ScellContainer.size="<<ScellContainer->size() << " or gTowerContainer.size=" << gTowerContainer->size() << " or triggerTowerContainer.size=" << triggerTowerContainer->size() );
80  return StatusCode::SUCCESS;
81  }
82 
83  // building Scell ID pointers
84  std::unordered_map< uint64_t, const CaloCell*> map_ScellID2ptr;
85 
86  for(const CaloCell* scell : *ScellContainer){
87  const uint64_t ID = scell->ID().get_compact();
88  map_ScellID2ptr[ID] = scell;
89  }
90 
91  // building Tile ID pointers
92  std::unordered_map< uint32_t, const xAOD::TriggerTower*> map_TileID2ptr;
93 
94  for(const xAOD::TriggerTower* tower : *triggerTowerContainer){
95 
96  // keeping just
97  if(std::abs(tower->eta())>1.5 || tower->sampling()!=1) continue;
98  map_TileID2ptr[tower->coolId()]=tower;
99  }
100 
101  //Setup Decorator Handlers
113 
114  //looping over the gTowers to decorate them
115  for(const xAOD::gFexTower* gTower : *gTowerContainer){
116 
117  uint32_t gFexID = gTower->gFEXtowerID();
118  uint16_t gFexEt = gTower->towerEt();
119  uint16_t scSumEtEncoded = 0;
120 
121  std::vector<float> scEt;
122  std::vector<float> scEta;
123  std::vector<float> scPhi;
124  std::vector<int> scID;
125  std::vector<int> scSample;
126 
127  std::vector<int> TileEt;
128  std::vector<float> TileEta;
129  std::vector<float> TilePhi;
130  std::vector<int> TileID;
131 
132  //check that the gFEX Tower ID exists in the map
133  auto it_TTower2SCells = (m_map_TTower2SCells).find(gFexID);
134  if(it_TTower2SCells == (m_map_TTower2SCells).end()) {
135  ATH_MSG_ERROR("ID: "<<gFexID<< " not found on map m_map_TTower2SCells");
136  return StatusCode::FAILURE;
137  }
138 
139  for (auto const& SCellID : it_TTower2SCells->second ) {
140 
141  //check that the SCell Identifier exists in the map
142  auto it_ScellID2ptr = map_ScellID2ptr.find(SCellID);
143  if(it_ScellID2ptr == map_ScellID2ptr.end()) {
144  ATH_MSG_WARNING("Scell ID: 0x"<<std::hex<<(SCellID >> 32)<<std::dec<< " not found on map map_ScellID2ptr");
145 
146  scEt.push_back(-9999);
147  scEta.push_back(-99);
148  scPhi.push_back(-99);
149  // bit shifting to get only a 32 bit number
150  scID.push_back( SCellID >> 32 );
151  scSample.push_back(-99);
152 
153  }
154 
155  else{
156 
157  const CaloCell* myCell = it_ScellID2ptr->second;
158  float et = myCell->et();
159  const CaloSampling::CaloSample sample = (myCell)->caloDDE()->getSampling();
160 
161 
162  // The following is to check if any SuperCells from data are permanently masked, and if so the masking is applied
163  int prov = (myCell)->provenance();
164  int SCprov = prov&0xFFF;
165  bool isMasked = (SCprov&0x80)==0x80;//prov looks like 0000 0000 1000 0000 if the cell is masked
166  if (isMasked) et=0;
167 
168  scEt.push_back(et);
169  scEta.push_back(myCell->eta());
170  scPhi.push_back(myCell->phi());
171  // bit shifting to get only a 32 bit number
172  scID.push_back( SCellID >> 32 );
173  scSample.push_back(sample);
174 
175  }
176  }
177 
178  //emulated encoded Et
179  float tmpSCellEt = 0;
180  for(const auto& tmpet : scEt){
181  tmpSCellEt += tmpet;
182  }
183 
184  scSumEtEncoded = gFEXCompression::compress( tmpSCellEt );
185 
186  // Decorating the tower with the corresponding information
187  gTowerSCellEt (*gTower) = std::move(scEt);
188  gTowerSCellEta (*gTower) = std::move(scEta);
189  gTowerSCellPhi (*gTower) = std::move(scPhi);
190  gTowerSCellID (*gTower) = std::move(scID);
191  gTowerSCellSample (*gTower) = std::move(scSample);
192  gTowerEtMeV (*gTower) = gFexEt * 200;
193  gTowerSCEtEncoded (*gTower) = scSumEtEncoded;
194 
195 
196  auto it_TTower2Tile = (m_map_TTower2Tile).find(gFexID);
197  //check that the gFEX Tower ID exists in the map
198  if(it_TTower2Tile == (m_map_TTower2Tile).end()) {
199  continue;
200  }
201 
202  for (auto const& TileTowerID : it_TTower2Tile->second ) {
203 
204  //check that the Tile Identifier exists in the map
205  auto it_TileID2ptr = map_TileID2ptr.find(TileTowerID);
206  if(it_TileID2ptr == map_TileID2ptr.end()) {
207 
208  ATH_MSG_WARNING("Tile ID: "<<TileID<<std::dec<< " not found on map map_TileID2ptr");
209 
210  TileEt.push_back(-9999);
211  TileEta.push_back(-99);
212  TilePhi.push_back(-99);
213  TileID.push_back(-99);
214  }
215  else{
216 
217  const xAOD::TriggerTower* tileTower = it_TileID2ptr->second;
218  TileEt.push_back(tileTower->jepET()*1000); //1000 is the Tile energy resolution
219  TileEta.push_back(tileTower->eta());
220  float phi = tileTower->phi() < M_PI ? tileTower->phi() : tileTower->phi()-2*M_PI;
221  TilePhi.push_back(phi);
222  TileID.push_back(TileTowerID);
223 
224  }
225 
226 
227  }
228 
229 
230  // Decorating the tower with the corresponding information
231  gTowerTileEt (*gTower) = std::move(TileEt);
232  gTowerTileID (*gTower) = std::move(TileID);
233  gTowerTileEta (*gTower) = std::move(TileEta);
234  gTowerTilePhi (*gTower) = std::move(TilePhi);
235  }
236 
237  // Return gracefully
238  return StatusCode::SUCCESS;
239 }
240 
241 
243 
244  std::string myline;
245  //open file with ifstream
246  std::ifstream myfile(fileName);
247 
248  if ( !myfile.is_open() ){
249  ATH_MSG_FATAL("Could not open file:" << fileName);
250  return StatusCode::FAILURE;
251  }
252 
253  //loading the mapping information into an unordered_map <Fex Tower ID, vector of SCell IDs>
254  while ( std::getline (myfile, myline) ) {
255  std::vector<uint64_t> SCellvector;
256  SCellvector.clear();
257 
258  //removing the header of the file (it is just information!)
259  myline.erase(myline.begin(), std::find_if(myline.begin(), myline.end(), [](int ch) {
260  return !std::isspace(ch);
261  }));
262  if(myline[0] == '#') continue;
263 
264  //Splitting myline in different substrings
265  std::stringstream oneSCellID(myline);
266 
267  //reading elements
268  std::string substr = "";
269  int TTID = 0;
270  int elem = 0;
271 
272  while(std::getline(oneSCellID, substr, ' '))
273  {
274  ++elem;
275  if(elem == 1){
276  TTID = std::stoi(substr);
277  }
278  else{
279  //Check if it looks like a SCell Identifier
280  if(isBadSCellID(substr)){
281  return StatusCode::FAILURE;
282  }
283 
284  // converts hex number to unsigned long long int
285  uint64_t scid_uint64 = std::strtoull(substr.c_str(), nullptr, 0);
286 
287  //empty slots are filled with 0xffffffffffffffff
288  if(scid_uint64 == 0xffffffffffffffff) continue;
289 
290  SCellvector.push_back(scid_uint64);
291  }
292  }
293 
294  m_map_TTower2SCells[TTID] = std::move(SCellvector);
295 
296  }
297  myfile.close();
298 
299  return StatusCode::SUCCESS;
300 }
301 
302 bool gFexTower2SCellDecorator::isBadSCellID(const std::string& ID) const{
303 
304  // does it start with "0x"?, if so then is a GOOD SCell ID!
305  if (ID.find("0x") == std::string::npos) {
306  ATH_MSG_ERROR("Invalid SuperCell ID " << ID << ". Expecting hexadecimal number on the mapping file");
307  return true;
308  }
309  return false;
310 }
311 
312 
314 
315  std::string myline;
316 
317  //openning file with ifstream
318  std::ifstream myfile(fileName);
319 
320  if ( !myfile.is_open() ){
321  ATH_MSG_FATAL("Could not open file:" << fileName);
322  return StatusCode::FAILURE;
323  }
324 
325  //loading the mapping information into an unordered_map <Fex Tower ID, vector of SCell IDs>
326  while ( std::getline (myfile, myline) ) {
327 
328  std::vector<uint32_t> Tilevector;
329  Tilevector.clear();
330  //removing the header of the file
331  myline.erase(myline.begin(), std::find_if(myline.begin(), myline.end(), [](int ch) {
332  return !std::isspace(ch);
333  }));
334  if(myline[0] == '#') continue;
335 
336  //Splitting myline in different substrings
337  std::stringstream oneTileID(myline);
338 
339  //reading elements
340  std::string substr = "";
341  int gTowerID = 0;
342  int elem = 0;
343 
344  while(std::getline(oneTileID, substr, ' ')){
345  ++elem;
346  if(elem == 1){
347  gTowerID = std::stoi(substr);
348  }
349  else{
350  uint32_t tileid_uint32 = std::strtoul(substr.c_str(), nullptr, 0);
351  Tilevector.push_back(tileid_uint32);
352  }
353  }
354 
355  m_map_TTower2Tile[gTowerID] = std::move(Tilevector);
356 
357  }
358  myfile.close();
359 
360  return StatusCode::SUCCESS;
361 }
362 
363 
364 
365 
366 
367 }
PathResolver::find_calib_file
static std::string find_calib_file(const std::string &logical_file_name)
Definition: PathResolver.cxx:384
LVL1::gFexTower2SCellDecorator::ReadSCfromFile
StatusCode ReadSCfromFile(const std::string &)
Definition: gFexTower2SCellDecorator.cxx:242
et
Extra patterns decribing particle interation process.
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
CaloCell::phi
virtual double phi() const override final
get phi (through CaloDetDescrElement)
Definition: CaloCell.h:359
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ID
std::vector< Identifier > ID
Definition: CalibHitIDCheck.h:24
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
xAOD::TriggerTower_v2::phi
virtual double phi() const final
The azimuthal angle ( ) of the particle.
Definition: TriggerTower_v2.cxx:222
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
LVL1::gFEXCompression::compress
static unsigned int compress(float Energy)
Compress data.
Definition: gFEXCompression.cxx:20
LVL1::gFexTower2SCellDecorator::m_gSCellIDdecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gSCellIDdecorKey
Definition: gFexTower2SCellDecorator.h:52
LVL1::gFexTower2SCellDecorator::m_gFEX2Tilemapping
Gaudi::Property< std::string > m_gFEX2Tilemapping
Definition: gFexTower2SCellDecorator.h:64
LVL1::gTower
The gTower class is an interface object for gFEX trigger algorithms The purposes are twofold:
Definition: gTower.h:38
M_PI
#define M_PI
Definition: ActiveFraction.h:11
LVL1::gFexTower2SCellDecorator::m_gTileIDdecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gTileIDdecorKey
Definition: gFexTower2SCellDecorator.h:59
gFexTower2SCellDecorator.h
LVL1::gFexTower2SCellDecorator::m_gSCellEtdecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gSCellEtdecorKey
Definition: gFexTower2SCellDecorator.h:49
LVL1::gFexTower2SCellDecorator::m_gTowersReadKey
SG::ReadHandleKey< xAOD::gFexTowerContainer > m_gTowersReadKey
Definition: gFexTower2SCellDecorator.h:46
LVL1
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
Definition: ICMMCPHitsCnvTool.h:18
LVL1::gFexTower2SCellDecorator::initialize
virtual StatusCode initialize() override
Function initialising the algorithm.
Definition: gFexTower2SCellDecorator.cxx:30
gFEXCompression.h
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
LVL1::gFexTower2SCellDecorator::m_gSCellPhidecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gSCellPhidecorKey
Definition: gFexTower2SCellDecorator.h:51
LVL1::gFexTower2SCellDecorator::m_gtowerEtMeVdecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gtowerEtMeVdecorKey
Definition: gFexTower2SCellDecorator.h:54
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:113
LVL1::gFexTower2SCellDecorator::m_gTileEtMeVdecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gTileEtMeVdecorKey
Definition: gFexTower2SCellDecorator.h:56
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
TileID
Helper class for TileCal offline identifiers.
Definition: TileID.h:68
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
LVL1::gFexTower2SCellDecorator::m_gTowerEtdecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gTowerEtdecorKey
Definition: gFexTower2SCellDecorator.h:55
xAOD::TriggerTower_v2
Description of TriggerTower_v2.
Definition: TriggerTower_v2.h:49
xAOD::TriggerTower_v2::eta
virtual double eta() const final
The pseudorapidity ( ) of the particle.
Definition: TriggerTower_v2.cxx:210
CaloCell::et
virtual double et() const override final
get et
Definition: CaloCell.h:407
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::gFexTower_v1
Class describing input data of a LVL1 eFEX.
Definition: gFexTower_v1.h:22
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
LVL1::gFexTower2SCellDecorator::m_gTileEtadecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gTileEtadecorKey
Definition: gFexTower2SCellDecorator.h:57
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
LVL1::gTowerContainer
Definition: gTowerContainer.h:25
TrigConf::name
Definition: HLTChainList.h:35
LVL1::gFexTower2SCellDecorator::isBadSCellID
bool isBadSCellID(const std::string &) const
Definition: gFexTower2SCellDecorator.cxx:302
SG::VarHandleBase::key
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:64
LVL1::gFexTower2SCellDecorator::m_gSCellSampledecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gSCellSampledecorKey
Definition: gFexTower2SCellDecorator.h:53
LVL1::gFexTower2SCellDecorator::execute
virtual StatusCode execute(const EventContext &) const override
Function executing the algorithm.
Definition: gFexTower2SCellDecorator.cxx:55
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
LVL1::gFexTower2SCellDecorator::m_map_TTower2Tile
std::unordered_map< uint32_t, std::vector< uint32_t > > m_map_TTower2Tile
Definition: gFexTower2SCellDecorator.h:71
LVL1::gFexTower2SCellDecorator::m_gSCellEtadecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gSCellEtadecorKey
Definition: gFexTower2SCellDecorator.h:50
LVL1::gFexTower2SCellDecorator::ReadTilefromFile
StatusCode ReadTilefromFile(const std::string &)
Definition: gFexTower2SCellDecorator.cxx:313
LVL1::gFexTower2SCellDecorator::m_triggerTowerKey
SG::ReadHandleKey< xAOD::TriggerTowerContainer > m_triggerTowerKey
Definition: gFexTower2SCellDecorator.h:41
LVL1::gFexTower2SCellDecorator::m_map_TTower2SCells
std::unordered_map< uint32_t, std::vector< uint64_t > > m_map_TTower2SCells
Definition: gFexTower2SCellDecorator.h:70
LVL1::gFexTower2SCellDecorator::m_gTilePhidecorKey
SG::WriteDecorHandleKey< xAOD::gFexTowerContainer > m_gTilePhidecorKey
Definition: gFexTower2SCellDecorator.h:58
LVL1::gFexTower2SCellDecorator::m_gFEX2Scellmapping
Gaudi::Property< std::string > m_gFEX2Scellmapping
Definition: gFexTower2SCellDecorator.h:63
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::TriggerTower_v2::jepET
uint8_t jepET() const
get jepET from peak of lut_jep
Definition: TriggerTower_v2.cxx:186
LVL1::gFexTower2SCellDecorator::m_SCellKey
SG::ReadHandleKey< CaloCellContainer > m_SCellKey
Definition: gFexTower2SCellDecorator.h:38
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
CaloCell::eta
virtual double eta() const override final
get eta (through CaloDetDescrElement)
Definition: CaloCell.h:366
LVL1::gFexTower2SCellDecorator::gFexTower2SCellDecorator
gFexTower2SCellDecorator(const std::string &name, ISvcLocator *svc)
Definition: gFexTower2SCellDecorator.cxx:28