Bug fix in the constructor (thanks to A.Marin)
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALTriggerTRU.cxx
... / ...
CommitLineData
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 "AliEMCALTriggerTRUDCSConfig.h"
28#include "AliLog.h"
29
30#include <TClonesArray.h>
31#include <TSystem.h>
32#include <Riostream.h>
33
34namespace
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
42ClassImp(AliEMCALTriggerTRU)
43
44//________________
45AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard(),
46fDCSConfig(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//________________
53AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALTriggerTRUDCSConfig* dcsConf, const TVector2& rSize, Int_t mapType) :
54AliEMCALTriggerBoard(rSize),
55fDCSConfig(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//________________
93AliEMCALTriggerTRU::~AliEMCALTriggerTRU()
94{
95 //
96}
97
98//________________
99void 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//________________
129Int_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
231 for (Int_t x = 0; x < xsize; x++)
232 {
233 delete [] peaks[x];
234 }
235 delete [] peaks;
236
237 continue;
238 }
239
240 // Threshold
241 // FIXME: for now consider just one threshold for all patches, should consider one per patch?
242 // ANSWE: both solutions will be implemented in the TRU
243 // return the list of patches above threshold
244 // Theshold checked out from OCDB
245
246 SlidingWindow(kL0, fDCSConfig->GetGTHRL0(), i);
247
248// for(Int_t j=0; j<fRegionSize->X(); j++)
249// for (Int_t k=0; k<fRegionSize->Y(); k++) fRegion[j][k] = fRegion[j][k]>>2; // go to 12b before shipping to STU
250
251 for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
252 {
253 AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At( j );
254
255 if ( AliDebugLevel() ) p->Print("");
256
257 TVector2 v; p->Position(v);
258
259 Int_t sizeX = (Int_t)(fPatchSize->X() * fSubRegionSize->X());
260
261 Int_t sizeY = (Int_t)(fPatchSize->Y() * fSubRegionSize->Y());
262
263 const Int_t psize = sizeX * sizeY; // Number of FastOR in the patch
264
265 Int_t foundPeak = 0;
266
267 Int_t* idx = new Int_t[psize];
268
269 for (Int_t xx=0;xx<sizeX;xx++)
270 {
271 for (Int_t yy=0;yy<sizeY;yy++)
272 {
273 Int_t index = xx*sizeY+yy;
274
275 idx[index] = fMap[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels
276
277 if (peaks[int(v.X() * fSubRegionSize->X()) + xx][int(v.Y() * fSubRegionSize->Y()) + yy])
278 {
279 foundPeak++;
280
281 p->SetPeak(xx, yy, sizeX, sizeY);
282 }
283
284 if (AliDebugLevel() >= 999) ShowFastOR(i, idx[index]);
285 }
286 }
287
288 delete [] idx;
289
290 if ( !foundPeak )
291 {
292 fPatches->RemoveAt( j );
293 fPatches->Compress();
294 }
295 }
296
297 //Delete, avoid leak
298 for (Int_t x = 0; x < xsize; x++)
299 {
300 delete [] peaks[x];
301 }
302 delete [] peaks;
303
304 if ( !fPatches->GetEntriesFast() ) // No patch left
305 ZeroRegion();
306 else // Stop the algo when at least one patch is found ( thres & max )
307 {
308 for (Int_t xx = 0; xx < fRegionSize->X(); xx++)
309 {
310 for (Int_t yy = 0; yy < fRegionSize->Y(); yy++)
311 {
312 // Prepare data to be sent to STU for further L1 processing
313 // Sent time sum (rollback tuning) is the one before L0 is issued (maximum time sum)
314 fRegion[xx][yy] = buffer[xx][yy][1];
315 }
316 }
317
318 break;
319 }
320 }
321
322 //Delete, avoid leak
323 for (Int_t x = 0; x < xsize; x++)
324 {
325 for (Int_t y = 0; y < ysize; y++)
326 {
327 delete [] buffer[x][y];
328 }
329 delete [] buffer[x];
330 }
331 delete [] buffer;
332
333 return fPatches->GetEntriesFast();
334}
335
336//________________
337void AliEMCALTriggerTRU::SetADC( Int_t channel, Int_t bin, Int_t sig )
338{
339 //Set ADC value
340 if (channel > 95 || bin > 255) {
341 AliError("TRU has 96 ADC channels and 256 bins only!");
342 }
343 else{
344 fADC[channel][bin] = sig;
345 }
346}
347
348//________________
349void AliEMCALTriggerTRU::SaveRegionADC(Int_t iTRU, Int_t iEvent)
350{
351 // O for STU Hw
352 //
353 gSystem->Exec(Form("mkdir -p Event%d",iEvent));
354
355 ofstream outfile(Form("Event%d/data_TRU%d.txt",iEvent,iTRU),ios_base::trunc);
356
357 for (Int_t i=0;i<96;i++)
358 {
359 Int_t ietam = 23 - i/4;
360
361 Int_t iphim = 3 - i%4;
362
363 outfile << fRegion[ietam][iphim] << endl;
364 }
365
366 outfile.close();
367}
368
369//________________
370void AliEMCALTriggerTRU::Reset()
371{
372 //
373 fPatches->Delete();
374
375 ZeroRegion();
376
377 for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
378}
379