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