]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliEMCALTriggerTRU.cxx
trigger code update from 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         // 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                         ZeroRegion();
235                         continue;
236                 }
237                 
238                 // Threshold 
239                 // FIXME: for now consider just one threshold for all patches, should consider one per patch?
240                 // ANSWE: both solutions will be implemented in the TRU
241                 // return the list of patches above threshold
242                 // Theshold checked out from OCDB
243                 
244                 SlidingWindow( kGamma, fDCSConfig->GetGTHRL0() );
245                 
246 //              for(Int_t j=0; j<fRegionSize->X(); j++)
247 //                      for (Int_t k=0; k<fRegionSize->Y(); k++) fRegion[j][k] = fRegion[j][k]>>2; // go to 12b before shipping to STU
248                 
249                 for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
250                 {
251                         AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At( j );
252
253                         if ( AliDebugLevel() ) p->Print("");
254
255                         TVector2 v; p->Position(v);
256                         
257                         Int_t sizeX = (Int_t)(fPatchSize->X() * fSubRegionSize->X());
258                         
259                         Int_t sizeY = (Int_t)(fPatchSize->Y() * fSubRegionSize->Y());
260                         
261                         const Int_t psize =  sizeX * sizeY; // Number of FastOR in the patch
262                         
263                         Int_t foundPeak = 0;
264                         
265                         Int_t* idx = new Int_t[psize];
266                         
267                         for (Int_t xx=0;xx<sizeX;xx++) 
268                         {
269                                 for (Int_t yy=0;yy<sizeY;yy++) 
270                                 {   
271                                         Int_t index = xx*sizeY+yy;
272                                         
273                                         idx[index] = fMap[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels 
274                                         
275                                         if (peaks[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]) foundPeak++;
276                                         
277                                         if ( AliDebugLevel() ) 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
298                 {
299                         break;     // Stop the algo when at least one patch is found ( thres & max )
300                 }
301         }
302         
303         //Delete, avoid leak
304         for (Int_t x = 0; x < xsize; x++)
305         {
306                 for (Int_t y = 0; y < ysize; y++)
307                 {
308                         delete [] buffer[x][y];
309                 }
310                 delete [] buffer[x];
311         }
312         delete [] buffer;
313         
314         return fPatches->GetEntriesFast();
315 }
316
317 //________________
318 void AliEMCALTriggerTRU::SetADC( Int_t channel, Int_t bin, Int_t sig )
319 {
320         //
321         if (channel>95) AliError("TRU has 96 ADC channels only!");
322         fADC[channel][bin] = sig;
323 }
324
325 //________________
326 void AliEMCALTriggerTRU::SaveRegionADC(Int_t iTRU, Int_t iEvent)
327 {
328         // O for STU Hw
329         //
330         gSystem->Exec(Form("mkdir -p Event%d",iEvent));
331         
332         ofstream outfile(Form("Event%d/data_TRU%d.txt",iEvent,iTRU),ios_base::trunc);
333         
334         for (Int_t i=0;i<96;i++) 
335         {
336                 Int_t ietam = 23 - i/4;
337         
338                 Int_t iphim =  3 - i%4;
339                 
340                 outfile << fRegion[ietam][iphim] << endl;
341         }
342
343         outfile.close();
344 }
345
346 //________________
347 void AliEMCALTriggerTRU::Reset()
348 {
349         //
350         fPatches->Delete();
351         
352         ZeroRegion();
353         
354         for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
355 }
356