ATLAS Offline Software
Loading...
Searching...
No Matches
EfexCellMapping.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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 //Basic Lamdas to gen search pairs
105 auto genintstr = [] (int col, std::string str )
106 {return std::make_pair(col , str );};
107 auto genintint = [] (int col,int intstr)
108 {return std::make_pair(col , std::to_string(intstr) );};
109 using searchpairs = std::vector<std::pair<int,std::string>>;
110
111 //Complete CSV search
112
113 //METHOD #1 to retrieve eta-phi-layer
114 auto tab4search = searchpairs();
115 tab4search.push_back(genintstr(0,efexcords));
116 tab4search.push_back(genintint(1,fpga));
117 tab4search.push_back(genintint(2,quad));
118 tab4search.push_back(genintint(3,mgtchannel));
119 auto tab4line = m_tables.GetTable(4)->FindLine(tab4search);
120 if ( tab4line->size() == 0 )
121 return;
122// std::cout << "Table4 Search Found:" << std::endl;
123// for(auto entry : *tab4line ){std::cout << entry << " ,";}
124// std::cout << std::endl;
125
126 //Create a valid minipod str
127 std::string mpod = tab4line->at(4);
128 auto tab3search = searchpairs();
129 tab3search.push_back(genintstr(0,efexcords));
130 tab3search.push_back(genintstr(1,mpod));
131 auto tab3line = m_tables.GetTable(3)->FindLine(tab3search);
132 if ( tab3line->size() == 0 )
133 return;
134// std::cout << "Table3 Search Found:" << std::endl;
135// for(auto entry : *tab3line ){std::cout << entry << " ,";}
136// std::cout << std::endl;
137 m_inputconnector = std::stoi(tab3line->at(2));
138 m_fibrenumber = std::stoi(tab3line->at(3));
139
140 //Generate a valid HW info object
142 m_inputconnector,std::move(mpod));
143
144 auto tab2search = searchpairs();
145 tab2search.push_back(genintstr(0,efexcords));
146 tab2search.push_back(genintint(1,m_inputconnector));
147 tab2search.push_back(genintint(2,m_fibrenumber));
148 tab2search.push_back(genintint(3,dataword ));
149 auto tab2line = m_tables.GetTable(2)->FindLine(tab2search);
150 if ( tab2line->size() == 0 )
151 return;
152
153 int globaleta = std::stoi( tab2line->at(4) );
154 int globalphi = std::stoi( tab2line->at(5) );
155 //std::cout << "My layer str is " << tab2line->at(6) << std::endl;
156 int layer = std::stoi( tab2line->at(6),nullptr ,16 );
157 m_latomeid = tab2line->at(8);
158 //std::cout << "My layer int is " << tab2line->at(6) << std::endl;
159 //Once Search complete, generate detector region info
160
161 //Predeclare enum
162 auto efexlabel = L1CaloDetectorRegion::EFEX;
163 // enum layertype: int;
164 double supercelletawidth(0);
165 double supercellphiwidth(0.09817477);
166 int supercelletaoffset(0);
167 if(layer == 0){
168 supercelletawidth = 0.1;
169 }
170 else if(1 <= layer && layer <= 4){
171 supercelletawidth = 0.025;
172 supercelletaoffset = (layer - 1 )%4;
173 }
174 else if(5 <= layer && layer <= 8){
175 supercelletawidth = 0.025;
176 supercelletaoffset = (layer - 1 )%4;
177 }
178 else if(layer == 9 || layer == 10){
179 supercelletawidth = 0.1;
180 }
181 double toweretalowside = (double)globaleta/10;
182 double towerphilowside = (double)globalphi*0.09817477;
183 double supercelletacoord = toweretalowside + 0.025*(double)supercelletaoffset +
184 0.5*supercelletawidth ;
185 double supercellphicoord = towerphilowside + 0.5*supercellphiwidth;
186 if(layer == 0){
187 m_region = L1CaloDetectorRegion( efexlabel,
188 L1CaloDetectorRegion::Presampler, true, globaleta, globalphi,
189 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
190 }
191 else if(1 <= layer && layer <= 4){
192 m_region = L1CaloDetectorRegion( efexlabel,
193 L1CaloDetectorRegion::Front, true, globaleta, globalphi,
194 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
195 }
196 else if(5 <= layer && layer <= 8){
197 m_region = L1CaloDetectorRegion( efexlabel,
198 L1CaloDetectorRegion::Middle, true, globaleta, globalphi,
199 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
200 }
201 else if(layer == 9){
202 m_region = L1CaloDetectorRegion( efexlabel,
203 L1CaloDetectorRegion::Back, true, globaleta, globalphi,
204 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
205 }
206 else if(layer == 10){
207 m_region = L1CaloDetectorRegion( efexlabel,
208 L1CaloDetectorRegion::Hadronic, true, globaleta, globalphi,
209 supercelletawidth, supercellphiwidth , supercelletacoord, supercellphicoord);
210 }
211 int globalEta = m_region.getEtaIndex();
212 int globalPhi = m_region.getPhiIndex();
213 std::string miniPodLabel = m_hwinfo.getMpodLabel();
214 int moduleCBA = 2 - ( efexcords.at(0) - 'A' ); //ASCII operation
215 int octantNum = ( efexcords.at(1) - '0' ) - 1; //ASCII operation
216 int moduleBaseEta = -24 + (moduleCBA * 16);
217 int fpgaBaseEta = moduleBaseEta + (fpga * 4);
218 int fpgaLowerEta = fpgaBaseEta;
219 int fpgaUpperEta = fpgaBaseEta + 4;
220 if (moduleCBA == 0 && fpga == 0) { fpgaLowerEta--; }
221 else if (moduleCBA == 2 && fpga == 3) { fpgaUpperEta++; }
222 int shiftedPhi = (globalPhi + 62) % 64;
223 int lowerShiftedPhi = octantNum * 8;
224 int upperShiftedPhi = lowerShiftedPhi + 8;
225 int fpgaOverlap = 0;
226 if (shiftedPhi >= upperShiftedPhi || shiftedPhi < lowerShiftedPhi) {
227 // Set overlap bit 1 if phi is just below the core, 2 otherwise.
228 // We need special treatment of the wraparound near phi=0 (or 64).
229 if (octantNum == 0 || octantNum == 7) {
230 fpgaOverlap |= (shiftedPhi > 32) ? 1 : 2;
231 }
232 else {
233 fpgaOverlap |= (shiftedPhi < lowerShiftedPhi) ? 1 : 2;
234 }
235 }
236 if (globalEta >= fpgaUpperEta || globalEta < fpgaLowerEta) {
237 fpgaOverlap |= (globalEta < fpgaLowerEta) ? 4 : 8;
238 }
239 m_hwinfo.setOverlap(fpgaOverlap);
240
241}
242std::string EfexCellMapping::findModuleCords(int crate, int efexnumber) const {
243 // Set of sensible range checks, if out of range return so blank
244 // declaration of L1CaloDetector Region
245 if ( (crate<0 || crate>1) ){
246 throw std::out_of_range("Invalid Crate # created within eFEX mapping");
247 }
248 if ( efexnumber<0 || efexnumber>11 ){
249 throw std::out_of_range("Invalid Module # created within eFEX mapping");
250 }
251 // For input crate and efexnumber (assuming 'eFEX number' for
252 // efexnumber label)
253
254 // Find old eFEX labels in mapping csvs
255 // with octant [1:8] and eta slice [A,B,C]:
256 int octant = 4*crate + efexnumber/3 + 1; //Note int div
257 int etaslicenum = 3 - efexnumber%3; //obvious A=1 etc mapping
258 static constexpr const char* letters = "ABC";
259 char etaslice = letters[etaslicenum - 1];
260 return std::string(1, etaslice) + std::to_string(octant);
261}
#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...