]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/mapping/WriteRCUs.C
6afcb57ec5591e0afaaed573afb9499381614627
[u/mrichter/AliRoot.git] / EMCAL / mapping / WriteRCUs.C
1 /*
2 ROOT Macro to generate ascii files for AliCaloAltroMapping; offline decoder
3 - based on the map file produced by EMCALNumbering.C
4
5 Update: 20 Aug 2008 - update to write separate files for A and C sides +
6    added TRU and LED channels also.. 
7
8 LED channels look like regular FEE data; just from rcu=0, branch=0, FEC=0
9 TRU data has one block of data from the whole TRU; all other FEC=0 slots
10    (rcu, branch) = (0,1), (1,0), (1,1)
11
12 Some further documentation is available at:
13 http://cern.ch/dsilverm/mapping/emcal_mapping.html
14
15 Author: David Silvermyr, ORNL; silvermy@mail.phy.ornl.gov
16 */
17
18 // First we define some constants - the main method WriteRCUs comes later
19 const int kNTRU = 3;
20 const int kNTRUChanBlocks = 16; // per TRU - info from Dong and Hans, July 22, 2008
21 const int kNLED = 24; // one per StripModule
22
23 const int kNGAIN = 2; // low (0) and high (1)
24 const int kNFEEChannelsPerRCU = 1152;
25 int NChannelsPerRCU[2];
26 // RCU 0: FEE + NTRUChanBlocks + NLED*NGAIN 
27 NChannelsPerRCU[0] = kNFEEChannelsPerRCU + kNTRUChanBlocks + kNLED*kNGAIN; 
28 // RCU 1: FEE + 2*NTRUChanBlocks
29 NChannelsPerRCU[1] = kNFEEChannelsPerRCU + 2*kNTRUChanBlocks; 
30
31 const int kMaxHWAddress = (1 << 11) // branch
32   | (9 << 7) // FEC
33   | (4 << 4) // Altro
34   | 0xf; // channel
35
36 const int kNRCU = 2;
37 const int kNSides = 2;
38 char * sideStr[] = {"A", "C"};
39
40 const int kFirstFEC = 1;
41 const int kNFECPerGTL = 9; // NFEC/NGTL
42
43 int makeHWAddress(int ibranch, int ifec, int ichip, int ichan) {
44   int addr = (ibranch << 11) // branch
45     | (ifec << 7) // FEC
46     | (ichip << 4) // Altro
47     | ichan; // channel
48   return addr;
49 }
50
51 // HERE STARTS THE MAIN METHOD..
52 void WriteRCUs(const char *filename="map.root")
53 {
54   TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
55   if (!f) {
56     f = new TFile(filename);
57   }
58   TTree *tree = (TTree*)gDirectory->Get("tree");
59
60   const int kNTOW = 32; // per FEC
61   
62   //Declaration of leaves types
63   Int_t           iside;
64   Int_t           isect;
65   Int_t           iSM;
66   Int_t           iFEC;
67   Int_t           iRCU;
68   Int_t           iDDLEqId;
69   Int_t           iBranch;
70   Int_t           iGTL;
71   Int_t           nTow;
72   Int_t           CSP[kNTOW];
73   Int_t           chip[kNTOW];
74   Int_t           lowGainChan[kNTOW];
75   Int_t           highGainChan[kNTOW];
76   Int_t           towerCol[kNTOW];
77   Int_t           towerRow[kNTOW];
78   Int_t           towerOrder[kNTOW];
79   
80   // Set branch addresses.
81   tree->SetBranchAddress("iside",&iside);
82   tree->SetBranchAddress("isect",&isect);
83   tree->SetBranchAddress("iSM",&iSM);
84   tree->SetBranchAddress("iFEC",&iFEC);
85   tree->SetBranchAddress("iRCU",&iRCU);
86   tree->SetBranchAddress("iDDLEqId",&iDDLEqId);
87   tree->SetBranchAddress("iBranch",&iBranch);
88   tree->SetBranchAddress("iGTL",&iGTL);
89   tree->SetBranchAddress("nTow",&nTow);
90   tree->SetBranchAddress("CSP",CSP);
91   tree->SetBranchAddress("chip",chip);
92   tree->SetBranchAddress("lowGainChan",lowGainChan);
93   tree->SetBranchAddress("highGainChan",highGainChan);
94   tree->SetBranchAddress("towerCol",towerCol);
95   tree->SetBranchAddress("towerRow",towerRow);
96   tree->SetBranchAddress("towerOrder",towerOrder);
97   
98   Int_t nbytes = 0;
99
100   // also variables and branch setting for LED TTree
101   TTree *tLED = (TTree*)gDirectory->Get("tLED");
102
103   //Declaration of leaves types, not already declared
104   Int_t           nLED;
105   Int_t           iLEDCSP[kNLED];
106   Int_t           iLEDchip[kNLED];
107   Int_t           iLEDlowGainChan[kNLED];
108   Int_t           iLEDhighGainChan[kNLED];
109   Int_t           iLEDStrip[kNLED];
110
111   // Set branch addresses.
112   tLED->SetBranchAddress("iside",&iside);
113   tLED->SetBranchAddress("isect",&isect);
114   tLED->SetBranchAddress("iSM",&iSM);
115   tLED->SetBranchAddress("iDDLEqId",&iDDLEqId);
116   tLED->SetBranchAddress("iRCU",&iRCU);
117   tLED->SetBranchAddress("iBranch",&iBranch);
118   tLED->SetBranchAddress("iGTL",&iGTL);
119   tLED->SetBranchAddress("nLED",&nLED);
120   tLED->SetBranchAddress("iLEDCSP",iLEDCSP);
121   tLED->SetBranchAddress("iLEDchip",iLEDchip);
122   tLED->SetBranchAddress("iLEDlowGainChan",iLEDlowGainChan);
123   tLED->SetBranchAddress("iLEDhighGainChan",iLEDhighGainChan);
124   tLED->SetBranchAddress("iLEDStrip",iLEDStrip);
125
126   // and TRU TTree
127   TTree *tTRU = (TTree*)gDirectory->Get("tTRU");
128
129   //Declaration of leaves types, not already declared
130   Int_t           iTRUchip;
131   Int_t           iTRUFirstChan;
132   Int_t           iTRULastChan;
133   
134    // Set branch addresses.
135   tTRU->SetBranchAddress("iside",&iside);
136   tTRU->SetBranchAddress("isect",&isect);
137   tTRU->SetBranchAddress("iSM",&iSM);
138   tTRU->SetBranchAddress("iDDLEqId",&iDDLEqId);
139   tTRU->SetBranchAddress("iRCU",&iRCU);
140   tTRU->SetBranchAddress("iBranch",&iBranch);
141   tTRU->SetBranchAddress("iGTL",&iGTL);
142   tTRU->SetBranchAddress("iTRUchip",&iTRUchip);
143   tTRU->SetBranchAddress("iTRUFirstChan",&iTRUFirstChan);
144   tTRU->SetBranchAddress("iTRULastChan",&iTRULastChan);
145
146    // OK, setup done - let's proceed.. First with the regular data
147
148   int n[kNRCU][kNSides] = {0};
149   ofstream out[kNRCU][kNSides];
150   ofstream outFinal[kNRCU][kNSides];
151
152   // Open output files, and provide the necessary header
153   char fname[100];
154   for (iRCU=0; iRCU<kNRCU; iRCU++) {
155     for (iside=0; iside<kNSides; iside++) {
156       sprintf(fname, "RCU%d%s.data.unsorted",iRCU,sideStr[iside]);
157       out[iRCU][iside].open(fname);
158
159       sprintf(fname, "RCU%d%s.data",iRCU,sideStr[iside]);
160       outFinal[iRCU][iside].open(fname);
161
162       outFinal[iRCU][iside] << NChannelsPerRCU[iRCU] << endl;
163       outFinal[iRCU][iside] << kMaxHWAddress  << endl;
164
165       n[iRCU][iside] = 0;
166     }
167   }
168
169   int chid[kNGAIN] = {0};
170   int ig = 0; // gain flag
171
172   // loop over channels
173   for (Long64_t i=0; i<tree->GetEntries();i++) { 
174     nbytes += tree->GetEntry(i);
175
176     if (isect==0) { // just the 1st sector; other sectors will look the same internally (or be a subset in case of the 1/3 size ones)
177
178       /*
179         FECs should come in order so let's just worry about channel order
180         within an FEC
181         DS (Aug 2008): in principle we don't really need to do this anymore, 
182         since we anyway call a sort command at the end now, but since it was
183         already coded I kept this for now..
184       */
185       // The towerOrder array should have the needed indexing info
186       for (int it = 0; it<kNTOW; it++) {
187         int itow = towerOrder[it];
188
189         chid[0] = makeHWAddress( iBranch, (iFEC%kNFECPerGTL) + kFirstFEC, 
190                                  chip[itow], lowGainChan[itow] );
191         chid[1] = makeHWAddress( iBranch, (iFEC%kNFECPerGTL) + kFirstFEC, 
192                                  chip[itow], highGainChan[itow] );
193
194         // cout << " it " << it << " : " << chid[0] << " " << chid[1] << endl;
195
196         // start with the lowest
197         if (chid[0] < chid[1]) {
198           ig = 0;
199         }
200         else {
201           ig = 1;
202         }
203         
204         out[iRCU][iside] << chid[ig] << " " 
205                          << towerRow[itow] << " "
206                          << towerCol[itow] << " " << ig
207                          << endl;
208         n[iRCU][iside]++;
209         // and then the next
210         ig = 1 -ig;
211         out[iRCU][iside] << chid[ig] << " " 
212                          << towerRow[itow] << " "
213                          << towerCol[itow] << " " << ig
214                          << endl;
215         n[iRCU][iside]++;
216       } // loop over towers      
217     } // sector==0 selection
218   }
219   // done, with FEE data
220
221   // report on counts; just for early debugging..
222   for (iRCU=0; iRCU<kNRCU; iRCU++) {
223     for (iside=0; iside<kNSides; iside++) {
224       cout << " post-FEE count: RCU " << iRCU
225            << " iside " << iside
226            << " n = " << n[iRCU][iside] << endl;
227     }
228   }
229   
230   // Next, we have the fake ALTRO from the TRU
231   int caloFlag = 2; // from enum AliCaloRawStream::kTRUData
232   int dummyRow = 0; // need to have the right number of fields in print-out
233   int TRUchid = 0;
234   for (Long64_t i=0; i<tTRU->GetEntries(); i++) { 
235     nbytes += tTRU->GetEntry(i);
236     if (isect==0) { // select just the 1st sector; same motivation as for FEE
237       for (int ichan=iTRUFirstChan; ichan<=iTRULastChan; ichan++) {
238         TRUchid = makeHWAddress( iBranch, iGTL, 
239                                  iTRUchip, ichan );
240         out[iRCU][iside] << TRUchid << " " 
241                          << dummyRow << " "
242                          << ichan << " " // channel # coded as Column.. 
243                          << caloFlag << endl;
244         n[iRCU][iside]++;
245       }
246     }
247   }
248
249   // report on counts; just for early debugging..
250   for (iRCU=0; iRCU<kNRCU; iRCU++) {
251     for (iside=0; iside<kNSides; iside++) {
252       cout << " post-TRU count: RCU " << iRCU
253            << " iside " << iside
254            << " n = " << n[iRCU][iside] << endl;
255     }
256   }
257
258   // Then. LED data
259   caloFlag = 3; // from enum AliCaloRawStream::kLEDMonData
260   int LEDchid = 0; // assigned below
261
262   for (Long64_t i=0; i<tLED->GetEntries(); i++) { 
263     nbytes += tLED->GetEntry(i);
264     if (isect==0) { // just the 1st sector
265       for (int il=0; il<nLED; il++) {
266
267         // first low gain
268         ig = 0; 
269         LEDchid = makeHWAddress( iBranch, iGTL, 
270                                  iLEDchip[il], iLEDlowGainChan[il] );
271         out[iRCU][iside] << LEDchid << " " 
272                          << ig << " " // gain coded as row..
273                          << iLEDStrip[il] << " " // strip # coded as Column.. 
274                          << caloFlag << endl;
275         n[iRCU][iside]++;
276         
277         // then high gain
278         ig = 1; 
279         LEDchid = makeHWAddress( iBranch, iGTL, 
280                                  iLEDchip[il], iLEDhighGainChan[il] );
281         out[iRCU][iside] << LEDchid << " " 
282                          << ig << " " // gain coded as row..
283                          << iLEDStrip[il] << " " // strip # coded as Column.. 
284                          << caloFlag << endl;
285         n[iRCU][iside]++;
286       }
287     }
288   }
289
290   // Finally, let's close the output files - we should get the counts we expected
291   for (iRCU=0; iRCU<kNRCU; iRCU++) {
292     for (iside=0; iside<kNSides; iside++) {
293       out[iRCU][iside].close();
294       outFinal[iRCU][iside].close();
295       // report how many entries we encountered
296       cout << " final count: RCU " << iRCU
297            << " iside " << iside
298            << " n = " << n[iRCU][iside] 
299            << " expected " << NChannelsPerRCU[iRCU];
300       if (n[iRCU][iside] == NChannelsPerRCU[iRCU]) {
301         cout << " - OK! " << endl;
302       }
303       else {
304         cout << " - Wrong! " << endl;
305       }
306
307     }
308   }
309
310   // let's then do a final loop where we sort the lists into the final files
311   // I'm not sure if having the lists ordered is really needed but it is at 
312   // least more aestethically pleasing..
313   char cmd[200];
314   sprintf(cmd, "mkdir -p tmp"); // provide a temporary storage space - not to pollute the local dir. too much
315   gSystem->Exec(cmd);
316
317   for (iRCU=0; iRCU<kNRCU; iRCU++) {
318     for (iside=0; iside<kNSides; iside++) {
319       sprintf(cmd, "sort -n RCU%d%s.data.unsorted >> RCU%d%s.data", 
320               iRCU, sideStr[iside], iRCU, sideStr[iside]);
321       cout << "executing " << cmd << endl;
322       gSystem->Exec(cmd);
323       sprintf(cmd, "mv RCU%d%s.data.unsorted tmp/.", 
324               iRCU, sideStr[iside]);
325       cout << "executing " << cmd << endl;
326       gSystem->Exec(cmd);
327     }
328   }
329
330 }