New Trigger Emulation and Trigger access from data (Rachid Guernane)
authorgconesab <gconesab@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 19 Feb 2010 17:54:11 +0000 (17:54 +0000)
committergconesab <gconesab@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 19 Feb 2010 17:54:11 +0000 (17:54 +0000)
libEMCALbase.pkg, EMCALbaseLinkDef.h: add raw digit and STU raw stream decoder
libEMCALrec.pkg: include VZERO needed by trigger processor
libEMCALsim.pkg, EMCALsimLinkDef.h: add trigger classes

AliEMCALReconstructor* : invoque trigger processor (Rachid)

AliEMCALDigitizer.*: create trigger digits from tower digits (Rachid)

AliEMCALGeoUtils.*: add trigger mapping (Rachid)

AliEMCALRawUtils.*:modify Raw2Digits method to access FALTRO data (Rachid)

AliEMCALTriggerTRU.* TRU class

AliEMCALTriggerSTU.*: STU class

AliEMCALTriggerSTURawStream.*: STU data decoder

AliEMCALTriggerElectronics.*: Trigger processor

AliEMCALRawDigit.*: Elementary digit closest to raw data content

AliEMCALTriggerData.*: Trigger data for persistency

AliEMCALTriggerPatch.*: Object created by trigger algorithms (L0, L1)

AliEMCALTriggerBoard.*: Trigger electronic device base class

30 files changed:
EMCAL/AliEMCALDigitizer.cxx
EMCAL/AliEMCALDigitizer.h
EMCAL/AliEMCALGeoUtils.cxx
EMCAL/AliEMCALGeoUtils.h
EMCAL/AliEMCALRawDigit.cxx [new file with mode: 0644]
EMCAL/AliEMCALRawDigit.h [new file with mode: 0644]
EMCAL/AliEMCALRawUtils.cxx
EMCAL/AliEMCALRawUtils.h
EMCAL/AliEMCALReconstructor.cxx
EMCAL/AliEMCALReconstructor.h
EMCAL/AliEMCALShishKebabTrd1Module.cxx
EMCAL/AliEMCALTriggerBoard.cxx [new file with mode: 0644]
EMCAL/AliEMCALTriggerBoard.h [new file with mode: 0644]
EMCAL/AliEMCALTriggerData.cxx [new file with mode: 0644]
EMCAL/AliEMCALTriggerData.h [new file with mode: 0644]
EMCAL/AliEMCALTriggerElectronics.cxx [new file with mode: 0644]
EMCAL/AliEMCALTriggerElectronics.h [new file with mode: 0644]
EMCAL/AliEMCALTriggerPatch.cxx [new file with mode: 0644]
EMCAL/AliEMCALTriggerPatch.h [new file with mode: 0644]
EMCAL/AliEMCALTriggerSTU.cxx [new file with mode: 0644]
EMCAL/AliEMCALTriggerSTU.h [new file with mode: 0644]
EMCAL/AliEMCALTriggerSTURawStream.cxx [new file with mode: 0644]
EMCAL/AliEMCALTriggerSTURawStream.h [new file with mode: 0644]
EMCAL/AliEMCALTriggerTRU.cxx [new file with mode: 0644]
EMCAL/AliEMCALTriggerTRU.h [new file with mode: 0644]
EMCAL/EMCALbaseLinkDef.h
EMCAL/EMCALsimLinkDef.h
EMCAL/libEMCALbase.pkg
EMCAL/libEMCALrec.pkg
EMCAL/libEMCALsim.pkg

index 7252259..2c1c0f8 100644 (file)
@@ -66,6 +66,7 @@
 #include <TBrowser.h>
 #include <TObjectTable.h>
 #include <TRandom.h>
+#include <TF1.h>
 #include <cassert>
 
 // --- AliRoot header files ---
 #include "AliEMCALTick.h"
 #include "AliEMCALCalibData.h"
 #include "AliEMCALSimParam.h"
+#include "AliEMCALRawDigit.h"
+
+namespace
+{
+       Double_t HeavisideTheta(Double_t x)
+       {
+               Double_t signal = 0.;
+               
+               if (x > 0.) signal = 1.;  
+               
+               return signal;  
+       }
+       
+       Double_t AnalogFastORFunction(Double_t *x, Double_t *par)
+       {
+               Double_t v0 = par[0];
+               Double_t t0 = par[1];
+               Double_t tr = par[2];
+               
+               Double_t R1 = 1000.;
+               Double_t C1 = 33e-12;
+               Double_t R2 = 1800;
+               Double_t C2 = 22e-12;
+               
+               Double_t t  =   x[0];
+               
+               return (((0.8*(-((TMath::Power(C1,2)*C2*TMath::Power(TMath::E(),(-t + t0)/(C1*R1))*
+                                                 TMath::Power(R1,2)*R2)/(C1*R1 - C2*R2)) + 
+                                          C1*C2*R1*R2*(1 - (C2*TMath::Power(TMath::E(),(-t + t0)/(C2*R2))*R2)/(-(C1*R1) + C2*R2)))*v0*
+                                 HeavisideTheta(t - t0))/tr 
+                                - (0.8*(C1*C2*R1*R2 - 
+                                                (TMath::Power(C1,2)*C2*TMath::Power(TMath::E(),(-1.*t + t0 + 1.25*tr)/(C1*R1))*
+                                                 TMath::Power(R1,2)*R2)/(C1*R1 - C2*R2) + 
+                                                (C1*TMath::Power(C2,2)*TMath::Power(TMath::E(),(-1.*t + t0 + 1.25*tr)/(C2*R2))*
+                                                 R1*TMath::Power(R2,2))/(C1*R1 - C2*R2))*v0*
+                                       HeavisideTheta(t - t0 - 1.25*tr))/tr)/(C2*R1));
+       }
+}
 
 ClassImp(AliEMCALDigitizer)
 
@@ -540,6 +579,8 @@ void AliEMCALDigitizer::Exec(Option_t *option)
   Int_t nEvents   = fLastEvent - fFirstEvent + 1;
   Int_t ievent;
 
+  TClonesArray* digitsTRG = new TClonesArray("AliEMCALRawDigit", 32 * 96);
+  TClonesArray* digitsTMP = new TClonesArray("AliEMCALDigit",    32 * 96);
   rl->LoadSDigits("EMCAL");
   for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
     
@@ -548,6 +589,21 @@ void AliEMCALDigitizer::Exec(Option_t *option)
     Digitize(ievent) ; //Add prepared SDigits to digits and add the noise
 
     WriteDigits() ;
+         
+       //Trigger Digits
+       //-------------------------------------
+       Digits2FastOR(digitsTMP, digitsTRG);  
+         
+       WriteDigits(digitsTRG);
+         
+       emcalLoader->WriteDigits(   "OVERWRITE");
+       emcalLoader->WriteDigitizer("OVERWRITE");
+         
+       Unload();
+         
+       digitsTRG->Clear();
+       digitsTMP->Clear();
+       //-------------------------------------
 
     if(strstr(option,"deb"))
       PrintDigits(option);
@@ -567,6 +623,137 @@ void AliEMCALDigitizer::Exec(Option_t *option)
 }
 
 //____________________________________________________________________________ 
+void AliEMCALDigitizer::Digits2FastOR(TClonesArray* digitsTMP, TClonesArray* digitsTRG)
+{
+       // FEE digits afterburner to produce TRG digits 
+       // we are only interested in the FEE digit deposited energy
+       // to be converted later into a voltage value
+       
+       // push the FEE digit to its associated FastOR (numbered from 0:95)
+       // TRU is in charge of summing module digits
+       
+       AliRunLoader *runLoader = AliRunLoader::Instance();
+       
+       AliRun* run = runLoader->GetAliRun();
+       
+       AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(runLoader->GetDetectorLoader("EMCAL"));
+       
+       AliEMCALGeometry* geom = dynamic_cast<AliEMCAL*>(run->GetDetector("EMCAL"))->GetGeometry();
+       
+       // build FOR from simulated digits
+       // and xfer to the corresponding TRU input (mapping)
+       
+       TClonesArray* digits = emcalLoader->Digits();
+       
+       TIter NextDigit(digits);
+       while (AliEMCALDigit* digit = (AliEMCALDigit*)NextDigit())
+       {
+               Int_t id = digit->GetId();
+               
+               Int_t iSupMod, nModule, nIphi, nIeta, iphi, ieta, iphim, ietam;
+               
+               geom->GetCellIndex(              id, iSupMod, nModule, nIphi, nIeta );
+               geom->GetModulePhiEtaIndexInSModule( iSupMod, nModule, iphim, ietam );          
+               geom->GetCellPhiEtaIndexInSModule(   iSupMod, nModule, nIphi, nIeta, iphi, ieta); 
+               
+               // identify to which TRU this FEE digit belong
+               Int_t itru = (iSupMod < 11) ? iphim / 4 + 3 * iSupMod : 31;
+               
+               //---------
+               //
+               // FIXME: bad numbering solution to deal w/ the last 2 SM which have only 1 TRU each
+               // using the AliEMCALGeometry official numbering
+               // only 1 TRU/SM in SM 10 & SM 11
+               //
+               //---------
+               if ((itru == 31 && iphim < 2) || (itru == 30 && iphim > 5)) continue;
+               
+               // to be compliant with %4 per TRU
+               if (itru == 31) iphim -= 2;
+               
+               Int_t trgid;
+               Bool_t isOK = geom->GetAbsFastORIndexFromPositionInTRU(itru, ietam, iphim % 4, trgid);
+               
+               AliDebug(2,Form("trigger digit id: %d itru: %d isOK: %d\n",trgid,itru,isOK));
+               
+               if (isOK) 
+               {
+                       AliEMCALDigit* d = static_cast<AliEMCALDigit*>(digitsTMP->At(trgid));
+                       
+                       if (!d)
+                       {
+                               new((*digitsTMP)[trgid]) AliEMCALDigit(*digit);
+                               d = (AliEMCALDigit*)digitsTMP->At(trgid);
+                               d->SetId(trgid);
+                       }       
+                       else
+                       {
+                               *d = *d + *digit;
+                       }
+               }
+       }
+       
+       Int_t    nSamples = 32;
+       Int_t timeSamples[nSamples];
+       
+       NextDigit = TIter(digitsTMP);
+       while (AliEMCALDigit* digit = (AliEMCALDigit*)NextDigit())
+       {
+               if (digit)
+               {
+                       Int_t     id = digit->GetId();
+                       Float_t time = digit->GetTime();
+                                               
+                       Double_t depositedEnergy = 0.;
+                       for (Int_t j = 1; j <= digit->GetNprimary(); j++) depositedEnergy += digit->GetDEPrimary(j);
+                       
+                       // FIXME: Check digit time!
+                       if (depositedEnergy)
+                       {
+                               DigitalFastOR(time, depositedEnergy, timeSamples, nSamples);
+                               
+                               for (Int_t j=0;j<nSamples;j++) 
+                               {
+                                       timeSamples[j] = ((j << 12) & 0xFF000) | (timeSamples[j] & 0xFFF);
+                               }
+                               
+                               new((*digitsTRG)[digitsTRG->GetEntriesFast()]) AliEMCALRawDigit(id, timeSamples, nSamples);
+                       }
+               }
+       }
+}
+
+//____________________________________________________________________________ 
+void AliEMCALDigitizer::DigitalFastOR( Double_t time, Double_t dE, Int_t timeSamples[], Int_t nSamples )
+{
+       // parameters:  
+       // id: 0..95
+       const Int_t    reso = 11;      // 11-bit resolution ADC
+       const Double_t vFSR = 1;       // Full scale input voltage range
+       const Double_t Ne   = 125;     // signal of the APD per MeV of energy deposit in a tower: 125 photo-e-/MeV @ M=30
+       const Double_t vA   = .136e-6; // CSP output range: 0.136uV/e-
+       const Double_t rise = 40e-9;   // rise time (10-90%) of the FastOR signal before shaping
+       
+       const Double_t kTimeBinWidth = 25E-9; // sampling frequency (40MHz)
+       
+       Double_t vV = 1000. * dE * Ne * vA; // GeV 2 MeV
+       
+       TF1 signalF("signal", AnalogFastORFunction, 0, nSamples * kTimeBinWidth, 3);
+       signalF.SetParameter( 0,   vV ); 
+       signalF.SetParameter( 1, time ); // FIXME: when does the signal arrive? Might account for cable lengths
+       signalF.SetParameter( 2, rise );
+       
+       for (Int_t iTime=0; iTime<nSamples; iTime++) 
+       {
+               // FIXME: add noise (probably not simply Gaussian) according to DA measurements
+               // probably plan an access to OCDB
+               
+               timeSamples[iTime] = int((TMath::Power(2, reso) / vFSR) * signalF.Eval(iTime * kTimeBinWidth) + 0.5);
+       }
+}
+
+
+//____________________________________________________________________________ 
 //Float_t AliEMCALDigitizer::FrontEdgeTime(TClonesArray * ticks) 
 //{ 
 //  //  Returns the shortest time among all time ticks
@@ -859,12 +1046,40 @@ void AliEMCALDigitizer::WriteDigits()
     treeD->Branch("EMCAL","TClonesArray",&digits,bufferSize);
   //digitsBranch->SetTitle(fEventFolderName);
   treeD->Fill() ;
-  
+/*  
   emcalLoader->WriteDigits("OVERWRITE");
   emcalLoader->WriteDigitizer("OVERWRITE");
 
   Unload() ; 
+*/
+}
 
+//__________________________________________________________________
+void AliEMCALDigitizer::WriteDigits(TClonesArray* digits, const char* branchName)
+{
+       //
+       AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>(AliRunLoader::Instance()->GetDetectorLoader("EMCAL"));
+       
+       TTree* treeD = emcalLoader->TreeD(); 
+       if (!treeD) 
+       {
+               emcalLoader->MakeDigitsContainer();
+               treeD = emcalLoader->TreeD(); 
+       }
+       
+       // -- create Digits branch
+       Int_t bufferSize = 32000;
+       
+       if (TBranch* triggerBranch = treeD->GetBranch(branchName)) 
+       {
+               triggerBranch->SetAddress(&digits);
+       }
+       else
+       {
+               treeD->Branch(branchName,"TClonesArray",&digits,bufferSize);
+       }
+       
+       treeD->Fill();
 }
 
 //__________________________________________________________________
index 4f7c506..716933a 100644 (file)
@@ -82,13 +82,17 @@ private:
   void    PrintDigits(Option_t * option) ;
   void    Unload() ; 
   void    WriteDigits() ;         // Writes Digits the current event
+  void    WriteDigits(TClonesArray* digits, const char* branchName = "EMTRG"); //
   Float_t TimeOfNoise(void) ;     // Calculate time signal generated by noise
 
   //Calculate the time of crossing of the threshold by front edge
   //Float_t FrontEdgeTime(TClonesArray * ticks) ;
        
   Int_t   DigitizeEnergy(Float_t energy, Int_t AbsId) ;
