]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/mapping/WriteRCUs.C
add external setter for MC parents list
[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; // per SM
20 const int kNTRUChanBlocks = 128; // max. per TRU 
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("iTRUFirstChan",&iTRUFirstChan);
143   tTRU->SetBranchAddress("iTRULastChan",&iTRULastChan);
144
145    // OK, setup done - let's proceed.. First with the regular data
146
147   int n[kNRCU][kNSides] = {0};
148   ofstream out[kNRCU][kNSides];
149   ofstream outFinal[kNRCU][kNSides];
150
151   // Open output files, and provide the necessary header
152   char fname[100];
153   for (iRCU=0; iRCU<kNRCU; iRCU++) {
154     for (iside=0; iside<kNSides; iside++) {
155       sprintf(fname, "RCU%d%s.data.unsorted",iRCU,sideStr[iside]);
156       out[iRCU][iside].open(fname);
157
158       sprintf(fname, "RCU%d%s.data",iRCU,sideStr[iside]);
159       outFinal[iRCU][iside].open(fname);
160
161       outFinal[iRCU][iside] << NChannelsPerRCU[iRCU] << endl;
162       outFinal[iRCU][iside] << kMaxHWAddress  << endl;
163
164       n[iRCU][iside] = 0;
165     }
166   }
167
168   int chid[kNGAIN] = {0};
169   int ig = 0; // gain flag
170
171   // loop over channels
172   for (Long64_t i=0; i<tree->GetEntries();i++) { 
173     nbytes += tree->GetEntry(i);
174
175     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)
176
177       /*
178         FECs should come in order so let's just worry about channel order
179         within an FEC
180         DS (Aug 2008): in principle we don't really need to do this anymore, 
181         since we anyway call a sort command at the end now, but since it was
182         already coded I kept this for now..
183       */
184       // The towerOrder array should have the needed indexing info
185       for (int it = 0; it<kNTOW; it++) {
186         int itow = towerOrder[it];
187
188         chid[0] = makeHWAddress( iBranch, (iFEC%kNFECPerGTL) + kFirstFEC, 
189                                  chip[itow], lowGainChan[itow] );
190         chid[1] = makeHWAddress( iBranch, (iFEC%kNFECPerGTL) + kFirstFEC, 
191                                  chip[itow], highGainChan[itow] );
192
193         // cout << " it " << it << " : " << chid[0] << " " << chid[1] << endl;
194
195         // start with the lowest
196         if (chid[0] < chid[1]) {
197           ig = 0;
198         }
199         else {
200           ig = 1;
201         }
202         
203         out[iRCU][iside] << chid[ig] << " " 
204                          << towerRow[itow] << " "
205                          << towerCol[itow] << " " << ig
206                          << endl;
207         n[iRCU][iside]++;
208         // and then the next
209         ig = 1 -ig;
210         out[iRCU][iside] << chid[ig] << " " 
211                          << towerRow[itow] << " "
212                          << towerCol[itow] << " " << ig
213                          << endl;
214         n[iRCU][iside]++;
215       } // loop over towers      
216     } // sector==0 selection
217   }
218   // done, with FEE data
219
220   // report on counts; just for early debugging..
221   for (iRCU=0; iRCU<kNRCU; iRCU++) {
222     for (iside=0; iside<kNSides; iside++) {
223       cout << " post-FEE count: RCU " << iRCU
224            << " iside " << iside
225            << " n = " << n[iRCU][iside] << endl;
226     }
227   }
228   
229   // Next, we have the fake ALTRO from the TRU
230   int caloFlag = 2; // from enum AliCaloRawStream::kTRUData
231   int dummyRow = 0; // need to have the right number of fields in print-out
232   int TRUchid = 0;
233   for (Long64_t i=0; i<tTRU->GetEntries(); i++) { 
234     nbytes += tTRU->GetEntry(i);
235     if (isect==0) { // select just the 1st sector; same motivation as for FEE
236       for (int ichan=iTRUFirstChan; ichan<=iTRULastChan; ichan++) {
237         TRUchid = makeHWAddress( iBranch, iGTL, 
238                                  ichan/16, ichan%16 );
239         out[iRCU][iside] << TRUchid << " " 
240                          << dummyRow << " "
241                          << ichan << " " // channel # coded as Column.. 
242                          << caloFlag << endl;
243         n[iRCU][iside]++;
244       }
245     }
246   }
247
248   // report on counts; just for early debugging..
249   for (iRCU=0; iRCU<kNRCU; iRCU++) {
250     for (iside=0; iside<kNSides; iside++) {
251       cout << " post-TRU count: RCU " << iRCU
252            << " iside " << iside
253            << " n = " << n[iRCU][iside] << endl;
254     }
255   }
256
257   // Then. LED data
258   caloFlag = 3; // from enum AliCaloRawStream::kLEDMonData
259   int LEDchid = 0; // assigned below
260
261   for (Long64_t i=0; i<tLED->GetEntries(); i++) { 
262     nbytes += tLED->GetEntry(i);
263     if (isect==0) { // just the 1st sector
264       for (int il=0; il<nLED; il++) {
265
266         // first low gain
267         ig = 0; 
268         LEDchid = makeHWAddress( iBranch, iGTL, 
269                                  iLEDchip[il], iLEDlowGainChan[il] );
270         out[iRCU][iside] << LEDchid << " " 
271                          << ig << " " // gain coded as row..
272                          << iLEDStrip[il] << " " // strip # coded as Column.. 
273                          << caloFlag << endl;
274         n[iRCU][iside]++;
275         
276         // then high gain
277         ig = 1; 
278         LEDchid = makeHWAddress( iBranch, iGTL, 
279                                  iLEDchip[il], iLEDhighGainChan[il] );
280         out[iRCU][iside] << LEDchid << " " 
281                          << ig << " " // gain coded as row..
282                          << iLEDStrip[il] << " " // strip # coded as Column.. 
283                          << caloFlag << endl;
284         n[iRCU][iside]++;
285       }
286     }
287   }
288
289   // Finally, let's close the output files - we should get the counts we expected
290   for (iRCU=0; iRCU<kNRCU; iRCU++) {
291     for (iside=0; iside<kNSides; iside++) {
292       out[iRCU][iside].close();
293       outFinal[iRCU][iside].close();
294       // report how many entries we encountered
295       cout << " final count: RCU " << iRCU
296            << " iside " << iside
297            << " n = " << n[iRCU][iside] 
298            << " expected " << NChannelsPerRCU[iRCU];
299       if (n[iRCU][iside] == NChannelsPerRCU[iRCU]) {
300         cout << " - OK! " << endl;
301       }
302       else {
303         cout << " - Wrong! " << endl;
304       }
305
306     }
307   }
308
309   // let's then do a final loop where we sort the lists into the final files
310   // I'm not sure if having the lists ordered is really needed but it is at 
311   // least more aestethically pleasing..
312   char cmd[200];
313   sprintf(cmd, "mkdir -p tmp"); // provide a temporary storage space - not to pollute the local dir. too much
314   gSystem->Exec(cmd);
315
316   for (iRCU=0; iRCU<kNRCU; iRCU++) {
317     for (iside=0; iside<kNSides; iside++) {
318       sprintf(cmd, "sort -n RCU%d%s.data.unsorted >> RCU%d%s.data", 
319               iRCU, sideStr[iside], iRCU, sideStr[iside]);
320       cout << "executing " << cmd << endl;
321       gSystem->Exec(cmd);
322       sprintf(cmd, "mv RCU%d%s.data.unsorted tmp/.", 
323               iRCU, sideStr[iside]);
324       cout << "executing " << cmd << endl;
325       gSystem->Exec(cmd);
326     }
327   }
328
329 }