#include "AliEMCALTriggerTRU.h"
#include "AliEMCALTriggerPatch.h"
-#include "AliEMCALDigit.h"
-#include "AliEMCALTriggerSTU.h"
-#include "AliEMCALCalibData.h"
+#include "AliEMCALTriggerTRUDCSConfig.h"
#include "AliLog.h"
-#include <TF1.h>
-#include <TMath.h>
#include <TClonesArray.h>
#include <TSystem.h>
#include <Riostream.h>
namespace
{
- const Int_t kTimeBins = 64; // number of sampling bins of the FastOR signal
+ const Int_t kTimeBins = 16; // number of sampling bins of the FastOR signal
const Int_t kTimeWindowSize = 4; //
const Int_t kNup = 2; //
const Int_t kNdown = 1; //
ClassImp(AliEMCALTriggerTRU)
//________________
-AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard()//,
-//fDigits( 0x0 )
+AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard(),
+fDCSConfig(0x0)
{
//
for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
}
//________________
-AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALCalibData *calibData, const TVector2& rSize, Int_t mapType) :
-AliEMCALTriggerBoard(calibData, rSize)
+AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALTriggerTRUDCSConfig* dcsConf, const TVector2& rSize, Int_t mapType) :
+AliEMCALTriggerBoard(rSize),
+fDCSConfig(dcsConf)
{
//
for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
- // FIXME: use of class AliEMCALTriggerParam to get size
TVector2 size;
- size.Set( 1. , 1. );
- SetSubRegionSize( size ); // 1 by 1 FOR
-
- size.Set( 2. , 2. );
- SetPatchSize( size ); // 2 by 2 subregions
+ if (dcsConf->GetL0SEL() & 0x0001) // 4-by-4
+ {
+ size.Set( 1. , 1. );
+ SetSubRegionSize( size );
+
+ size.Set( 2. , 2. );
+ SetPatchSize( size );
+ }
+ else // 2-by-2
+ {
+ size.Set( 1. , 1. );
+ SetSubRegionSize( size );
+
+ size.Set( 1. , 1. );
+ SetPatchSize( size );
+ }
for (Int_t ietam=0;ietam<24;ietam++)
{
//________________
AliEMCALTriggerTRU::~AliEMCALTriggerTRU()
{
- // delete TRU digits only used as transient containers
- // to compute FastOR from energy deposit
-
-}
-
-//________________
-void AliEMCALTriggerTRU::Peaks(Int_t arr[96][2])
-{
- // Return max time bin & max value for all channels
- for (Int_t i=0;i<96;i++)
- {
- arr[i][0] = arr[i][1] = 0;
-
- Int_t max = 0, pos = 0;
- for (Int_t j=0;j<256;j++)
- {
- if (fADC[i][j]>max)
- {
- max = fADC[i][j];
- pos = j;
- }
- }
-
- arr[i][0] = max;
- arr[i][1] = pos;
- }
+ //
}
//________________
}
//________________
-Int_t AliEMCALTriggerTRU::L0v0()
+Int_t AliEMCALTriggerTRU::L0()
{
// Mimick the TRU L0 'virtual' since not yet released algo
// fill a matrix to support sliding window
// compute the time sum for all the FastOR of a given TRU
// and then move the space window
+
+ AliDebug(999,"=== Running TRU L0 algorithm ===");
+ const Int_t xsize = Int_t(fRegionSize->X());
+ const Int_t ysize = Int_t(fRegionSize->Y());
+ const Int_t zsize = kNup+kNdown;
+
+ Int_t ***buffer = new Int_t**[xsize];
+ for (Int_t x = 0; x < xsize; x++)
+ {
+ buffer[x] = new Int_t*[ysize];
+
+ for (Int_t y = 0; y < ysize; y++)
+ {
+ buffer[x][y] = new Int_t[zsize];
+ }
+ }
- Int_t sum[96][3] ;//= { 0 };
- for(Int_t i = 0; i < 96 ; i++)
- for(Int_t j = 0; j < 3 ; j++) sum[i][j] = 0;
-
- // Sliding window algorithm
+ for (Int_t i = 0; i < fRegionSize->X(); i++)
+ for (Int_t j = 0; j < fRegionSize->Y(); j++)
+ for (Int_t k = 0; k < kNup + kNdown; k++) buffer[i][j][k] = 0;
+
+ // Time sliding window algorithm
for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++)
{
- for(Int_t j=0; j<fRegionSize->X(); j++)
+ AliDebug(999,Form("----------- Time window: %d\n",i));
+
+ for (Int_t j=0; j<fRegionSize->X(); j++)
{
for (Int_t k=0; k<fRegionSize->Y(); k++)
{
for (Int_t l=i; l<i+kTimeWindowSize; l++)
{
// [eta][phi][time]
- fRegion[j][k] += fADC[fMap[j][k]][l];
+ fRegion[j][k] += fADC[fMap[j][k]][l];
+ }
+
+ buffer[j][k][i%(kNup + kNdown)] = fRegion[j][k];
+
+ if ( i > kNup + kNdown - 1 )
+ {
+ for (Int_t v = 0; v < kNup + kNdown - 1; v++) buffer[j][k][v] = buffer[j][k][v+1];
+
+ buffer[j][k][kNup + kNdown - 1] = fRegion[j][k];
+ }
+ else
+ {
+ buffer[j][k][i] = fRegion[j][k];
}
-// fRegion[j][k] = fRegion[j][k]>>2; // truncate time sum
+// if (kTimeWindowSize > 4) fRegion[j][k] = fRegion[j][k] >> 1; // truncate time sum to fit 14b
}
}
-
- // Threshold
- // FIXME: for now consider just one threshold for all patches, should consider one per patch?
- // return the list of patches above threshold
- // Should probably be checked out from OCDB
-
- Int_t vL0Threshold = 0;
- SlidingWindow( kGamma, vL0Threshold );
-
- Int_t nP = 0;
-
- for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
+ // Don't start to evaluate space sum if a peak can't be findable
+ if (i < kNup + kNdown - 1)
{
- AliEMCALTriggerPatch *p = (AliEMCALTriggerPatch*)fPatches->At( j );
-
- TVector2 v;
- p->Position(v);
-
- Int_t idx = fMap[int(v.X())][int(v.Y())];
-
- if ( i>2 )
- {
- // Now check the '2 up/1 down' on each patch
- if ( sum[idx][1]>sum[idx][0] && sum[idx][2]<=sum[idx][1] ) nP++;
-
- sum[idx][0] = sum[idx][1];
- sum[idx][1] = sum[idx][2];
- sum[idx][2] = p->Sum();
- }
- else
- {
- sum[idx][i] = p->Sum();
- }
+ ZeroRegion();
+ continue;
}
- if ( !nP )
- fPatches->Delete();
- else
- break; // Stop the algo when at least one patch is found ( thres & max )
+ Int_t **peaks = new Int_t*[xsize];
+ for (Int_t x = 0; x < xsize; x++)
+ {
+ peaks[x] = new Int_t[ysize];
+ }
- ZeroRegion(); // Clear fRegion for this time window before computing the next one
+ for (Int_t j=0; j<fRegionSize->X(); j++) for (Int_t k=0; k<fRegionSize->Y(); k++) peaks[j][k] = 0;
- }
-
- return fPatches->GetEntriesFast();
-}
-
-//________________
-Int_t AliEMCALTriggerTRU::L0v1()
-{
- // Mimick the TRU L0 'virtual' since not yet released algo
-
- // L0 issuing condition is: (2 up & 1 down) AND (time sum > thres)
- // fill a matrix to support sliding window
- // compute the time sum for all the FastOR of a given TRU
- // and then move the space window
-
- AliDebug(1,"=== Running TRU L0 v1 version ===");
-
- // Time sliding window algorithm
- for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++)
- {
- AliDebug(1,Form("----------- Time window: %d\n",i));
+ Int_t nPeaks = 0;
for (Int_t j=0; j<fRegionSize->X(); j++)
{
for (Int_t k=0; k<fRegionSize->Y(); k++)
{
- for (Int_t l=i; l<i+kTimeWindowSize; l++)
+ Int_t foundU = 0;
+
+ Int_t foundD = 0;
+
+ 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;
+
+ 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;
+
+ if ( foundU && foundD )
{
- // [eta][phi][time]
- fRegion[j][k] += fADC[fMap[j][k]][l];
+ peaks[j][k] = 1;
+ nPeaks++;
}
-
-// if (kTimeWindowSize > 4) fRegion[j][k] = fRegion[j][k] >> 1; // truncate time sum to fit 14b
}
}
+
+ if (!nPeaks)
+ {
+ ZeroRegion();
+
+ for (Int_t x = 0; x < xsize; x++)
+ {
+ delete [] peaks[x];
+ }
+ delete [] peaks;
+
+ continue;
+ }
// Threshold
// FIXME: for now consider just one threshold for all patches, should consider one per patch?
// ANSWE: both solutions will be implemented in the TRU
// return the list of patches above threshold
- // Should probably be checked out from OCDB
-
- Int_t vL0Threshold = 0;
+ // Theshold checked out from OCDB
- SlidingWindow( kGamma, vL0Threshold );
+ SlidingWindow(kL0, fDCSConfig->GetGTHRL0(), i);
// for(Int_t j=0; j<fRegionSize->X(); j++)
// for (Int_t k=0; k<fRegionSize->Y(); k++) fRegion[j][k] = fRegion[j][k]>>2; // go to 12b before shipping to STU
- Int_t nP = 0;
-
for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
{
AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At( j );
if ( AliDebugLevel() ) p->Print("");
- TVector2 v;
- p->Position(v);
+ TVector2 v; p->Position(v);
Int_t sizeX = (Int_t)(fPatchSize->X() * fSubRegionSize->X());
+
Int_t sizeY = (Int_t)(fPatchSize->Y() * fSubRegionSize->Y());
const Int_t psize = sizeX * sizeY; // Number of FastOR in the patch
- Int_t *idx= new Int_t[psize];
+ Int_t foundPeak = 0;
- Int_t aPeaks = 0;
+ Int_t* idx = new Int_t[psize];
for (Int_t xx=0;xx<sizeX;xx++)
{
for (Int_t yy=0;yy<sizeY;yy++)
{
- idx[xx*sizeY+yy] = fMap[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels
+ Int_t index = xx*sizeY+yy;
+
+ idx[index] = fMap[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels
- if (fRegion[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]) aPeaks++;
+ if (peaks[int(v.X() * fSubRegionSize->X()) + xx][int(v.Y() * fSubRegionSize->Y()) + yy])
+ {
+ foundPeak++;
+
+ p->SetPeak(xx, yy, sizeX, sizeY);
+ }
- if ( AliDebugLevel() ) ShowFastOR(i,idx[xx*sizeY+yy]);
+ if (AliDebugLevel() >= 999) ShowFastOR(i, idx[index]);
}
}
-
- Int_t nPeaks = 0;
-
- for (Int_t k=i;k<=i+kTimeWindowSize-(kNup+kNdown);k++)
- {
- // Now check the 'kNup up / kNdown down' on each FastOR of the patch
- PeakFinder( idx , psize , k , kNup , kNdown , nPeaks );
- }
- if (nPeaks == aPeaks)
+ delete [] idx;
+
+ if ( !foundPeak )
{
- if ( AliDebugLevel() )
- {
- printf("\t----- Valid patch (all FastOR have crossed a maximum)\n");
- for (Int_t xx=0;xx<sizeX;xx++) {
- for (Int_t yy=0;yy<sizeY;yy++) {
- Int_t index = xx*sizeY+yy;
- ShowFastOR(i,idx[index]);
- }
- }
- }
-
- nP++; // all FOR in the patch must have seen a max
- }
+ fPatches->RemoveAt( j );
+ fPatches->Compress();
+ }
}
- if ( !nP )
- fPatches->Delete();
- else
+ //Delete, avoid leak
+ for (Int_t x = 0; x < xsize; x++)
{
- AliDebug(1,Form("==========[ Found %4d valid patches out of %4d ]==========\n",nP,fPatches->GetEntriesFast()));
- break; // Stop the algo when at least one patch is found ( thres & max )
+ delete [] peaks[x];
}
+ delete [] peaks;
- ZeroRegion(); // Clear fRegion for this time window before computing the next one
- }
-
- return fPatches->GetEntriesFast();
-}
-
-
-//________________
-Int_t AliEMCALTriggerTRU::L0v2()
-{
- // Activity trigger
-
- // Sliding window algorithm
-
- for(Int_t j=0; j<fRegionSize->X(); j++)
- {
- for (Int_t k=0; k<fRegionSize->Y(); k++)
+ if ( !fPatches->GetEntriesFast() ) // No patch left
+ ZeroRegion();
+ else // Stop the algo when at least one patch is found ( thres & max )
{
- Int_t max = 0;
- for (Int_t l=0; l<kTimeBins; l++)
+ for (Int_t xx = 0; xx < fRegionSize->X(); xx++)
{
- if (fADC[fMap[j][k]][l] > max) max = fADC[fMap[j][k]][l];
- }
+ for (Int_t yy = 0; yy < fRegionSize->Y(); yy++)
+ {
+ // Prepare data to be sent to STU for further L1 processing
+ // Sent time sum (rollback tuning) is the one before L0 is issued (maximum time sum)
+ fRegion[xx][yy] = buffer[xx][yy][1];
+ }
+ }
- if (max>4) fRegion[j][k] = max;
+ break;
+ }
+ }
+
+ //Delete, avoid leak
+ for (Int_t x = 0; x < xsize; x++)
+ {
+ for (Int_t y = 0; y < ysize; y++)
+ {
+ delete [] buffer[x][y];
}
+ delete [] buffer[x];
}
-
- Int_t vL0Threshold = 0;
-
- SlidingWindow( kGamma, vL0Threshold );
+ delete [] buffer;
return fPatches->GetEntriesFast();
}
-
//________________
void AliEMCALTriggerTRU::SetADC( Int_t channel, Int_t bin, Int_t sig )
{
- //
- if (channel>95) AliError("TRU has 96 ADC channels only!");
- fADC[channel][bin] = sig;
-}
-
-//________________
-void AliEMCALTriggerTRU::PeakFinder( const Int_t idx[], Int_t nfastor, Int_t start, Int_t nup, Int_t ndown, Int_t& nPeaks )
-{
- //
- for (Int_t i=0;i<nfastor;i++)
- {
- Int_t foundU = 0;
- Int_t foundD = 0;
-
- 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;
- 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;
-
- if ( foundU && foundD ) nPeaks++;
- }
+ //Set ADC value
+ if (channel > 95 || bin > 255) {
+ AliError("TRU has 96 ADC channels and 256 bins only!");
+ }
+ else{
+ fADC[channel][bin] = sig;
+ }
}
//________________
outfile.close();
}
-/*
-//________________
-void AliEMCALTriggerTRU::Scan()
-{
- //
- for (Int_t i=0;i<96;i++)
- {
- Int_t ietam = 23 - i/4;
-
- Int_t iphim = 3 - i%4;
-
- printf("ADC: %2d fRegion[%2d][%2d]: %4d\n",i,ietam,iphim,fRegion[ietam][iphim]);
- }
-}
-*/
//________________
void AliEMCALTriggerTRU::Reset()
{