]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EMCAL/mapping/EMCalNumbering.C
Move AliWarning and AliInfo to AliDebug to reduce prints during reconstruction
[u/mrichter/AliRoot.git] / EMCAL / mapping / EMCalNumbering.C
CommitLineData
5cfb4b82 1/*
2ROOT Macro to generate all numbering believed to be relevant for EMCAL
3- at least as far as electronics is concerned.
4Includes FEE, TRU and LED information. Sorry if this macro does not quite
5adher to ALICE coding conventions (but on the other hand it is not used in AliRoot)
6
7Some further documentation is available at:
8http://cern.ch/dsilverm/mapping/emcal_mapping.html
9
10Author: David Silvermyr, ORNL; silvermy@mail.phy.ornl.gov
11*/
12
13/*
14First we define a number of constants; the main method EMCALNumbering starts below
15*/
16
17const int kDDLEqIdOffsetEMCAL = 0x1200; /* From AliDAQ; first equipment Id # for EMCAL*/
18
19// global arrays for chip, channel and CSP numbering
20// - in the area covered by a single FEC (32 CSPs covering a 4x8 tower area)
21const int kNROWS = 8;
22const int kNCOLS = 4;
23const int kNCSP = 32;
24
25// the way CSPs are populated, as seen from the back where we
26// plug in the T-cards
27const int kCspMap[kNROWS][kNCOLS] = {
28 0, 16, 8, 24, // 7
29 1, 17, 9, 25, // |
30 2, 18, 10, 26, // |
31 3, 19, 11, 27, // row
32 4, 20, 12, 28, // |
33 5, 21, 13, 29, // |
34 6, 22, 14, 30, // |
35 7, 23, 15, 31 // 0
36 // 0 <-col-> 3
37};
38// i.e. the highest row comes first, and this map should thus be indexed as [NROWS-1-irow][icol]
39// - Csp help array is constructed below.
40
41/*
42 The rest of the global Chan/Chip arrays are either fixed
43 from the Altro mapping, or a function of the CspMap above
44*/
45
46// Altro mapping for chips and channels, high and low gain
47const int kChip[kNCSP] = {
48 2, 2, 2, 2, 3, 3, 3, 3,
49 0, 0, 0, 0, 4, 4, 4, 4,
50 2, 2, 2, 2, 3, 3, 3, 3,
51 0, 0, 0, 0, 4, 4, 4, 4
52};
53
54const int kChanHigh[kNCSP] = {
55 10, 14, 5, 1, 1, 5, 14, 10,
56 10, 14, 5, 1, 1, 5, 14, 10,
57 8, 12, 7, 3, 3, 7, 12, 8,
58 8, 12, 7, 3, 3, 7, 12, 8
59};
60
61const int kChanLow[kNCSP] = {
62 11, 15, 4, 0, 0, 4, 15, 11,
63 11, 15, 4, 0, 0, 4, 15, 11,
64 9, 13, 6, 2, 2, 6, 13, 9,
65 9, 13, 6, 2, 2, 6, 13, 9
66};
67
68// Order that CSPs appear in the data
69const int kCspOrder[kNCSP] = { // just from ALTRO mapping of chips/channels to CSP
70 11, 27, 10, 26, 24, 8, 25, 9,
71 3, 19, 2, 18, 16, 0, 17, 1,
72 4, 20, 5, 21, 23, 7, 22, 6,
73 12, 28, 13, 29, 31, 15, 30, 14
74};
75
76// LED reference info:
77const int kNLED = 24; // per SuperModule; equals number of StripModules per SuperModule
78const int kNLEDPerTCard = kNLED / 2;
79// CSPs and LED are connected on a special T-card with only 12 connectors
80// Half of the StripModules in a SuperModule will be connected to the Top
81// (and half to the Bottom) T-card
82// First Top
83const int kCspMapLEDTop[kNLEDPerTCard] = {
84 1, 17, // Strips 0, 1
85 2, 18, // Strips 2, 3
86 3, 19, // Strips 4, 5
87 4, 20, // Strips 6, 7
88 5, 21, // Strips 8, 9
89 6, 22 // Strips 10,11
90};
91const int kStripModuleMapLEDTop[kNLEDPerTCard] = {
92 0, 1,
93 2, 3,
94 4, 5,
95 6, 7,
96 8, 9,
97 10,11
98};
99
100// Then Bottom
101const int kCspMapLEDBottom[kNLEDPerTCard] = {
102 9, 25, // Strips 12,13
103 10, 26, // Strips 14,15
104 11, 27, // Strips 16,17
105 12, 28, // Strips 18,19
106 13, 29, // Strips 20,21
107 14, 30 // Strips 22,23
108};
109const int kStripModuleMapLEDBottom[kNLEDPerTCard] = {
110 12,13,
111 14,15,
112 16,17,
113 18,19,
114 20,21,
115 22,23
116};
117
118// let's make some simpler/normal help index arrays too, that we'll use later on
119int ROW[kNCSP];
120int COL[kNCSP];
121int Csp[kNROWS][kNCOLS];
122
123// Order that Towers, appear in the data
124int towerOrder[kNCSP];
125
126void initTowers()
127{
128 for(int icol=0; icol<kNCOLS; icol++){
129 for(int irow=0; irow<kNROWS; irow++){
130 int csp = kCspMap[kNROWS-1-irow][icol];
131 COL[csp] = icol;
132 ROW[csp] = irow;
133 Csp[irow][icol] = csp;
134
135 cout << " icol " << icol
136 << " irow " << irow
137 << " csp " << csp << endl;
138 }
139 }
140
141 // let's also give the order that Towers appear in the data
142 for (int ic=0; ic<kNCSP; ic++) {
143 int towerid = ROW[kCspOrder[ic]]*kNCOLS + COL[kCspOrder[ic]];
144 towerOrder[ic] = towerid;
145 }
146
147}
148
149// help functions for TRU mapping:
150int getTRUADC(int iFEC) { // iFEC is a number 0-35, within a SM
151 // ADC channel 1-12 on TRU as a function of connected iFEC
152 return (iFEC%12 + 1);
153}
154
155int getTRUADCChan(int iCSP) { // iCSP is from 0 to 31
156 int bottom = (iCSP%16)/8; // 0 for top, 1 for bottom T-card
157 int iADCChan = (iCSP%8)/2 + 1; // within a T-card; 1-4
158 return (iADCChan + bottom*4);
159}
160// ok, done with TRU help methods also; let's do what needs to be done
161
162// HERE STARTS THE MAIN METHOD..
163void EMCalNumbering()
164{
165 /*
166 General coord. info: ALICE-INT-2003-038 EDMS doc.
167
168 z goes in the beam direction from RB26 (side C,where the muon arm is,Gex),
169 to RB24 (side A, Bellegarde), i.e. away from muon arm.
170
171 x is horizontal, perpendicular to the beam direction and points to the
172 accelerator (LHC ring) centre.
173 [visual aid.: pos. x = Saleve; Inside/I, negative = Jura; Outside/O]
174
175 y is vertical, perpendicular to z and x. Positive y points upward.
176 [pos. y = Up/U. neg. y = Down/D]
177
178 The usual relation to r, phi(-pi, pi), theta (0,pi) applies:
179 x = r * sin(theta) * cos(phi);
180 y = r * sin(theta) * sin(phi);
181 z = r * cos(theta)
182
183 r = sqrt(x*x + y*y +z*z);
184 theta = TMath::ACos(z/r);
185 phi = TMath::ATan2(y, x);
186 */
187
188 /* Numbering rules: ALICE-INT-2003-038 EDMS doc.
189
190 All numbering starts from 0.
191
192 Rotational Numbering: follows phi direction
193 [looks counter-clockwise from A, and clockwise from C]
194
195 Linear numbering: follows _reverse_ z-direction from A to C,
196 without interruption at z=0
197 [presumably to have a reasonable numbering in the muon system]
198
199 Radial numbering increases outwards, but EMCAL only has one layer.
200 so doesn't matter for us.
201 */
202
203 // EMCAL specifics
204
205 initTowers(); // prepare setup
206
207 // global info on sectors
208 const int kNFullSect = 5;
209 const int kNThirdSect = 1;
210 const int kNSides = 2; // supermodules for both positive and negative Z
211 // let's call side A '0', and side C '1'
212
213 // Number of SuperModules and DDLs total
214 const int kNSM = (kNFullSect + kNThirdSect)*kNSides; // 12
215 // const int NDDL = NSides*(NFullSect * 2 + NThirdSect*1); // 22
216
217 // per supermodule info
218 const int kNTowersZ = 48;
219 const int kNTowersPhi = 24;
220 const int kNTowersPerFEC = 32;
221 const int kNFEC = 36;
222 const int kNGTL = 4;
223 const int kNRCU = 2;
224 const int kNTRU = 3;
225
226 const int kNTowersSM = kNTowersZ*kNTowersPhi; // 1152
227
228 const int kNModulesZ = kNTowersZ/2; // 24
229 const int kNModulesPhi = kNTowersPhi/2; // 12
230 const int kNModulesSM = kNTowersSM/4; // 288
231
232 // per GTL
233 const int kNFECPerGTL = kNFEC/kNGTL; // 9
234 // per RCU
235 const int kNFECPerRCU = kNFEC/kNRCU; // 18
236 // per TRU
237 const int kNFECPerTRU = kNFEC/kNTRU; // 12
238
239 // and per FrontEndCard:
240 // 2 T-cards, each with 16 towers, per FEC
241 const int kNTCards = 2;
242 // each T-card covers a 2x8 tower area
243 const int kNTowersPhiTC = 8;
244 const int kNTowersZTC = 2;
245
246 // OK, that was all the setup and definitions of constants..
247
248 /* Now, how do we populate the Supermodule and it's GTL space?
249 Simplest seems to be to have 3 rows of 12 FECs each,
250 where each FEC's 2 T-cards cover a 4(z)*8(phi) tower area.
251 Do the coverage in order..
252 */
253 const int kNFECPerRow = kNFEC/3; // 12
254
255 TFile *f = new TFile("map.root","RECREATE");
256
257 // global variables
258 int iside = 0; // A=0, C=1
259 int isect = 0; // 0-5
260 int iSM = 0; // 0-11, offline SuperModule index
261 int iDDLEqId = 0; // kDDLEqIdOffsetEMCAL = 0x1200 upwards (NDDL)
262
263 // within SM
264 int iFEC = 0; // 0
265 int iTRU = 0; // 0-2, within SM
266 int iTRUADC = 0; // 1-8, within TRU
267 int iRCU = 0; // 0-1, within SM
268 int iBranch = 0; // A=0, B=1
269 int iGTL = 0; // address 1-9; TRU is in address slot 0
270 // within FEC
271 int nTow = kNCSP; // # of towers, per FEC
272 int CSP[kNCSP] = {0};
273 int chip[kNCSP] = {0};
274 int lowGainChan[kNCSP] = {0};
275 int highGainChan[kNCSP] = {0};
276 int towerCol[kNCSP] = {0};
277 int towerRow[kNCSP] = {0};
278 int iTRUADCChan[kNCSP] = {0};
279
280 TTree *t = new TTree("tree","ALICE EMCal tower map");
281 t->Branch("iside",&iside,"iside/I");
282 t->Branch("isect",&isect,"isect/I");
283 t->Branch("iSM",&iSM,"iSM/I");
284 t->Branch("iDDLEqId",&iDDLEqId,"iDDLEqId/I");
285 t->Branch("iFEC",&iFEC,"iFEC/I");
286 t->Branch("iTRU",&iTRU,"iTRU/I");
287 t->Branch("iTRUADC",&iTRUADC,"iTRUADC/I");
288 t->Branch("iRCU",&iRCU,"iRCU/I");
289 t->Branch("iBranch",&iBranch,"iBranch/I");
290 t->Branch("iGTL",&iGTL,"iGTL/I");
291 t->Branch("nTow",&nTow,"nTow/I");
292 t->Branch("CSP",CSP,"CSP[nTow]/I");
293 t->Branch("chip",chip,"chip[nTow]/I");
294 t->Branch("lowGainChan",lowGainChan,"lowGainChan[nTow]/I");
295 t->Branch("highGainChan",highGainChan,"highGainChan[nTow]/I");
296 t->Branch("towerCol",towerCol,"towerCol[nTow]/I");
297 t->Branch("towerRow",towerRow,"towerRow[nTow]/I");
298 t->Branch("towerOrder",towerOrder,"towerOrder[nTow]/I");
299 t->Branch("iTRUADCChan",iTRUADCChan,"iTRUADCChan[nTow]/I");
300
301 // LED TTree
302 TTree *tLED = new TTree("tLED","ALICE EMCal LED reference map");
303 tLED->Branch("iside",&iside,"iside/I");
304 tLED->Branch("isect",&isect,"isect/I");
305 tLED->Branch("iSM",&iSM,"iSM/I");
306 tLED->Branch("iDDLEqId",&iDDLEqId,"iDDLEqId/I");
307 tLED->Branch("iRCU",&iRCU,"iRCU/I");
308 tLED->Branch("iBranch",&iBranch,"iBranch/I");
309 tLED->Branch("iGTL",&iGTL,"iGTL/I");
310 int nLED = kNLED;
311 tLED->Branch("nLED",&nLED,"nLED/I");
312 int iLEDCSP[kNLED] = {0};
313 int iLEDchip[kNLED] = {0};
314 int iLEDhighGainChan[kNLED] = {0};
315 int iLEDlowGainChan[kNLED] = {0};
316 int iLEDStrip[kNLED] = {0};
317 tLED->Branch("iLEDCSP",iLEDCSP,"iLEDCSP[nLED]/I");
318 tLED->Branch("iLEDchip",iLEDchip,"iLEDchip[nLED]/I");
319 tLED->Branch("iLEDlowGainChan",iLEDlowGainChan,"iLEDlowGainChan[nLED]/I");
320 tLED->Branch("iLEDhighGainChan",iLEDhighGainChan,"iLEDhighGainChan[nLED]/I");
321 tLED->Branch("iLEDStrip",iLEDStrip,"iLEDStrip[nLED]/I");
322
323 // TRU TTree
324 TTree *tTRU = new TTree("tTRU","ALICE EMCal TRU fake-altro map");
325 tTRU->Branch("iside",&iside,"iside/I");
326 tTRU->Branch("isect",&isect,"isect/I");
327 tTRU->Branch("iSM",&iSM,"iSM/I");
328 tTRU->Branch("iDDLEqId",&iDDLEqId,"iDDLEqId/I");
329 tTRU->Branch("iRCU",&iRCU,"iRCU/I");
330 tTRU->Branch("iBranch",&iBranch,"iBranch/I");
331 tTRU->Branch("iGTL",&iGTL,"iGTL/I");
6d3af2f0 332 // TRU is identified by (GTL==0 && !(Branch==0 && RCU==0))
5cfb4b82 333 int iTRUFirstChan = 0;
6d3af2f0 334 int iTRULastChan = 127; // maximum allowed number of fake ALTRO channels=128 from TRU
5cfb4b82 335 tTRU->Branch("iTRUFirstChan",&iTRUFirstChan,"iTRUFirstChan/I");
336 tTRU->Branch("iTRULastChan",&iTRULastChan,"iTRULastChan/I");
337
338 for (isect = 0; isect<(kNFullSect+kNThirdSect); isect++) {
339 for (iside=0; iside<kNSides; iside++) { // A or C sides
340 // half sector only has one third of the FECs
341 int MINFEC = 0;
342 int MAXFEC = kNFEC;
343 int MINTRU = 0;
344 int MAXTRU = kNTRU;
345 if (isect==kNFullSect) { // meaning last third-size-sector
346 if (iside==0) { // A side
347 MAXFEC = kNFEC / 3;
348 MAXTRU = 1;
349 }
350 else if (iside==1) { // C side
351 MINFEC = 2 * kNFEC / 3;
352 MINTRU = 2;
353 }
354 }
355
356 iSM = isect*2 + iside;
357 for (iFEC=MINFEC; iFEC<MAXFEC; iFEC++) {
358
359 // ok, where does this FEC belong? Use the local iFEC index which starts with 0
360 // closest to the crate and revert to global z and phi index at the end..
361
362 iTRU = iFEC / (kNFECPerTRU);
363 iTRUADC = getTRUADC(iFEC);
364 iRCU = iFEC / (kNFECPerRCU);
365 iBranch = (iFEC%kNFECPerRCU) / kNFECPerGTL; // local index inside RCU
366 iGTL = iFEC % kNFECPerGTL + 1;
367
368 iDDLEqId = kDDLEqIdOffsetEMCAL + iSM*kNRCU + iRCU;
369
370 // tower limits/indices
371 int tcolLow = (iFEC%kNFECPerRow)*kNCOLS;
372 int trowLow = (iFEC/kNFECPerRow)*kNROWS;
373 /*
374 printf("iside %d iSM %d: FEC %02d RCU %d Branch %d iGTL\n",
375 iside, iSM, iFEC, iRCU, iBranch, iGTL);
376 */
377 for (int col=0; col<kNCOLS; col++) {
378 for (int row=0; row<kNROWS; row++) {
379 int tcol = col + tcolLow;
380 int trow = row + trowLow;
381
382 int itow = row*kNCOLS + col;
383
384 CSP[itow] = Csp[row][col];
385 chip[itow] = kChip[CSP[itow]];
386 lowGainChan[itow] = kChanLow[CSP[itow]];
387 highGainChan[itow] = kChanHigh[CSP[itow]];
388
389 iTRUADCChan[itow] = getTRUADCChan(CSP[itow]);
390
391 // we need to switch to global indices if we are on side C
392 if (iside==1) {
393 tcol = kNTowersZ-1 - tcol; // flip axis
394 trow = kNTowersPhi-1 - trow; // just flip axis
395 }
396
397 towerCol[itow] = tcol;
398 towerRow[itow] = trow;
399
400 } // row
401 }// col
402 tree->Fill();
403 } // iFEC
404
405 // also handle special LED and TRU mapping
406 iGTL = 0; // they are all in GTL/FEC slot 0
407
408 // start with LED..
409 iRCU = 0; iBranch = 0;
410 iDDLEqId = kDDLEqIdOffsetEMCAL + iSM*kNRCU + iRCU;
411
412 /* for the special 'half'/third sector, side C, there is
413 no RCU=0.. So we put the LED in RCU=1 instead then.
414 There is only 1 TRU in this sector (RCU=1, branch=1), so no problem..
415 */
416 if (MINTRU == 2) { // key for this special sector
417 iRCU++;
418 iDDLEqId++;
419 }
420
421 // loop over attached CSPs
422 // First Top
423 for (int iled = 0; iled<kNLEDPerTCard; iled++) {
424 int il = iled;
425 iLEDCSP[il] = kCspMapLEDTop[iled];
426 iLEDStrip[il] = kStripModuleMapLEDTop[iled];
427 /*
428 cout << " LED CSP " << iLEDCSP[il]
429 << " Strip " << iLEDStrip[il] << endl;
430 */
431 iLEDchip[il] = kChip[iLEDCSP[il]];
432 iLEDlowGainChan[il] = kChanLow[iLEDCSP[il]];
433 iLEDhighGainChan[il] = kChanHigh[iLEDCSP[il]];
434 }
435 // Then Bottom
436 for (int iled = 0; iled<kNLEDPerTCard; iled++) {
437 int il = iled + kNLEDPerTCard; // just a convenient index
438 iLEDCSP[il] = kCspMapLEDBottom[iled];
439 iLEDStrip[il] = kStripModuleMapLEDBottom[iled];
440 /*
441 cout << " LED CSP " << iLEDCSP[il]
442 << " Strip " << iLEDStrip[il] << endl;
443 */
444 iLEDchip[il] = kChip[iLEDCSP[il]];
445 iLEDlowGainChan[il] = kChanLow[iLEDCSP[il]];
446 iLEDhighGainChan[il] = kChanHigh[iLEDCSP[il]];
447 }
448 tLED->Fill();
449
450 // then we also have the TRUs (fake ALTRO)
451 for (iTRU=MINTRU; iTRU<MAXTRU; iTRU++) {
452
453 if (iTRU == 0) { iRCU = 0; iBranch = 1; }
454 else if (iTRU == 1) { iRCU = 1; iBranch = 0; }
455 else if (iTRU == 2) { iRCU = 1; iBranch = 1; }
456 /*
457 cout << " TRU " << iTRU
458 << " RCU " << iRCU
459 << " Branch " << iBranch << endl;
460 */
461 iDDLEqId = kDDLEqIdOffsetEMCAL + iSM*kNRCU + iRCU;
462 /*
463 last sector only has 1 TRU, but it's probably called TRU 0 on A
464 and TRU 2 on C side..
465 This is handled via MINFEC/MAXFEC and MINTRU/MAXTRU at the start
466 of this loop.
467 */
468 tTRU->Fill();
469
470 }
471
472 } // isect / iSM
473 } // iside
474
475 f->Write();
476}