ATLAS Offline Software
Loading...
Searching...
No Matches
CaloNeighbours.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5//-----------------------------------------------------------------------
6//
7// Description: see CaloNeighbours.h
8//
9// Environment:
10// Software developed for the ATLAS Detector at CERN LHC
11//
12// Author List:
13// Sven Menke
14//
15//-----------------------------------------------------------------------
16
17//-----------------------
18// This Class's Header --
19//-----------------------
21//---------------
22// C++ Headers --
23//---------------
24#include <fstream>
25#include <iomanip>
26#include <iostream>
27#include <iterator>
28#include <sstream>
29
31#include "Identifier/Identifier.h"
33#include "Identifier/Range.h"
35
36#define MAX_BUFFER_LEN 1024
37
38//###############################################################################
39
41 const CaloCell_Base_ID *theCaloId) :
42 m_name(name),
44 m_calo_id(theCaloId),
45 m_hasPhi(false),
46 m_iPhiSource(0),
47 m_iPhiTarget(0),
48 m_hasSide(false),
51 m_isValidMinus(false),
52 m_isValidPlus(false)
53{
54}
55
56//###############################################################################
57
59= default;
60
61//###############################################################################
62
67
68//###############################################################################
69
71{
72 m_sourceRange = theRange;
73 for(unsigned int i=0;i<theRange[SIDE].get_indices();i++) {
74 if ( theRange[SIDE].get_value_at(i) < 0 )
75 m_isValidMinus = true;
76 else
77 m_isValidPlus = true;
78 }
79}
80
81//###############################################################################
82
84{
85 m_targetRange = theRange;
86}
87
88//###############################################################################
89
90void CaloNeighbourRegion::setSide(const int side1, const int side2)
91{
92 m_hasSide = true;
93 m_iSideSource = side1;
94 m_iSideTarget = side2;
95}
96
97//###############################################################################
98
99void CaloNeighbourRegion::setPhi(const int phi1, const int phi2)
100{
101 m_hasPhi = true;
102 m_iPhiSource = phi1;
103 m_iPhiTarget = phi2;
104
105}
106
107//###############################################################################
108
109int CaloNeighbourRegion::getId(ExpandedIdentifier& id, Identifier &rID, const Range &theRange, const int side, const int dphi) const
110{
111 // modify id for side and phi
112 // ExpandedIdentifier id(oid);
113 if ( m_hasSide && side != 1 )
114 id[SIDE] = side*id[SIDE];
115 if ( m_hasPhi && dphi != 0 ) {
116 if ( m_calo_id->is_lar_em(id) || m_calo_id->is_lar_hec(id) )
117 id[PHI] = id[PHI]+dphi;
118 else if ( m_calo_id->is_lar_fcal(id) )
119 id[FCALPHI] = id[FCALPHI]+dphi;
120 else
121 id[TILEPHI] = id[TILEPHI]+dphi;
122 }
123
124 // first check if id is in the specified range
125 if ( !theRange.match(id) ) {
126 std::cout << "CaloNeighbours::set_neighbours ERROR: " << (std::string)id << " is not within the Range " << (std::string)theRange << std::endl;
127 return 1;
128 }
129
130 CaloCell_ID::SUBCALO subCalo;
131 if ( m_calo_id->is_lar_em(id) ) {
132 subCalo = CaloCell_ID::LAREM;
133 rID = m_calo_id->cell_id(subCalo,
134 id[SIDE],
135 id[SAMPL],
136 id[REGION],
137 id[ETA],
138 id[PHI]);
139 }
140 else if ( m_calo_id->is_lar_hec(id) ) {
141 subCalo = CaloCell_ID::LARHEC;
142 rID = m_calo_id->cell_id(subCalo,
143 id[SIDE],
144 id[SAMPL],
145 id[REGION],
146 id[ETA],
147 id[PHI]);
148 }
149 else if ( m_calo_id->is_lar_fcal(id) ) {
150 subCalo = CaloCell_ID::LARFCAL;
151 rID = m_calo_id->cell_id(subCalo,
152 id[SIDE],
153 id[SAMPL],
154 0,
155 id[FCALETA],
156 id[FCALPHI]);
157 }
158 else if ( m_calo_id->is_tile(id) ) {
159 subCalo = CaloCell_ID::TILE;
161 if (id.fields() > TILESAMPL)
162 sampl = id[TILESAMPL];
163 rID = m_calo_id->cell_id(subCalo,
164 id[TILESECTION],
165 id[SIDE],
166 id[TILEPHI],
167 id[TILEETA],
168 sampl);
169 }
170 else {
171 std::cout << "CaloNeighbours::get_id ERROR: " << (std::string)id << " is not in the LAr or Tile calorimeters" << std::endl;
172 return 1;
173 }
174 return 0;
175}
176
177//###############################################################################
178
180 std::vector<ExpandedIdentifier>& id2,
181 std::map<IdentifierHash, std::vector<IdentifierHash>, ltIdHash>& neighbourMapPlus,
182 std::map<IdentifierHash, std::vector<IdentifierHash>, ltIdHash>& neighbourMapMinus)
183{
184 int result = 0;
185
186 // build an Identifier from the ExpandedIdentifier
187 int nMaxSides=1;
188 int nMaxPhi=1;
189 float rPhi=1;
190 if ( m_hasSide )
191 nMaxSides = 2;
192 if ( m_hasPhi ) {
193 nMaxPhi = m_sourceRange[m_iPhiSource].get_indices();
194 rPhi = ((float)m_targetRange[m_iPhiTarget].get_indices())/((float)nMaxPhi);
195 }
196
197 for (int theSide = 0;theSide<nMaxSides;theSide++) {
198 for (int theDPhi = 0;theDPhi<nMaxPhi;theDPhi++) {
199 int side = +1;
200 int dphi2 = (int)(theDPhi*rPhi+0.05);
201 if ( theSide > 0 ) {
202 side = -1;
203 }
204 // only continous region mapping in phi is supported -
205 // therefore theDPhi = delta phi ...
206 Identifier myId;
207 ExpandedIdentifier myExpID(id1);
208 if ( getId(myExpID,myId,m_sourceRange,side,theDPhi) ) {
209 return 1;
210 }
211 // get hash ID's for the source
212 IdentifierHash myHash = m_calo_id->calo_cell_hash (myId);
213 // get ID's and hash ID's for the target
214 std::vector<IdentifierHash> theTargetHashIDs;
215 for (const ExpandedIdentifier& eid : id2) {
216 Identifier myTargetId;
217 ExpandedIdentifier myNExpID(eid);
218 if ( getId(myNExpID,myTargetId,m_targetRange,side,dphi2) ) {
219 return 1;
220 }
221 // get hash ID's for the target
222 IdentifierHash myTargetHash = m_calo_id->calo_cell_hash (myTargetId);
223 theTargetHashIDs.push_back(myTargetHash);
224 }
225 if ( id1[SIDE]*side > 0 ) {
226 neighbourMapPlus[myHash] = std::move(theTargetHashIDs);
227 }
228 else {
229 neighbourMapMinus[myHash] = std::move(theTargetHashIDs);
230 }
231 }
232 }
233 return result;
234}
235
236//###############################################################################
237
238void CaloNeighbourRegion::initializeVectors(std::map<IdentifierHash, std::vector<IdentifierHash>, ltIdHash>& neighbourMapPlus, std::map<IdentifierHash, std::vector<IdentifierHash>, ltIdHash>& neighbourMapMinus)
239{
240 if ( m_isValidMinus ) {
241 m_minHashMinus = neighbourMapMinus.begin()->first;
242 m_maxHashMinus = neighbourMapMinus.rbegin()->first;
243 m_neighbours_minus.resize((unsigned int)(m_maxHashMinus-m_minHashMinus+1));
244 for (const auto& p : neighbourMapMinus) {
245 m_neighbours_minus[(unsigned int)(p.first-m_minHashMinus)] = std::make_unique<std::vector<IdentifierHash> >(p.second);
246 }
247 }
248 if ( m_isValidPlus ) {
249 m_minHashPlus = neighbourMapPlus.begin()->first;
250 m_maxHashPlus = neighbourMapPlus.rbegin()->first;
251 m_neighbours_plus.resize((unsigned int)(m_maxHashPlus-m_minHashPlus+1));
252 for (const auto& p : neighbourMapPlus) {
253 m_neighbours_plus[(unsigned int)(p.first-m_minHashPlus)] = std::make_unique<std::vector<IdentifierHash> >(p.second);
254 }
255 }
256
257}
258
259//###############################################################################
260
261int CaloNeighbourRegion::getNeighbours(const IdentifierHash caloHash, std::vector<IdentifierHash>& neighbourList) const
262{
263 int result = 0;
264
265 if ( m_isValidMinus && caloHash >= m_minHashMinus && caloHash <= m_maxHashMinus && m_neighbours_minus[(unsigned int)(caloHash-m_minHashMinus)] ) {
266 neighbourList.insert(neighbourList.end(),
267 m_neighbours_minus[(unsigned int)(caloHash-m_minHashMinus)]->begin(),
268 m_neighbours_minus[(unsigned int)(caloHash-m_minHashMinus)]->end());
269 }
270 else if ( m_isValidPlus && caloHash >= m_minHashPlus && caloHash <= m_maxHashPlus && m_neighbours_plus[(unsigned int)(caloHash-m_minHashPlus)] ) {
271 neighbourList.insert(neighbourList.end(),
272 m_neighbours_plus[(unsigned int)(caloHash-m_minHashPlus)]->begin(),
273 m_neighbours_plus[(unsigned int)(caloHash-m_minHashPlus)]->end());
274 }
275
276 return result;
277}
278
279
280//###############################################################################
281
285
286//###############################################################################
287
289= default;
290
291//###############################################################################
292
294 const std::string& filename)
295{
296 int result =0;
297 // std::cout << " CaloNeighbours::initialize " << std::endl;
298 m_calo_id = caloID;
299 m_next_regions.resize(0);
300 m_prev_regions.resize(0);
301 // Find the full path to filename:
302 std::string file = PathResolver::find_file (filename, "DATAPATH");
303 // std::cout << "Reading file " << file << std::endl;
304 std::ifstream fin;
305 if (!file.empty()) {
306 fin.open(file.c_str());
307 }
308 else {
309 std::cout << "CaloNeighbours::initialize ERROR Could not find input file " << filename << std::endl;
310 return 1;
311 }
312 if (fin.bad()) {
313 std::cout << "CaloNeighbours::initialize ERROR Could not open file " << file << std::endl;
314 return 1;
315 }
316
317 //
318 // Parse the input file
319 //
320
321 char aLine[MAX_BUFFER_LEN],dummy;
322 std::string sLine;
323 std::string cPrevOrNext,cName,cSourceRange,cTargetRange;
324 std::string cExpId;
325 Range mySourceRange,myTargetRange;
326 std::string oArg;
327 bool isComment = true;
328 bool isNext = false;
329 bool isPrev = false;
330 const std::string cmdNext("nextSuperCalo");
331 const std::string cmdPrev("prevSuperCalo");
332 const std::string cmdPhi("calcPhi(");
333 const std::string cmdSide("calcSide(");
334
335 while( isComment ) {
336 sLine.resize( 0 );
337 do {
338 fin.getline(aLine,sizeof(aLine)-1);
339 sLine = std::string(aLine);
340 } while (sLine.empty() && !fin.eof());
341 isComment = ( sLine.find('#') != std::string::npos );
342 }
343 do {
344 while ( sLine.empty() && !fin.eof()) {
345 fin.getline(aLine,sizeof(aLine)-1);
346 sLine = std::string(aLine);
347 }
348 std::istringstream header( sLine.c_str() );
349 bool hasPhi=false;
350 bool hasSide=false;
351 int iPhiSource,iPhiTarget;
352 int iSideSource,iSideTarget;
353 if ( header >> cPrevOrNext >> cName >> cSourceRange >> cTargetRange) {
354 mySourceRange.build(cSourceRange);
355 myTargetRange.build(cTargetRange);
356 while ( header >> oArg ) {
357 if (oArg.find(cmdSide) != std::string::npos ) {
358 hasSide = true;
359 oArg.erase(0,cmdSide.size());
360 std::istringstream iside( oArg.c_str() );
361 iside >> iSideSource >> dummy >> iSideTarget;
362 }
363 else if ( oArg.find(cmdPhi) != std::string::npos ) {
364 hasPhi = true;
365 oArg.erase(0,cmdPhi.size());
366 std::istringstream iphi( oArg.c_str() );
367 iphi >> iPhiSource >> dummy >> iPhiTarget;
368 }
369 }
370 sLine.resize(0);
371 bool endOfBlock = false;
372 isNext = (cPrevOrNext.find(cmdNext) != std::string::npos);
373 isPrev = (cPrevOrNext.find(cmdPrev) != std::string::npos);
374 if ( isNext^isPrev ) {
375// std::cout << (isNext?cmdNext:cmdPrev) << " "
376// << cName << " "
377// << (std::string)mySourceRange << " "
378// << (std::string)myTargetRange;
379// if ( hasSide ) {
380// std::cout << " hasSide(" << iSideSource << "," << iSideTarget << ")";
381// }
382// if ( hasPhi ) {
383// std::cout << " hasPhi(" << iPhiSource << "," << iPhiTarget << ")";
384// }
385// std::cout << std::endl;
386 // create new CaloNeighbourRegion
387 auto myRegion = std::make_unique<CaloNeighbourRegion>(cName,m_calo_id);
388 if ( isNext )
389 myRegion->setType(nextInCalo);
390 else
391 myRegion->setType(prevInCalo);
392 if ( hasSide )
393 myRegion->setSide(iSideSource,iSideTarget);
394 if ( hasPhi )
395 myRegion->setPhi(iPhiSource,iPhiTarget);
396 myRegion->setSourceRange(mySourceRange);
397 myRegion->setTargetRange(myTargetRange);
398 // create temporary neighbour maps
399 std::map<IdentifierHash, std::vector<IdentifierHash>, ltIdHash> neighbourMapPlus,neighbourMapMinus;
400
401 do {
402 while ( !endOfBlock && sLine.empty() && !fin.eof()) {
403 fin.getline(aLine,sizeof(aLine)-1);
404 sLine = std::string(aLine);
405 if ( sLine.empty() || fin.eof() )
406 endOfBlock = true;
407 }
408 if (!endOfBlock) {
409 std::istringstream neighbour( sLine.c_str() );
410 ExpandedIdentifier myCell,myNeighbourCell;
411 std::vector<ExpandedIdentifier> myNeighbourCells;
412 if ( neighbour >> cExpId ) {
413 myCell = ExpandedIdentifier(cExpId);
414 // std::cout << (std::string)myCell << ":";
415 while ( neighbour >> cExpId ) {
416 myNeighbourCell = ExpandedIdentifier(cExpId);
417 // std::cout << " " << (std::string)myNeighbourCell;
418 myNeighbourCells.push_back(myNeighbourCell);
419 }
420 // std::cout << std::endl;
421 sLine.resize(0);
422 result = myRegion->setNeighbours(myCell,myNeighbourCells,neighbourMapPlus,neighbourMapMinus);
423 if ( result != 0 )
424 return result;
425 }
426 }
427 } while (!fin.eof() && !endOfBlock);
428 myRegion->initializeVectors(neighbourMapPlus,neighbourMapMinus);
429 if (isNext)
430 m_next_regions.push_back(std::move(myRegion));
431 else
432 m_prev_regions.push_back(std::move(myRegion));
433 }
434 else {
435 std::cout << "CaloNeighbours::initialize ERROR Invalid neighbour dat file, exiting ... " << std::endl;
436 return 1;
437 }
438 }
439 }while (!fin.eof()) ;
440 fin.close();
441
442 return 0;
443}
444
445//###############################################################################
446
447int CaloNeighbours::get_nextInCalo(const IdentifierHash &id,std::vector<IdentifierHash>& neighbourList) const
448{
449 return get_neighbours(id,m_next_regions,neighbourList);
450}
451
452//###############################################################################
453
454int CaloNeighbours::get_prevInCalo(const IdentifierHash &id,std::vector<IdentifierHash>& neighbourList) const
455{
456 return get_neighbours(id,m_prev_regions,neighbourList);
457}
458
459//###############################################################################
460
462 const std::vector<std::unique_ptr<CaloNeighbourRegion> > &regions,
463 std::vector<IdentifierHash>& neighbourList)
464{
465 int result = 0;
466 for (const std::unique_ptr<CaloNeighbourRegion>& p : regions) {
467 result = p->getNeighbours(id,neighbourList);
468 if ( result != 0 )
469 return result;
470 }
471 return result;
472}
473
#define MAX_BUFFER_LEN
NEIGHBOURTYPE
@ nextInCalo
@ prevInCalo
HWIdentifier id2
static const std::vector< std::string > regions
Helper base class for offline cell identifiers.
CaloCell_Base_ID::SUBCALO SUBCALO
Definition CaloCell_ID.h:50
std::vector< std::unique_ptr< std::vector< IdentifierHash > > > m_neighbours_minus
CaloNeighbourRegion(const std::string &name, const CaloCell_Base_ID *theCaloId)
void initializeVectors(std::map< IdentifierHash, std::vector< IdentifierHash >, ltIdHash > &neighbourMapPlus, std::map< IdentifierHash, std::vector< IdentifierHash >, ltIdHash > &neighbourMapMinus)
void setSourceRange(const Range &theRange)
IdentifierHash m_maxHashPlus
virtual ~CaloNeighbourRegion()
IdentifierHash m_minHashPlus
int getNeighbours(const IdentifierHash caloHash, std::vector< IdentifierHash > &neighbourList) const
IdentifierHash m_maxHashMinus
int getId(ExpandedIdentifier &id, Identifier &rID, const Range &theRange, const int side=+1, const int dphi=0) const
void setTargetRange(const Range &theRange)
void setType(const NEIGHBOURTYPE type)
void setPhi(const int phi1, const int phi2)
void setSide(const int side1, const int side2)
IdentifierHash m_minHashMinus
NEIGHBOURTYPE m_type
const CaloCell_Base_ID * m_calo_id
int setNeighbours(ExpandedIdentifier &id1, std::vector< ExpandedIdentifier > &id2, std::map< IdentifierHash, std::vector< IdentifierHash >, ltIdHash > &neighbourMapPlus, std::map< IdentifierHash, std::vector< IdentifierHash >, ltIdHash > &neighbourMapMinus)
std::vector< std::unique_ptr< std::vector< IdentifierHash > > > m_neighbours_plus
int initialize(const CaloCell_Base_ID *caloID, const std::string &filename)
std::vector< std::unique_ptr< CaloNeighbourRegion > > m_next_regions
virtual ~CaloNeighbours()
std::vector< std::unique_ptr< CaloNeighbourRegion > > m_prev_regions
int get_nextInCalo(const IdentifierHash &id, std::vector< IdentifierHash > &neighbourList) const
int get_prevInCalo(const IdentifierHash &id, std::vector< IdentifierHash > &neighbourList) const
const CaloCell_Base_ID * m_calo_id
static int get_neighbours(const IdentifierHash &id, const std::vector< std::unique_ptr< CaloNeighbourRegion > > &regions, std::vector< IdentifierHash > &neighbourList)
This is a "hash" representation of an Identifier.
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
int match(const ExpandedIdentifier &id) const
Match an identifier.
void build(const std::string &text)
Build Range from a textual description.
TFile * file