]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EMCAL/mapping/WriteRCUs.C
Changes needed for evaporation and fragmentation
[u/mrichter/AliRoot.git] / EMCAL / mapping / WriteRCUs.C
CommitLineData
5cfb4b82 1/*
2ROOT Macro to generate ascii files for AliCaloAltroMapping; offline decoder
3- based on the map file produced by EMCALNumbering.C
4
5Update: 20 Aug 2008 - update to write separate files for A and C sides +
6 added TRU and LED channels also..
7
8LED channels look like regular FEE data; just from rcu=0, branch=0, FEC=0
9TRU 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
12Some further documentation is available at:
13http://cern.ch/dsilverm/mapping/emcal_mapping.html
14
15Author: David Silvermyr, ORNL; silvermy@mail.phy.ornl.gov
16*/
17
18// First we define some constants - the main method WriteRCUs comes later
6d3af2f0 19const int kNTRU = 3; // per SM
20const int kNTRUChanBlocks = 128; // max. per TRU
5cfb4b82 21const int kNLED = 24; // one per StripModule
22
23const int kNGAIN = 2; // low (0) and high (1)
24const int kNFEEChannelsPerRCU = 1152;
25int NChannelsPerRCU[2];
26// RCU 0: FEE + NTRUChanBlocks + NLED*NGAIN
27NChannelsPerRCU[0] = kNFEEChannelsPerRCU + kNTRUChanBlocks + kNLED*kNGAIN;
28// RCU 1: FEE + 2*NTRUChanBlocks
29NChannelsPerRCU[1] = kNFEEChannelsPerRCU + 2*kNTRUChanBlocks;
30
31const int kMaxHWAddress = (1 << 11) // branch
32 | (9 << 7) // FEC
33 | (4 << 4) // Altro
34 | 0xf; // channel
35
36const int kNRCU = 2;
37const int kNSides = 2;
38char * sideStr[] = {"A", "C"};
39
40const int kFirstFEC = 1;
41const int kNFECPerGTL = 9; // NFEC/NGTL
42
43int 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..
52void 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);
5cfb4b82 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,
6d3af2f0 238 ichan/16, ichan%16 );
5cfb4b82 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}