1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
21 Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
25 #include "AliEMCALTriggerTRU.h"
26 #include "AliEMCALTriggerPatch.h"
27 #include "AliEMCALDigit.h"
28 #include "AliEMCALTriggerSTU.h"
29 #include "AliEMCALCalibData.h"
34 #include <TClonesArray.h>
36 #include <Riostream.h>
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; //
46 ClassImp(AliEMCALTriggerTRU)
49 AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard()//,
53 for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
57 AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALCalibData *calibData, const TVector2& rSize, Int_t mapType) :
58 AliEMCALTriggerBoard(calibData, rSize)
61 for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
63 // FIXME: use of class AliEMCALTriggerParam to get size
67 SetSubRegionSize( size ); // 1 by 1 FOR
70 SetPatchSize( size ); // 2 by 2 subregions
72 for (Int_t ietam=0;ietam<24;ietam++)
74 for (Int_t iphim=0;iphim<4;iphim++)
76 // idx: 0..95 since iphim: 0..11 ietam: 0..23
77 Int_t idx = ( !mapType ) ? ( 3 - iphim ) + ietam * 4 : iphim + (23 - ietam) * 4;
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
86 AliEMCALTriggerTRU::~AliEMCALTriggerTRU()
88 // delete TRU digits only used as transient containers
89 // to compute FastOR from energy deposit
94 void AliEMCALTriggerTRU::Peaks(Int_t arr[96][2])
96 // Return max time bin & max value for all channels
97 for (Int_t i=0;i<96;i++)
99 arr[i][0] = arr[i][1] = 0;
101 Int_t max = 0, pos = 0;
102 for (Int_t j=0;j<256;j++)
117 void AliEMCALTriggerTRU::ShowFastOR(Int_t iTimeWindow, Int_t iChannel)
120 Int_t iChanF, iChanL;
122 if (iChannel != -1) iChanF = iChanL = iChannel;
129 for (Int_t i=iChanF;i<iChanL+1;i++)
131 printf("\tChannel: %2d - ",i);
132 for (Int_t j=0;j<60;j++)
134 if (j == iTimeWindow)
135 printf(" | %4d",fADC[i][j]);
136 else if (j == iTimeWindow+kTimeWindowSize-1)
137 printf(" %4d |",fADC[i][j]);
139 printf(" %4d",fADC[i][j]);
147 Int_t AliEMCALTriggerTRU::L0v0()
149 // Mimick the TRU L0 'virtual' since not yet released algo
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
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;
160 // Sliding window algorithm
161 for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++)
163 for(Int_t j=0; j<fRegionSize->X(); j++)
165 for (Int_t k=0; k<fRegionSize->Y(); k++)
167 for (Int_t l=i; l<i+kTimeWindowSize; l++)
170 fRegion[j][k] += fADC[fMap[j][k]][l];
173 // fRegion[j][k] = fRegion[j][k]>>2; // truncate time sum
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
182 Int_t vL0Threshold = 0;
184 SlidingWindow( kGamma, vL0Threshold );
188 for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
190 AliEMCALTriggerPatch *p = (AliEMCALTriggerPatch*)fPatches->At( j );
195 Int_t idx = fMap[int(v.X())][int(v.Y())];
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++;
202 sum[idx][0] = sum[idx][1];
203 sum[idx][1] = sum[idx][2];
204 sum[idx][2] = p->Sum();
208 sum[idx][i] = p->Sum();
215 break; // Stop the algo when at least one patch is found ( thres & max )
217 ZeroRegion(); // Clear fRegion for this time window before computing the next one
221 return fPatches->GetEntriesFast();
225 Int_t AliEMCALTriggerTRU::L0v1()
227 // Mimick the TRU L0 'virtual' since not yet released algo
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
234 AliDebug(1,"=== Running TRU L0 v1 version ===");
236 // Time sliding window algorithm
237 for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++)
239 AliDebug(1,Form("----------- Time window: %d\n",i));
241 for (Int_t j=0; j<fRegionSize->X(); j++)
243 for (Int_t k=0; k<fRegionSize->Y(); k++)
245 for (Int_t l=i; l<i+kTimeWindowSize; l++)
248 fRegion[j][k] += fADC[fMap[j][k]][l];
251 // if (kTimeWindowSize > 4) fRegion[j][k] = fRegion[j][k] >> 1; // truncate time sum to fit 14b
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
261 Int_t vL0Threshold = 0;
263 SlidingWindow( kGamma, vL0Threshold );
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
270 for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
272 AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At( j );
274 if ( AliDebugLevel() ) p->Print("");
279 Int_t sizeX = (Int_t)(fPatchSize->X() * fSubRegionSize->X());
280 Int_t sizeY = (Int_t)(fPatchSize->Y() * fSubRegionSize->Y());
282 const Int_t psize = sizeX * sizeY; // Number of FastOR in the patch
284 Int_t *idx= new Int_t[psize];
288 for (Int_t xx=0;xx<sizeX;xx++)
290 for (Int_t yy=0;yy<sizeY;yy++)
292 idx[xx*sizeY+yy] = fMap[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels
294 if (fRegion[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]) aPeaks++;
296 if ( AliDebugLevel() ) ShowFastOR(i,idx[xx*sizeY+yy]);
302 for (Int_t k=i;k<=i+kTimeWindowSize-(kNup+kNdown);k++)
304 // Now check the 'kNup up / kNdown down' on each FastOR of the patch
305 PeakFinder( idx , psize , k , kNup , kNdown , nPeaks );
308 if (nPeaks == aPeaks)
310 if ( AliDebugLevel() )
312 printf("\t----- Valid patch (all FastOR have crossed a maximum)\n");
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]);
321 nP++; // all FOR in the patch must have seen a max
329 AliDebug(1,Form("==========[ Found %4d valid patches out of %4d ]==========\n",nP,fPatches->GetEntriesFast()));
330 break; // Stop the algo when at least one patch is found ( thres & max )
333 ZeroRegion(); // Clear fRegion for this time window before computing the next one
336 return fPatches->GetEntriesFast();
341 Int_t AliEMCALTriggerTRU::L0v2()
345 // Sliding window algorithm
347 for(Int_t j=0; j<fRegionSize->X(); j++)
349 for (Int_t k=0; k<fRegionSize->Y(); k++)
352 for (Int_t l=0; l<kTimeBins; l++)
354 if (fADC[fMap[j][k]][l] > max) max = fADC[fMap[j][k]][l];
357 if (max>4) fRegion[j][k] = max;
361 Int_t vL0Threshold = 0;
363 SlidingWindow( kGamma, vL0Threshold );
365 return fPatches->GetEntriesFast();
370 void AliEMCALTriggerTRU::SetADC( Int_t channel, Int_t bin, Int_t sig )
373 if (channel>95) AliError("TRU has 96 ADC channels only!");
374 fADC[channel][bin] = sig;
378 void AliEMCALTriggerTRU::PeakFinder( const Int_t idx[], Int_t nfastor, Int_t start, Int_t nup, Int_t ndown, Int_t& nPeaks )
381 for (Int_t i=0;i<nfastor;i++)
386 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;
387 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;
389 if ( foundU && foundD ) nPeaks++;
394 void AliEMCALTriggerTRU::SaveRegionADC(Int_t iTRU, Int_t iEvent)
398 gSystem->Exec(Form("mkdir -p Event%d",iEvent));
400 ofstream outfile(Form("Event%d/data_TRU%d.txt",iEvent,iTRU),ios_base::trunc);
402 for (Int_t i=0;i<96;i++)
404 Int_t ietam = 23 - i/4;
406 Int_t iphim = 3 - i%4;
408 outfile << fRegion[ietam][iphim] << endl;
416 void AliEMCALTriggerTRU::Scan()
419 for (Int_t i=0;i<96;i++)
421 Int_t ietam = 23 - i/4;
423 Int_t iphim = 3 - i%4;
425 printf("ADC: %2d fRegion[%2d][%2d]: %4d\n",i,ietam,iphim,fRegion[ietam][iphim]);
430 void AliEMCALTriggerTRU::Reset()
437 for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;