-
+  void    Digits2FastOR(TClonesArray*digitsTMP, TClonesArray* digitsTRG);
+  void    DigitalFastOR(Double_t time, Double_t dE, Int_t timeSamples[], Int_t nSamples);
+       
+       
 private:
   
   Bool_t  fDefaultInit;           //! Says if the task was created by defaut ctor (only parameters are initialized)
index 8266fe9..f15ea1e 100644 (file)
@@ -977,6 +977,99 @@ Int_t AliEMCALGeoUtils::GetAbsTRUNumberFromNumberInSm(const Int_t row, const Int
   return itru;
 }
 
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromTRU(const Int_t iTRU, const Int_t iADC, Int_t& id) const
+{
+    if (iTRU > 31 || iTRU < 0 || iADC > 95 || iADC < 0) 
+       {
+               AliError("TRU out of range!");
+               return kFALSE;
+       }
+                                
+       id = iADC + iTRU * 96;
+       
+       return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iADC) const
+{
+       if (id > 3071 || id < 0)
+       {
+               AliError("Id out of range!");
+               return kFALSE;
+       }
+       
+       iTRU = id / 96;
+       iADC = id % 96;
+       
+       return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetPositionInTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iEta, Int_t& iPhi) const
+{
+       Int_t iADC;
+       
+       Bool_t isOK = GetTRUFromAbsFastORIndex(id, iTRU, iADC);
+       
+       if (!isOK) return kFALSE;
+       
+       Int_t x = iADC / 4;
+       Int_t y = iADC % 4;
+       
+       if ( int( iTRU / 3 ) % 2 ) // C side 
+       {
+               iEta = 23 - x;
+               iPhi =      y;
+       }
+       else                       // A side
+       {
+               iEta =      x;
+               iPhi =  3 - y;
+       }
+       
+       return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetPositionInSMFromAbsFastORIndex(const Int_t id, Int_t& iSM, Int_t& iEta, Int_t& iPhi) const
+{
+       Int_t iTRU;
+       Bool_t isOK = GetPositionInTRUFromAbsFastORIndex(id, iTRU, iEta, iPhi);
+       
+       if (!isOK) return kFALSE;
+       
+       iSM  = iTRU / 3;
+       
+       if ( int( iTRU / 3 ) % 2 ) // C side
+       {
+               iPhi = iPhi + 4 * ( 2 - ( iTRU % 3 ) );
+       }
+       else                       // A side
+       {
+               iPhi = iPhi + 4 * (       iTRU % 3   );
+       }
+       
+       return kTRUE;
+}
+
+//________________________________________________________________________________________________
+Bool_t AliEMCALGeoUtils::GetAbsFastORIndexFromPositionInTRU(const Int_t iTRU, const Int_t iEta, const Int_t iPhi, Int_t& id) const
+{
+       if (iTRU < 0 || iTRU > 31 || iEta < 0 || iEta > 23 || iPhi < 0 || iPhi > 3) return kFALSE;
+       
+       if ( int( iTRU / 3 ) % 2 ) // C side
+       {
+               id =      iPhi  + 4 * ( 23 - iEta ) + iTRU * 96;
+       }
+       else 
+       {
+               id = (3 - iPhi) + 4 *        iEta + iTRU * 96;
+       }
+       
+       return kTRUE;
+}
 
 //____________________________________________________________________________
 const TGeoHMatrix * AliEMCALGeoUtils::GetMatrixForSuperModule(Int_t smod) const {
index 8cac92c..a9e0b58 100644 (file)
@@ -126,6 +126,11 @@ public:
   void     GetModulePhiEtaIndexInSModuleFromTRUIndex(
               Int_t itru, Int_t iphitru, Int_t ietatru, Int_t &ietaSM, Int_t &iphiSM) const;
   Int_t   GetAbsTRUNumberFromNumberInSm(const Int_t row, const Int_t col, const Int_t sm) const ;
+  Bool_t   GetAbsFastORIndexFromTRU(const Int_t iTRU, const Int_t iADC, Int_t& id) const;
+  Bool_t                    GetAbsFastORIndexFromPositionInTRU(const Int_t iTRU, const Int_t iEta, const Int_t iPhi, Int_t& id) const; 
+  Bool_t             GetTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iADC) const;
+  Bool_t   GetPositionInTRUFromAbsFastORIndex(const Int_t id, Int_t& iTRU, Int_t& iEta, Int_t& iPhi) const;
+  Bool_t    GetPositionInSMFromAbsFastORIndex(const Int_t id, Int_t& iSM, Int_t& iEta, Int_t& iPhi) const;
   
 
 
diff --git a/EMCAL/AliEMCALRawDigit.cxx b/EMCAL/AliEMCALRawDigit.cxx
new file mode 100644 (file)
index 0000000..a7a8910
--- /dev/null
@@ -0,0 +1,127 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+// --- ROOT system ---
+#include <Riostream.h>
+#include <TMath.h>
+
+// --- Standard library ---
+
+// --- AliRoot header files ---
+
+#include "AliEMCALRawDigit.h"
+
+ClassImp(AliEMCALRawDigit)
+
+//____________________________________________________________________________
+AliEMCALRawDigit::AliEMCALRawDigit() : TObject(),
+fId(-1),
+fNSamples(0),
+fSamples(0x0)
+{
+       // default ctor 
+}
+
+//____________________________________________________________________________
+AliEMCALRawDigit::AliEMCALRawDigit(Int_t id, Int_t timeSamples[], Int_t nSamples) : TObject(),
+fId(id),
+fNSamples(nSamples),
+fSamples(0x0)
+{
+       //
+       fSamples = new Int_t[fNSamples] ;
+       for (Int_t i=0; i < fNSamples; i++) fSamples[i] = timeSamples[i];
+}
+
+//____________________________________________________________________________
+AliEMCALRawDigit::AliEMCALRawDigit(const AliEMCALRawDigit& digit) : TObject(),//AliDigitNew(digit),
+fId(digit.fId),
+fNSamples(digit.fNSamples),
+fSamples(0x0)
+
+{
+       // Copy ctor
+       // Data members of the base class (AliNewDigit)
+       
+//     fAmp         = digit.fAmp;
+//     fIndexInList = digit.fIndexInList;
+       fSamples     = new Int_t[fNSamples]; 
+       for (Int_t i=0; i < digit.fNSamples; i++) fSamples[i] = digit.fSamples[i];
+}
+
+//____________________________________________________________________________
+AliEMCALRawDigit::~AliEMCALRawDigit() 
+{
+       // Delete array of time samples
+    delete [] fSamples;
+}
+
+//____________________________________________________________________________
+Bool_t AliEMCALRawDigit::GetTimeSample(const Int_t iSample, Int_t& timeBin, Int_t& amp) const
+{
+       if (iSample > fNSamples || iSample < 0) return kFALSE;
+       
+       amp     =  fSamples[iSample] & 0xFFF;
+       timeBin = (fSamples[iSample] >> 12) & 0xFF;
+
+       return kTRUE;
+}
+
+//____________________________________________________________________________
+void AliEMCALRawDigit::Print(const Option_t* /*opt*/) const
+{
+       printf("===\nDigit id: %4d / %d Time Samples: \n",fId,fNSamples);
+       for (Int_t i=0; i < fNSamples; i++) 
+       {
+               Int_t timeBin, amp;
+               GetTimeSample(i, timeBin, amp);
+               printf("(%d,%d) ",timeBin,amp);
+       }
+       
+       printf("\n");
+}
+
+//____________________________________________________________________________
+Int_t AliEMCALRawDigit::Compare(const TObject* obj) const
+{
+       // Compares two digits with respect to its Id
+       // to sort according increasing Id
+
+       Int_t rv;
+
+       AliEMCALRawDigit* digit = (AliEMCALRawDigit *)obj; 
+
+       Int_t iddiff = fId - digit->GetId(); 
+
+       if ( iddiff > 0 ) 
+               rv = 1;
+       else if ( iddiff < 0 )
+               rv = -1; 
+       else
+               rv = 0;
+  
+       return rv; 
+}
+
+//____________________________________________________________________________
+Bool_t AliEMCALRawDigit::operator==(AliEMCALRawDigit const & digit) const 
+{
+       // Two digits are equal if they have the same Id
+  
+       if(fId == digit.fId) 
+               return kTRUE;
+       else 
+               return kFALSE;
+}
diff --git a/EMCAL/AliEMCALRawDigit.h b/EMCAL/AliEMCALRawDigit.h
new file mode 100644 (file)
index 0000000..04c50c1
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef ALIEMCALRAWDIGIT_H
+#define ALIEMCALRAWDIGIT_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliEMCALRawDigit.h 17335 2007-03-10 03:40:17Z mvl $ */
+
+// --- ROOT system ---
+
+#include "TObject.h" 
+
+// --- Standard library ---
+
+// --- AliRoot header files ---
+//#include "AliDigitNew.h"
+
+class AliEMCALRawDigit : public TObject 
+{
+//     friend ostream& operator<<(ostream& , const AliEMCALRawDigit&);
+
+public:
+       
+       AliEMCALRawDigit();
+       AliEMCALRawDigit(Int_t id, Int_t timeSamples[], Int_t nSamples);
+       AliEMCALRawDigit(const AliEMCALRawDigit& digit);
+       
+       virtual ~AliEMCALRawDigit();
+
+       Bool_t operator==(const AliEMCALRawDigit &rValue) const;
+       const AliEMCALRawDigit& operator = (const AliEMCALRawDigit&) {return *this;}
+
+       Int_t   Compare(const TObject* obj) const;
+       Bool_t  IsSortable() const {return kTRUE;}
+       void    SetId(Int_t id) {fId = id;}
+    Int_t   GetId() const {return fId;}
+       
+       Int_t   GetNSamples() const {return fNSamples;}
+       Bool_t  GetTimeSample(const Int_t iSample, Int_t& timeBin, Int_t& amp) const;
+       virtual void Print(const Option_t* opt) const;
+       
+private: 
+       Int_t   fId;            //Absolute id
+       Int_t   fNSamples;      //Number of time samples
+       Int_t*  fSamples;           //[fNSamples]
+       
+       ClassDef(AliEMCALRawDigit,1)   // Digit in EMCAL 
+};
+#endif
+
index edc4f5c..a53b33b 100644 (file)
@@ -47,6 +47,7 @@ class AliCaloAltroMapping;
 #include "AliEMCALGeometry.h"
 class AliEMCALDigitizer;
 #include "AliEMCALDigit.h"
+#include "AliEMCALRawDigit.h"
 #include "AliEMCAL.h"
 #include "AliCaloCalibPedestal.h"  
 #include "AliCaloFastAltroFitv0.h"
@@ -69,7 +70,7 @@ Double_t AliEMCALRawUtils::fgTimeTrigger = 1.5E-6 ;   // 15 time bins ~ 1.5 muse
 // some digitization constants
 Int_t    AliEMCALRawUtils::fgThreshold = 1;
 Int_t    AliEMCALRawUtils::fgDDLPerSuperModule = 2;  // 2 ddls per SuperModule
-Int_t    AliEMCALRawUtils::fgPedestalValue = 0;     // pedestal value for digits2raw
+Int_t    AliEMCALRawUtils::fgPedestalValue = 0;     // pedestal value for digits2raw, default generate ZS data
 Double_t AliEMCALRawUtils::fgFEENoise = 3.;          // 3 ADC channels of noise (sampled)
 
 AliEMCALRawUtils::AliEMCALRawUtils(fitAlgorithm fitAlgo)
@@ -100,8 +101,7 @@ AliEMCALRawUtils::AliEMCALRawUtils(fitAlgorithm fitAlgo)
   //To make sure we match with the geometry in a simulation file,
   //let's try to get it first.  If not, take the default geometry
   AliRunLoader *rl = AliRunLoader::Instance();
-  if(!rl) AliError("Cannot find RunLoader!");
-  if (rl->GetAliRun() && rl->GetAliRun()->GetDetector("EMCAL")) {
+  if (rl && rl->GetAliRun() && rl->GetAliRun()->GetDetector("EMCAL")) {
     fGeom = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
   } else {
     AliInfo(Form("Using default geometry in raw reco"));
@@ -309,7 +309,7 @@ void AliEMCALRawUtils::Digits2Raw()
 }
 
 //____________________________________________________________________________
-void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap)
+void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap, TClonesArray *digitsTRG)
 {
   // convert raw data of the current event to digits                                                                                     
 
@@ -339,15 +339,29 @@ void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr,
 
   // start loop over input stream 
   while (in.NextDDL()) {
+         
+//    if ( in.GetDDLNumber() != 0 && in.GetDDLNumber() != 2 ) continue;
+
     while (in.NextChannel()) {
 
+/*
+         Int_t    hhwAdd    = in.GetHWAddress();
+         UShort_t iiBranch  = ( hhwAdd >> 11 ) & 0x1; // 0/1
+         UShort_t iiFEC     = ( hhwAdd >>  7 ) & 0xF;
+         UShort_t iiChip    = ( hhwAdd >>  4 ) & 0x7;
+         UShort_t iiChannel =   hhwAdd         & 0xF;
+                
+         if ( !( iiBranch == 0 && iiFEC == 1 && iiChip == 3 && ( iiChannel >= 8 && iiChannel <= 15 ) ) && !( iiBranch == 1 && iiFEC == 0 && in.GetColumn() == 0 ) ) continue;
+*/
+               
       //Check if the signal  is high or low gain and then do the fit, 
       //if it  is from TRU or LEDMon do not fit
       caloFlag = in.GetCaloFlag();
-      if (caloFlag != 0 && caloFlag != 1) continue; 
-             
-      //Do not fit bad channels
-      if(fRemoveBadChannels && pedbadmap->IsBadChannel(in.GetModule(),in.GetColumn(),in.GetRow())) {
+//             if (caloFlag != 0 && caloFlag != 1) continue; 
+         if (caloFlag > 2) continue; // Work with ALTRO and FALTRO 
+               
+      //Do not fit bad channels of ALTRO
+      if(caloFlag < 2 && fRemoveBadChannels && pedbadmap->IsBadChannel(in.GetModule(),in.GetColumn(),in.GetRow())) {
        //printf("Tower from SM %d, column %d, row %d is BAD!!! Skip \n", in.GetModule(),in.GetColumn(),in.GetRow());
        continue;
       }  
@@ -357,9 +371,12 @@ void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr,
        bunchlist.push_back( AliCaloBunchInfo(in.GetStartTimeBin(), in.GetBunchLength(), in.GetSignals() ) );
       } // loop over bunches
 
-      Float_t time = 0; 
-      Float_t amp = 0; 
-
+   
+    if ( caloFlag < 2 ){ // ALTRO
+               
+         Float_t time = 0; 
+         Float_t amp = 0; 
+               
       if ( fFittingAlgorithm == kFastFit || fFittingAlgorithm == kNeuralNet || fFittingAlgorithm == kLMS || fFittingAlgorithm == kPeakFinder || fFittingAlgorithm == kCrude) {
        // all functionality to determine amp and time etc is encapsulated inside the Evaluate call for these methods 
        AliCaloFitResults fitResults = fRawAnalyzer->Evaluate( bunchlist, in.GetAltroCFG1(), in.GetAltroCFG2()); 
@@ -429,6 +446,45 @@ void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr,
        AddDigit(digitsArr, id, lowGain, TMath::Nint(amp), time); 
       }
       
+       }//ALTRO
+       else 
+       {// Fake ALTRO
+               //              if (maxTimeBin && gSig->GetN() > maxTimeBin + 10) gSig->Set(maxTimeBin + 10); // set actual max size of TGraph
+               
+               Int_t    hwAdd    = in.GetHWAddress();
+               UShort_t iRCU     = in.GetDDLNumber() % 2; // 0/1
+               UShort_t iBranch  = ( hwAdd >> 11 ) & 0x1; // 0/1
+               
+               // Now find TRU number
+               Int_t itru = 3 * in.GetModule() + ( (iRCU << 1) | iBranch ) - 1;
+               
+               AliDebug(1,Form("Found TRG digit in TRU: %2d ADC: %2d",itru,in.GetColumn()));
+               
+               Int_t idtrg;
+               
+               Bool_t isOK = fGeom->GetAbsFastORIndexFromTRU(itru, in.GetColumn(), idtrg);
+               
+               Int_t timeSamples[256]; for (Int_t j=0;j<256;j++) timeSamples[j] = 0;
+               Int_t nSamples = 0;
+               
+               for (std::vector<AliCaloBunchInfo>::iterator itVectorData = bunchlist.begin(); itVectorData != bunchlist.end(); itVectorData++)
+               {
+                       AliCaloBunchInfo bunch = *(itVectorData);
+                       
+                       const UShort_t* sig = bunch.GetData();
+                       Int_t startBin = bunch.GetStartBin();
+                       
+                       for (Int_t iS = 0; iS < bunch.GetLength(); iS++) 
+                       {
+                               Int_t time = startBin--;
+                               Int_t amp  = sig[iS];
+                               
+                               if ( amp ) timeSamples[nSamples++] = ( ( time << 12 ) & 0xFF000 ) | ( amp & 0xFFF );
+                       }
+               }
+               
+               if (nSamples && isOK) AddDigit(digitsTRG, idtrg, timeSamples, nSamples);
+       }//Fake ALTRO
    } // end while over channel   
   } //end while over DDL's, of input stream 
 
@@ -436,6 +492,15 @@ void AliEMCALRawUtils::Raw2Digits(AliRawReader* reader,TClonesArray *digitsArr,
 }
 
 //____________________________________________________________________________ 
+void AliEMCALRawUtils::AddDigit(TClonesArray *digitsArr, Int_t id, Int_t timeSamples[], Int_t nSamples) 
+{
+       new((*digitsArr)[digitsArr->GetEntriesFast()]) AliEMCALRawDigit(id, timeSamples, nSamples);     
+       
+       //      Int_t idx = digitsArr->GetEntriesFast()-1;
+       //      AliEMCALRawDigit* d = (AliEMCALRawDigit*)digitsArr->At(idx);
+}
+
+//____________________________________________________________________________ 
 void AliEMCALRawUtils::AddDigit(TClonesArray *digitsArr, Int_t id, Int_t lowGain, Int_t amp, Float_t time) {
   //
   // Add a new digit. 
@@ -713,8 +778,8 @@ Bool_t AliEMCALRawUtils::RawSampledResponse(const Double_t dtime, const Double_t
        
   Double_t signal=0.0, noise=0.0;
   for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) {
-    signal = signalF.Eval(iTime) ;     
-
+    signal = signalF.Eval(iTime) ;  
+       
     // Next lines commeted for the moment but in principle it is not necessary to add
     // extra noise since noise already added at the digits level.      
 
@@ -749,7 +814,8 @@ Bool_t AliEMCALRawUtils::RawSampledResponse(const Double_t dtime, const Double_t
 void AliEMCALRawUtils::SetFittingAlgorithm(Int_t fitAlgo)              
 {
        //Set fitting algorithm and initialize it if this same algorithm was not set before.
-       
+       //printf("**** Set Algorithm , number %d ****\n",fitAlgo);
+
        if(fitAlgo == fFittingAlgorithm && fRawAnalyzer) {
                //Do nothing, this same algorithm already set before.
                //printf("**** Algorithm already set before, number %d, %s ****\n",fitAlgo, fRawAnalyzer->GetName());
index 7a17da7..68d3f13 100644 (file)
@@ -40,9 +40,11 @@ class AliEMCALRawUtils : public TObject {
   AliEMCALRawUtils& operator =(const AliEMCALRawUtils& rawUtils);
 
   void Digits2Raw();
-  void Raw2Digits(AliRawReader *reader, TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap);
+  void Raw2Digits(AliRawReader *reader, TClonesArray *digitsArr, const AliCaloCalibPedestal* pedbadmap,
+                                 TClonesArray *digitsTRG=0x0);
 
   void AddDigit(TClonesArray *digitsArr, Int_t id, Int_t lowGain, Int_t amp, Float_t time);
+  void AddDigit(TClonesArray *digitsArr, Int_t id, Int_t timeSamples[], Int_t nSamples);
 
   // Signal shape parameters
   Double_t GetRawFormatHighLowGainFactor() const { return fHighLowGainFactor ;}
index 3c907f7..e4c41b8 100644 (file)
@@ -58,6 +58,9 @@
 #include "AliCDBManager.h"
 #include "AliRunLoader.h"
 #include "AliRun.h"
+#include "AliEMCALTriggerData.h"
+#include "AliEMCALTriggerElectronics.h"
+#include "AliVZEROLoader.h"
 
 ClassImp(AliEMCALReconstructor) 
 
@@ -65,6 +68,7 @@ const AliEMCALRecParam* AliEMCALReconstructor::fgkRecParam = 0;  // EMCAL rec. p
 AliEMCALRawUtils* AliEMCALReconstructor::fgRawUtils = 0;   // EMCAL raw utilities class
 AliEMCALClusterizer* AliEMCALReconstructor::fgClusterizer = 0;   // EMCAL clusterizer class
 TClonesArray*     AliEMCALReconstructor::fgDigitsArr = 0;  // shoud read just once at event
+AliEMCALTriggerElectronics* AliEMCALReconstructor::fgTriggerProcessor = 0x0;
 //____________________________________________________________________________
 AliEMCALReconstructor::AliEMCALReconstructor() 
   : fDebug(kFALSE), fList(0), fGeom(0),fCalibData(0),fPedestalData(0) 
@@ -111,6 +115,7 @@ AliEMCALReconstructor::AliEMCALReconstructor()
        
   if(!fGeom) AliFatal(Form("Could not get geometry!"));
 
+  fgTriggerProcessor = new AliEMCALTriggerElectronics();
 } 
 
 //____________________________________________________________________________
@@ -120,7 +125,8 @@ AliEMCALReconstructor::~AliEMCALReconstructor()
   delete fGeom;
   delete fgRawUtils;
   delete fgClusterizer;
-       
+  delete fgTriggerProcessor;
+
   AliCodeTimer::Instance()->Print();
 } 
 
@@ -145,6 +151,40 @@ void AliEMCALReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree)
   ReadDigitsArrayFromTree(digitsTree);
   fgClusterizer->InitParameters();
   fgClusterizer->SetOutput(clustersTree);
+
+  AliEMCALTriggerData* trgData = new AliEMCALTriggerData();
+       
+  Int_t bufferSize = 32000;
+
+  if (TBranch* triggerBranch = clustersTree->GetBranch("EMTRG"))
+         triggerBranch->SetAddress(&trgData);
+  else
+         clustersTree->Branch("EMTRG","AliEMCALTriggerData",&trgData,bufferSize);
+
+  AliVZEROLoader* vzeroLoader = dynamic_cast<AliVZEROLoader*>(AliRunLoader::Instance()->GetDetectorLoader("VZERO"));
+  
+  TTree* treeV0 = 0x0;
+       
+  if (vzeroLoader) 
+  {
+         vzeroLoader->LoadDigits("READ");
+      treeV0 = vzeroLoader->TreeD();
+  }
+
+  TClonesArray *trgDigits = new TClonesArray("AliEMCALRawDigit",1000);
+  TBranch *branchdig = digitsTree->GetBranch("EMTRG");
+  if (!branchdig) 
+  { 
+         AliError("Can't get the branch with the EMCAL trigger digits !");
+         return;
+  }
+
+  branchdig->SetAddress(&trgDigits);
+  branchdig->GetEntry(0);
+
+  fgTriggerProcessor->Digits2Trigger(trgDigits, treeV0, trgData);
+       
+  trgDigits->Delete();
        
   if(fgDigitsArr && fgDigitsArr->GetEntries()) {
 
@@ -159,6 +199,9 @@ void AliEMCALReconstructor::Reconstruct(TTree* digitsTree, TTree* clustersTree)
 
   }
 
+  clustersTree->Fill();        
+
+  delete trgData;
 }
 
 //____________________________________________________________________________
@@ -172,8 +215,11 @@ void AliEMCALReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digits
   rawReader->Reset() ; 
 
   TClonesArray *digitsArr = new TClonesArray("AliEMCALDigit",200);
+  TClonesArray *digitsTrg = new TClonesArray("AliEMCALRawDigit", 200);
+
   Int_t bufsize = 32000;
   digitsTree->Branch("EMCAL", &digitsArr, bufsize);
+  digitsTree->Branch("EMTRG", &digitsTrg, bufsize);
 
   //must be done here because, in constructor, option is not yet known
   fgRawUtils->SetOption(GetOption());
@@ -186,11 +232,13 @@ void AliEMCALReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digits
   fgRawUtils->SetRemoveBadChannels(GetRecParam()->GetRemoveBadChannels());
   fgRawUtils->SetFittingAlgorithm(GetRecParam()->GetFittingAlgorithm());
 
-  fgRawUtils->Raw2Digits(rawReader,digitsArr,fPedestalData);
+  fgRawUtils->Raw2Digits(rawReader,digitsArr,fPedestalData,digitsTrg);
 
   digitsTree->Fill();
   digitsArr->Delete();
+  digitsTrg->Delete();
   delete digitsArr;
+  delete digitsTrg;
 
 }
 
@@ -514,3 +562,4 @@ void AliEMCALReconstructor::ReadDigitsArrayFromTree(TTree *digitsTree) const
   branch->GetEntry(0);
 }
 
+
index 8b491f9..36d9ef7 100644 (file)
@@ -39,6 +39,7 @@ class AliEMCALRawUtils;
 class AliEMCALGeometry;
 class AliEMCALCalibData ;
 class AliCaloCalibPedestal ;
+class AliEMCALTriggerElectronics;
 
 // --- Standard library ---
 
@@ -98,8 +99,11 @@ private:
   AliEMCALCalibData    * fCalibData   ;   //! Calibration database if aval
   AliCaloCalibPedestal * fPedestalData ;   //! Tower status database if aval
 
-  ClassDef(AliEMCALReconstructor,8)  // Reconstruction algorithm class (Base Class)
+  static AliEMCALTriggerElectronics* fgTriggerProcessor;
+
+  ClassDef(AliEMCALReconstructor,9)  // Reconstruction algorithm class (Base Class)
 
 }; 
 
 #endif // ALIEMCALRECONSTRUCTOR_H
