ATLAS Offline Software
Loading...
Searching...
No Matches
EfexCellMapping.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
9
10EfexCellMapping::EfexCellMapping(int crate, int efexnumber,
11 int fpga, int mgtchannelout , int dataword)
12{
13 auto genintint = [] (int col,int intstr)
14 {return std::make_pair(col , std::to_string(intstr) );};
15 using searchpairs = std::vector<std::pair<int,std::string>>;
16
17 //Retrieve input quad inMGT pair
18 auto tab6search = searchpairs();
19 tab6search.push_back(genintint(0,fpga));
20 tab6search.push_back(genintint(3,mgtchannelout));
21 auto tab6line = m_tables.GetTable(6)->FindLine(tab6search);
22 int quad = std::stoi( tab6line->at(1) );
23 int mgtin = std::stoi( tab6line->at(2) );
24 this->init(crate,efexnumber, fpga, quad, mgtin, dataword);
25}
26
27EfexCellMapping::EfexCellMapping( roiType, int crate, int efexnumber,
28 int fpga, int eta, int phi )
29{
30 if ( (crate<0) || (crate>1) || (efexnumber<0) || (efexnumber>11) )
31 return;
32 if ( (eta<0) || (eta>5) || (phi<0) || (phi>7) )
33 return;
34
35 int etaIndex = (efexnumber%3)*16 + fpga*4 + eta - 25;
36 int phiIndex = crate*32 +(efexnumber/3)*8 + phi + 2;
37 phiIndex %= 64;
38 double etaWidth = 0.1;
39 double phiWidth = M_PI/32.0;
40 double etaCoord = (etaIndex+0.5)*etaWidth;
41 double phiCoord = (phiIndex+0.5)*phiWidth;
42
45 true, etaIndex, phiIndex,
46 etaWidth, phiWidth,
47 etaCoord, phiCoord );
48}
49
50EfexCellMapping::EfexCellMapping( roiType, int crate, int efexnumber,
51 int fpga, int eta, int phi, int seed )
52{
53 if ( (crate<0) || (crate>1) || (efexnumber<0) || (efexnumber>11) )
54 return;
55 if ( (eta<0) || (eta>5) || (phi<0) || (phi>7) )
56 return;
57 if ( (seed<0) || (seed>3) )
58 return;
59
60 int etaIndex = (efexnumber%3)*64 + fpga*16 + eta*4 + seed - 100;
61 int phiIndex = crate*32 +(efexnumber/3)*8 + phi + 2;
62 phiIndex %= 64;
63 double etaWidth = 0.025;
64 double phiWidth = M_PI/32.0;
65 double etaCoord = (etaIndex+0.5)*etaWidth;
66 double phiCoord = (phiIndex+0.5)*phiWidth;
67
70 true, etaIndex, phiIndex,
71 etaWidth, phiWidth,
72 etaCoord, phiCoord );
73}
74
75
80
86{
87 return m_latomeid;
88}
89void EfexCellMapping::init(int crate, int efexnumber,
90 int fpga, int quad, int mgtchannel , int dataword){
91 //Ensure m_region always exists even if invalid
94 //Run common constructor methods
95 std::string efexcords = this->findModuleCords(crate, efexnumber);
96 // Test data read in
97 /*
98 for(int tableidx=1 ; tableidx<6; tableidx++ ){
99 std::cout << "Printing Table:" << std::to_string(tableidx)<< std::endl;
100 ((m_tables)->GetTable(tableidx))->PrintTable(true);
101 }
102 */
103 // (m_tables)->GetTable(4)->PrintTable();
104
105 using searchpairs = std::vector<std::pair<int,std::string>>;
106
107 //Complete CSV search
108
109 //METHOD #1 to retrieve eta-phi-layer
110 auto tab4search = searchpairs();
111 tab4search.emplace_back(0,efexcords);
112 tab4search.emplace_back(1,std::to_string(fpga));
113 tab4search.emplace_back(2,std::to_string(quad));
114 tab4search.emplace_back(3,std::to_string(mgtchannel));
115 auto tab4line = m_tables.GetTable(4)->FindLine(tab4search);
116 if ( tab4line->size() == 0 )
117 return;
118// std::cout << "Table4 Search Found:" << std::endl;
119// for(auto entry : *tab4line ){std::cout << entry << " ,";}
120// std::cout << std::endl;
121
122 //Create a valid minipod str
123 std::string mpod = tab4line->at(4);
124 auto tab3search = searchpairs();
125 tab3search.emplace_back(0,efexcords);
126 tab3search.emplace_back(1,mpod);
127 auto tab3line = m_tables.GetTable(3)->FindLine(tab3search);
128 if ( tab3line->size() == 0 )
129 return;
130// std::cout << "Table3 Search Found:" << std::endl;
131// for(auto entry : *tab3line ){std::cout << entry << " ,";}
132// std::cout << std::endl;
133 m_inputconnector = std::stoi(tab3line->at(2));
134 m_fibrenumber = std::stoi(tab3line->at(3));
135
136 //Generate a valid HW info object
138 m_inputconnector,std::move(mpod));
139
140 auto tab2search = searchpairs();
141 tab2search.emplace_back(0,efexcords);
142 tab2search.emplace_back(1,std::to_string(m_inputconnector));
143 tab2search.emplace_back(2,std::to_string(m_fibrenumber));
144 tab2search.emplace_back(3,std::to_string(dataword ));
145 auto tab2line = m_tables.GetTable(2)->FindLine(tab2search);
146 if ( tab2line->size() == 0 )
147 return;
148
149 int globaleta = std::stoi( tab2line->at(4) );
150 int globalphi = std::stoi( tab2line->at(5) );
151 //std::cout << "My layer str is " << tab2line->at(6) << std::endl;
152 int layer = std::stoi( tab2line->at(6),nullptr ,16 );
153 m_latomeid = tab2line->at(8);
154 //std::cout << "My layer int is " << tab2line->at(6) << std::endl;
155 //Once Search complete, generate detector region info
156
157 //Predeclare enum
158 auto efexlabel = L1CaloDetectorRegion::EFEX;
159 // enum layertype: int;
160 double supercelletawidth(0);
161 double supercellphiwidth(0.09817477);
162 int supercelletaoffset(0);
163 if(layer == 0){
164 supercelletawidth = 0.1;
165 }
166 else if(1 <= layer && layer <= 4){
167 supercelletawidth = 0.025;
168 supercelletaoffset = (layer - 1 )%4;
169 }
170 else if(5 <= layer && layer <= 8){
171 supercelletawidth = 0.025;
172 supercelletaoffset = (layer - 1 )%4;
173 }
174 else if(layer == 9 || layer == 10){
175 supercelletawidth = 0.1;
176 }
177 double toweretalowside = (double)globaleta/10;
178 double towerphilowside = (double)globalphi*0.09817477;
179 double supercelletacoord = toweretalowside + 0.025*(double)supercelletaoffset +
180 0.5*supercelletawidth ;
181 double supercellphicoord = towerphilowside + 0.5*supercellphiwidth;
182 if(layer == 0){
183 m_region = L1CaloDetectorRegion( efexlabel,
184 L1CaloDetectorRegion::Presampler, true, globaleta, globalphi,
185 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
186 }
187 else if(1 <= layer && layer <= 4){
188 m_region = L1CaloDetectorRegion( efexlabel,
189 L1CaloDetectorRegion::Front, true, globaleta, globalphi,
190 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
191 }
192 else if(5 <= layer && layer <= 8){
193 m_region = L1CaloDetectorRegion( efexlabel,
194 L1CaloDetectorRegion::Middle, true, globaleta, globalphi,
195 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
196 }
197 else if(layer == 9){
198 m_region = L1CaloDetectorRegion( efexlabel,
199 L1CaloDetectorRegion::Back, true, globaleta, globalphi,
200 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
201 }
202 else if(layer == 10){
203 m_region = L1CaloDetectorRegion( efexlabel,
204 L1CaloDetectorRegion::Hadronic, true, globaleta, globalphi,
205 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
206 }
207 int globalEta = m_region.getEtaIndex();
208 int globalPhi = m_region.getPhiIndex();
209 std::string miniPodLabel = m_hwinfo.getMpodLabel();
210 int moduleCBA = 2 - ( efexcords.at(0) - 'A' ); //ASCII operation
211 int octantNum = ( efexcords.at(1) - '0' ) - 1; //ASCII operation
212 int moduleBaseEta = -24 + (moduleCBA * 16);
213 int fpgaBaseEta = moduleBaseEta + (fpga * 4);
214 int fpgaLowerEta = fpgaBaseEta;
215 int fpgaUpperEta = fpgaBaseEta + 4;
216 if (moduleCBA == 0 && fpga == 0) { fpgaLowerEta--; }
217 else if (moduleCBA == 2 && fpga == 3) { fpgaUpperEta++; }
218 int shiftedPhi = (globalPhi + 62) % 64;
219 int lowerShiftedPhi = octantNum * 8;
220 int upperShiftedPhi = lowerShiftedPhi + 8;
221 int fpgaOverlap = 0;
222 if (shiftedPhi >= upperShiftedPhi || shiftedPhi < lowerShiftedPhi) {
223 // Set overlap bit 1 if phi is just below the core, 2 otherwise.
224 // We need special treatment of the wraparound near phi=0 (or 64).
225 if (octantNum == 0 || octantNum == 7) {
226 fpgaOverlap |= (shiftedPhi > 32) ? 1 : 2;
227 }
228 else {
229 fpgaOverlap |= (shiftedPhi < lowerShiftedPhi) ? 1 : 2;
230 }
231 }
232 if (globalEta >= fpgaUpperEta || globalEta < fpgaLowerEta) {
233 fpgaOverlap |= (globalEta < fpgaLowerEta) ? 4 : 8;
234 }
235 m_hwinfo.setOverlap(fpgaOverlap);
236
237}
238std::string EfexCellMapping::findModuleCords(int crate, int efexnumber) const {
239 // Set of sensible range checks, if out of range return so blank
240 // declaration of L1CaloDetector Region
241 if ( (crate<0 || crate>1) ){
242 throw std::out_of_range("Invalid Crate # created within eFEX mapping");
243 }
244 if ( efexnumber<0 || efexnumber>11 ){
245 throw std::out_of_range("Invalid Module # created within eFEX mapping");
246 }
247 // For input crate and efexnumber (assuming 'eFEX number' for
248 // efexnumber label)
249
250 // Find old eFEX labels in mapping csvs
251 // with octant [1:8] and eta slice [A,B,C]:
252 int octant = 4*crate + efexnumber/3 + 1; //Note int div
253 int etaslicenum = 3 - efexnumber%3; //obvious A=1 etc mapping
254 static constexpr const char* letters = "ABC";
255 char etaslice = letters[etaslicenum - 1];
256 return std::string(1, etaslice) + std::to_string(octant);
257}
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
std::string m_latomeid
void init(int crate, int efexnumber, int fpga, int quad, int mgtchannel, int dataword)
EfexCellMapping(int crate, int efexnumber, int fpga, int quad, int mgtchannel, int dataword)
std::string findModuleCords(int crate, int efexnumber) const
EfexHardwareInfo m_hwinfo
L1CaloDetectorRegion getDetectorRegion() const
std::string getLatomeID() const
EfexHardwareInfo getHardwareInfo() const
L1CaloDetectorRegion m_region
EfexCSVTables & m_tables
Simple class to mainly store eta/phi information (indices, granularity, trigger tower coordinates) as...