ATLAS Offline Software
jFexEmulatedTowers.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //***************************************************************************
6 // jFexEmulatedTowers - description
7 // -------------------
8 // This reentrant algorithm is meant build jFEX Towers from LAr and Tile
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 : 01 11 2022
13 // email : sergi.rodriguez@cern.ch
14 //***************************************************************************/
15 
16 
17 #include "jFexEmulatedTowers.h"
19 
20 #include <iostream>
21 #include <fstream>
22 #include <sstream>
23 #include <algorithm>
24 #include <string>
25 #include <stdio.h>
26 
27 namespace LVL1 {
28 
30 
32 
33  ATH_MSG_INFO( "Initializing L1CaloFEXAlgos/jFexEmulatedTowers algorithm with name: "<< name());
34  ATH_MSG_INFO( "Writting into SG key: "<< m_jTowersWriteKey);
35  ATH_MSG_INFO( "SCell masking: "<< m_apply_masking);
36  ATH_MSG_INFO( "Thinnig towers: "<< m_doThinning);
37 
39  ATH_CHECK( m_triggerTowerKey.initialize() );
40  ATH_CHECK( m_jTowersWriteKey.initialize() );
41 
42 
43  //Reading from CVMFS Fiber mapping
45 
46  //Reading from CVMFS Trigger Tower and their corresponding SCell ID
49 
50  return StatusCode::SUCCESS;
51 }
52 
53 StatusCode jFexEmulatedTowers::execute(const EventContext& ctx) const {
54 
55  //Reading the Scell container
56  SG::ReadHandle<CaloCellContainer> ScellContainer(m_SCellKey, ctx);
57  if(!ScellContainer.isValid()) {
58  ATH_MSG_ERROR("Could not retrieve collection " << ScellContainer.key() );
59  return StatusCode::FAILURE;
60  }
61 
62  //Reading the TriggerTower container
64  if(!triggerTowerContainer.isValid()) {
65  ATH_MSG_ERROR("Could not retrieve collection " << triggerTowerContainer.key() );
66  return StatusCode::FAILURE;
67  }
68 
69  //WriteHandle for jFEX EDMs
70  //---jTower EDM
72  ATH_CHECK(jTowersContainer.record(std::make_unique<xAOD::jFexTowerContainer>(), std::make_unique<xAOD::jFexTowerAuxContainer>()));
73  ATH_MSG_DEBUG("Recorded jFexEmulatedTower container with key " << jTowersContainer.key());
74 
75  if(ScellContainer->empty() || triggerTowerContainer->empty() ){
76  ATH_MSG_WARNING("Cannot fill jTowers here, at least one container is empty. ScellContainer.size="<<ScellContainer->size() << " or triggerTowerContainer.size=" << triggerTowerContainer->size() );
77  return StatusCode::SUCCESS;
78  }
79 
80  // building Scell ID pointers
81  std::unordered_map< uint64_t, const CaloCell*> map_ScellID2ptr;
82 
83  for(const CaloCell* scell : *ScellContainer){
84  const uint64_t ID = scell->ID().get_compact();
85  map_ScellID2ptr[ID] = scell;
86  }
87 
88  // building Tile ID pointers
89  std::unordered_map< uint32_t, const xAOD::TriggerTower*> map_TileID2ptr;
90 
91  for(const xAOD::TriggerTower* tower : *triggerTowerContainer){
92 
93  // keeping just tile information
94  if(std::abs(tower->eta())>1.5 || tower->sampling()!=1) continue;
95 
96  map_TileID2ptr[tower->coolId()]=tower;
97  }
98 
99 
100  for( const auto& [key, element] : m_Firm2Tower_map){
101 
102  unsigned int jfex = (key >> 16) & 0xf;
103  unsigned int fpga = (key >> 12) & 0xf;
104  unsigned int channel = (key >> 4 ) & 0xff;
105  unsigned int tower = (key >> 0 ) & 0xf;
106 
107  const auto [f_IDSimulation, eta, phi, f_source, f_iEta, f_iPhi] = element;
108 
109  //elements that need to be casted
110  unsigned int IDSimulation = static_cast<int>(f_IDSimulation);
111  unsigned int source = static_cast<int>(f_source);
112  unsigned int iEta = static_cast<int>(f_iEta);
113  unsigned int iPhi = static_cast<int>(f_iPhi);
114 
115 
116  uint16_t Total_Et_encoded = 0;
117  char jTower_sat = 0;
118 
119  if( source != 1 ){
120 
121  const std::unordered_map< uint32_t, std::vector<uint64_t> > * ptr_TTower2Cells;
122 
123  //HAD layer for HEC, FCAL2 and FCAL3
124  if(source == 3 or source > 4){
125  ptr_TTower2Cells = &m_map_TTower2SCellsHAD;
126  }
127  else{
128  ptr_TTower2Cells = &m_map_TTower2SCellsEM;
129  }
130 
131  //check that the jFEX Tower ID exists in the map
132  auto it_TTower2SCells = (*ptr_TTower2Cells).find(IDSimulation);
133  if(it_TTower2SCells == (*ptr_TTower2Cells).end()) {
134  ATH_MSG_ERROR("jFEX ID: "<<IDSimulation<< " not found on map m_map_TTower2SCellsEM/HAD");
135  return StatusCode::FAILURE;
136  }
137 
138  float Total_Et = 0;
139  unsigned int countMasked = 0;
140  for (auto const& SCellID : it_TTower2SCells->second ) {
141 
142  //check that the SCell Identifier exists in the map
143  auto it_ScellID2ptr = map_ScellID2ptr.find(SCellID);
144  if(it_ScellID2ptr == map_ScellID2ptr.end()) {
145  if(m_isDATA) ATH_MSG_DEBUG("Scell ID: 0x"<<std::hex<< (SCellID >> 32) <<std::dec<< " not found in the CaloCell Container, skipping");
146  continue;
147  }
148 
149  const CaloCell* myCell = it_ScellID2ptr->second;
150 
151  float et = myCell->et();
152  if( (myCell->provenance() >> 7 & 0x1) and m_apply_masking ) {
153  //if masked then Et = 0
154  et = 0.0;
155  countMasked++;
156  }
157 
158  if(myCell->quality() == 1){
159  jTower_sat = 1;
160  }
161 
162  Total_Et += et;
163 
164  }
165 
166  Total_Et_encoded = jFEXCompression::Compress( Total_Et, countMasked == (it_TTower2SCells->second).size() ? true : false );
167 
168  }
169  else{
170 
171  //check that the jFEX Tower ID exists in the map
172  auto it_TTower2Tile = m_map_TTower2Tile.find(IDSimulation);
173  if(it_TTower2Tile == m_map_TTower2Tile.end()) {
174  ATH_MSG_ERROR("ID: "<<IDSimulation<< " not found on map m_map_TTower2Tile");
175  return StatusCode::FAILURE;
176  }
177 
178  uint32_t TileID = std::get<0>( it_TTower2Tile->second );
179 
180  //check that the Tile Identifier exists in the map
181  auto it_TileID2ptr = map_TileID2ptr.find(TileID);
182  if(it_TileID2ptr == map_TileID2ptr.end()) {
183  if(m_isDATA) ATH_MSG_WARNING("Tile cool ID: "<<TileID<< " not found in the xAOD::TriggerTower, skipping");
184  continue;
185  }
186  else{
187  Total_Et_encoded = (it_TileID2ptr->second)->cpET();
188  }
189  }
190 
191  std::vector<uint16_t> vtower_ET;
192  vtower_ET.clear();
193  vtower_ET.push_back(Total_Et_encoded);
194 
195  std::vector<char> vtower_SAT;
196  vtower_SAT.clear();
197 
198  //Needs to be updated with Saturation flag from LAr CaloCell container, not ready yet!
199  vtower_SAT.push_back(jTower_sat);
200 
201  jTowersContainer->push_back( std::make_unique<xAOD::jFexTower>() );
202  jTowersContainer->back()->initialize(eta, phi, iEta, iPhi, IDSimulation, source, vtower_ET, jfex, fpga, channel, tower, vtower_SAT );
203 
204  if( m_doThinning && !jTowersContainer->back()->isCore() ){
205  jTowersContainer->pop_back();
206  }
207  }
208 
209  // Return gracefully
210  return StatusCode::SUCCESS;
211 }
212 
213 
215 
216 
217 
218  //openning file with ifstream
219  std::ifstream file(fileName);
220 
221  if ( !file.is_open() ){
222  ATH_MSG_ERROR("Could not open file:" << fileName);
223  return StatusCode::FAILURE;
224  }
225 
226  std::string line;
227  //loading the mapping information
228  while ( std::getline (file, line) ) {
229 
230  //removing the header of the file (it is just information!)
231  if(line[0] == '#') continue;
232 
233  //Splitting line in different substrings
234  std::stringstream oneLine(line);
235 
236  //reading elements
237  std::vector<float> elements;
238  std::string element;
239  while(std::getline(oneLine, element, ' '))
240  {
241  elements.push_back(std::stof(element));
242  }
243 
244  // It should have 10 elements
245  // ordered as: jfex fpga channel towerNr source globalEtaIndex globalPhiIndex IDSimulation eta phi
246  if(elements.size() != 10){
247  ATH_MSG_ERROR("Unexpected number of elemennts (10 expected) in file: "<< fileName);
248  return StatusCode::FAILURE;
249  }
250  // building array of <IDSimulation, eta, phi, source, iEta, iPhi>
251  std::array<float,6> aux_arr{ {elements.at(7),elements.at(8),elements.at(9),elements.at(4),elements.at(5),elements.at(6)} };
252 
253  //filling the map with the hash given by mapIndex()
254  m_Firm2Tower_map[ mapIndex(elements.at(0),elements.at(1),elements.at(2),elements.at(3)) ] = aux_arr;
255 
256  }
257  file.close();
258 
259  return StatusCode::SUCCESS;
260 }
261 
262 
263 constexpr unsigned int jFexEmulatedTowers::mapIndex(unsigned int jfex, unsigned int fpga, unsigned int channel, unsigned int tower) {
264  // values from hardware: jfex=[0,5] 4 bits, fpga=[0,3] 4 bits, channel=[0,59] 8 bits, tower=[0,15] 4 bits
265  return (jfex << 16) | (fpga << 12) | (channel << 4) | tower;
266 }
267 
269 
270 
271 
272  //openning file with ifstream
273  std::ifstream file(fileName);
274 
275  if ( !file.is_open() ){
276  ATH_MSG_ERROR("Could not open file:" << fileName);
277  return StatusCode::FAILURE;
278  }
279 
280  std::string line;
281  //loading the mapping information into an unordered_map <Fex Tower ID, vector of SCell IDs>
282  while ( std::getline (file, line) ) {
283  std::vector<uint64_t> SCellvectorEM;
284  SCellvectorEM.clear();
285  std::vector<uint64_t> SCellvectorHAD;
286  SCellvectorHAD.clear();
287 
288  //removing the header of the file (it is just information!)
289  if(line[0] == '#') continue;
290 
291  //Splitting line in different substrings
292  std::stringstream oneSCellID(line);
293 
294  //reading elements
295  std::string substr = "";
296  int TTID = 0;
297  int elem = 0;
298 
299  while(std::getline(oneSCellID, substr, ' '))
300  {
301  ++elem;
302  if(elem == 1){
303  TTID = std::stoi(substr);
304  }
305  else{
306  //Check if it looks like a SCell Identifier
307  if(isBadSCellID(substr)){
308  return StatusCode::FAILURE;
309  }
310 
311  // converts hex number to unsigned long long int
312  uint64_t scid_uint64 = std::strtoull(substr.c_str(), nullptr, 0);
313 
314  //empty slots are filled with 0xffffffffffffffff
315  if(scid_uint64 == 0xffffffffffffffff) continue;
316 
317  //from element from 2 to 13 are EM SCells, element 14 is a HAD SCell
318  if(elem<14) SCellvectorEM.push_back(scid_uint64);
319  else SCellvectorHAD.push_back(scid_uint64);
320  }
321  }
322 
323  m_map_TTower2SCellsEM[TTID] = SCellvectorEM;
324  m_map_TTower2SCellsHAD[TTID] = SCellvectorHAD;
325 
326  }
327  file.close();
328 
329  return StatusCode::SUCCESS;
330 }
331 
332 bool jFexEmulatedTowers::isBadSCellID(const std::string& ID) const{
333 
334  // does it start with "0x"?, if so then is a GOOD SCell ID!
335  if (ID.find("0x") == std::string::npos) {
336  ATH_MSG_ERROR("Invalid SuperCell ID " << ID << ". Expecting hexadecimal number on the mapping file");
337  return true;
338  }
339  return false;
340 }
341 
342 
343 
344 
346 
347  //openning file with ifstream
348  std::ifstream file(fileName);
349 
350  if ( !file.is_open() ){
351  ATH_MSG_ERROR("Could not open file:" << fileName);
352  return StatusCode::FAILURE;
353  }
354 
355  std::string line;
356  //loading the mapping information into an unordered_map <Fex Tower ID, vector of SCell IDs>
357  while ( std::getline (file, line) ) {
358 
359  //removing the header of the file (it is just information!)
360  if(line[0] == '#') continue;
361 
362  //Splitting line in different substrings
363  std::stringstream oneLine(line);
364 
365  std::vector<std::string> elements;
366  std::string element = "";
367 
368  while(std::getline(oneLine, element, ' ')){
369  elements.push_back(element);
370  }
371 
372  if(elements.size() != 4){
373  ATH_MSG_ERROR("Invalid number of element in " << line << ". Expecting 4 elements {jFexID, TileID, eta, phi}");
374  return StatusCode::FAILURE;
375  }
376 
377  uint32_t jFexID = std::stoi( elements.at(0) );
378  uint32_t TileID = std::stoi( elements.at(1) );
379  float eta = std::stof( elements.at(2) );
380  float phi = std::stof( elements.at(3) );
381 
382  m_map_TTower2Tile[jFexID] = {TileID,eta,phi};
383 
384  }
385  file.close();
386 
387  return StatusCode::SUCCESS;
388 }
389 
390 
391 
392 
393 
394 }
LVL1::jFexEmulatedTowers::execute
virtual StatusCode execute(const EventContext &) const override
Function executing the algorithm.
Definition: jFexEmulatedTowers.cxx:53
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
et
Extra patterns decribing particle interation process.
checkFileSG.line
line
Definition: checkFileSG.py:75
plotting.yearwise_efficiency.channel
channel
Definition: yearwise_efficiency.py:24
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ID
std::vector< Identifier > ID
Definition: CalibHitIDCheck.h:24
xAOD::et
et
Definition: TrigEMCluster_v1.cxx:25
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
LVL1::jFexEmulatedTowers::initialize
virtual StatusCode initialize() override
Function initialising the algorithm.
Definition: jFexEmulatedTowers.cxx:31
LVL1::jFexEmulatedTowers::m_jFEX2Scellmapping
Gaudi::Property< std::string > m_jFEX2Scellmapping
Definition: jFexEmulatedTowers.h:62
LVL1::jFexEmulatedTowers::ReadTilefromFile
StatusCode ReadTilefromFile(const std::string &)
Definition: jFexEmulatedTowers.cxx:345
CaloCell::provenance
uint16_t provenance() const
get provenance (data member)
Definition: CaloCell.h:338
LVL1
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
Definition: ICMMCPHitsCnvTool.h:18
LVL1::jFexEmulatedTowers::isBadSCellID
bool isBadSCellID(const std::string &) const
Definition: jFexEmulatedTowers.cxx:332
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
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
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
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
LVL1::jFEXCompression::Compress
static unsigned int Compress(float floatEt, bool empty=false)
Compress data.
Definition: jFEXCompression.cxx:25
xAOD::TriggerTower_v2
Description of TriggerTower_v2.
Definition: TriggerTower_v2.h:49
file
TFile * file
Definition: tile_monitor.h:29
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
LVL1::jFexEmulatedTowers::jFexEmulatedTowers
jFexEmulatedTowers(const std::string &name, ISvcLocator *svc)
Definition: jFexEmulatedTowers.cxx:29
LVL1::jFexEmulatedTowers::m_Firm2Tower_map
std::unordered_map< unsigned int, std::array< float, 6 > > m_Firm2Tower_map
Definition: jFexEmulatedTowers.h:78
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
DataVector::back
const T * back() const
Access the last element in the collection as an rvalue.
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CaloCell::quality
uint16_t quality() const
get quality (data member)
Definition: CaloCell.h:332
LVL1::jFexEmulatedTowers::m_jTowersWriteKey
SG::WriteHandleKey< xAOD::jFexTowerContainer > m_jTowersWriteKey
Definition: jFexEmulatedTowers.h:51
TrigConf::name
Definition: HLTChainList.h:35
LVL1::jFexEmulatedTowers::m_map_TTower2SCellsHAD
std::unordered_map< uint32_t, std::vector< uint64_t > > m_map_TTower2SCellsHAD
Definition: jFexEmulatedTowers.h:73
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
LVL1::jFexEmulatedTowers::m_map_TTower2SCellsEM
std::unordered_map< uint32_t, std::vector< uint64_t > > m_map_TTower2SCellsEM
Definition: jFexEmulatedTowers.h:72
LVL1::jFexEmulatedTowers::m_triggerTowerKey
SG::ReadHandleKey< xAOD::TriggerTowerContainer > m_triggerTowerKey
Definition: jFexEmulatedTowers.h:48
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::jFexEmulatedTowers::m_SCellKey
SG::ReadHandleKey< CaloCellContainer > m_SCellKey
Definition: jFexEmulatedTowers.h:45
Trk::iPhi
@ iPhi
Definition: ParamDefs.h:47
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
LVL1::jFexEmulatedTowers::m_jFEX2Tilemapping
Gaudi::Property< std::string > m_jFEX2Tilemapping
Definition: jFexEmulatedTowers.h:63
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DataVector::pop_back
void pop_back()
Remove the last element from the collection.
LVL1::jFexEmulatedTowers::ReadSCfromFile
StatusCode ReadSCfromFile(const std::string &)
Definition: jFexEmulatedTowers.cxx:268
jFEXCompression.h
LVL1::jFexEmulatedTowers::m_apply_masking
Gaudi::Property< bool > m_apply_masking
Definition: jFexEmulatedTowers.h:57
copySelective.source
string source
Definition: copySelective.py:32
LVL1::jFexEmulatedTowers::m_isDATA
Gaudi::Property< bool > m_isDATA
Definition: jFexEmulatedTowers.h:58
LVL1::jFexEmulatedTowers::ReadFibersfromFile
StatusCode ReadFibersfromFile(const std::string &)
Definition: jFexEmulatedTowers.cxx:214
LVL1::jFexEmulatedTowers::m_map_TTower2Tile
std::unordered_map< uint32_t, std::tuple< uint32_t, float, float > > m_map_TTower2Tile
Definition: jFexEmulatedTowers.h:74
LVL1::jFexEmulatedTowers::m_FiberMapping
Gaudi::Property< std::string > m_FiberMapping
Definition: jFexEmulatedTowers.h:54
xAOD::iEta
setScale setgFexType iEta
Definition: gFexJetRoI_v1.cxx:77
LVL1::jFexEmulatedTowers::m_doThinning
Gaudi::Property< bool > m_doThinning
Definition: jFexEmulatedTowers.h:59
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
jFexEmulatedTowers.h
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
LVL1::jFexEmulatedTowers::mapIndex
constexpr static unsigned int mapIndex(unsigned int jfex, unsigned int fpga, unsigned int channel, unsigned int tower)
Definition: jFexEmulatedTowers.cxx:263
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37