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