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