Coverity fixes
[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         const Int_t kNup            =  2; // 
39         const Int_t kNdown          =  1; // 
40 }
41
42 ClassImp(AliEMCALTriggerTRU)
43
44 //________________
45 AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard(),
46 fDCSConfig(0x0),
47 fL0Time(0)
48 {
49         // Ctor
50         
51         for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
52 }
53
54 //________________
55 AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALTriggerTRUDCSConfig* dcsConf, const TVector2& rSize, Int_t mapType) : 
56 AliEMCALTriggerBoard(rSize),
57 fDCSConfig(dcsConf),
58 fL0Time(0)
59 {
60         // Ctor
61         
62         for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
63
64         TVector2 size;
65         
66         if (dcsConf->GetL0SEL() & 0x0001) // 4-by-4
67         {
68                 size.Set( 1. , 1. );
69                 SetSubRegionSize( size );
70                 
71                 size.Set( 2. , 2. );
72                 SetPatchSize( size );
73         }       
74         else                              // 2-by-2
75         {
76                 size.Set( 1. , 1. );
77                 SetSubRegionSize( size );
78                 
79                 size.Set( 1. , 1. );
80                 SetPatchSize( size );   
81         }       
82         
83         for (Int_t ietam=0;ietam<24;ietam++)
84         {
85                 for (Int_t iphim=0;iphim<4;iphim++)
86                 {
87                         // idx: 0..95 since iphim: 0..11 ietam: 0..23
88                         Int_t idx = ( !mapType ) ? ( 3 - iphim ) + ietam * 4 : iphim + (23 - ietam) * 4;        
89         
90                         // Build a matrix used to get TRU digit id (ADC channel) from (eta,phi)|SM
91                         fMap[ietam][iphim] = idx; // [0..11][0..3] namely [eta][phi] in SM
92                 }
93         }
94 }
95
96 //________________
97 AliEMCALTriggerTRU::~AliEMCALTriggerTRU()
98 {
99         // Dtor
100 }
101
102 //________________
103 void AliEMCALTriggerTRU::ShowFastOR(Int_t iTimeWindow, Int_t iChannel)
104 {
105         // Dump
106         
107         Int_t iChanF, iChanL;
108         
109         if (iChannel != -1) iChanF = iChanL = iChannel;
110         else
111         {
112                 iChanF =  0;
113                 iChanL = 96;
114         }
115         
116         for (Int_t i=iChanF;i<iChanL+1;i++)
117         {
118                 printf("\tChannel: %2d - ",i);
119                 for (Int_t j=0;j<60;j++) 
120                 {
121                         if (j == iTimeWindow)
122                                 printf(" | %4d",fADC[i][j]);
123                         else if (j == iTimeWindow+kTimeWindowSize-1)
124                                 printf(" %4d |",fADC[i][j]);
125                         else
126                                 printf(" %4d",fADC[i][j]);
127                 }
128                 
129                 printf("\n");
130         }
131 }
132
133 //________________
134 Int_t AliEMCALTriggerTRU::L0()
135 {
136         // L0 issuing condition is: (2 up & 1 down) AND (patch sum > thres)
137         // fill a matrix to support sliding window
138         // compute the time sum for all the FastOR of a given TRU
139         // and then move the space window
140
141         AliDebug(999,"=== Running TRU L0 algorithm ===");
142         const Int_t xsize    = Int_t(fRegionSize->X());
143         const Int_t ysize    = Int_t(fRegionSize->Y());
144         const Int_t zsize    = kNup+kNdown;
145
146         Int_t ***buffer = new Int_t**[xsize];
147         for (Int_t x = 0; x < xsize; x++)
148         {
149                 buffer[x] = new Int_t*[ysize];
150                 
151                 for (Int_t y = 0; y < ysize; y++)
152                 {
153                         buffer[x][y] = new Int_t[zsize];
154                 }
155         }
156         
157         for (Int_t i = 0; i < fRegionSize->X(); i++) 
158                 for (Int_t j = 0; j < fRegionSize->Y(); j++) 
159                         for (Int_t k = 0; k < kNup + kNdown; k++) buffer[i][j][k] = 0;
160                 
161         // Time sliding window algorithm
162         for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++) 
163         {
164                 AliDebug(999,Form("----------- Time window: %d\n",i));
165                 
166                 for (Int_t j=0; j<fRegionSize->X(); j++)
167                 {               
168                         for (Int_t k=0; k<fRegionSize->Y(); k++)
169                         {
170                                 for (Int_t l=i; l<i+kTimeWindowSize; l++) 
171                                 {
172                                         // [eta][phi][time]
173                                         fRegion[j][k] += fADC[fMap[j][k]][l];   
174                                 }
175                                 
176                                 buffer[j][k][i%(kNup + kNdown)] = fRegion[j][k];
177                                 
178                                 if ( i > kNup + kNdown - 1 ) 
179                                 {       
180                                         for (Int_t v = 0; v < kNup + kNdown - 1; v++) buffer[j][k][v] =  buffer[j][k][v+1];
181         
182                                         buffer[j][k][kNup + kNdown - 1] = fRegion[j][k];
183                                 }
184                                 else
185                                 {
186                                         buffer[j][k][i] = fRegion[j][k];
187                                 }
188                                 
189 //                              if (kTimeWindowSize > 4) fRegion[j][k] = fRegion[j][k] >> 1; // truncate time sum to fit 14b
190                         }
191                 }
192                 
193                 // Don't start to evaluate space sum if a peak can't be findable
194                 if (i < kNup + kNdown - 1) 
195                 {
196                         ZeroRegion();
197                         continue; 
198                 }
199                 
200                 Int_t **peaks = new Int_t*[xsize];
201                 for (Int_t x = 0; x < xsize; x++)
202                 {
203                         peaks[x] = new Int_t[ysize];
204                 }
205                 
206                 for (Int_t j=0; j<fRegionSize->X(); j++) for (Int_t k=0; k<fRegionSize->Y(); k++) peaks[j][k] = 0;
207                 
208                 Int_t nPeaks = 0;
209                 
210                 for (Int_t j=0; j<fRegionSize->X(); j++)
211                 {               
212                         for (Int_t k=0; k<fRegionSize->Y(); k++)
213                         {
214                                 Int_t foundU = 0;
215                                 
216                                 Int_t foundD = 0;
217                 
218                                 for (Int_t l=   1;l<kNup       ;l++) foundU = ( buffer[j][k][l]> buffer[j][k][l-1] && buffer[j][k][l-1] ) ? 1 : 0;
219                                 
220                                 for (Int_t l=kNup;l<kNup+kNdown;l++) foundD = ( buffer[j][k][l]<=buffer[j][k][l-1] && buffer[j][k][l  ] ) ? 1 : 0; 
221                 
222                                 if ( foundU && foundD ) 
223                                 {
224                                         peaks[j][k] = 1;
225                                         nPeaks++;
226                                 }
227                         }
228                 }
229
230                 if (!nPeaks)
231                 {
232                         ZeroRegion();
233
234                         for (Int_t x = 0; x < xsize; x++)
235                         {
236                           delete [] peaks[x];
237                         }
238                         delete [] peaks;
239
240                         continue;
241                 }
242                 
243                 // Threshold 
244                 // FIXME: for now consider just one threshold for all patches, should consider one per patch?
245                 // ANSWE: both solutions will be implemented in the TRU
246                 // return the list of patches above threshold
247                 // Theshold checked out from OCDB
248                 
249                 SlidingWindow(kL0, fDCSConfig->GetGTHRL0(), i);
250                 
251 //              for(Int_t j=0; j<fRegionSize->X(); j++)
252 //                      for (Int_t k=0; k<fRegionSize->Y(); k++) fRegion[j][k] = fRegion[j][k]>>2; // go to 12b before shipping to STU
253                 
254                 for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
255                 {
256                         AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At( j );
257
258                         if ( AliDebugLevel() ) p->Print("");
259
260                         TVector2 v; p->Position(v);
261                         
262                         Int_t sizeX = (Int_t)(fPatchSize->X() * fSubRegionSize->X());
263                         
264                         Int_t sizeY = (Int_t)(fPatchSize->Y() * fSubRegionSize->Y());
265                         
266                         const Int_t psize =  sizeX * sizeY; // Number of FastOR in the patch
267                         
268                         Int_t foundPeak = 0;
269                         
270                         Int_t* idx = new Int_t[psize];
271                         
272                         for (Int_t xx=0;xx<sizeX;xx++) 
273                         {
274                                 for (Int_t yy=0;yy<sizeY;yy++) 
275                                 {   
276                                         Int_t index = xx*sizeY+yy;
277                                         
278                                         idx[index] = fMap[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels 
279                                         
280                                         if (peaks[int(v.X() * fSubRegionSize->X()) + xx][int(v.Y() * fSubRegionSize->Y()) + yy]) 
281                                         {
282                                                 foundPeak++;
283                                                 
284                                                 p->SetPeak(xx, yy, sizeX, sizeY);
285                                         }
286                                         
287                                         if (AliDebugLevel() >= 999) ShowFastOR(i, idx[index]);
288                                 }
289                         }
290                         
291                         delete [] idx;
292
293                         if ( !foundPeak ) 
294                         {
295                                 fPatches->RemoveAt( j );
296                                 fPatches->Compress();
297                         }
298                 }
299                 
300                 //Delete, avoid leak
301                 for (Int_t x = 0; x < xsize; x++)
302                 {
303                         delete [] peaks[x];
304                 }
305                 delete [] peaks;
306
307                 if ( !fPatches->GetEntriesFast() ) // No patch left
308                         ZeroRegion();
309                 else                             // Stop the algo when at least one patch is found ( thres & max )
310                 {
311                         fL0Time = i;
312                         
313                         for (Int_t xx = 0; xx < fRegionSize->X(); xx++) 
314                         {
315                                 for (Int_t yy = 0; yy < fRegionSize->Y(); yy++) 
316                                 {   
317                                         // Prepare data to be sent to STU for further L1 processing
318                                         // Sent time sum (rollback tuning) is the one before L0 is issued (maximum time sum)
319                                         fRegion[xx][yy] = buffer[xx][yy][1];
320                                 }
321                         }
322                         
323                         break;
324                 }               
325         }
326         
327         //Delete, avoid leak
328         for (Int_t x = 0; x < xsize; x++)
329         {
330                 for (Int_t y = 0; y < ysize; y++)
331                 {
332                         delete [] buffer[x][y];
333                 }
334                 delete [] buffer[x];
335         }
336         delete [] buffer;
337         
338         return fPatches->GetEntriesFast();
339 }
340
341 //________________
342 void AliEMCALTriggerTRU::SetADC( Int_t channel, Int_t bin, Int_t sig )
343 {
344   //Set ADC value
345   if (channel > 95 || bin > 255) {
346     AliError("TRU has 96 ADC channels and 256 bins only!");
347   }
348   else{ 
349     fADC[channel][bin] = sig;
350   }
351 }
352
353 //________________
354 void AliEMCALTriggerTRU::GetL0Region(const int time, Int_t arr[][4])
355 {
356         Int_t r0 = time + fDCSConfig->GetRLBKSTU();
357         
358         if (r0 < 0) 
359         {
360                 AliError(Form("TRU buffer not accessible! time: %d rollback: %d", time, fDCSConfig->GetRLBKSTU()));
361                 return;
362         }
363         
364         for (Int_t i = 0; i < fRegionSize->X(); i++) 
365         {
366                 for (Int_t j = 0; j < fRegionSize->Y(); j++) 
367                 {
368                         for (Int_t k = r0; k < r0 + kTimeWindowSize; k++)
369                         {
370                                 arr[i][j] += fADC[fMap[i][j]][k];
371                         }
372                 }
373         }
374 }
375
376 //________________
377 void AliEMCALTriggerTRU::SaveRegionADC(Int_t iTRU, Int_t iEvent)
378 {
379         // O for STU Hw
380         //
381         gSystem->Exec(Form("mkdir -p Event%d",iEvent));
382         
383         ofstream outfile(Form("Event%d/data_TRU%d.txt",iEvent,iTRU),ios_base::trunc);
384         
385         for (Int_t i=0;i<96;i++) 
386         {
387                 Int_t ietam = 23 - i/4;
388         
389                 Int_t iphim =  3 - i%4;
390                 
391                 outfile << fRegion[ietam][iphim] << endl;
392         }
393
394         outfile.close();
395 }
396
397 //________________
398 void AliEMCALTriggerTRU::Reset()
399 {
400         // Reset
401         
402         fPatches->Delete();
403         
404         ZeroRegion();
405         
406         for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
407 }
408