+
index a1839de..6759ef8 100644 (file)
@@ -66,7 +66,7 @@ AliEMCALShishKebabTrd1Module::AliEMCALShishKebabTrd1Module(Double_t theta, AliEM
     }
   } else Warning("AliEMCALShishKebabTrd1Module(theta)","You should call this constractor just once !!");
   DefineName(fTheta);
-  AliInfo(Form("AliEMCALShishKebabTrd1Module - first module:  theta %1.4f geometry %s",fTheta,g->GetName()));  
+  AliDebug(1,Form("AliEMCALShishKebabTrd1Module - first module:  theta %1.4f geometry %s",fTheta,g->GetName()));  
 }
 
 //_____________________________________________________________________________
diff --git a/EMCAL/AliEMCALTriggerBoard.cxx b/EMCAL/AliEMCALTriggerBoard.cxx
new file mode 100644 (file)
index 0000000..8a6c707
--- /dev/null
@@ -0,0 +1,173 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+
+EMCal trigger board super class
+run the sliding window algorithm
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include "AliEMCALTriggerBoard.h"
+#include "AliEMCALTriggerPatch.h"
+
+#include <TClonesArray.h>
+
+#include <iostream.h>
+
+ClassImp(AliEMCALTriggerBoard)
+
+//_______________
+AliEMCALTriggerBoard::AliEMCALTriggerBoard() : TObject(),
+fRegion(0x0),
+fMap(0x0),
+fRegionSize(0x0),
+fSubRegionSize(0x0),
+fPatchSize(0x0),
+fPatches( new TClonesArray("AliEMCALTriggerPatch",10) )
+{
+       
+}      
+
+//_______________
+AliEMCALTriggerBoard::AliEMCALTriggerBoard(const AliEMCALCalibData */*calibData*/, const TVector2& RS) : TObject(),
+fRegion(0x0),
+fMap(0x0),
+fRegionSize(    new TVector2( RS ) ),
+fSubRegionSize( new TVector2() ),
+fPatchSize(     new TVector2() ),
+fPatches( new TClonesArray("AliEMCALTriggerPatch",10) )
+{
+   fRegion = (int**)malloc( (int)fRegionSize->X() * sizeof( int* ) );  
+
+   if (!fRegion) printf("Error: malloc could not allocate %d bytes for fRegion\n",
+                        int(fRegionSize->X() * sizeof( int* )));
+
+      fMap = (int**)malloc( (int)fRegionSize->X() * sizeof( int* ) );
+
+      if (!fMap) printf("Error: malloc could not allocate %d bytes for fMap\n",
+                        int(fRegionSize->X() * sizeof( int* )));
+
+   for (Int_t i=0;i<fRegionSize->X();i++)
+   {
+      fRegion[i] = (int*)malloc( (int)fRegionSize->Y() * sizeof( int ) );
+      
+      if (!fRegion[i]) printf("Error: malloc could not allocate %d bytes for fRegion[%d]\n",
+                              i,int(fRegionSize->Y() * sizeof( int )));
+
+         fMap[i] = (int*)malloc( (int)fRegionSize->Y() * sizeof( int ) );
+
+            if (!fMap[i]) printf("Error: malloc could not allocate %d bytes for fMap[%d]\n",
+                              i,int(fRegionSize->Y() * sizeof( int )));
+   }
+
+       // Initialize region matrix
+       ZeroRegion();
+       
+       for (int i=0; i<fRegionSize->X(); ++i)
+               for (int j=0; j<fRegionSize->Y(); ++j) fMap[i][j] = 0;
+}
+
+//_______________
+AliEMCALTriggerBoard::~AliEMCALTriggerBoard()
+{
+   for (Int_t i=0;i<fRegionSize->X();i++) 
+   {
+      if (fRegion[i]) {delete fRegion[i]; fRegion[i] = 0;}
+      if (   fMap[i]) {delete    fMap[i];    fMap[i] = 0;}
+   }
+   
+   delete [] fRegion; fRegion = 0x0;
+   delete []    fMap;    fMap = 0x0;
+   
+       fPatches->Delete();
+}
+
+//_______________
+void AliEMCALTriggerBoard::ZeroRegion()
+{
+       //
+       for (Int_t i=0;i<int(fRegionSize->X());i++) for (Int_t j=0;j<int(fRegionSize->Y());j++) fRegion[i][j] = 0;
+}
+
+//_______________
+void AliEMCALTriggerBoard::SlidingWindow( L1TriggerType_t /*type*/, Int_t thres )
+{
+       //
+       Int_t ipatch = 0;
+       
+       for (Int_t i=0; i<=int(fRegionSize->X()-fPatchSize->X()*fSubRegionSize->X()); i+=int(fSubRegionSize->X()))
+       {
+               for (Int_t j=0; j<=int(fRegionSize->Y()-fPatchSize->Y()*fSubRegionSize->Y()); j+=int(fSubRegionSize->Y()))
+               {
+                       ipatch++;
+                       
+                       Int_t sum = 0;
+                       
+                       for (Int_t k=0; k<int(fPatchSize->X()*fSubRegionSize->X()); k++)
+                       {
+                               for (Int_t l=0; l<int(fPatchSize->Y()*fSubRegionSize->Y()); l++)
+                               {
+                                       sum += fRegion[i+k][j+l];
+                               }
+                       }
+
+                       if ( sum > thres ) 
+                       {
+                               //if ( type == kJet ) sum /= 4; // truncate patch sum for jet case
+                               
+                               new((*fPatches)[fPatches->GetLast()+1]) 
+                                               AliEMCALTriggerPatch( int(i/fSubRegionSize->X()), int(j/fSubRegionSize->Y()), int(sum) );
+                       }
+               }
+       }
+}
+
+//__________
+void AliEMCALTriggerBoard::Scan()
+{
+       //
+       cout << "     ";
+       for (Int_t i=0; i<int(fRegionSize->X()); i++) printf("%8d ",i);
+       cout << "\n";
+       for (Int_t i=0; i<int(fRegionSize->X())-5; i++) printf("-------");
+       cout << "\n";
+       
+       for (Int_t i=0; i<int(fRegionSize->Y()); i++)
+       {
+               if (i && !(i%12))
+               {
+                       for (Int_t j=0; j<int(fRegionSize->X())-5; j++) printf("-------");
+                       cout << endl;
+               }
+               
+               printf("%3d |",i);
+               for (Int_t j=0; j<int(fRegionSize->X()); j++) 
+               {
+                       printf("%2d/%5d ", fMap[j][i], fRegion[j][i]);
+               }
+               cout << endl;
+       }
+}
+
+//__________
+void AliEMCALTriggerBoard::Reset()
+{
+       //
+       fPatches->Delete();
+       ZeroRegion();
+}
+
diff --git a/EMCAL/AliEMCALTriggerBoard.h b/EMCAL/AliEMCALTriggerBoard.h
new file mode 100644 (file)
index 0000000..3b5921e
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef ALIEMCALTRIGGERBOARD_H
+#define ALIEMCALTRIGGERBOARD_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/*
+EMCal trigger board super class
+run the sliding window algorithm
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include "TVector2.h"
+
+class TClonesArray;
+class AliEMCALCalibData;
+
+typedef enum { kGamma, kJet } L1TriggerType_t;
+
+class AliEMCALTriggerBoard : public TObject 
+{      
+       
+public:
+                AliEMCALTriggerBoard();
+                AliEMCALTriggerBoard(const AliEMCALCalibData *calibData, const TVector2& RegionSize);
+       virtual ~AliEMCALTriggerBoard();
+       
+       virtual void SlidingWindow(L1TriggerType_t type, Int_t Threshold);
+
+       virtual void ZeroRegion();
+       
+       virtual void Scan();
+       virtual void Reset();
+       
+       virtual void          PatchSize(TVector2& Size) const {Size =     *fPatchSize;}
+       virtual TVector2*     PatchSize(              ) const {     return fPatchSize;}
+       virtual void         RegionSize(TVector2& Size) const {Size =    *fRegionSize;}
+       virtual TVector2*    RegionSize(              ) const {    return fRegionSize;}
+       virtual void      SubRegionSize(TVector2& Size) const {Size = *fSubRegionSize;}
+       virtual TVector2* SubRegionSize(              ) const { return fSubRegionSize;}
+       
+       virtual const TClonesArray& Patches() const {return *fPatches;}
+       
+       virtual void    SetRegionSize(const TVector2& Size) {    *fRegionSize = Size;}
+       virtual void     SetPatchSize(const TVector2& Size) {     *fPatchSize = Size;}
+       virtual void SetSubRegionSize(const TVector2& Size) { *fSubRegionSize = Size;}
+       
+       virtual Int_t** Region() {return fRegion;}
+       virtual Int_t**    Map() {return    fMap;}
+       virtual void       Map(Int_t arr[][64], const TVector2& Size) {for (Int_t i=0;i<Size.X();i++) for (Int_t j=0;j<Size.Y();j++) arr[i][j] = fMap[i][j];}
+
+private:
+       
+    AliEMCALTriggerBoard(const AliEMCALTriggerBoard& rhs);            // NOT implemented
+       AliEMCALTriggerBoard& operator=(const AliEMCALTriggerBoard& rhs); // NOT implemented
+       
+protected:
+       
+       Int_t**       fRegion;        //! 
+       Int_t**       fMap;           //! Map the position to digit index (which eq. to ADC channel)
+       TVector2*     fRegionSize;    //! in FastOR unit
+       TVector2*     fSubRegionSize; //! in FastOR unit
+       TVector2*     fPatchSize;     //! in subregion unit
+       TClonesArray* fPatches;       //!
+       
+       ClassDef(AliEMCALTriggerBoard,1)
+};
+#endif
diff --git a/EMCAL/AliEMCALTriggerData.cxx b/EMCAL/AliEMCALTriggerData.cxx
new file mode 100644 (file)
index 0000000..17adddd
--- /dev/null
@@ -0,0 +1,149 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpeateose. It is      *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+EMCal trigger data container
+for persistency of produced data presently stored in TTreeD
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include "AliEMCALTriggerData.h"
+#include "AliEMCALTriggerPatch.h"
+
+ClassImp(AliEMCALTriggerData)
+
+//_____________
+AliEMCALTriggerData::AliEMCALTriggerData() : TObject(),
+fL0Patches( new TClonesArray("AliEMCALTriggerPatch") ),
+fL0NPatches(),
+fL0RegionSize(0,0),
+fL0SubRegionSize(0,0),
+fL0PatchSize(0,0),
+fL0Peaks(),
+fL1GammaPatches( new TClonesArray("AliEMCALTriggerPatch") ),
+fL1JetPatches( new TClonesArray("AliEMCALTriggerPatch") ),
+fL1RegionSize(0,0),
+fL1GammaPatchSize(0,0),
+fL1GammaSubRegionSize(0,0),
+fL1JetPatchSize(0,0),
+fL1JetSubRegionSize(0,0)
+{  
+       for (Int_t i=0;i<32;i++) fL0NPatches[i] = 0;
+       for (Int_t i=0;i<48;i++) for (Int_t j=0;j<64;j++) fL1Region[i][j] = 0;
+       
+       fL1V0[0] = fL1V0[1] = 0;
+}
+
+//_____________
+AliEMCALTriggerData::~AliEMCALTriggerData()
+{
+}
+
+//_____________
+void AliEMCALTriggerData::SetL0Patches(Int_t i, const TClonesArray& patches)
+{
+       Int_t new_size = patches.GetEntriesFast();
+       Int_t old_size = fL0Patches->GetEntriesFast();
+
+       fL0NPatches[i] = new_size;
+       
+       Int_t size = 0;
+       for (Int_t j=0;j<=i;j++) size += fL0NPatches[j];
+               
+       fL0Patches->Expand( size );
+                       
+       for (Int_t j=0;j<new_size;j++)
+       {
+               AliEMCALTriggerPatch* p = static_cast<AliEMCALTriggerPatch*>( patches.At(j) );
+               new((*fL0Patches)[old_size+j]) AliEMCALTriggerPatch( *p );
+       }
+}
+
+//_____________
+void AliEMCALTriggerData::SetL1GammaPatches(const TClonesArray& patches)
+{
+       Int_t size = patches.GetEntriesFast();
+       fL1GammaPatches->Expand( size );
+
+       for (Int_t j=0;j<size;j++)
+       {
+               AliEMCALTriggerPatch* p = static_cast<AliEMCALTriggerPatch*>( patches.At(j) );
+               new((*fL1GammaPatches)[j]) AliEMCALTriggerPatch( *p );
+       }
+}
+
+//_____________
+void AliEMCALTriggerData::SetL1JetPatches(const TClonesArray& patches)
+{
+       Int_t size = patches.GetEntriesFast();
+       
+       fL1JetPatches->Expand( size );
+       
+       for (Int_t j=0;j<size;j++)
+       {
+               AliEMCALTriggerPatch* p = static_cast<AliEMCALTriggerPatch*>( patches.At(j) );
+               new((*fL1JetPatches)[j]) AliEMCALTriggerPatch( *p );
+       }
+}
+
+//_____________
+void AliEMCALTriggerData::SetL1Region(Int_t**& region)
+{
+       //
+       for (Int_t i=0;i<48;i++)
+               for (Int_t j=0;j<64;j++)
+               {
+                       fL1Region[i][j] = region[i][j];
+               }
+}
+
+//_____________
+void AliEMCALTriggerData::SetL1V0(const Int_t*& arr)
+{
+       for (Int_t i=0;i<2;i++) fL1V0[i] = arr[i];
+}
+
+//_____________
+void AliEMCALTriggerData::Scan() const
+{
+       //
+       printf("L0:\n");
+       for (Int_t i=0;i<32;i++) printf("\tFound %2d patches in TRU %2d\n",fL0NPatches[i],i);
+       
+       printf("L1:\n");
+       printf("\tRegion of size.....................(%2d,%2d)\n",int(fL1RegionSize.X()),int(fL1RegionSize.Y()));
+       printf("\tGamma sub-region size..............(%2d,%2d)\n",int(fL1GammaSubRegionSize.X()),int(fL1GammaSubRegionSize.Y()));
+       printf("\tJet sub-region size................(%2d,%2d)\n",int(fL1JetSubRegionSize.X()),int(fL1JetSubRegionSize.Y()));
+       printf("\tFound %4d gamma patches of size...(%2d,%2d)\n",fL1GammaPatches->GetEntriesFast(),int(fL1GammaPatchSize.X()),int(fL1GammaPatchSize.Y()));
+       printf("\tFound %4d jet patches of size.....(%2d,%2d)\n",fL1JetPatches->GetEntriesFast(),int(fL1JetPatchSize.X()),int(fL1JetPatchSize.Y()));
+}
+
+//_____________
+void AliEMCALTriggerData::Reset()
+{
+       //
+    if (fL0Patches)           fL0Patches->Delete(); 
+       if (fL1GammaPatches) fL1GammaPatches->Delete();
+       if (fL1JetPatches)     fL1JetPatches->Delete(); 
+
+       for (Int_t i=0;i<32;i++) fL0NPatches[i] = 0;
+       for (Int_t i=0;i<48;i++) for (Int_t j=0;j<64;j++) fL1Region[i][j] = 0;
+       fL1V0[0] = fL1V0[1] = 0;
+}
+
+
+
diff --git a/EMCAL/AliEMCALTriggerData.h b/EMCAL/AliEMCALTriggerData.h
new file mode 100644 (file)
index 0000000..8fd1628
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef ALIEMCALTRIGGERDATA_H
+#define ALIEMCALTRIGGERDATA_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/*
+EMCal trigger data container
+for persistency of produced data presently stored in TTreeD
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include <TObject.h>
+#include <TVector2.h>
+
+//#include <TObjArray.h>
+//#include <Riostream.h>
+
+#include <TClonesArray.h>
+
+class AliEMCALTriggerData : public TObject 
+{
+
+public:
+                    AliEMCALTriggerData();
+       virtual     ~AliEMCALTriggerData();
+       
+       virtual void SetL0Patches(Int_t i, const TClonesArray& patches);
+       virtual void SetL0RegionSize(       TVector2 size ) {    fL0RegionSize = size; }
+       virtual void SetL0SubRegionSize(    TVector2 size ) { fL0SubRegionSize = size; }
+       virtual void SetL0PatchSize(        TVector2 size ) {     fL0PatchSize = size; }
+       virtual void SetL0Peaks(Int_t v, Int_t arr[96][2] ) { for (Int_t i=0;i<96;i++) for (Int_t j=0;j<2;j++) fL0Peaks[v][i][j] = arr[i][j]; }
+       
+       virtual void SetL1GammaPatches(const TClonesArray& patches);
+       virtual void SetL1JetPatches(const TClonesArray& patches);
+
+       virtual void SetL1Region(Int_t**& region);
+       virtual void SetL1V0(const Int_t*& arr);
+
+       virtual void SetL1RegionSize(         TVector2 size ) {         fL1RegionSize = size; }
+       virtual void SetL1GammaPatchSize(     TVector2 size ) {     fL1GammaPatchSize = size; }
+       virtual void SetL1GammaSubRegionSize( TVector2 size ) { fL1GammaSubRegionSize = size; }
+       virtual void SetL1JetPatchSize(       TVector2 size ) {       fL1JetPatchSize = size; }
+       virtual void SetL1JetSubRegionSize(   TVector2 size ) {   fL1JetSubRegionSize = size; }
+
+       virtual void          L0Patches(       TClonesArray& patches ) const { patches =  *fL0Patches;            }
+       virtual TClonesArray* L0Patches(                             ) const {     return  fL0Patches;            }
+       virtual void          L0RegionSize(        TVector2 size     ) const { size =      fL0RegionSize;         }
+       virtual TVector2      L0RegionSize(                          ) const {     return  fL0RegionSize;         }
+       virtual void          L0PatchSize(         TVector2 size     ) const { size =      fL0PatchSize;          }
+       virtual TVector2      L0PatchSize(                           ) const {     return  fL0PatchSize;          }
+       virtual void          L0SubRegionSize(     TVector2 size     ) const { size =      fL0SubRegionSize;      }
+       virtual TVector2      L0SubRegionSize(                       ) const {     return  fL0SubRegionSize;      }
+       virtual void          L0NPatches( Int_t arr[32]              ) const { for (Int_t i=0;i<32;i++) arr[i] = fL0NPatches[i]; }
+       virtual void          L0Peaks(    Int_t arr[32][96][2]       ) const { 
+               for (Int_t i=0;i<32;i++) for (Int_t j=0;j<96;j++) for (Int_t k=0;k<2;k++) arr[i][j][k] = fL0Peaks[i][j][k]; }
+
+       virtual void          L1GammaPatches(  TClonesArray& patches ) const { patches =  *fL1GammaPatches;       }
+       virtual TClonesArray* L1GammaPatches(                        ) const {     return  fL1GammaPatches;       }
+       virtual void          L1JetPatches(    TClonesArray& patches ) const { patches =  *fL1JetPatches;         }
+       virtual TClonesArray* L1JetPatches(                          ) const {     return  fL1JetPatches;         }
+       virtual void          L1Region( Int_t arr[][64]              ) const { for (Int_t i=0;i<48;i++) for (Int_t j=0;j<64;j++) { arr[i][j] = fL1Region[i][j]; } }
+       virtual Int_t*        L1V0(                                  )       {     return &fL1V0[0];              }
+       virtual void          L1RegionSize(         TVector2& size   ) const { size =      fL1RegionSize;         }
+       virtual TVector2      L1RegionSize(                          ) const {     return  fL1RegionSize;         }
+       virtual void          L1GammaPatchSize(     TVector2& size   ) const { size =      fL1GammaPatchSize;     }
+       virtual TVector2      L1GammaPatchSize(                      ) const {     return  fL1GammaPatchSize;     }
+       virtual void          L1GammaSubRegionSize( TVector2& size   ) const { size =      fL1GammaSubRegionSize; }
+       virtual TVector2      L1GammaSubRegionSize(                  ) const {     return  fL1GammaSubRegionSize; }
+       virtual void          L1JetPatchSize(       TVector2& size   ) const { size =      fL1JetPatchSize;       }
+       virtual TVector2      L1JetPatchSize(                        ) const {     return  fL1JetPatchSize;       }
+       virtual void          L1JetSubRegionSize(   TVector2& size   ) const { size =      fL1JetSubRegionSize;   }
+       virtual TVector2      L1JetSubRegionSize(                    ) const {     return  fL1JetSubRegionSize;   }
+
+       virtual void Scan() const;
+
+       virtual void Reset();
+       
+private:
+
+    AliEMCALTriggerData(const AliEMCALTriggerData& rhs);            // NOT implemented
+       AliEMCALTriggerData& operator=(const AliEMCALTriggerData& rhs); // NOT implemented
+       
+       TClonesArray*  fL0Patches;            // array of patches  
+       Int_t          fL0NPatches[32];
+       TVector2       fL0RegionSize;         // region size in units of fast or
+       TVector2       fL0SubRegionSize;      // subregion size in units of fast or
+       TVector2       fL0PatchSize;          // patch size in units of subregion
+       Int_t          fL0Peaks[32][96][2];   // max & pos of the max for ADC channels
+       
+       TClonesArray*  fL1GammaPatches;       // array of patches  
+       TClonesArray*  fL1JetPatches;         // array of patches  
+       Int_t          fL1Region[48][64];     // STU FastOR 48-by-124
+       Int_t          fL1V0[2];              // V0A V0C multiplicity estimates 
+       TVector2       fL1RegionSize;         // region size in units of fast or
+       TVector2       fL1GammaPatchSize;     // patch size in units of subregion
+       TVector2       fL1GammaSubRegionSize; // subregion size in units of fast or
+       TVector2       fL1JetPatchSize;       // patch size in units of subregion
+       TVector2       fL1JetSubRegionSize;   // subregion size in units of fast or 
+       
+       ClassDef(AliEMCALTriggerData,1)
+};
+
+#endif
diff --git a/EMCAL/AliEMCALTriggerElectronics.cxx b/EMCAL/AliEMCALTriggerElectronics.cxx
new file mode 100644 (file)
index 0000000..e78c6b0
--- /dev/null
@@ -0,0 +1,218 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+EMCal trigger electronics manager L0/L1
+can handle both simulated digits and raw data
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include "AliEMCALTriggerElectronics.h"
+#include "AliEMCALTriggerTRU.h"
+#include "AliEMCALTriggerSTU.h"
+#include "AliEMCALGeometry.h"
+#include "AliRunLoader.h"
+#include "AliEMCAL.h" 
+#include "AliRun.h" 
+#include "AliEMCALTriggerData.h"
+#include "AliEMCALDigit.h"
+#include "AliCaloRawStreamV3.h"
+//#include "AliVZERORawStream.h"
+#include "AliEMCALTriggerSTURawStream.h"
+#include "AliEMCALDigit.h"
+#include "AliEMCALRawDigit.h"
+
+#include <TVector2.h>
+#include <TClonesArray.h>
+//#include <Riostream.h>
+
+namespace
+{
+       const Int_t kNTRU = 32;
+}
+
+ClassImp(AliEMCALTriggerElectronics)
+
+//__________________
+AliEMCALTriggerElectronics::AliEMCALTriggerElectronics(AliEMCALCalibData *calibData) : TObject(),
+fTRU(new TClonesArray("AliEMCALTriggerTRU",32)),
+fSTU(0x0)
+{
+       TVector2 rSize;
+       
+       rSize.Set( 24.,  4. );
+
+       // 32 TRUs
+       for (Int_t i=0;i<kNTRU;i++) new ((*fTRU)[i]) AliEMCALTriggerTRU(calibData, rSize, int(i/3) % 2);
+   
+       rSize.Set( 48., 64. );
+       
+       // 1 STU
+       fSTU = new AliEMCALTriggerSTU(calibData, rSize);
+       
+       for (Int_t i=0;i<kNTRU;i++) fSTU->BuildMap( i, 
+                                                                                         (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->Map(), 
+                                                                                         (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->RegionSize() 
+                                                                                         );
+}
+
+//________________
+AliEMCALTriggerElectronics::~AliEMCALTriggerElectronics()
+{
+       //
+       fTRU->Delete();
+       delete fSTU;
+}
+
+//__________________
+void AliEMCALTriggerElectronics::Digits2Trigger(const TClonesArray* digits, const TTree* treeV0, AliEMCALTriggerData* data)
+{
+       //
+       AliEMCALGeometry* geom = 0x0;
+       
+       AliRunLoader *rl = AliRunLoader::Instance();
+       if (rl->GetAliRun() && rl->GetAliRun()->GetDetector("EMCAL"))
+               geom = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
+       else 
+               geom =  AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaultGeometryName());
+
+       if (!geom) AliError("Cannot access geometry!");
+       
+       TIter NextDigit(digits);
+       while (AliEMCALRawDigit* digit = (AliEMCALRawDigit*)NextDigit())
+       {
+               if ( digit )
+               {
+                       Int_t id = digit->GetId();
+                       
+//                     digit->Print();
+                       
+                       Int_t iTRU, iADC;
+                       Bool_t isOK1 = geom->GetTRUFromAbsFastORIndex(id, iTRU, iADC);
+                       
+                       for (Int_t i = 0; i < digit->GetNSamples(); i++)
+                       {
+                               Int_t time, amp;
+                               Bool_t isOK2 = digit->GetTimeSample(i, time, amp);
+                               
+                               if (isOK1 && isOK2 && amp) (static_cast<AliEMCALTriggerTRU*>(fTRU->At(iTRU)))->SetADC(iADC, time, amp);
+                       }
+               }
+       }
+       /*
+       for (Int_t i=0; i<kNTRU; i++) 
+       {
+               printf("===========< TRU %2d >============\n",i);
+               (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->Scan();
+       }
+       */
+       Int_t iL0 = 0;
+
+       // At this point all FastOR are available for digitization
+       // digitization is done in the TRU and produces time samples
+       // Now run the trigger algo & consecutively write trigger outputs in TreeD dedicated branch
+
+       for (Int_t i=0; i<kNTRU; i++) 
+       {
+               AliDebug(1,Form("===========< TRU %2d >============\n",i));
+               
+               AliEMCALTriggerTRU *iTRU = static_cast<AliEMCALTriggerTRU*>(fTRU->At(i));
+
+               iL0 += iTRU->L0v1();
+
+               Int_t vL0Peaks[96][2]; iTRU->Peaks( vL0Peaks );
+                       
+               data->SetL0Patches( i , iTRU->Patches() );                      
+               data->SetL0Peaks(   i , vL0Peaks );
+
+               if ( !i ) // do it once since identical for all TRU 
+               {
+                       data->SetL0RegionSize(    *iTRU->RegionSize()    );
+                       data->SetL0SubRegionSize( *iTRU->SubRegionSize() );
+               data->SetL0PatchSize(     *iTRU->PatchSize()     );
+               } 
+               
+               //              if ( i == 31 ) i = 35;
+               //
+               //              if ( ( i / 3 ) % 2 ) {
+               //                      TRU->Print( 15 - 2 + ( i - int( i / 3 ) * 3 ) - 3 * ( (i / 3) / 2 ) , runLoader->GetEventNumber() );
+               //                      printf("print data of TRU: from %2d to %2d\n",i,15 - 2 + ( i - int( i / 3 ) * 3 ) - 3 * ( (i / 3) / 2));
+               //              }
+               //              else
+               //              {
+               //                      TRU->Print( 31 - i % 3 - 3 * ( (i / 3) / 2 ) , runLoader->GetEventNumber() );
+               //                      printf("print data of TRU: from %2d to %2d\n",i,31 - i % 3 - 3 * ( (i / 3) / 2 ));
+               //              }               
+       }
+
+       // A L0 has been issued, run L1
+       if ( iL0 ) 
+       {
+               for (Int_t i=0; i<kNTRU; i++) fSTU->FetchFOR( i, 
+                                                                                                   (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->Region(), 
+                                                                                                   (static_cast<AliEMCALTriggerTRU*>(fTRU->At(i)))->RegionSize() 
+                                                                                                   );
+
+//             fSTU->Scan();
+               
+               TTree* tr = const_cast<TTree*>(treeV0);
+               if ( tr ) fSTU->V0Multiplicity( *tr );
+
+               TVector2 size;
+
+               size.Set( 1. , 1. );
+               fSTU->SetSubRegionSize( size ); data->SetL1GammaSubRegionSize( size );
+               
+               size.Set( 2. , 2. );
+               fSTU->SetPatchSize( size );     data->SetL1GammaPatchSize(     size );
+
+               fSTU->L1( kGamma );
+
+               data->SetL1GammaPatches(       fSTU->Patches()       );
+
+               fSTU->Reset();
+
+               size.Set( 4. , 4. ); 
+               fSTU->SetSubRegionSize( size ); data->SetL1JetSubRegionSize( size );
+               
+               size.Set( 2. , 2. ); 
+               fSTU->SetPatchSize( size );     data->SetL1JetPatchSize(     size );
+
+               fSTU->L1( kJet );
+
+               data->SetL1JetPatches(         fSTU->Patches()       );
+               data->SetL1RegionSize(        *fSTU->RegionSize()    );
+
+               Int_t** region = fSTU->Region();
+               data->SetL1Region(      region      );
+               const Int_t* mv0 = fSTU->V0(); 
+               data->SetL1V0(          mv0         );
+       }
+
+       // Now reset the electronics for a fresh start with next event
+       Reset();
+}
+
+//__________________
+void AliEMCALTriggerElectronics::Reset()
+{
+       //
+       TIter NextTRU(fTRU);
+       while ( AliEMCALTriggerTRU *TRU = (AliEMCALTriggerTRU*)NextTRU() ) TRU->Reset();
+       
+       fSTU->Reset();
+}
diff --git a/EMCAL/AliEMCALTriggerElectronics.h b/EMCAL/AliEMCALTriggerElectronics.h
new file mode 100644 (file)
index 0000000..445f04a
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef ALIEMCALTRIGGERELECTRONICS_H
+#define ALIEMCALTRIGGERELECTRONICS_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/*
+EMCal trigger electronics manager L0/L1
+can handle both simulated digits and raw data
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#ifndef ROOT_TObject
+#  include "TObject.h"
+#endif
+#include "TClonesArray.h"
+
+class AliRawReader;
+class AliEMCALCalibData;
+class TTree;
+class AliEMCALTriggerData;
+class AliEMCALTriggerSTU;
+class AliESDVZERO;
+class AliEMCALTriggerTRU;
+
+class AliEMCALTriggerElectronics : public TObject 
+{
+public:
+                              AliEMCALTriggerElectronics(AliEMCALCalibData* calibData = 0x0); // ctor
+       virtual       ~AliEMCALTriggerElectronics();                                   // dtor
+       
+       virtual void   Digits2Trigger(const TClonesArray* digits, const TTree* treeV0, AliEMCALTriggerData* data);      
+       virtual void   Reset();  
+       
+       virtual AliEMCALTriggerTRU* GetTRU( Int_t iTRU ) {return (AliEMCALTriggerTRU*)fTRU->At(iTRU);}
+       virtual AliEMCALTriggerSTU* GetSTU(            ) {return                      fSTU;}
+       
+private:
+
+       AliEMCALTriggerElectronics(const AliEMCALTriggerElectronics& other);            // Not implemented
+       AliEMCALTriggerElectronics& operator=(const AliEMCALTriggerElectronics& other); // Not implemented
+
+       TClonesArray*        fTRU; // 32 TRU
+       AliEMCALTriggerSTU*  fSTU; //  1 STU
+               
+  ClassDef(AliEMCALTriggerElectronics,1)
+};
+
+#endif
diff --git a/EMCAL/AliEMCALTriggerPatch.cxx b/EMCAL/AliEMCALTriggerPatch.cxx
new file mode 100644 (file)
index 0000000..d480268
--- /dev/null
@@ -0,0 +1,114 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+
+
+Patch object implementation: one patch is made of subregions (Olivier's nomenclature)
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include "AliEMCALTriggerPatch.h"
+#include "AliRunLoader.h"
+#include "AliRun.h"
+#include "AliEMCALGeometry.h"
+#include "AliEMCAL.h"
+
+#include "TArrayI.h"
+
+ClassImp(AliEMCALTriggerPatch)
+
+//____________
+AliEMCALTriggerPatch::AliEMCALTriggerPatch() : TObject(),
+fPosition(0x0),
+fSum(0)
+{
+       // Default constructor
+}
+
+//____________
+AliEMCALTriggerPatch::AliEMCALTriggerPatch( Int_t i, Int_t j,  Int_t k ) : TObject(),
+fPosition(new TVector2( i , j )),
+fSum(k)
+{
+}
+
+//____________
+
+//____________________________________________________________________
+AliEMCALTriggerPatch::AliEMCALTriggerPatch(const AliEMCALTriggerPatch& other) : TObject(other), 
+fPosition( new TVector2(*other.fPosition) ),
+fSum( other.fSum )
+{      
+       // Copy ctor
+}
+
+//____________
+AliEMCALTriggerPatch::~AliEMCALTriggerPatch()
+{      
+       if (fPosition) delete fPosition;
+}
+
+//____________
+void AliEMCALTriggerPatch::Print(const Option_t*) const
+{
+       printf("]> Patch at (%2d , %2d) w/ sum %3d\n",
+                  (int)fPosition->X(),(int)fPosition->Y(),fSum); 
+}
+
+//________________
+void AliEMCALTriggerPatch::GetAbsCellIdsFromPatchPosition( TVector2& pSize, TVector2& sSize, TArrayI& absid )
+{
+       AliRunLoader*     runLoader = AliRunLoader::Instance();
+       AliEMCALGeometry*      geom = dynamic_cast<AliEMCAL*>(runLoader->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
+       
+       Int_t nTowersinpatch = pSize.X() * pSize.Y() * sSize.X() * sSize.Y() * 4;
+       
+       absid.Set( nTowersinpatch );
+       
+       // fPosition: patch position in the STU region
+       Int_t ix = ( fPosition->X() + pSize.X() ) * sSize.X(); 
+       Int_t iy = ( fPosition->Y() + pSize.Y() ) * sSize.Y();
+       
+       Int_t it = 0;
+       
+       for (Int_t i=fPosition->X() * sSize.X(); i<ix; i++) // Loop over subregions FastOR
+       {
+               for (Int_t j=fPosition->Y() * sSize.Y(); j<iy; j++) 
+               {
+                       Int_t nSupMod = int(i/24) + 2 * int(j/12);
+                       
+                       Int_t nModule = 0;
+                       
+                       if ( nSupMod<10 )
+                               nModule = ( i < 24 ) ? 12 * ( 23 - i ) + 11 - j%12 : 12 * ( i%24 ) + 11 - j%12;
+                       else
+                               nModule = ( i < 24 ) ?  6 * ( 23 - i ) +  5 - j%12 :  6 * ( i%24 ) +  5 - j;
+                       
+                       // Convert (TRU,eta,phi) to Id 
+                       for (Int_t k=0;k<2;k++)
+                       {
+                               for (Int_t l=0;l<2;l++)
+                               {
+                                       Int_t iphi, ieta;
+                                       geom->GetCellPhiEtaIndexInSModule(nSupMod, nModule, k, l, iphi, ieta);
+
+                                       absid.SetAt( geom->GetAbsCellIdFromCellIndexes(nSupMod, iphi, ieta) , it++ );
+                               }
+                       }
+               }
+       }
+}
diff --git a/EMCAL/AliEMCALTriggerPatch.h b/EMCAL/AliEMCALTriggerPatch.h
new file mode 100644 (file)
index 0000000..0f532fd
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef ALIEMCALTRIGGERPATCH_H
+#define ALIEMCALTRIGGERPATCH_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/*
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#ifndef ROOT_TObject
+#  include "TObject.h"
+#endif
+
+#include "TVector2.h"
+
+class TArrayI;
+
+class AliEMCALTriggerPatch : public TObject {
+
+public:
+                 AliEMCALTriggerPatch();                                  // default ctor
+                 AliEMCALTriggerPatch(const AliEMCALTriggerPatch& other); // copy ctor
+              AliEMCALTriggerPatch(Int_t i, Int_t j, Int_t e);
+        virtual ~AliEMCALTriggerPatch();
+
+       void      Position(TVector2& pos) const {pos = *fPosition;}
+       TVector2* Position(             ) const {return fPosition;}
+       Int_t     Sum() const {return fSum;} // in ADC counts
+       void      Print(const Option_t*) const;
+       void      GetAbsCellIdsFromPatchPosition(TVector2& psize, TVector2& ssize, TArrayI& absid);
+       
+private:
+       
+       AliEMCALTriggerPatch& operator=(const AliEMCALTriggerPatch& other); // Not implemented
+       
+       TVector2*         fPosition;
+       Int_t             fSum;
+       
+       ClassDef(AliEMCALTriggerPatch,1)
+};
+
+#endif
diff --git a/EMCAL/AliEMCALTriggerSTU.cxx b/EMCAL/AliEMCALTriggerSTU.cxx
new file mode 100644 (file)
index 0000000..60a395f
--- /dev/null
@@ -0,0 +1,347 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+
+
+
+
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include "AliEMCALTriggerSTU.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliEMCALCalibData.h"
+#include "AliVZEROCalibData.h"
+#include "AliVZEROdigit.h"
+#include "AliEMCALTriggerPatch.h"
+#include "AliESDVZERO.h"
+#include "AliLog.h"
+
+#include <TClonesArray.h>
+#include <TSystem.h>
+#include <TH2F.h>
+#include <TFile.h>
+#include <TTree.h>
+
+#include <fstream>
+#include <Riostream.h>
+
+ClassImp(AliEMCALTriggerSTU)
+
+//_______________
+AliEMCALTriggerSTU::AliEMCALTriggerSTU() : AliEMCALTriggerBoard()
+{
+       //
+       fV0M[0] = fV0M[1] = 0;
+}
+
+//_______________
+AliEMCALTriggerSTU::AliEMCALTriggerSTU(AliEMCALCalibData *calibData, const TVector2& RS) : 
+AliEMCALTriggerBoard(calibData, RS)
+{
+       //
+       fV0M[0] = fV0M[1] = 0;
+}
+
+//_______________
+AliEMCALTriggerSTU::~AliEMCALTriggerSTU()
+{
+       //
+}
+
+//_______________
+void AliEMCALTriggerSTU::BuildMap( Int_t iTRU, Int_t** M, const TVector2* rSize )
+{
+       //
+       if ( iTRU == 31 ) iTRU = 35;
+       
+       Int_t i2y = iTRU / 3 / 2;
+       
+       if ( ( iTRU / 3 ) % 2 ) // odd (z<0) C side
+       {
+               Int_t i1y = 2 - ( iTRU - int( iTRU / 3 ) * 3 ); // 0 1 2 w/ increasing phi
+
+               for (Int_t i=0; i<rSize->X(); i++) 
+                       for (Int_t j=0; j<rSize->Y(); j++) fMap[24+i][j + i1y * 4 + i2y * 12] = M[i][j];
+       }
+       else                   // A side
+       {
+               Int_t i1y =       iTRU - int( iTRU / 3 ) * 3;
+               
+               for (Int_t i=0; i<rSize->X(); i++)
+                       for (Int_t j=0; j<rSize->Y(); j++) fMap[   i][j + i1y * 4 + i2y * 12] = M[i][j];
+       }       
+}
+
+//_______________
+void AliEMCALTriggerSTU::L1( L1TriggerType_t type )
+{
+       //
+       SlidingWindow( type, int(ThresholdFromV0( type )) );    
+}
+
+//________________
+void AliEMCALTriggerSTU::PrintADC( L1TriggerType_t type, TVector2& pos, TVector2& idx )
+{
+       //
+       Int_t ix = ( pos.X() + fPatchSize->X() ) * fSubRegionSize->X();
+       Int_t iy = ( pos.Y() + fPatchSize->Y() ) * fSubRegionSize->Y();
+       
+       TString subRegionADC[] = {"0->15", "16->31", "32->47", "48->63", "64->79", "80->95"};
+       
+       switch ( type )
+       {
+               case kGamma:
+               {
+                       Int_t iTRU = ( (ix-1) < 24 ) ? 31 - int(pos.Y() / 4) : 15 - int(pos.Y() / 4);
+                       
+                       printf("TRU #%d row #%d col #%d fastor: ",iTRU,int(idx.Y()),int(idx.X()));
+                       
+                       for (Int_t i=pos.X() * fSubRegionSize->X();i<ix;i++) 
+                       {
+                               for (Int_t j=pos.Y() * fSubRegionSize->Y();j<iy;j++) 
+                               {
+                                       Int_t jtru = ( i < 24 ) ? 31 - j / 4 : 15 - j / 4;
+                                       printf("TRU#%d_%d ",jtru,fMap[i][j]);
+                               }
+                       }
+                       
+                       cout << endl;
+               }       
+               break;
+               case kJet:
+               {
+                       //Int_t jTRU = ( (ix-1) < 24 ) ? 31 - (iy-1) / 4 : 15 - (iy-1) / 4;
+                       
+                       printf("jet found at row : %d and col : %d",int(idx.X()),int(idx.Y()));
+                       
+                       Char_t* vPair = 0x0;
+                       Int_t nSubRegion = 0;
+                       
+                       for (Int_t i=pos.X() * fSubRegionSize->X();i<ix;i++) 
+                       {
+                               for (Int_t j=pos.Y() * fSubRegionSize->Y();j<iy;j++) 
+                               {
+                                       Int_t itru = ( i < 24 ) ? 31 - j / 4 : 15 - j / 4;
+                                       
+                                       Int_t idSR = fMap[i][j]/16;
+                                       
+                                       Char_t value = ((itru << 3) & 0xF8) | (idSR & 0x7);
+                                       
+                                       Bool_t isFound = kFALSE;
+                                       
+                                       for (Int_t k=0;k<nSubRegion && nSubRegion;k++)
+                                       {
+                                               if (vPair[k] == value) isFound = kTRUE;
+                                       }
+                                       
+                                       if (!isFound) 
+                                       {       
+                                               nSubRegion++;
+                                               vPair = (Char_t*)realloc(vPair, nSubRegion * sizeof(Char_t));
+                                               if (vPair == NULL) {AliError("Error (re)allocating PrintADC() memory");}
+                                               
+                                               vPair[nSubRegion-1] = value;
+                                       }
+                               }
+                       }
+                       
+                       cout << " fastor:"; 
+                       for (Int_t i=0;i<nSubRegion;i++)
+                       {
+                               cout << " TRU#" << ((vPair[i] & 0xF8) >> 3) << "_" << subRegionADC[(vPair[i] & 0x7)];
+                       }
+               
+                       cout << endl;
+                       if (vPair) delete[] vPair;
+               }
+               break;
+               default:
+                       AliError("AliEMCALTriggerSTU::PrintADC(): Undefined trigger type, pls check!");
+       }
+}
+
+//________________
+void AliEMCALTriggerSTU::V0Multiplicity( TTree& treeV0 )
+{  
+       //
+    AliCDBManager *man = AliCDBManager::Instance();
+    AliCDBEntry *entry = man->Get("VZERO/Calib/Data");
+    AliVZEROCalibData *calibdata = (AliVZEROCalibData*)entry->GetObject();
+       
+    TClonesArray* digitsArray = 0x0;
+    treeV0.SetBranchAddress("VZERODigit",&digitsArray);
+
+       Float_t mult[64];
+       Short_t  adc[64];
+   
+       for (Int_t i=0; i<64; i++)
+       {
+               adc[i]    = 0;
+               mult[i]   = 0.0;
+       }
+
+       Int_t nEntries = (Int_t)treeV0.GetEntries();
+
+       for (Int_t e=0; e<nEntries; e++) 
+       {
+               treeV0.GetEvent(e);
+
+               Int_t nDigits = digitsArray->GetEntriesFast();
+          
+               for (Int_t d=0; d<nDigits; d++) 
+               {    
+                       AliVZEROdigit* digit = (AliVZEROdigit*)digitsArray->At(d);      
+                       Int_t  pmNumber      = digit->PMNumber();
+                       
+                       if (adc[pmNumber] > (int(1.0/calibdata->GetMIPperADC(pmNumber)) /2) ) 
+                               mult[pmNumber] += float(adc[pmNumber])*calibdata->GetMIPperADC(pmNumber);
+               }
+       }
+  
+       //  0..31 V0C 
+       // 32..63 V0A
+       for (Int_t j=0; j<32; j++) 
+       {
+               fV0M[0] += short(mult[j   ]+0.5); 
+               fV0M[1] += short(mult[j+32]+0.5); 
+       }
+}
+
+//________________
+void AliEMCALTriggerSTU::FetchFOR( Int_t iTRU, Int_t **R, const TVector2* rSize )
+{
+       // L1 triggers run over the whole EMCal surface
+       // STU builds its own fRegion aggregating TRU fRegion into one 
+       
+       // STU I from TRUs O in Olivier's coordinate system
+       
+       if ( iTRU == 31 ) iTRU = 35;
+               
+       Int_t i2y = iTRU / 3 / 2;       
+       
+       if ( ( iTRU / 3 ) % 2 ) // C side odd (z<0)
+       {
+               Int_t i1y = 2 - ( iTRU - int( iTRU / 3 ) * 3 ); // 0 1 2 w/ increasing phi
+               
+               for (Int_t i=0; i<rSize->X(); i++)                                            //  0:23 0:4 
+                       for (Int_t j=0; j<rSize->Y(); j++) fRegion[24+i][j + i1y * 4 + i2y * 12] = R[i][j];
+       }
+       else                    // A side
+       {
+               Int_t i1y =       iTRU - int( iTRU / 3 ) * 3;
+               
+               for (Int_t i=0; i<rSize->X(); i++)
+                       for (Int_t j=0; j<rSize->Y(); j++) fRegion[   i][j + i1y * 4 + i2y * 12] = R[i][j];
+       }
+}
+
+//___________
+void AliEMCALTriggerSTU::PatchGenerator(const TClonesArray* lpos, Int_t val)
+{
+       ZeroRegion();
+       
+       Int_t vTRU[32][24][4] ;//= {0};
+       
+       for (Int_t i = 0; i < 32; i++) 
+               for (Int_t j = 0; j < 24; j++) 
+                       for (Int_t k = 0; k < 4; k++) vTRU[i][j][k]=0;
+       
+       
+       AliWarning("AliEMCALTriggerSTU::PatchGenerator(): STU region has been reset!");
+       
+       // Fill the patch FOR at 'pos' w/ value 'val'
+       
+       TIter NextPosition( lpos );
+       
+       while ( TVector2 *pos = (TVector2*)NextPosition() )
+       {
+               pos->Print();
+               for (Int_t i=pos->X()*fSubRegionSize->X(); i<int((pos->X()+fPatchSize->X())*fSubRegionSize->X()); i++)
+                       for (Int_t j=pos->Y()*fSubRegionSize->Y(); j<int((pos->Y()+fPatchSize->Y())*fSubRegionSize->Y()); j++) 
+                               fRegion[i][j] = val;
+       }
+       
+       for (Int_t i=0; i<2; i++)
+       {
+               for (Int_t j=0; j<16; j++)
+               {
+                       Int_t iTRU = ( !i ) ? 31 - j : 15 - j;
+                       
+                       for (Int_t i1=24*i; i1<24*(i+1); i1++)
+                       {
+                               for (Int_t j1=4*j; j1<4*(j+1); j1++)
+                               {
+                                       vTRU[iTRU][i1%24][j1%4] = fRegion[i1][j1];
+                               }
+                       }
+               }
+       }
+       
+       gSystem->Exec(Form("mkdir -p GP"));
+
+       for (Int_t i=0; i<32; i++)
+       {
+               std::ofstream outfile(Form("GP/data_TRU%d.txt",i),std::ios::trunc);
+       
+               for (Int_t j=0;j<96;j++) 
+               {
+                       Int_t ietam, iphim;
+                       
+                       if ( int(i / 16) )
+                       {
+                               ietam =      j/4;
+                               iphim =  3 - j%4;
+                       }
+                       else
+                       {                                       
+                               ietam = 23 - j/4;
+                               iphim =      j%4;
+                       }
+                       
+                       outfile << vTRU[i][ietam][iphim] << endl;
+               }
+       
+               outfile.close();
+       }
+}
+
+//___________
+Float_t AliEMCALTriggerSTU::ThresholdFromV0( L1TriggerType_t type )
+{      
+       // Compute threshold FIXME: need an access to the OCDB
+       // to get f(V0) parameters depending on trigger type
+       
+       switch ( type )
+       {
+               case kGamma:
+                       break;
+               case kJet:
+//                     return 15.;
+                       break;
+               default:
+                       AliError("AliEMCALTriggerSTU::ThresholdFromV0(): Undefined trigger type, pls check!");
+       }
+       
+       return 0.;
+}
+
+//__________
+void AliEMCALTriggerSTU::Reset()
+{
+       fPatches->Delete();
+}
diff --git a/EMCAL/AliEMCALTriggerSTU.h b/EMCAL/AliEMCALTriggerSTU.h
new file mode 100644 (file)
index 0000000..ea1f10a
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef ALIEMCALTRIGGERSTU_H
+#define ALIEMCALTRIGGERSTU_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/*
+
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include <AliEMCALTriggerBoard.h>
+
+class TTree;
+
+class AliEMCALTriggerSTU : public AliEMCALTriggerBoard 
+{
+public:
+       
+                     AliEMCALTriggerSTU();
+                     AliEMCALTriggerSTU(AliEMCALCalibData *calibData, const TVector2& rsize);
+       virtual      ~AliEMCALTriggerSTU();
+       
+       virtual void  FetchFOR(Int_t i, Int_t** Region, const TVector2* rSize);
+       virtual void  BuildMap(Int_t i, Int_t**    Map, const TVector2* rSize);
+       virtual void  PrintADC(L1TriggerType_t type, TVector2& pos, TVector2& idx);
+       virtual void  L1(L1TriggerType_t type);//, TTree& treeV0);
+       virtual void  PatchGenerator(const TClonesArray* lpos, Int_t val);
+       virtual const Int_t* V0() const {return fV0M;}
+       virtual void  SetV0Multiplicity(Int_t M[], Int_t n) { for (Int_t i=0;i<n;i++) fV0M[i] = M[i]; } // for raw data rec
+       virtual void  V0Multiplicity(TTree& treeV0);
+       virtual void  Reset();
+       
+protected:
+                           AliEMCALTriggerSTU(const AliEMCALTriggerSTU& rhs);
+                       AliEMCALTriggerSTU& operator=(const AliEMCALTriggerSTU& rhs);
+
+private:
+       
+       virtual Float_t ThresholdFromV0(L1TriggerType_t type);
+       
+               Int_t   fV0M[2]; //! 0/1: V0C/V0A
+
+       ClassDef(AliEMCALTriggerSTU,1)
+};
+#endif
diff --git a/EMCAL/AliEMCALTriggerSTURawStream.cxx b/EMCAL/AliEMCALTriggerSTURawStream.cxx
new file mode 100644 (file)
index 0000000..9546dde
--- /dev/null
@@ -0,0 +1,349 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+
+
+
+This class provides access to STU DDL raw data.
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include "AliEMCALTriggerSTURawStream.h"
+#include "AliRawReader.h"
+#include "AliLog.h"
+
+#include "Riostream.h"
+#include "TBits.h"
+
+namespace
+{
+       const Int_t kPayLoadSize = 944;
+}
+
+ClassImp(AliEMCALTriggerSTURawStream)
+
+//_____________________________________________________________________________
+AliEMCALTriggerSTURawStream::AliEMCALTriggerSTURawStream() : TObject(),
+fRawReader(0x0),
+fL1JetThreshold(0),
+fL1GammaThreshold(0),
+fL0GammaPatchIndex(0x0),
+fL1GammaPatchIndex(0x0),
+fL1JetPatchIndex(0x0),
+fNL0GammaPatch(0),
+fNL1JetPatch(0),
+fNL1GammaPatch(0),
+fL0(0)
+{
+       //
+}
+
+//_____________________________________________________________________________
+AliEMCALTriggerSTURawStream::AliEMCALTriggerSTURawStream(AliRawReader* rawReader) : TObject(),
+fRawReader(rawReader),
+fL1JetThreshold(0),
+fL1GammaThreshold(0),
+fL0GammaPatchIndex(0x0),
+fL1GammaPatchIndex(0x0),
+fL1JetPatchIndex(0x0),
+fNL0GammaPatch(0),
+fNL1JetPatch(0),
+fNL1GammaPatch(0),
+fL0(0)
+{
+       //
+       fRawReader->Reset();
+       fRawReader->Select("EMCAL",44);
+}
+
+//_____________________________________________________________________________
+AliEMCALTriggerSTURawStream::~AliEMCALTriggerSTURawStream()
+{
+       // destructor
+}
+
+//_____________________________________________________________________________
+void AliEMCALTriggerSTURawStream::Reset()
+{
+       //
+       if (fRawReader) fRawReader->Reset();
+}
+
+//_____________________________________________________________________________
+Bool_t AliEMCALTriggerSTURawStream::ReadPayLoad()
+{
+       // STU data decoder from Olivier Bourrion LPSC CNRS-IN2P3
+       // bourrion@lpsc.in2p3.fr
+       
+       UInt_t word32[1772]; // 32b words
+
+       Int_t iword = 0;
+       
+       UInt_t w32;
+       while (fRawReader->ReadNextInt(w32)) word32[iword++] = w32;
+       
+       if (iword < kPayLoadSize) 
+       {
+               AliError(Form("STU raw data size is too small: %d word32 only!", iword));
+               return kFALSE;
+       } 
+       else if (iword > kPayLoadSize )
+       {
+               AliLog::Message(AliLog::kInfo, "TRU raw data in the STU payload enabled","EMCAL","AliEMCALTriggerSTURawStream","ReadPayLoad()","AliEMCALTriggerSTURawStream.cxx",104);
+       }
+
+       fL0 = 0;
+       
+         fL1JetThreshold = ((word32[0]>>16) & 0xFFF);
+       fL1GammaThreshold =  (word32[0]      & 0xFFF);
+       
+       for (Int_t jet_row=0; jet_row<11; jet_row++)
+       {
+               UInt_t currentrow = word32[1+jet_row];
+               
+               for (Int_t jet_col=0; jet_col<15; jet_col++)
+               {
+                       if (currentrow & (1 << jet_col))
+                       {
+                               fNL1JetPatch++;
+                               fL1JetPatchIndex = (UShort_t*)realloc(fL1JetPatchIndex, fNL1JetPatch * sizeof(UShort_t));
+                               if (fL1JetPatchIndex == NULL) {AliError("Error (re)allocating L1 jet patch memory");}
+                               
+                               fL1JetPatchIndex[fNL1JetPatch-1] = ((jet_row << 8) & 0xFF00) | (jet_col & 0xFF);
+                       }
+               }
+       }
+       
+       //////////////////////////////////////////////////////////
+       // index des L0                                         //
+       //////////////////////////////////////////////////////////
+       // FIXME: still not interpreted to be done with Jiri
+       
+       unsigned short TRU_L0_indexes[32][6];
+       
+       // extraction from stream
+       for (Int_t index=0;index<6;index++)
+       {
+               for (Int_t tru_num=0;tru_num<16;tru_num++)
+               {
+                       TRU_L0_indexes[2*tru_num  ][index] = ( word32[12+index*16+tru_num]      & 0xFFFF);
+                       TRU_L0_indexes[2*tru_num+1][index] = ((word32[12+index*16+tru_num]>>16) & 0xFFFF);
+               }
+       }
+
+       for (Int_t tru_num=0;tru_num<32;tru_num++) 
+       {
+               for (Int_t index=0;index<6;index++) 
+               {
+                       for (Int_t bit_num=0;bit_num<12;bit_num++)
+                       {
+                               if ((TRU_L0_indexes[tru_num][index] & (1 << bit_num)))
+                               {
+                                       fL0 = 1;
+
+                                       Int_t idx = 12 * index + bit_num;
+                                       
+                                       Int_t col = idx / 3;
+                                       Int_t row = idx % 3;
+                                       
+                                       fNL0GammaPatch++;
+                                       fL0GammaPatchIndex = (UShort_t*)realloc(fL0GammaPatchIndex, fNL0GammaPatch * sizeof(UShort_t));
+                                       
+                                       if (fL0GammaPatchIndex == NULL) {AliError("Error (re)allocating L0 gamma patch memory");}
+                                       
+                                       fL0GammaPatchIndex[fNL0GammaPatch-1] = (((row << 10) & 0xC00) | ((col << 5) & 0x3E0) | (tru_num & 0x1F));
+                               }
+                       }
+               }
+       }
+
+       //////////////////////////////////////////////////////////
+       // index des L1 gamma                                   //
+       //////////////////////////////////////////////////////////
+       
+       unsigned short TRU_L1_indexes[32][8];
+       
+       // extraction from stream
+       for (Int_t index=0;index<8;index++)
+       {
+               for (Int_t tru_num=0;tru_num<16;tru_num++)
+               {
+                       TRU_L1_indexes[2*tru_num  ][index] = ( word32[108+index*16+tru_num]      & 0xFFFF);
+                       TRU_L1_indexes[2*tru_num+1][index] = ((word32[108+index*16+tru_num]>>16) & 0xFFFF);
+               }
+       }       
+
+       // interpretation
+       int gammacolnum;
+       short indexcopy;
+       
+       for (Int_t tru_num=0;tru_num<32;tru_num++)
+       {
+               for (Int_t index=0;index<8;index++)
+               {
+                       for (Int_t bit_num=0; bit_num<12; bit_num++)
+                       {
+                               if ((TRU_L1_indexes[tru_num][index] & (1<<bit_num)) != 0)
+                               {
+                                       if (index<4) // Even
+                                       {
+                                               gammacolnum = (2*bit_num  );
+                                               indexcopy   = index;
+                                       }
+                                       else         // Odd
+                                       {
+                                               gammacolnum = (2*bit_num+1);
+                                               indexcopy   = index-4;
+                                       }                                               
+                                       
+                                       fNL1GammaPatch++;
+                                       fL1GammaPatchIndex = (UShort_t*)realloc(fL1GammaPatchIndex, fNL1GammaPatch * sizeof(UShort_t));
+
+                                       if (fL1GammaPatchIndex == NULL) {AliError("Error (re)allocating L1 gamma patch memory");}
+                                       
+                                       fL1GammaPatchIndex[fNL1GammaPatch-1] = (((indexcopy << 10) & 0xC00) | ((gammacolnum << 5) & 0x3E0) | (tru_num & 0x1F));
+                               }
+                       }
+               }
+       }       
+
+       //////////////////////////////////////////////////////////
+       // raw output                                           //
+       //////////////////////////////////////////////////////////
+       
+       if ( iword <= kPayLoadSize ) return kFALSE;
+       
+       // extraction from stream
+       for (Int_t index=0;index<96;index++)
+       {
+               for (Int_t tru_num=0;tru_num<16;tru_num++)
+               {
+                       fADC[2*tru_num  ][index] = ( word32[236+index*16+tru_num]      & 0xFFFF);
+                       fADC[2*tru_num+1][index] = ((word32[236+index*16+tru_num]>>16) & 0xFFFF);
+               }
+       }       
+
+       for (Int_t tru_num=16;tru_num<32;tru_num++) // A side
+       {
+               for (Int_t index=0;index<96;index++)
+               {
+                       fADC[tru_num][index] = fADC[tru_num][95-index];
+               }
+       }
+       
+       return kFALSE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliEMCALTriggerSTURawStream::GetL0GammaPatch(const Int_t i, Int_t& tru, Int_t& col, Int_t& row) const
+{
+       //
+       if (i > fNL0GammaPatch) return kFALSE;
+       
+       tru =  fL0GammaPatchIndex[i] & 0x1F;
+       col = (fL0GammaPatchIndex[i] & 0x3E0) >> 5;
+       row = (fL0GammaPatchIndex[i] & 0xC00) >> 10;
+       
+       return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliEMCALTriggerSTURawStream::GetL1GammaPatch(const Int_t i, Int_t& tru, Int_t& col, Int_t& row) const
+{
+       //
+       if (i > fNL1GammaPatch) return kFALSE;
+       
+       tru =  fL1GammaPatchIndex[i] & 0x1F;
+       col = (fL1GammaPatchIndex[i] & 0x3E0) >> 5;
+       row = (fL1GammaPatchIndex[i] & 0xC00) >> 10;
+       
+       return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliEMCALTriggerSTURawStream::GetL1JetPatch(const Int_t i, Int_t& col, Int_t& row) const
+{
+       //
+       if (i > fNL1JetPatch) return kFALSE;
+       
+       col =  fL1JetPatchIndex[i] & 0xFF;
+       row = (fL1JetPatchIndex[i] & 0xFF00) >> 8;
+       
+       return kTRUE;
+}
+
+//_____________________________________________________________________________
+void AliEMCALTriggerSTURawStream::GetADC(Int_t iTRU, UInt_t ADC[])
+{
+       //
+       for (Int_t i=0; i<96; i++) ADC[i] = fADC[iTRU][i];
+}
+
+//_____________________________________________________________________________
+void AliEMCALTriggerSTURawStream::Dump(const Option_t *option) const
+{
+       //
+       TString op = option;
+       
+       cout << "Jet Threshold: " << fL1JetThreshold << " Gamma threshold: " << fL1GammaThreshold << endl;
+       
+       Int_t itru, col, row;
+
+       Bool_t isOK;
+       
+       if (op.Contains("L0") || op.Contains("ALL"))
+       {
+               for (Int_t i=0;i<fNL0GammaPatch;i++)
+               {
+                       isOK = GetL0GammaPatch(i,itru,col,row);
+                       if (isOK) cout << "> Found L0 gamma in TRU #" << setw(2) << itru
+                                               <<  " at: ( col: " << setw(2) << col << " , row: " << setw(2) << row << " )" << endl;
+               }
+       }
+       
+       if (op.Contains("L1") || op.Contains("ALL"))
+       {
+               for (Int_t i=0;i<fNL1GammaPatch;i++)
+               {
+                       isOK = GetL1GammaPatch(i,itru,col,row);
+                       if (isOK) cout << "> Found L1 gamma in TRU #" << setw(2) << itru
+                                               <<  " at: ( col: " << setw(2) << col << " , row: " << setw(2) << row << " )" << endl;
+               }
+
+               for (Int_t i=0;i<fNL1JetPatch;i++)
+               {
+                       isOK = GetL1JetPatch(i,col,row);
+                       if (isOK) cout << "> Found L1 jet at: ( col: " << setw(2) << col << " , row: " << setw(2) << row << " )" << endl;
+               }
+       }
+       
+       if (op.Contains("ADC") || op.Contains("ALL"))
+       {
+               for (Int_t i=0;i<32;i++)
+               {
+                       cout << "--------\n";
+                       cout << "TRU #" << setw(2) << i << ":";
+                       for (Int_t j=0;j<96;j++) 
+                       { 
+                               TBits xadc(12); xadc.Set(12,&fADC[i][j]); 
+                               if ((j%4)==0) cout << endl;
+                               //cout << setw(2) << j << ": " << xadc << " ";
+                               printf("%2d: %3x / ",j,fADC[i][j]); 
+                       }
+                       cout << "\n";
+               }
+       }
+}
diff --git a/EMCAL/AliEMCALTriggerSTURawStream.h b/EMCAL/AliEMCALTriggerSTURawStream.h
new file mode 100644 (file)
index 0000000..5f0157f
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef ALIEMCALTRIGGERSTURAWSTREAM_H
+#define ALIEMCALTRIGGERSTURAWSTREAM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/*
+
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include <TObject.h>
+#include <map>
+
+class AliRawReader;
+
+class AliEMCALTriggerSTURawStream: public TObject 
+{
+  public:
+                AliEMCALTriggerSTURawStream();
+             AliEMCALTriggerSTURawStream(AliRawReader* rawReader);
+    virtual ~AliEMCALTriggerSTURawStream();
+  
+    virtual void   Reset();
+    virtual Bool_t ReadPayLoad();
+       virtual void   Dump(const Option_t *option = "ALL") const;
+
+       virtual void                GetADC(Int_t iTRU, UInt_t ADC[]);
+       virtual UInt_t   GetL1JetThreshold() const {return   fL1JetThreshold;}
+       virtual UInt_t GetL1GammaThreshold() const {return fL1GammaThreshold;}
+       
+       virtual Int_t     GetNL0GammaPatch() const {return fNL0GammaPatch;}
+       virtual Int_t     GetNL1GammaPatch() const {return fNL1GammaPatch;}
+       virtual Int_t       GetNL1JetPatch() const {return fNL1JetPatch;}
+       
+       virtual Bool_t     GetL0GammaPatch(const Int_t i, Int_t& x, Int_t& y, Int_t& z) const;
+       virtual Bool_t     GetL1GammaPatch(const Int_t i, Int_t& x, Int_t& y, Int_t& z) const;
+       virtual Bool_t       GetL1JetPatch(const Int_t i, Int_t& x, Int_t& y) const;
+       
+       virtual UInt_t L0() {return fL0;}
+       
+private:
+    
+       AliEMCALTriggerSTURawStream(const AliEMCALTriggerSTURawStream& rhs);
+    AliEMCALTriggerSTURawStream& operator = (const AliEMCALTriggerSTURawStream& rhs);
+
+    AliRawReader* fRawReader;   // object for reading the raw data
+
+       UInt_t                                fL1JetThreshold;
+       UInt_t                              fL1GammaThreshold;
+       UShort_t*                          fL0GammaPatchIndex; // [fNL0GammaPatch]
+       UShort_t*                          fL1GammaPatchIndex; // [fNL1GammaPatch]
+       UShort_t*                            fL1JetPatchIndex; // [fNL1JetPatch]
+       
+       Int_t                                  fNL0GammaPatch;
+       Int_t                                    fNL1JetPatch;
+       Int_t                                  fNL1GammaPatch;
+       
+       UInt_t                                           fADC[32][96];
+       UInt_t                                                                                    fL0;
+       
+    ClassDef(AliEMCALTriggerSTURawStream,1)   // class for reading EMCAL STU DDL raw data
+};
+
+#endif
diff --git a/EMCAL/AliEMCALTriggerTRU.cxx b/EMCAL/AliEMCALTriggerTRU.cxx
new file mode 100644 (file)
index 0000000..3730bf9
--- /dev/null
@@ -0,0 +1,435 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+
+
+
+
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+
+#include "AliEMCALTriggerTRU.h"
+#include "AliEMCALTriggerPatch.h"
+#include "AliEMCALDigit.h"
+#include "AliEMCALTriggerSTU.h"
+#include "AliEMCALCalibData.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 kTimeWindowSize =  4; // 
+       const Int_t kNup            =  2; // 
+       const Int_t kNdown          =  1; // 
+}
+
+ClassImp(AliEMCALTriggerTRU)
+
+//________________
+AliEMCALTriggerTRU::AliEMCALTriggerTRU() : AliEMCALTriggerBoard()//,
+//fDigits(    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)
+{
+       //
+       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
+       
+       for (Int_t ietam=0;ietam<24;ietam++)
+       {
+               for (Int_t iphim=0;iphim<4;iphim++)
+               {
+                       // idx: 0..95 since iphim: 0..11 ietam: 0..23
+                       Int_t idx = ( !mapType ) ? ( 3 - iphim ) + ietam * 4 : iphim + (23 - ietam) * 4;        
+       
+                       // Build a matrix used to get TRU digit id (ADC channel) from (eta,phi)|SM
+                       fMap[ietam][iphim] = idx; // [0..11][0..3] namely [eta][phi] in SM
+               }
+       }
+}
+
+//________________
+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;
+       }
+}
+
+//________________
+void AliEMCALTriggerTRU::ShowFastOR(Int_t iTimeWindow, Int_t iChannel)
+{
+       //
+       Int_t iChanF, iChanL;
+       
+       if (iChannel != -1) iChanF = iChanL = iChannel;
+       else
+       {
+               iChanF =  0;
+               iChanL = 96;
+       }
+       
+       for (Int_t i=iChanF;i<iChanL+1;i++)
+       {
+               printf("\tChannel: %2d - ",i);
+               for (Int_t j=0;j<60;j++) 
+               {
+                       if (j == iTimeWindow)
+                               printf(" | %4d",fADC[i][j]);
+                       else if (j == iTimeWindow+kTimeWindowSize-1)
+                               printf(" %4d |",fADC[i][j]);
+                       else
+                               printf(" %4d",fADC[i][j]);
+               }
+               
+               printf("\n");
+       }
+}
+
+//________________
+Int_t AliEMCALTriggerTRU::L0v0()
+{
+       // 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
+       
+       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<=(kTimeBins-kTimeWindowSize); 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] = fRegion[j][k]>>2; // truncate time sum
+                       }
+               }
+                               
+               // 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++)
+               {
+                       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();
+                       }
+               }
+               
+               if ( !nP ) 
+                       fPatches->Delete();
+               else
+                       break;     // Stop the algo when at least one patch is found ( thres & max )
+               
+               ZeroRegion();  // Clear fRegion for this time window before computing the next one
+               
+       }
+       
+       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));
+               
+               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];
+                               }
+                               
+//                             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?
+               // 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;
+               
+               SlidingWindow( kGamma, vL0Threshold );
+               
+//             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);
+                       
+                       Int_t sizeX = fPatchSize->X() * fSubRegionSize->X();
+                       Int_t sizeY = fPatchSize->Y() * fSubRegionSize->Y();
+                       
+                       const Int_t psize =  sizeX * sizeY; // Number of FastOR in the patch
+                       
+                       Int_t idx[psize];
+                       
+                       Int_t aPeaks = 0;
+                       
+                       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 
+                                       
+                                       if (fRegion[int(v.X()*fSubRegionSize->X())+xx][int(v.Y()*fSubRegionSize->Y())+yy]) aPeaks++;
+                                       
+                                       if ( AliDebugLevel() ) ShowFastOR(i,idx[xx*sizeY+yy]);
+                               }
+                       }
+
+                       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) 
+                       {
+                               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++) ShowFastOR(i,idx[xx*sizeY+yy]); 
+                               }
+                               
+                               nP++; // all FOR in the patch must have seen a max
+                       }
+               }
+               
+               if ( !nP ) 
+                       fPatches->Delete();
+               else
+               {
+                       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 )
+               }
+
+               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++)
+               {
+                       Int_t max = 0;
+                       for (Int_t l=0; l<kTimeBins; l++) 
+                       {
+                               if (fADC[fMap[j][k]][l] > max) max = fADC[fMap[j][k]][l];
+                       }       
+                       
+                       if (max>4) fRegion[j][k] = max;
+               }
+       }
+               
+       Int_t vL0Threshold = 0;
+               
+       SlidingWindow( kGamma, vL0Threshold );
+       
+       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++;
+       }
+}
+
+//________________
+void AliEMCALTriggerTRU::SaveRegionADC(Int_t iTRU, Int_t iEvent)
+{
+       // O for STU Hw
+       //
+       gSystem->Exec(Form("mkdir -p Event%d",iEvent));
+       
+       ofstream outfile(Form("Event%d/data_TRU%d.txt",iEvent,iTRU),ios_base::trunc);
+       
+       for (Int_t i=0;i<96;i++) 
+       {
+               Int_t ietam = 23 - i/4;
+       
+               Int_t iphim =  3 - i%4;
+               
+               outfile << fRegion[ietam][iphim] << endl;
+       }
+
+       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()
+{
+       //
+       fPatches->Delete();
+       
+       ZeroRegion();
+       
+       for (Int_t i=0;i<96;i++) for (Int_t j=0;j<256;j++) fADC[i][j] = 0;
+}
+
diff --git a/EMCAL/AliEMCALTriggerTRU.h b/EMCAL/AliEMCALTriggerTRU.h
new file mode 100644 (file)
index 0000000..71600cd
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef ALIEMCALTRIGGERTRU_H
+#define ALIEMCALTRIGGERTRU_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/*
+Author: R. GUERNANE LPSC Grenoble CNRS/IN2P3
+*/
+
+#include <AliEMCALTriggerBoard.h>
+
+class AliEMCALTriggerSTU;
+class AliEMCALDigit;
+class AliEMCALCalibData;
+
+class AliEMCALTriggerTRU : public AliEMCALTriggerBoard 
+{
+public:
+       
+                      AliEMCALTriggerTRU();
+                      AliEMCALTriggerTRU(AliEMCALCalibData *calibData, const TVector2& rSize, Int_t mapType);
+       virtual       ~AliEMCALTriggerTRU();
+       
+       virtual Int_t  L0v0(); // space sum has reached a max
+       virtual Int_t  L0v1(); // one of the 4 FastOR in the patch has reached a max
+       virtual Int_t  L0v2(); // activity trigger
+       
+       virtual void   PeakFinder(const Int_t idx[], Int_t nfastor, Int_t start, Int_t nup, Int_t ndown, Int_t& npeaks); 
+       virtual void   SetADC(Int_t channel, Int_t bin, Int_t sig );
+       
+       virtual void   SaveRegionADC(Int_t iTRU, Int_t iEvent);
+//     virtual void   Scan();
+       virtual void   Reset();
+       virtual void   Peaks(Int_t arr[96][2]);
+       virtual void   ShowFastOR(Int_t timewindow, Int_t chan = -1);
+       
+private:
+                           AliEMCALTriggerTRU(const AliEMCALTriggerTRU& rhs);
+                AliEMCALTriggerTRU& operator=(const AliEMCALTriggerTRU& rhs);
+       
+       Int_t         fADC[96][256]; //! FIXME: Check the maximum number of samples
+       
+       ClassDef(AliEMCALTriggerTRU,1)
+};
+#endif
index 4285f67..17003ab 100644 (file)
@@ -41,6 +41,9 @@
 #pragma link C++ class AliEMCALSuperModuleCalibReference+;
 #pragma link C++ class AliEMCALCalibMapAPDVal+;
 #pragma link C++ class AliEMCALSuperModuleCalibMapAPD+;
+#pragma link C++ class AliEMCALRawDigit+;
+#pragma link C++ class AliEMCALTriggerSTURawStream+;
 // #pragma link C++ class AliEMCALShishKebabTrd1Module+;
 
 #endif
+
index ed5c57d..4d44ab0 100644 (file)
 #pragma link C++ class AliEMCALDigitizer+;
 #pragma link C++ class AliEMCALRawUtils+;
 #pragma link C++ class AliEMCALQADataMakerSim+;
+#pragma link C++ class AliEMCALTriggerBoard+;
+#pragma link C++ class AliEMCALTriggerPatch+;
+#pragma link C++ class AliEMCALTriggerSTU+;
+#pragma link C++ class AliEMCALTriggerTRU+;
+#pragma link C++ class AliEMCALTriggerData+;
+#pragma link C++ class AliEMCALTriggerElectronics+;
 
 #endif
+
index b977050..ebb53cd 100644 (file)
@@ -30,7 +30,9 @@ AliEMCALBiasAPD.cxx \
 AliEMCALCalibAbs.cxx \
 AliEMCALCalibReference.cxx \
 AliEMCALCalibMapAPD.cxx \
-SMcalib/AliEMCALCCUSBRawStream.cxx 
+SMcalib/AliEMCALCCUSBRawStream.cxx \
+AliEMCALRawDigit.cxx \
+AliEMCALTriggerSTURawStream.cxx
 # AliEMCALShishKebabTrd1Module.cxx \
 
 
@@ -47,3 +49,4 @@ PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \
                          -lRAWDatarec -lRAWDatabase \
                          -L$(ROOTLIBDIR) -lVMC -lGeom -lMinuit
 endif
+
index 7a764a0..a7e8584 100644 (file)
@@ -26,10 +26,11 @@ CINTHDRS:= $(HDRS) AliEMCALGeometry.h AliEMCALGeoUtils.h
 
 DHDR:=EMCALrecLinkDef.h
 # have to tune
-EINCLUDE:=PYTHIA6 RAW EVGEN THijing 
+EINCLUDE:=PYTHIA6 RAW EVGEN THijing VZERO 
 
 ifeq (win32gcc,$(ALICE_TARGET))
 PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \
                          -lEMCALUtils -lEMCALbase -lEMCALsim -lSTEER -lESD -lCDB -lSTEERBase \
                          -L$(ROOTLIBDIR) -lMinuit
 endif
+
index 14ebe15..797e0c5 100644 (file)
@@ -11,13 +11,19 @@ AliEMCALDigitizer.cxx \
 AliEMCALTick.cxx \
 AliEMCALRawUtils.cxx \
 AliEMCALTrigger.cxx \
-AliEMCALQADataMakerSim.cxx
+AliEMCALQADataMakerSim.cxx \
+AliEMCALTriggerBoard.cxx \
+AliEMCALTriggerPatch.cxx \
+AliEMCALTriggerSTU.cxx \
+AliEMCALTriggerTRU.cxx \
+AliEMCALTriggerData.cxx \
+AliEMCALTriggerElectronics.cxx
 
 HDRS= $(SRCS:.cxx=.h) 
 
 DHDR:=EMCALsimLinkDef.h
 # have to tune
-EINCLUDE:=PYTHIA6 RAW EVGEN THijing 
+EINCLUDE:=PYTHIA6 RAW EVGEN THijing VZERO 
 
 ifeq (win32gcc,$(ALICE_TARGET))
 PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \
@@ -25,3 +31,5 @@ PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \
                          -lRAWDatarec -lRAWDatasim  -lRAWDatabase \
                          -L$(ROOTLIBDIR) -lVMC -lGeom
 endif
+
+