Coding conventions
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALTriggerTRU.cxx
CommitLineData
916f1e76 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
21Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
22*/
23
24
25#include "AliEMCALTriggerTRU.h"
26#include "AliEMCALTriggerPatch.h"
27#include "AliEMCALDigit.h"
28#include "AliEMCALTriggerSTU.h"
29#include "AliEMCALCalibData.h"
30#include "AliLog.h"
31
32#include <TF1.h>
33#include <TMath.h>
34#include <TClonesArray.h>
35#include <TSystem.h>
36#include <Riostream.h>
37
38namespace
39{
40 const Int_t kTimeBins = 64; // number of sampling bins of the FastOR signal
41 const Int_t kTimeWindowSize = 4; //
42 const Int_t kNup = 2; //
43 const Int_t kNdown = 1; //
44}
45
46ClassImp(AliEMCALTriggerTRU)
47
48//________________
49AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard()//,
50//fDigits( 0x0 )
51{
52 //
53 for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
54}
55
56//________________
57AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALCalibData *calibData, const TVector2& rSize, Int_t mapType) :
58AliEMCALTriggerBoard(calibData, rSize)
59{
60 //
61 for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
62
63 // FIXME: use of class AliEMCALTriggerParam to get size
64 TVector2 size;
65
66 size.Set( 1. , 1. );
67 SetSubRegionSize( size ); // 1 by 1 FOR
68
69 size.Set( 2. , 2. );
70 SetPatchSize( size ); // 2 by 2 subregions
71
72 for (Int_t ietam=0;ietam<24;ietam++)
73 {
74 for (Int_t iphim=0;iphim<4;iphim++)
75 {
76 // idx: 0..95 since iphim: 0..11 ietam: 0..23
77 Int_t idx = ( !mapType ) ? ( 3 - iphim ) + ietam * 4 : iphim + (23 - ietam) * 4;
78
79 // Build a matrix used to get TRU digit id (ADC channel) from (eta,phi)|SM
80 fMap[ietam][iphim] = idx; // [0..11][0..3] namely [eta][phi] in SM
81 }
82 }
83}
84
85//________________
86AliEMCALTriggerTRU::~AliEMCALTriggerTRU()
87{
88 // delete TRU digits only used as transient containers
89 // to compute FastOR from energy deposit
90
91}
92
93//________________
94void AliEMCALTriggerTRU::Peaks(Int_t arr[96][2])
95{
96 // Return max time bin & max value for all channels
97 for (Int_t i=0;i<96;i++)
98 {
99 arr[i][0] = arr[i][1] = 0;
100
101 Int_t max = 0, pos = 0;
102 for (Int_t j=0;j<256;j++)
103 {
104 if (fADC[i][j]>max)
105 {
106 max = fADC[i][j];
107 pos = j;
108 }
109 }
110
111 arr[i][0] = max;
112 arr[i][1] = pos;
113 }
114}
115
116//________________
117void AliEMCALTriggerTRU::ShowFastOR(Int_t iTimeWindow, Int_t iChannel)
118{
119 //
120 Int_t iChanF, iChanL;
121
122 if (iChannel != -1) iChanF = iChanL = iChannel;
123 else
124 {
125 iChanF = 0;
126 iChanL = 96;
127 }
128
129 for (Int_t i=iChanF;i<iChanL+1;i++)
130 {
131 printf("\tChannel: %2d - ",i);
132 for (Int_t j=0;j<60;j++)
133 {
134 if (j == iTimeWindow)
135 printf(" | %4d",fADC[i][j]);
136 else if (j == iTimeWindow+kTimeWindowSize-1)
137 printf(" %4d |",fADC[i][j]);
138 else
139 printf(" %4d",fADC[i][j]);
140 }
141
142 printf("\n");
143 }
144}
145
146//________________
147Int_t AliEMCALTriggerTRU::L0v0()
148{
149 // Mimick the TRU L0 'virtual' since not yet released algo
150
151 // L0 issuing condition is: (2 up & 1 down) AND (time sum > thres)
152 // fill a matrix to support sliding window
153 // compute the time sum for all the FastOR of a given TRU
154 // and then move the space window
155
156 Int_t sum[96][3] ;//= { 0 };
157 for(Int_t i = 0; i < 96 ; i++)
158 for(Int_t j = 0; j < 3 ; j++) sum[i][j] = 0;
159
160 // Sliding window algorithm
161 for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); 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// fRegion[j][k] = fRegion[j][k]>>2; // truncate time sum
174 }
175 }
176
177 // Threshold
178 // FIXME: for now consider just one threshold for all patches, should consider one per patch?
179 // return the list of patches above threshold
180 // Should probably be checked out from OCDB
181
182 Int_t vL0Threshold = 0;
183
184 SlidingWindow( kGamma, vL0Threshold );
185
186 Int_t nP = 0;
187
188 for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
189 {
190 AliEMCALTriggerPatch *p = (AliEMCALTriggerPatch*)fPatches->At( j );
191
192 TVector2 v;
193 p->Position(v);
194
195 Int_t idx = fMap[int(v.X())][int(v.Y())];
196
197 if ( i>2 )
198 {
199 // Now check the '2 up/1 down' on each patch
200 if ( sum[idx][1]>sum[idx][0] && sum[idx][2]<=sum[idx][1] ) nP++;
201
202 sum[idx][0] = sum[idx][1];
203 sum[idx][1] = sum[idx][2];
204 sum[idx][2] = p->Sum();
205 }
206 else
207 {
208 sum[idx][i] = p->Sum();
209 }
210 }
211
212 if ( !nP )
213 fPatches->Delete();
214 else
215 break; // Stop the algo when at least one patch is found ( thres & max )
216
217 ZeroRegion(); // Clear fRegion for this time window before computing the next one
218
219 }
220
221 return fPatches->GetEntriesFast();
222}
223
224//________________
225Int_t AliEMCALTriggerTRU::L0v1()
226{
227 // Mimick the TRU L0 'virtual' since not yet released algo
228
229 // L0 issuing condition is: (2 up & 1 down) AND (time sum > thres)
230 // fill a matrix to support sliding window
231 // compute the time sum for all the FastOR of a given TRU
232 // and then move the space window
233
234 AliDebug(1,"=== Running TRU L0 v1 version ===");
235
236 // Time sliding window algorithm
237 for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++)
238 {
239 AliDebug(1,Form("----------- Time window: %d\n",i));
240
241 for (Int_t j=0; j<fRegionSize->X(); j++)
242 {
243 for (Int_t k=0; k<fRegionSize->Y(); k++)
244 {
245 for (Int_t l=i; l<i+kTimeWindowSize; l++)
246 {
247 // [eta][phi][time]
248 fRegion[j][k] += fADC[fMap[j][k]][l];
249 }
250
251// if (kTimeWindowSize > 4) fRegion[j][k] = fRegion[j][k] >> 1; // truncate time sum to fit 14b
252 }
253 }
254
255 // Threshold
256 // FIXME: for now consider just one threshold for all patches, should consider one per patch?
257 // ANSWE: both solutions will be implemented in the TRU
258 // return the list of patches above threshold
259 // Should probably be checked out from OCDB
260
261 Int_t vL0Threshold = 0;
262
263 SlidingWindow( kGamma, vL0Threshold );
264
265// for(Int_t j=0; j<fRegionSize->X(); j++)
266// for (Int_t k=0; k<fRegionSize->Y(); k++) fRegion[j][k] = fRegion[j][k]>>2; // go to 12b before shipping to STU
267
268 Int_t nP = 0;
269
270 for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
271 {
272 AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At( j );
273
274 if ( AliDebugLevel() ) p->Print("");
275
276 TVector2 v;
277 p->Position(v);
278
da509d54 279 Int_t sizeX = (Int_t)(fPatchSize->X() * fSubRegionSize->X());
280 Int_t sizeY = (Int_t)(fPatchSize->Y() * fSubRegionSize->Y());
916f1e76 281
282 const Int_t psize = sizeX * sizeY; // Number of FastOR in the patch
283
da509d54 284 Int_t *idx= new Int_t[psize];
916f1e76 285
286 Int_t aPeaks = 0;
287
288 for (Int_t xx=0;xx<sizeX;xx++)
289 {
290 for (Int_t yy=0;yy<sizeY;yy++)
291 {
292 idx[xx*sizeY+yy] = fMap[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels
293
294 if (fRegion[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]) aPeaks++;
295
296 if ( AliDebugLevel() ) ShowFastOR(i,idx[xx*sizeY+yy]);
297 }
298 }
299
300 Int_t nPeaks = 0;
301
302 for (Int_t k=i;k<=i+kTimeWindowSize-(kNup+kNdown);k++)
303 {
304 // Now check the 'kNup up / kNdown down' on each FastOR of the patch
305 PeakFinder( idx , psize , k , kNup , kNdown , nPeaks );
306 }
307
308 if (nPeaks == aPeaks)
309 {
310 if ( AliDebugLevel() )
311 {
312 printf("\t----- Valid patch (all FastOR have crossed a maximum)\n");
da509d54 313 for (Int_t xx=0;xx<sizeX;xx++) {
314 for (Int_t yy=0;yy<sizeY;yy++) {
315 Int_t index = xx*sizeY+yy;
316 ShowFastOR(i,idx[index]);
317 }
318 }
916f1e76 319 }
320
321 nP++; // all FOR in the patch must have seen a max
322 }
0341167b 323
324 delete [] idx;
916f1e76 325 }
326
327 if ( !nP )
328 fPatches->Delete();
329 else
330 {
331 AliDebug(1,Form("==========[ Found %4d valid patches out of %4d ]==========\n",nP,fPatches->GetEntriesFast()));
332 break; // Stop the algo when at least one patch is found ( thres & max )
333 }
334
335 ZeroRegion(); // Clear fRegion for this time window before computing the next one
336 }
337
338 return fPatches->GetEntriesFast();
339}
340
341
342//________________
343Int_t AliEMCALTriggerTRU::L0v2()
344{
345 // Activity trigger
346
347 // Sliding window algorithm
348
349 for(Int_t j=0; j<fRegionSize->X(); j++)
350 {
351 for (Int_t k=0; k<fRegionSize->Y(); k++)
352 {
353 Int_t max = 0;
354 for (Int_t l=0; l<kTimeBins; l++)
355 {
356 if (fADC[fMap[j][k]][l] > max) max = fADC[fMap[j][k]][l];
357 }
358
359 if (max>4) fRegion[j][k] = max;
360 }
361 }
362
363 Int_t vL0Threshold = 0;
364
365 SlidingWindow( kGamma, vL0Threshold );
366
367 return fPatches->GetEntriesFast();
368}
369
370
371//________________
372void AliEMCALTriggerTRU::SetADC( Int_t channel, Int_t bin, Int_t sig )
373{
374 //
375 if (channel>95) AliError("TRU has 96 ADC channels only!");
376 fADC[channel][bin] = sig;
377}
378
379//________________
380void AliEMCALTriggerTRU::PeakFinder( const Int_t idx[], Int_t nfastor, Int_t start, Int_t nup, Int_t ndown, Int_t& nPeaks )
381{
382 //
383 for (Int_t i=0;i<nfastor;i++)
384 {
385 Int_t foundU = 0;
386 Int_t foundD = 0;
387
388 for (Int_t j=start+ 1;j<start+nup ;j++) foundU = ( fADC[idx[i]][j]> fADC[idx[i]][j-1] && fADC[idx[i]][j-1] ) ? 1 : 0;
389 for (Int_t j=start+nup;j<start+nup+ndown;j++) foundD = ( fADC[idx[i]][j]<=fADC[idx[i]][j-1] && fADC[idx[i]][j ] ) ? 1 : 0;
390
391 if ( foundU && foundD ) nPeaks++;
392 }
393}
394
395//________________
396void AliEMCALTriggerTRU::SaveRegionADC(Int_t iTRU, Int_t iEvent)
397{
398 // O for STU Hw
399 //
400 gSystem->Exec(Form("mkdir -p Event%d",iEvent));
401
402 ofstream outfile(Form("Event%d/data_TRU%d.txt",iEvent,iTRU),ios_base::trunc);
403
404 for (Int_t i=0;i<96;i++)
405 {
406 Int_t ietam = 23 - i/4;
407
408 Int_t iphim = 3 - i%4;
409
410 outfile << fRegion[ietam][iphim] << endl;
411 }
412
413 outfile.close();
414}
415
416/*
417//________________
418void AliEMCALTriggerTRU::Scan()
419{
420 //
421 for (Int_t i=0;i<96;i++)
422 {
423 Int_t ietam = 23 - i/4;
424
425 Int_t iphim = 3 - i%4;
426
427 printf("ADC: %2d fRegion[%2d][%2d]: %4d\n",i,ietam,iphim,fRegion[ietam][iphim]);
428 }
429}
430*/
431//________________
432void AliEMCALTriggerTRU::Reset()
433{
434 //
435 fPatches->Delete();
436
437 ZeroRegion();
438
439 for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
440}
441