ATLAS Offline Software
Loading...
Searching...
No Matches
PpmMappingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <cmath>
6
7#include "GaudiKernel/IInterface.h"
8#include "GaudiKernel/MsgStream.h"
9#include "GaudiKernel/StatusCode.h"
10
11#include "PpmMappingTool.h"
12
13namespace LVL1 {
14
15// Static constants
16
20
22{
23 msg(MSG::INFO) << "Initializing " << name() << endmsg;
24 setupMap();
26
27 return StatusCode::SUCCESS;
28}
29
31{
32 return StatusCode::SUCCESS;
33}
34
35// Return eta, phi and layer mapping for given crate/module/channel
36
37bool PpmMappingTool::mapping(const int crate, const int module,
38 const int channel, double& eta, double& phi, int& layer) const
39{
40 if (crate < 0 || crate >= s_crates || module < 0 || module >= s_modules ||
41 channel < 0 || channel >= s_channels) return false;
42
43 const ModuleMap& modMap = m_crateInfo[crate];
44 const ModuleInfo& modInfo = modMap[module];
45 const double etaOffset = modInfo.first.first;
46 const double phiOffset = modInfo.first.second;
47 const CoordinateMap* currentMap = modInfo.second;
48
49 if (!currentMap) return false;
50
51 // Set the output
52
53 ChannelCoordinate relCoord = (*currentMap)[channel];
54 if (relCoord.layer() == ChannelCoordinate::NONE) return false;
55
56 relCoord.setEta(relCoord.eta() + etaOffset);
57 eta = etaSim(relCoord);
58 phi = relCoord.phi() + phiOffset;
59 layer = (relCoord.layer() == ChannelCoordinate::EM) ? 0 : 1;
60 return true;
61}
62
63// Return crate, module and channel mapping for given eta/phi/layer
64
65bool PpmMappingTool::mapping(const double eta, const double phi,
66 const int layer, int& crate, int& module, int& channel) const
67{
68 const unsigned int invalidChanId = s_crates*s_modules*s_channels;
69
70 const unsigned int key = etaPhiKey(eta, phi);
71 EtaPhiMap::const_iterator iter = m_etaPhiMap.find(key);
72 if (iter == m_etaPhiMap.end()) {
73 msg(MSG::WARNING) << "Invalid eta/phi: " << eta
74 << "/" << phi << endmsg;
75 return false;
76 }
77 const ChannelIds& ids(iter->second);
78 const unsigned int chanId = (layer == 0) ? ids.first : ids.second;
79 if (chanId == invalidChanId) {
80 msg(MSG::WARNING) << "Invalid ChanId - shouldn't happen" << endmsg;
81 return false;
82 }
83 crate = chanId / (s_channels * s_modules);
84 module = (chanId / s_channels) % s_modules;
85 channel = chanId % s_channels;
86 return true;
87}
88
89// Set up crate/module map
90
92{
93 // Input to Output channel mappings.
94 // Inputs are numbered 1-16 (x4) and outputs 0-63
95 // There are four output sets obtained by adding 0,4,8,12 to out
96
97 // input = 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16
98 const int out[16] = { 19,51,35, 3,18,50,34, 2,17,49,33, 1,16,48,32, 0 };
99
100 // Mapping types.
101 //
102 // Type 1.
103 // Eta -2.4 to 2.4. Inputs for 4x4 block
104 //
105 // +----+----+----+----+
106 // | 16 | 15 | 12 | 11 |
107 // +----+----+----+----+
108 // | 13 | 14 | 9 | 10 |
109 // +----+----+----+----+ PI/8
110 // | 4 | 3 | 8 | 7 |
111 // +----+----+----+----+
112 // | 1 | 2 | 5 | 6 |
113 // +----+----+----+----+
114 // 0.4
115
116 const int in1[16] = { 16,15,12,11,13,14, 9,10, 4, 3, 8, 7, 1, 2, 5, 6 };
117
118 // Type 2.
119 // Eta 2.4 to 2.9. 4x1 plus 2x2 block
120 //
121 // +----+--------+--------+
122 // | 16 | | |
123 // +----+ 15 | 12 |
124 // | 13 | | |
125 // +----+--------+--------+ PI/8
126 // | 4 | | |
127 // +----+ 3 | 8 |
128 // | 1 | | |
129 // +----+--------+--------+
130 // 0.5
131
132 const int in2a[4] = { 16,13, 4, 1 };
133 const int in2b[4] = { 15,12, 3, 8 };
134
135 // Type 3.
136 // Eta -2.9 to -2.4. 2x2 plus 4x1 block
137 //
138 // +--------+--------+----+
139 // | | | 11 |
140 // | 16 | 12 +----+
141 // | | | 10 |
142 // +--------+--------+----+ PI/8
143 // | | | 7 |
144 // | 4 | 8 +----+
145 // | | | 6 |
146 // +--------+--------+----+
147 // 0.5
148
149 const int in3a[4] = { 16,12, 4, 8 };
150 const int in3b[4] = { 11,10, 7, 6 };
151
152 // Type 4.
153 // Eta 2.9 to 3.2 and -3.2 to -2.9. 4x1 plus 4x1
154 // + -
155 // +--------+----+ +----+--------+
156 // | | | | | |
157 // | 16 | 15 | | 16 | 15 |
158 // | | | | | |
159 // +--------+----+ +----+--------+
160 // | | | | | |
161 // | 12 | 11 | | 12 | 11 |
162 // | | | | | |
163 // +--------+----+ +----+--------+ PI/4
164 // | | | | | |
165 // | 8 | 7 | | 8 | 7 |
166 // | | | | | |
167 // +--------+----+ +----+--------+
168 // | | | | | |
169 // | 4 | 3 | | 4 | 3 |
170 // | | | | | |
171 // +--------+----+ +----+--------+
172 // 0.3 0.3
173
174 const int in4a[4] = { 16,12, 8, 4 };
175 const int in4b[4] = { 15,11, 7, 3 };
176
177 // Type 5.
178 // Eta 3.2 to 4.9 and -4.9 to -3.2 EM FCAL. 4x4
179 //
180 // +----+----+----+----+
181 // | | | | |
182 // | 16 | 15 | 14 | 13 |
183 // | | | | |
184 // +----+----+----+----+
185 // | | | | |
186 // | 12 | 11 | 10 | 9 |
187 // | | | | |
188 // +----+----+----+----+ PI/2
189 // | | | | |
190 // | 8 | 7 | 6 | 5 |
191 // | | | | |
192 // +----+----+----+----+
193 // | | | | |
194 // | 4 | 3 | 2 | 1 |
195 // | | | | |
196 // +----+----+----+----+
197 // 1.7
198
199 const int in5[16] = { 16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
200
201 // Type 6.
202 // Eta 3.2 to 4.9 and -4.9 to -3.2 Had FCAL2 and FCAL3. 4x2 plus 4x2
203 // NB. FCAL2 and FCAL3 have the same eta/phi coordinates.
204 // FCAL2 FCAL3
205 // +--------+--------+ +--------+--------+
206 // | | | | | |
207 // | 16 | 14 | | 15 | 13 |
208 // | | | | | |
209 // +--------+--------+ +--------+--------+
210 // | | | | | |
211 // | 12 | 10 | | 11 | 9 |
212 // | | | | | |
213 // +--------+--------+ +--------+--------+ PI/2
214 // | | | | | |
215 // | 8 | 6 | | 7 | 5 |
216 // | | | | | |
217 // +--------+--------+ +--------+--------+
218 // | | | | | |
219 // | 4 | 2 | | 3 | 1 |
220 // | | | | | |
221 // +--------+--------+ +--------+--------+
222 // 1.7 1.7
223
224 const int in6a[8] = { 16,14,12,10, 8, 6, 4, 2 };
225 const int in6b[8] = { 15,13,11, 9, 7, 5, 3, 1 };
226
227 // Construct coordinate maps for each module type
228 // Four blocks of each type make up the complete map
229
230 for (int i = 0; i < 12; ++i) m_coordMaps.push_back(std::make_unique<CoordinateMap>());
231 for (int block = 0; block < 4; ++block) {
232 const int incr = block * 4;
233 std::vector<std::unique_ptr<CoordinateMap> >::iterator pos = m_coordMaps.begin();
234
235 // Map 0 : Type 1 EM
236 addCoords(4,4,0.1,M_PI/32.,0.,block*M_PI/8.,in1,out,incr,
237 ChannelCoordinate::EM, **pos);
238 ++pos;
239
240 // Map 1 : Type 1 Had
241 addCoords(4,4,0.1,M_PI/32.,0.,block*M_PI/8.,in1,out,incr,
243 ++pos;
244
245 // Map 2 : Type 2 EM
246 addCoords(4,1,0.1,M_PI/32.,0.0,block*M_PI/8.,in2a,out,incr,
247 ChannelCoordinate::EM, **pos);
248 addCoords(2,2,0.2,M_PI/16.,0.1,block*M_PI/8.,in2b,out,incr,
249 ChannelCoordinate::EM, **pos);
250 ++pos;
251
252 // Map 3 : Type 2 Had
253 addCoords(4,1,0.1,M_PI/32.,0.0,block*M_PI/8.,in2a,out,incr,
255 addCoords(2,2,0.2,M_PI/16.,0.1,block*M_PI/8.,in2b,out,incr,
257 ++pos;
258
259 // Map 4 : Type 3 EM
260 addCoords(2,2,0.2,M_PI/16.,0.0,block*M_PI/8.,in3a,out,incr,
261 ChannelCoordinate::EM, **pos);
262 addCoords(4,1,0.1,M_PI/32.,0.4,block*M_PI/8.,in3b,out,incr,
263 ChannelCoordinate::EM, **pos);
264 ++pos;
265
266 // Map 5 : Type 3 Had
267 addCoords(2,2,0.2,M_PI/16.,0.0,block*M_PI/8.,in3a,out,incr,
269 addCoords(4,1,0.1,M_PI/32.,0.4,block*M_PI/8.,in3b,out,incr,
271 ++pos;
272
273 // Map 6 : Type 4 EM positive eta
274 addCoords(4,1,0.2,M_PI/16.,0.0,block*M_PI/4.,in4a,out,incr,
275 ChannelCoordinate::EM, **pos);
276 addCoords(4,1,0.1,M_PI/16.,0.2,block*M_PI/4.,in4b,out,incr,
277 ChannelCoordinate::EM, **pos);
278 ++pos;
279
280 // Map 7 : Type 4 Had positive eta
281 addCoords(4,1,0.2,M_PI/16.,0.0,block*M_PI/4.,in4a,out,incr,
283 addCoords(4,1,0.1,M_PI/16.,0.2,block*M_PI/4.,in4b,out,incr,
285 ++pos;
286
287 // Map 8 : Type 4 EM negative eta
288 addCoords(4,1,0.1,M_PI/16.,0.0,block*M_PI/4.,in4a,out,incr,
289 ChannelCoordinate::EM, **pos);
290 addCoords(4,1,0.2,M_PI/16.,0.1,block*M_PI/4.,in4b,out,incr,
291 ChannelCoordinate::EM, **pos);
292 ++pos;
293
294 // Map 9 : Type 4 Had negative eta
295 addCoords(4,1,0.1,M_PI/16.,0.0,block*M_PI/4.,in4a,out,incr,
297 addCoords(4,1,0.2,M_PI/16.,0.1,block*M_PI/4.,in4b,out,incr,
299 ++pos;
300
301 // Map 10 : Type 5 EM FCAL
302 addCoords(4,4,0.425,M_PI/8.,0.0,block*M_PI/2.,in5,out,incr,
303 ChannelCoordinate::EM, **pos);
304 ++pos;
305
306 // Map 11 : Type 6 Had FCAL2 and FCAL3
307 addCoords(4,2,0.85,M_PI/8.,0.0,block*M_PI/2.,in6a,out,incr,
309 addCoords(4,2,0.85,M_PI/8.,0.0,block*M_PI/2.,in6b,out,incr,
311 }
312
313 // Fill crate map
314
315 std::vector<std::unique_ptr<CoordinateMap> >::const_iterator pos = m_coordMaps.begin();
316
317 // Map 0 : all of crates 0,1
318 // crate 2 modules 1,2,5,6,9,10,13,14
319 // crate 3 modules 2,3,6,7,10,11,14,15
320 addMods(0,0,4,4, 0.0,0.0,0.4,M_PI/2.,pos->get());
321 addMods(1,0,4,4,-1.6,0.0,0.4,M_PI/2.,pos->get());
322 addMods(2,1,4,2, 1.6,0.0,0.4,M_PI/2.,pos->get());
323 addMods(3,2,4,2,-2.4,0.0,0.4,M_PI/2.,pos->get());
324 ++pos;
325
326 // Map 1 : crate 4 modules 1,2,5,6,9,10,13,14
327 // crate 5 modules 2,3,6,7,10,11,14,15
328 // all of crates 6,7
329 addMods(4,1,4,2, 1.6,0.0,0.4,M_PI/2.,pos->get());
330 addMods(5,2,4,2,-2.4,0.0,0.4,M_PI/2.,pos->get());
331 addMods(6,0,4,4, 0.0,0.0,0.4,M_PI/2.,pos->get());
332 addMods(7,0,4,4,-1.6,0.0,0.4,M_PI/2.,pos->get());
333 ++pos;
334
335 // Map 2 : crate 2 modules 3,7,11,15
336 addMods(2,3,4,1, 2.4,0.0,0.5,M_PI/2.,pos->get());
337 ++pos;
338
339 // Map 3 : crate 4 modules 3,7,11,15
340 addMods(4,3,4,1, 2.4,0.0,0.5,M_PI/2.,pos->get());
341 ++pos;
342
343 // Map 4 : crate 3 modules 1,5,9,13
344 addMods(3,1,4,1,-2.9,0.0,0.5,M_PI/2.,pos->get());
345 ++pos;
346
347 // Map 5 : crate 5 modules 1,5,9,13
348 addMods(5,1,4,1,-2.9,0.0,0.5,M_PI/2.,pos->get());
349 ++pos;
350
351 // Map 6 : crate 2 modules 4,12
352 addMods(2, 4,1,1, 2.9,0.0,0.3,M_PI,pos->get());
353 addMods(2,12,1,1, 2.9,M_PI,0.3,M_PI,pos->get());
354 ++pos;
355
356 // Map 7 : crate 4 modules 4,12
357 addMods(4, 4,1,1, 2.9,0.0,0.3,M_PI,pos->get());
358 addMods(4,12,1,1, 2.9,M_PI,0.3,M_PI,pos->get());
359 ++pos;
360
361 // Map 8 : crate 3 modules 4,12
362 addMods(3, 4,1,1,-3.2,0.0,0.3,M_PI,pos->get());
363 addMods(3,12,1,1,-3.2,M_PI,0.3,M_PI,pos->get());
364 ++pos;
365
366 // Map 9 : crate 5 modules 4,12
367 addMods(5, 4,1,1,-3.2,0.0,0.3,M_PI,pos->get());
368 addMods(5,12,1,1,-3.2,M_PI,0.3,M_PI,pos->get());
369 ++pos;
370
371 // Map 10 : crate 4 module 0, crate 5 module 0
372 addMods(4,0,1,1, 3.2,0.0,1.7,2*M_PI,pos->get());
373 addMods(5,0,1,1,-4.9,0.0,1.7,2*M_PI,pos->get());
374 ++pos;
375
376 // Map 11 : crate 4 module 8, crate 5 module 8
377 addMods(4,8,1,1, 3.2,0.0,1.7,2*M_PI,pos->get());
378 addMods(5,8,1,1,-4.9,0.0,1.7,2*M_PI,pos->get());
379}
380
381// Set up eta/phi map
382
384{
385 const unsigned int invalidChanId = s_crates*s_modules*s_channels;
386
387 for (int cr = 0; cr < s_crates; ++cr) {
388 for (int mod = 0; mod < s_modules; ++mod) {
389 for (int chan = 0; chan < s_channels; ++chan) {
390 double tmpEta, tmpPhi;
391 int tmpLayer;
392 if (mapping(cr, mod, chan, tmpEta, tmpPhi, tmpLayer)) {
393 const unsigned int key = etaPhiKey(tmpEta, tmpPhi);
394 const unsigned int chanId = (cr * s_modules + mod) * s_channels + chan;
395 EtaPhiMap::iterator iter = m_etaPhiMap.find(key);
396 if (iter == m_etaPhiMap.end()) {
397 ChannelIds ids(invalidChanId, invalidChanId);
398 if (tmpLayer == 0) ids.first = chanId;
399 else ids.second = chanId;
400 m_etaPhiMap.insert(std::make_pair(key, ids));
401 } else {
402 ChannelIds& ids(iter->second);
403 if (tmpLayer == 0) ids.first = chanId;
404 else ids.second = chanId;
405 }
406 }
407 }
408 }
409 }
410}
411
412// Add entries to a coordinate map
413
414void PpmMappingTool::addCoords(const int nrows, const int ncols,
415 const double etaGran, const double phiGran, const double etaOffset,
416 const double phiOffset, const int* in, const int* out, const int incr,
417 const ChannelCoordinate::CaloLayer layer, CoordinateMap& coordMap)
418{
419 for (int row = 0; row < nrows; ++row) {
420 const double phi = (double(row) + 0.5) * phiGran + phiOffset;
421 for (int col = 0; col < ncols; ++col) {
422 const double eta = (double(col) + 0.5) * etaGran + etaOffset;
423 const int channel = out[in[row*ncols+col]-1] + incr;
424 assert (channel < s_channels);
425 coordMap[channel] = ChannelCoordinate(layer, eta, phi, etaGran, phiGran);
426 }
427 }
428}
429
430// Add a block of similar modules to a crate
431
432void PpmMappingTool::addMods(const int crate, const int modOffset,
433 const int nrows, const int ncols, const double etaBase,
434 const double phiBase, const double etaRange, const double phiRange,
435 const CoordinateMap* coordMap)
436{
437 assert (crate < static_cast<int>(m_crateInfo.size()));
438 ModuleMap& modMap = m_crateInfo[crate];
439 for (int row = 0; row < nrows; ++row) {
440 for (int col = 0; col < ncols; ++col) {
441 const int module = row*4 + col + modOffset;
442 const double etaOffset = etaRange * double(col) + etaBase;
443 const double phiOffset = phiRange * double(row) + phiBase;
444 Offsets off(etaOffset, phiOffset);
445 modMap[module] = ModuleInfo (off, coordMap);
446 }
447 }
448}
449
450// Correction for Had FCAL eta which is adjusted to EM value in TriggerTower
451
453{
454 double eta = coord.eta();
455 const ChannelCoordinate::CaloLayer layer = coord.layer();
456 if (layer == ChannelCoordinate::FCAL2 || layer == ChannelCoordinate::FCAL3) {
457 const double etaCorrection = coord.etaGranularity()/4.;
458 if (layer == ChannelCoordinate::FCAL2) eta -= etaCorrection;
459 else eta += etaCorrection;
460 }
461 return eta;
462}
463
464// Simple eta/phi key
465
466unsigned int PpmMappingTool::etaPhiKey(double eta, double phi) const
467{
468 const double etaOffsets[5] = { 0., 2.5, 3.1, 3.2, 4.9 };
469 const double etaGrans[4] = { 0.1, 0.2, 0.1, 0.425 };
470 const double phiGrans[4] = { M_PI/32., M_PI/16., M_PI/16., M_PI/8. };
471 const int side = (eta < 0.) ? 0 : 1;
472 int region = 0;
473 int ieta = 0;
474 int iphi = 0;
475 const double absEta = fabs(eta);
476 for (int i = 0; i < 4; ++i) {
477 if (absEta < etaOffsets[i+1]) {
478 region = i;
479 ieta = int((absEta - etaOffsets[i]) / etaGrans[i]);
480 iphi = int(phi / phiGrans[i]);
481 break;
482 }
483 }
484 unsigned int key = (side << 20) + (region << 16) + (ieta << 8) + iphi;
485 return key;
486}
487
488} // end namespace
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
double coord
Type of coordination system.
Holds eta/phi coordinates corresponding to a crate/module channel.
virtual bool mapping(int crate, int module, int channel, double &eta, double &phi, int &layer) const override
Return eta, phi and layer mapping for given crate/module/channel.
std::pair< Offsets, const CoordinateMap * > ModuleInfo
static const int s_modules
std::array< ModuleInfo, s_modules > ModuleMap
std::array< ModuleMap, s_crates > m_crateInfo
Pointer to crate/module map.
std::array< ChannelCoordinate, s_channels > CoordinateMap
static const int s_channels
void addCoords(int nrows, int ncols, double etaGran, double phiGran, double etaOffset, double phiOffset, const int *in, const int *out, int incr, ChannelCoordinate::CaloLayer layer, CoordinateMap &coordMap)
Add entries to a coordinate map.
double etaSim(const ChannelCoordinate &coord) const
Correction for Had FCAL eta which is adjusted to EM value in TriggerTower.
unsigned int etaPhiKey(double eta, double phi) const
Simple eta/phi key.
void setupInverseMap()
Set up eta/phi map.
void addMods(int crate, int modOffset, int nrows, int ncols, double etaBase, double phiBase, double etaRange, double phiRange, const CoordinateMap *coordMap)
Add a block of similar modules to a crate.
std::pair< unsigned int, unsigned int > ChannelIds
virtual StatusCode initialize() override
void setupMap()
Set up crate/module map.
std::vector< std::unique_ptr< CoordinateMap > > m_coordMaps
Vector of CoordinateMaps.
virtual StatusCode finalize() override
std::pair< double, double > Offsets
static const int s_crates
EtaPhiMap m_etaPhiMap
Pointer to inverse map.
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
MsgStream & msg
Definition testRead.cxx:32