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