#include <TClonesArray.h>
#include <TSystem.h>
#include <Riostream.h>
-
+#include <TFile.h>
+#include <TROOT.h>
+
namespace
{
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; //
}
+using std::ofstream;
+using std::endl;
+using std::ios_base;
ClassImp(AliEMCALTriggerTRU)
//________________
-AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard()
-,fDCSConfig(0x0)
+AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard(),
+fDCSConfig(0x0),
+fL0Time(0)
{
- //
+ // Ctor
+
for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
}
//________________
AliEMCALTriggerTRU::AliEMCALTriggerTRU(AliEMCALTriggerTRUDCSConfig* dcsConf, const TVector2& rSize, Int_t mapType) :
-AliEMCALTriggerBoard(rSize)
-,fDCSConfig(dcsConf)
+AliEMCALTriggerBoard(rSize),
+fDCSConfig(dcsConf),
+fL0Time(0)
{
- //
+ // Ctor
+
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
+ TVector2 size;
- 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
- delete [] fADC;
+ // Dtor
}
//________________
void AliEMCALTriggerTRU::ShowFastOR(Int_t iTimeWindow, Int_t iChannel)
{
- //
+ // Dump
+
Int_t iChanF, iChanL;
if (iChannel != -1) iChanF = iChanL = iChannel;
else
{
iChanF = 0;
- iChanL = 96;
+ iChanL = 95;
}
for (Int_t i=iChanF;i<iChanL+1;i++)
//________________
Int_t AliEMCALTriggerTRU::L0()
{
- // Mimick the TRU L0 'virtual' since not yet released algo
+ // L0 algo depending on TRU fw version
+
+ const Int_t xsize = Int_t(fRegionSize->X());
+ const Int_t ysize = Int_t(fRegionSize->Y());
+
+ Int_t asum = 0;
+ for (Int_t j = 0; j < xsize; j++) {
+ for (Int_t k = 0; k < ysize; k++) {
+ for (Int_t l = 0; l < kTimeBins; l++) {
+ asum += fADC[fMap[j][k]][l];
+ }
+ }
+ }
+
+ // TRU has no signal, return!
+ if (!asum) {
+ AliDebug(999,"=== TRU has no signal ===");
+ return 0;
+ }
+
+ AliDebug(999,Form("=== TRU PF: %x",fDCSConfig->GetSELPF()));
+
+ UInt_t ma = fDCSConfig->GetSELPF() & 0xffff;
+
+ // Set default peak finder if null
+ if (!ma) ma = 0x1e1f;
+
+ int nb = ma & 0x7f;
+
+ ma = (ma >> 8) & 0x7f;
+
+ AliDebug(999,Form("=== TRU fw version %x ===",fDCSConfig->GetFw()));
+
+ if (fDCSConfig->GetFw() < 0x4d) {
+ return L0v0(nb, ma);
+ } else {
+ return L0v1(nb, ma);
+ }
+}
+
+//________________
+Int_t AliEMCALTriggerTRU::L0v0(int mask, int pattern)
+{
+ // L0 issuing condition is: (2x2 PF) AND (4x4 > thres)
- // 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(999,"=== Running TRU L0 algorithm version 0 ===");
- AliDebug(1,"=== Running TRU L0 algorithm ===");
const Int_t xsize = Int_t(fRegionSize->X());
- Int_t buffer[xsize][xsize][kNup+kNdown];
+ const Int_t ysize = Int_t(fRegionSize->Y());
+
+ Int_t **othr = new Int_t*[xsize];
+ Int_t **patt = new Int_t*[xsize];
+ Int_t **buff = new Int_t*[xsize];
- 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;
-
+ for (Int_t x = 0; x < xsize; x++) {
+ othr[x] = new Int_t[ysize];
+ patt[x] = new Int_t[ysize];
+ buff[x] = new Int_t[ysize];
+ }
+
+ for (Int_t i = 0; i < xsize; i++) {
+ for (Int_t j = 0; j < ysize; j++) {
+ othr[i][j] = 0;
+ patt[i][j] = 0;
+ buff[i][j] = 0;
+ }
+ }
+
// Time sliding window algorithm
- for (Int_t i=0; i<=(kTimeBins-kTimeWindowSize); i++)
+ for (int i = 0; i <= (kTimeBins - kTimeWindowSize); i++)
{
- AliDebug(1,Form("----------- Time window: %d\n",i));
+ 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++)
- {
-// printf("fRegion[%2d][%2d]: %d += fADC[%2d][%2d]: %d\n",j,k,fRegion[j][k],fMap[j][k],l,fADC[fMap[j][k]][l]);
- // [eta][phi][time]
- fRegion[j][k] += fADC[fMap[j][k]][l];
- }
+ if (AliDebugLevel()) ShowFastOR(i, -1);
+
+ for (int j = 0; j < xsize; j++) {
+ for (int k = 0; k < ysize; k++) {
- buffer[j][k][i%(kNup + kNdown)] = fRegion[j][k];
+// if (
+// !(j % int(fSubRegionSize->X()))
+// &&
+// !(k % int(fSubRegionSize->Y()))
+// &&
+// (j + int(fPatchSize->X() * fSubRegionSize->X()) <= xsize)
+// &&
+// (k + int(fPatchSize->Y() * fSubRegionSize->Y()) <= ysize)
+// )
+// {
+// int sum = 0;
+//
+// for (int l = 0; l < int(fPatchSize->X() * fSubRegionSize->X()); l++)
+// for (int m = 0; m < int(fPatchSize->Y() * fSubRegionSize->Y()); m++) sum += fRegion[j + l][k + m];
+//
+// if (sum > int(fDCSConfig->GetGTHRL0())) {
+// AliDebug(999,Form("----------- Patch (%2d,%2d) is over threshold\n", j, k));
+// othr[j][k] = sum;
+// }
+// }
- 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];
+ buff[j][k] = fRegion[j][k];
+
+ fRegion[j][k] = 0;
+ for (Int_t l = i; l < i + kTimeWindowSize; l++) fRegion[j][k] += fADC[fMap[j][k]][l];
+
+ if (fRegion[j][k] > buff[j][k]) {
+ patt[j][k] |= 0x1;
}
-
-/*
- for (Int_t v = 0; v<kNup + kNdown; v++)
- printf("buffer[%2d][%2d][%2d]: %d\n",j,k,v,buffer[j][k][v]);
-*/
-// if (kTimeWindowSize > 4) fRegion[j][k] = fRegion[j][k] >> 1; // truncate time sum to fit 14b
+ if (patt[j][k]) AliDebug(999,Form("----------- (%2d,%2d) New: %d Old: %d patt: %x / pattern: %x / mask: %x", j, k, fRegion[j][k], buff[j][k], patt[j][k], pattern, mask));
}
}
- // Don't start to evaluate space sum if a peak can't be findable
- if (i < kNup + kNdown - 1)
- {
- ZeroRegion();
- continue;
- }
-
- Int_t peaks[xsize][xsize];
-
- for (Int_t j=0; j<fRegionSize->X(); j++) for (Int_t k=0; k<fRegionSize->Y(); k++) peaks[j][k] = 0;
-
- Int_t nPeaks = 0;
-
- for (Int_t j=0; j<fRegionSize->X(); j++)
- {
- for (Int_t k=0; k<fRegionSize->Y(); k++)
- {
- Int_t foundU = 0;
+ for (int j = 0; j <= int(fRegionSize->X() - fPatchSize->X() * fSubRegionSize->X()); j += int(fSubRegionSize->X())) {
+ for (int k = 0; k <= int(fRegionSize->Y() - fPatchSize->Y() * fSubRegionSize->Y()); k += int(fSubRegionSize->Y())) {
- 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;
+// if (!othr[j][k]) continue;
+ int sizeX = int(fPatchSize->X() * fSubRegionSize->X());
+ int sizeY = int(fPatchSize->Y() * fSubRegionSize->Y());
+
+ int foundPeak = 0;
+ int sum = 0;
+
+ for (int l = 0; l < sizeX; l++) {
+ for (int m = 0; m < sizeY; m++) {
+ sum += fRegion[j + l][k + m];
+
+ if ((patt[j + l][k + m] & mask) == pattern) foundPeak++;
+ }
+ }
- 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 (sum > int(fDCSConfig->GetGTHRL0())) othr[j][k] = sum;
- if ( foundU && foundD )
- {
- peaks[j][k] = 1;
- nPeaks++;
+ if (foundPeak && othr[j][k]) {
+
+ new((*fPatches)[fPatches->GetEntriesFast()]) AliEMCALTriggerPatch(j, k, othr[j][k], i);
+
+ AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At(fPatches->GetEntriesFast() - 1);
+
+ if (AliDebugLevel()) p->Print("");
+
+ const Int_t psize = sizeX * sizeY; // Number of FastOR in the patch
+
+ Int_t* idx = new Int_t[psize];
+
+ for (Int_t l = 0; l < sizeX; l++)
+ {
+ for (Int_t m = 0; m < sizeY; m++)
+ {
+ Int_t index = l * sizeY + m;
+
+ idx[index] = fMap[int(j * fSubRegionSize->X()) + l][int(k * fSubRegionSize->Y()) + m];
+
+ if ((patt[j + l][k + m] & mask) == (pattern & mask)) {
+// cout << "setting peak at " << l << " " << m << endl;
+ p->SetPeak(l, m, sizeX, sizeY);
+ }
+
+ if (AliDebugLevel() >= 999) ShowFastOR(i, idx[index]);
+ }
+ }
+
+ delete [] idx;
}
}
}
+
+ if (fPatches->GetEntriesFast() && !fL0Time) {
+ // Stop the algo when at least one patch is found ( thres & max )
+ fL0Time = i;
-/*
- for (Int_t j=0; j<fRegionSize->X(); j++)
- {
- for (Int_t k=0; k<fRegionSize->Y(); k++)
- {
- printf("peaks[%2d][%2d]: %d\n",j,k,peaks[j][k]);
- }
- }
-*/
- if ( !nPeaks )
- {
- ZeroRegion();
- continue;
+// break;
}
- // 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
- // Theshold checked out from OCDB
+ for (int j = 0; j < xsize; j++)
+ for (int k = 0; k < ysize; k++) patt[j][k] <<= 1;
+ }
+
+ for (Int_t x = 0; x < xsize; x++) {
+ delete [] othr[x];
+ delete [] patt[x];
+ delete [] buff[x];
+ }
+
+ delete [] othr;
+ delete [] patt;
+ delete [] buff;
+
+ return fPatches->GetEntriesFast();
+}
+
+//________________
+Int_t AliEMCALTriggerTRU::L0v1(int mask, int pattern)
+{
+ // L0 issuing condition is: (4x4 PF) AND (4x4 > thres)
+
+ AliDebug(999,"=== Running TRU L0 algorithm version 1 ===");
+
+ const Int_t xsize = Int_t(fRegionSize->X());
+ const Int_t ysize = Int_t(fRegionSize->Y());
- SlidingWindow( kGamma, fDCSConfig->GetGTHRL0() );
+ Int_t **othr = new Int_t*[xsize];
+ Int_t **buff = new Int_t*[xsize];
+ Int_t **patt = new Int_t*[xsize];
+
+ for (Int_t i = 0; i < xsize; i++) {
+ buff[i] = new Int_t[ysize];
+ patt[i] = new Int_t[ysize];
+ othr[i] = new Int_t[ysize];
+ }
+
+ for (Int_t i = 0; i < xsize; i++) for (Int_t j = 0; j < ysize; j++) {
+ othr[i][j] = 0;
+ patt[i][j] = 0;
+ buff[i][j] = 0;
+ }
+
+ // Time sliding window algorithm
+ for (Int_t i = 0; i <= (kTimeBins - kTimeWindowSize); 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
+ AliDebug(999,Form("----------- Time window: %d\n",i));
- Int_t nP = 0;
+ for (int j = 0; j < xsize; j++) {
+ for (int k = 0; k < ysize; k++) {
+
+// if (
+// !(j % int(fSubRegionSize->X()))
+// &&
+// !(k % int(fSubRegionSize->Y()))
+// &&
+// (j + int(fPatchSize->X() * fSubRegionSize->X()) <= xsize)
+// &&
+// (k + int(fPatchSize->Y() * fSubRegionSize->Y()) <= ysize)
+// )
+// {
+// int sum = 0;
+//
+// for (int l = 0; l < int(fPatchSize->X() * fSubRegionSize->X()); l++)
+// for (int m = 0; m < int(fPatchSize->Y() * fSubRegionSize->Y()); m++) sum += fRegion[j + l][k + m];
+//
+// if (sum > buff[j][k]) patt[j][k] |= 0x1;
+//
+// AliDebug(999,Form("----------- Patch (%2d,%2d) has sum %d while its whole time pattern is %x\n", j, k, sum, patt[j][k]));
+//
+// buff[j][k] = sum;
+//
+// if (sum > int(fDCSConfig->GetGTHRL0())) {
+// AliDebug(999,Form("----------- Patch (%2d,%2d) is over threshold\n", j, k));
+// othr[j][k] = sum;
+// }
+// }
+
+ fRegion[j][k] = 0;
+ for (Int_t l = i; l < i + kTimeWindowSize; l++) fRegion[j][k] += fADC[fMap[j][k]][l];
+ }
+ }
- for (Int_t j=0; j<fPatches->GetEntriesFast(); j++)
- {
- AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At( j );
-
- if ( AliDebugLevel() ) p->Print("");
-
- 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];
-
- for (Int_t xx=0;xx<sizeX;xx++)
- {
- for (Int_t yy=0;yy<sizeY;yy++)
- {
- Int_t index = xx*sizeY+yy;
+ for (int j = 0; j <= int(fRegionSize->X() - fPatchSize->X() * fSubRegionSize->X()); j += int(fSubRegionSize->X())) {
+ for (int k = 0; k <= int(fRegionSize->Y() - fPatchSize->Y() * fSubRegionSize->Y()); k += int(fSubRegionSize->Y())) {
- idx[index] = fMap[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]; // Get current patch FastOR ADC channels
+ int sum = 0;
+
+ for (int l = 0; l < int(fPatchSize->X() * fSubRegionSize->X()); l++)
+ for (int m = 0; m < int(fPatchSize->Y() * fSubRegionSize->Y()); m++) sum += fRegion[j + l][k + m];
+
+ if (sum > buff[j][k]) patt[j][k] |= 0x1;
+
+ if (sum > int(fDCSConfig->GetGTHRL0())) {
+ AliDebug(999,Form("----------- Patch (%2d,%2d) is over threshold\n", j, k));
- if (peaks[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]) nP++;
+ othr[j][k] = sum;
+ }
+
+ AliDebug(999,Form("----------- Patch (%2d,%2d) has sum %d while its whole time pattern is %x\n", j, k, sum, patt[j][k]));
+
+ buff[j][k] = sum;
+
+ if (othr[j][k] && ((patt[j][k] & mask) == (pattern & mask))) {
+
+ new((*fPatches)[fPatches->GetEntriesFast()]) AliEMCALTriggerPatch(j, k, othr[j][k], i);
+
+// AliDebug(999,Form("=== New L0 patch at (%2d,%2d) time: %2d",j, k, i));
- if ( AliDebugLevel() ) ShowFastOR(i,idx[index]);
+ int sizeX = int(fPatchSize->X() * fSubRegionSize->X());
+ int sizeY = int(fPatchSize->Y() * fSubRegionSize->Y());
+
+ for (int xx = 0; xx < sizeX; xx++) {
+ for (int yy = 0; yy < sizeY; yy++) {
+ ((AliEMCALTriggerPatch*)fPatches->At(fPatches->GetEntriesFast() - 1))->SetPeak(xx, yy, sizeX, sizeY);
+ }
+ }
+
+ AliEMCALTriggerPatch* p = (AliEMCALTriggerPatch*)fPatches->At(fPatches->GetEntriesFast() - 1);
+
+ if (AliDebugLevel()) p->Print("");
}
}
-
- if ( nP )
- {
-// cout << "break patch loop" << endl;
- break;
- }
}
- if ( !nP )
- fPatches->Delete();
- else
- {
-// cout << "break time loop" << endl;
- break; // Stop the algo when at least one patch is found ( thres & max )
- }
+ if (fPatches->GetEntriesFast() && !fL0Time) {
+ fL0Time = i;
+
+// break;
+ }
- ZeroRegion(); // Clear fRegion for this time window before computing the next one
+ for (int j = 0; j < xsize; j++)
+ for (int k = 0; k < ysize; k++) patt[j][k] <<= 1;
}
-// cout << "Nof patches: " << fPatches->GetEntriesFast() << endl;
-
+ for (Int_t x = 0; x < xsize; x++) {
+ delete [] othr[x];
+ delete [] patt[x];
+ delete [] buff[x];
+ }
+
+ delete [] othr;
+ delete [] patt;
+ delete [] buff;
+
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;
+ //Set ADC value
+ if (channel > 95 || bin > 255) {
+ AliError("TRU has 96 ADC channels and 256 bins only!");
+ }
+ else{
+ if (((fDCSConfig->GetMaskReg(int(channel / 16)) >> (channel % 16)) & 0x1) == 0) fADC[channel][bin] = sig;
+ }
+}
+
+//________________
+void AliEMCALTriggerTRU::GetL0Region(const int time, Int_t arr[][4])
+{
+ Int_t r0 = time - fDCSConfig->GetRLBKSTU();
+
+ if (r0 < 0)
+ {
+ AliError(Form("TRU buffer not accessible! time: %d rollback: %d", time, fDCSConfig->GetRLBKSTU()));
+ return;
+ }
+
+ for (Int_t i = 0; i < fRegionSize->X(); i++)
+ {
+ for (Int_t j = 0; j < fRegionSize->Y(); j++)
+ {
+ for (Int_t k = r0; k < r0 + kTimeWindowSize; k++)
+ {
+ arr[i][j] += fADC[fMap[i][j]][k];
+ }
+ }
+ }
}
//________________
//________________
void AliEMCALTriggerTRU::Reset()
{
- //
+ // Reset
+
fPatches->Delete();
ZeroRegion();