Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : /*
17 :
18 :
19 :
20 :
21 : Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
22 : */
23 :
24 :
25 : #include "AliEMCALTriggerTRU.h"
26 : #include "AliEMCALTriggerPatch.h"
27 : #include "AliEMCALTriggerTRUDCSConfig.h"
28 : #include "AliLog.h"
29 :
30 : #include <TClonesArray.h>
31 : #include <TSystem.h>
32 : #include <Riostream.h>
33 : #include <TFile.h>
34 : #include <TROOT.h>
35 :
36 : namespace
37 : {
38 : const Int_t kTimeBins = 16; // number of sampling bins of the FastOR signal
39 : const Int_t kTimeWindowSize = 4; //
40 : }
41 :
42 : using std::ofstream;
43 : using std::endl;
44 : using std::ios_base;
45 42 : ClassImp(AliEMCALTriggerTRU)
46 :
47 : //________________
48 0 : AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard(),
49 0 : fDCSConfig(0x0),
50 0 : fL0Time(0)
51 0 : {
52 : // Ctor
53 :
54 0 : for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
55 0 : }
56 :
57 : //________________
58 : AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALTriggerTRUDCSConfig* dcsConf, const TVector2& rSize, Int_t mapType) :
59 60 : AliEMCALTriggerBoard(rSize),
60 60 : fDCSConfig(dcsConf),
61 60 : fL0Time(0)
62 300 : {
63 : // Ctor
64 :
65 2972280 : for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
66 :
67 60 : TVector2 size;
68 :
69 120 : if (dcsConf->GetL0SEL() & 0x0001) // 4-by-4
70 : {
71 60 : size.Set( 1. , 1. );
72 120 : SetSubRegionSize( size );
73 :
74 60 : size.Set( 2. , 2. );
75 60 : SetPatchSize( size );
76 : }
77 : else // 2-by-2
78 : {
79 : size.Set( 1. , 1. );
80 0 : SetSubRegionSize( size );
81 :
82 0 : size.Set( 1. , 1. );
83 0 : SetPatchSize( size );
84 : }
85 :
86 3000 : for (Int_t ietam=0;ietam<24;ietam++)
87 : {
88 14400 : for (Int_t iphim=0;iphim<4;iphim++)
89 : {
90 : // idx: 0..95 since iphim: 0..11 ietam: 0..23
91 17280 : Int_t idx = ( !mapType ) ? ( 3 - iphim ) + ietam * 4 : iphim + (23 - ietam) * 4;
92 :
93 : // Build a matrix used to get TRU digit id (ADC channel) from (eta,phi)|SM
94 5760 : fMap[ietam][iphim] = idx; // [0..11][0..3] namely [eta][phi] in SM
95 : }
96 : }
97 120 : }
98 :
99 : //________________
100 : AliEMCALTriggerTRU::~AliEMCALTriggerTRU()
101 240 : {
102 : // Dtor
103 240 : }
104 :
105 : //________________
106 : void AliEMCALTriggerTRU::ShowFastOR(Int_t iTimeWindow, Int_t iChannel)
107 : {
108 : // Dump
109 :
110 : Int_t iChanF, iChanL;
111 :
112 0 : if (iChannel != -1) iChanF = iChanL = iChannel;
113 : else
114 : {
115 : iChanF = 0;
116 : iChanL = 95;
117 : }
118 :
119 0 : for (Int_t i=iChanF;i<iChanL+1;i++)
120 : {
121 0 : printf("\tChannel: %2d - ",i);
122 0 : for (Int_t j=0;j<60;j++)
123 : {
124 0 : if (j == iTimeWindow)
125 0 : printf(" | %4d",fADC[i][j]);
126 0 : else if (j == iTimeWindow+kTimeWindowSize-1)
127 0 : printf(" %4d |",fADC[i][j]);
128 : else
129 0 : printf(" %4d",fADC[i][j]);
130 : }
131 :
132 0 : printf("\n");
133 : }
134 0 : }
135 :
136 : //________________
137 : Int_t AliEMCALTriggerTRU::L0()
138 : {
139 : // L0 algo depending on TRU fw version
140 :
141 480 : const Int_t xsize = Int_t(fRegionSize->X());
142 240 : const Int_t ysize = Int_t(fRegionSize->Y());
143 :
144 : Int_t asum = 0;
145 12000 : for (Int_t j = 0; j < xsize; j++) {
146 57600 : for (Int_t k = 0; k < ysize; k++) {
147 783360 : for (Int_t l = 0; l < kTimeBins; l++) {
148 368640 : asum += fADC[fMap[j][k]][l];
149 : }
150 : }
151 : }
152 :
153 : // TRU has no signal, return!
154 480 : if (!asum) {
155 678 : AliDebug(999,"=== TRU has no signal ===");
156 226 : return 0;
157 : }
158 :
159 282 : AliDebug(999,Form("=== TRU PF: %x",fDCSConfig->GetSELPF()));
160 :
161 14 : UInt_t ma = fDCSConfig->GetSELPF() & 0xffff;
162 :
163 : // Set default peak finder if null
164 14 : if (!ma) ma = 0x1e1f;
165 :
166 14 : int nb = ma & 0x7f;
167 :
168 14 : ma = (ma >> 8) & 0x7f;
169 :
170 42 : AliDebug(999,Form("=== TRU fw version %x ===",fDCSConfig->GetFw()));
171 :
172 28 : if (fDCSConfig->GetFw() < 0x4d) {
173 28 : return L0v0(nb, ma);
174 : } else {
175 0 : return L0v1(nb, ma);
176 : }
177 240 : }
178 :
179 : //________________
180 : Int_t AliEMCALTriggerTRU::L0v0(int mask, int pattern)
181 : {
182 : // L0 issuing condition is: (2x2 PF) AND (4x4 > thres)
183 :
184 56 : AliDebug(999,"=== Running TRU L0 algorithm version 0 ===");
185 :
186 14 : const Int_t xsize = Int_t(fRegionSize->X());
187 14 : const Int_t ysize = Int_t(fRegionSize->Y());
188 :
189 14 : Int_t **othr = new Int_t*[xsize];
190 14 : Int_t **patt = new Int_t*[xsize];
191 14 : Int_t **buff = new Int_t*[xsize];
192 :
193 700 : for (Int_t x = 0; x < xsize; x++) {
194 336 : othr[x] = new Int_t[ysize];
195 336 : patt[x] = new Int_t[ysize];
196 336 : buff[x] = new Int_t[ysize];
197 : }
198 :
199 700 : for (Int_t i = 0; i < xsize; i++) {
200 3360 : for (Int_t j = 0; j < ysize; j++) {
201 1344 : othr[i][j] = 0;
202 1344 : patt[i][j] = 0;
203 1344 : buff[i][j] = 0;
204 : }
205 : }
206 :
207 : // Time sliding window algorithm
208 392 : for (int i = 0; i <= (kTimeBins - kTimeWindowSize); i++)
209 : {
210 546 : AliDebug(999,Form("----------- Time window: %d\n",i));
211 :
212 546 : if (AliDebugLevel()) ShowFastOR(i, -1);
213 :
214 9100 : for (int j = 0; j < xsize; j++) {
215 43680 : for (int k = 0; k < ysize; k++) {
216 :
217 : // if (
218 : // !(j % int(fSubRegionSize->X()))
219 : // &&
220 : // !(k % int(fSubRegionSize->Y()))
221 : // &&
222 : // (j + int(fPatchSize->X() * fSubRegionSize->X()) <= xsize)
223 : // &&
224 : // (k + int(fPatchSize->Y() * fSubRegionSize->Y()) <= ysize)
225 : // )
226 : // {
227 : // int sum = 0;
228 : //
229 : // for (int l = 0; l < int(fPatchSize->X() * fSubRegionSize->X()); l++)
230 : // for (int m = 0; m < int(fPatchSize->Y() * fSubRegionSize->Y()); m++) sum += fRegion[j + l][k + m];
231 : //
232 : // if (sum > int(fDCSConfig->GetGTHRL0())) {
233 : // AliDebug(999,Form("----------- Patch (%2d,%2d) is over threshold\n", j, k));
234 : // othr[j][k] = sum;
235 : // }
236 : // }
237 :
238 17472 : buff[j][k] = fRegion[j][k];
239 :
240 17472 : fRegion[j][k] = 0;
241 174720 : for (Int_t l = i; l < i + kTimeWindowSize; l++) fRegion[j][k] += fADC[fMap[j][k]][l];
242 :
243 17472 : if (fRegion[j][k] > buff[j][k]) {
244 128 : patt[j][k] |= 0x1;
245 128 : }
246 :
247 18546 : if (patt[j][k]) AliDebug(999,Form("----------- (%2d,%2d) New: %d Old: %d patt: %x / pattern: %x / mask: %x", j, k, fRegion[j][k], buff[j][k], patt[j][k], pattern, mask));
248 : }
249 : }
250 :
251 8736 : for (int j = 0; j <= int(fRegionSize->X() - fPatchSize->X() * fSubRegionSize->X()); j += int(fSubRegionSize->X())) {
252 33488 : for (int k = 0; k <= int(fRegionSize->Y() - fPatchSize->Y() * fSubRegionSize->Y()); k += int(fSubRegionSize->Y())) {
253 :
254 : // if (!othr[j][k]) continue;
255 12558 : int sizeX = int(fPatchSize->X() * fSubRegionSize->X());
256 12558 : int sizeY = int(fPatchSize->Y() * fSubRegionSize->Y());
257 :
258 : int foundPeak = 0;
259 : int sum = 0;
260 :
261 75348 : for (int l = 0; l < sizeX; l++) {
262 150696 : for (int m = 0; m < sizeY; m++) {
263 50232 : sum += fRegion[j + l][k + m];
264 :
265 50307 : if ((patt[j + l][k + m] & mask) == pattern) foundPeak++;
266 : }
267 : }
268 :
269 13232 : if (sum > int(fDCSConfig->GetGTHRL0())) othr[j][k] = sum;
270 :
271 12622 : if (foundPeak && othr[j][k]) {
272 :
273 64 : new((*fPatches)[fPatches->GetEntriesFast()]) AliEMCALTriggerPatch(j, k, othr[j][k], i);
274 :
275 64 : AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At(fPatches->GetEntriesFast() - 1);
276 :
277 192 : if (AliDebugLevel()) p->Print("");
278 :
279 64 : const Int_t psize = sizeX * sizeY; // Number of FastOR in the patch
280 :
281 64 : Int_t* idx = new Int_t[psize];
282 :
283 384 : for (Int_t l = 0; l < sizeX; l++)
284 : {
285 768 : for (Int_t m = 0; m < sizeY; m++)
286 : {
287 256 : Int_t index = l * sizeY + m;
288 :
289 256 : idx[index] = fMap[int(j * fSubRegionSize->X()) + l][int(k * fSubRegionSize->Y()) + m];
290 :
291 256 : if ((patt[j + l][k + m] & mask) == (pattern & mask)) {
292 : // cout << "setting peak at " << l << " " << m << endl;
293 75 : p->SetPeak(l, m, sizeX, sizeY);
294 75 : }
295 :
296 768 : if (AliDebugLevel() >= 999) ShowFastOR(i, idx[index]);
297 : }
298 : }
299 :
300 128 : delete [] idx;
301 64 : }
302 : }
303 : }
304 :
305 297 : if (fPatches->GetEntriesFast() && !fL0Time) {
306 : // Stop the algo when at least one patch is found ( thres & max )
307 7 : fL0Time = i;
308 :
309 : // break;
310 7 : }
311 :
312 9100 : for (int j = 0; j < xsize; j++)
313 43680 : for (int k = 0; k < ysize; k++) patt[j][k] <<= 1;
314 : }
315 :
316 700 : for (Int_t x = 0; x < xsize; x++) {
317 672 : delete [] othr[x];
318 672 : delete [] patt[x];
319 672 : delete [] buff[x];
320 : }
321 :
322 28 : delete [] othr;
323 28 : delete [] patt;
324 28 : delete [] buff;
325 :
326 14 : return fPatches->GetEntriesFast();
327 0 : }
328 :
329 : //________________
330 : Int_t AliEMCALTriggerTRU::L0v1(int mask, int pattern)
331 : {
332 : // L0 issuing condition is: (4x4 PF) AND (4x4 > thres)
333 :
334 0 : AliDebug(999,"=== Running TRU L0 algorithm version 1 ===");
335 :
336 0 : const Int_t xsize = Int_t(fRegionSize->X());
337 0 : const Int_t ysize = Int_t(fRegionSize->Y());
338 :
339 0 : Int_t **othr = new Int_t*[xsize];
340 0 : Int_t **buff = new Int_t*[xsize];
341 0 : Int_t **patt = new Int_t*[xsize];
342 :
343 0 : for (Int_t i = 0; i < xsize; i++) {
344 0 : buff[i] = new Int_t[ysize];
345 0 : patt[i] = new Int_t[ysize];
346 0 : othr[i] = new Int_t[ysize];
347 : }
348 :
349 0 : for (Int_t i = 0; i < xsize; i++) for (Int_t j = 0; j < ysize; j++) {
350 0 : othr[i][j] = 0;
351 0 : patt[i][j] = 0;
352 0 : buff[i][j] = 0;
353 : }
354 :
355 : // Time sliding window algorithm
356 0 : for (Int_t i = 0; i <= (kTimeBins - kTimeWindowSize); i++) {
357 :
358 0 : AliDebug(999,Form("----------- Time window: %d\n",i));
359 :
360 0 : for (int j = 0; j < xsize; j++) {
361 0 : for (int k = 0; k < ysize; k++) {
362 :
363 : // if (
364 : // !(j % int(fSubRegionSize->X()))
365 : // &&
366 : // !(k % int(fSubRegionSize->Y()))
367 : // &&
368 : // (j + int(fPatchSize->X() * fSubRegionSize->X()) <= xsize)
369 : // &&
370 : // (k + int(fPatchSize->Y() * fSubRegionSize->Y()) <= ysize)
371 : // )
372 : // {
373 : // int sum = 0;
374 : //
375 : // for (int l = 0; l < int(fPatchSize->X() * fSubRegionSize->X()); l++)
376 : // for (int m = 0; m < int(fPatchSize->Y() * fSubRegionSize->Y()); m++) sum += fRegion[j + l][k + m];
377 : //
378 : // if (sum > buff[j][k]) patt[j][k] |= 0x1;
379 : //
380 : // AliDebug(999,Form("----------- Patch (%2d,%2d) has sum %d while its whole time pattern is %x\n", j, k, sum, patt[j][k]));
381 : //
382 : // buff[j][k] = sum;
383 : //
384 : // if (sum > int(fDCSConfig->GetGTHRL0())) {
385 : // AliDebug(999,Form("----------- Patch (%2d,%2d) is over threshold\n", j, k));
386 : // othr[j][k] = sum;
387 : // }
388 : // }
389 :
390 0 : fRegion[j][k] = 0;
391 0 : for (Int_t l = i; l < i + kTimeWindowSize; l++) fRegion[j][k] += fADC[fMap[j][k]][l];
392 : }
393 : }
394 :
395 0 : for (int j = 0; j <= int(fRegionSize->X() - fPatchSize->X() * fSubRegionSize->X()); j += int(fSubRegionSize->X())) {
396 0 : for (int k = 0; k <= int(fRegionSize->Y() - fPatchSize->Y() * fSubRegionSize->Y()); k += int(fSubRegionSize->Y())) {
397 :
398 : int sum = 0;
399 :
400 0 : for (int l = 0; l < int(fPatchSize->X() * fSubRegionSize->X()); l++)
401 0 : for (int m = 0; m < int(fPatchSize->Y() * fSubRegionSize->Y()); m++) sum += fRegion[j + l][k + m];
402 :
403 0 : if (sum > buff[j][k]) patt[j][k] |= 0x1;
404 :
405 0 : if (sum > int(fDCSConfig->GetGTHRL0())) {
406 0 : AliDebug(999,Form("----------- Patch (%2d,%2d) is over threshold\n", j, k));
407 :
408 0 : othr[j][k] = sum;
409 0 : }
410 :
411 0 : AliDebug(999,Form("----------- Patch (%2d,%2d) has sum %d while its whole time pattern is %x\n", j, k, sum, patt[j][k]));
412 :
413 0 : buff[j][k] = sum;
414 :
415 0 : if (othr[j][k] && ((patt[j][k] & mask) == (pattern & mask))) {
416 :
417 0 : new((*fPatches)[fPatches->GetEntriesFast()]) AliEMCALTriggerPatch(j, k, othr[j][k], i);
418 :
419 : // AliDebug(999,Form("=== New L0 patch at (%2d,%2d) time: %2d",j, k, i));
420 :
421 0 : int sizeX = int(fPatchSize->X() * fSubRegionSize->X());
422 0 : int sizeY = int(fPatchSize->Y() * fSubRegionSize->Y());
423 :
424 0 : for (int xx = 0; xx < sizeX; xx++) {
425 0 : for (int yy = 0; yy < sizeY; yy++) {
426 0 : ((AliEMCALTriggerPatch*)fPatches->At(fPatches->GetEntriesFast() - 1))->SetPeak(xx, yy, sizeX, sizeY);
427 : }
428 : }
429 :
430 0 : AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At(fPatches->GetEntriesFast() - 1);
431 :
432 0 : if (AliDebugLevel()) p->Print("");
433 0 : }
434 : }
435 : }
436 :
437 0 : if (fPatches->GetEntriesFast() && !fL0Time) {
438 0 : fL0Time = i;
439 :
440 : // break;
441 0 : }
442 :
443 0 : for (int j = 0; j < xsize; j++)
444 0 : for (int k = 0; k < ysize; k++) patt[j][k] <<= 1;
445 : }
446 :
447 0 : for (Int_t x = 0; x < xsize; x++) {
448 0 : delete [] othr[x];
449 0 : delete [] patt[x];
450 0 : delete [] buff[x];
451 : }
452 :
453 0 : delete [] othr;
454 0 : delete [] patt;
455 0 : delete [] buff;
456 :
457 0 : return fPatches->GetEntriesFast();
458 0 : }
459 :
460 : //________________
461 : void AliEMCALTriggerTRU::SetADC( Int_t channel, Int_t bin, Int_t sig )
462 : {
463 : //Set ADC value
464 458 : if (channel > 95 || bin > 255) {
465 0 : AliError("TRU has 96 ADC channels and 256 bins only!");
466 0 : }
467 : else{
468 458 : if (((fDCSConfig->GetMaskReg(int(channel / 16)) >> (channel % 16)) & 0x1) == 0) fADC[channel][bin] = sig;
469 : }
470 229 : }
471 :
472 : //________________
473 : void AliEMCALTriggerTRU::GetL0Region(const int time, Int_t arr[][4])
474 : {
475 240 : Int_t r0 = time - fDCSConfig->GetRLBKSTU();
476 :
477 120 : if (r0 < 0)
478 : {
479 0 : AliError(Form("TRU buffer not accessible! time: %d rollback: %d", time, fDCSConfig->GetRLBKSTU()));
480 0 : return;
481 : }
482 :
483 6000 : for (Int_t i = 0; i < fRegionSize->X(); i++)
484 : {
485 28800 : for (Int_t j = 0; j < fRegionSize->Y(); j++)
486 : {
487 115200 : for (Int_t k = r0; k < r0 + kTimeWindowSize; k++)
488 : {
489 46080 : arr[i][j] += fADC[fMap[i][j]][k];
490 : }
491 : }
492 : }
493 240 : }
494 :
495 : //________________
496 : void AliEMCALTriggerTRU::SaveRegionADC(Int_t iTRU, Int_t iEvent)
497 : {
498 : // O for STU Hw
499 : //
500 0 : gSystem->Exec(Form("mkdir -p Event%d",iEvent));
501 :
502 0 : ofstream outfile(Form("Event%d/data_TRU%d.txt",iEvent,iTRU),ios_base::trunc);
503 :
504 0 : for (Int_t i=0;i<96;i++)
505 : {
506 0 : Int_t ietam = 23 - i/4;
507 :
508 0 : Int_t iphim = 3 - i%4;
509 :
510 0 : outfile << fRegion[ietam][iphim] << endl;
511 : }
512 :
513 0 : outfile.close();
514 0 : }
515 :
516 : //________________
517 : void AliEMCALTriggerTRU::Reset()
518 : {
519 : // Reset
520 :
521 480 : fPatches->Delete();
522 :
523 240 : ZeroRegion();
524 :
525 11889120 : for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
526 240 : }
527 :
|