PHOS trigger information in the ESD.
authorpolicheh <policheh@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sat, 10 Dec 2011 16:17:18 +0000 (16:17 +0000)
committerpolicheh <policheh@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sat, 10 Dec 2011 16:17:18 +0000 (16:17 +0000)
13 files changed:
PHOS/AliPHOSReconstructor.cxx
PHOS/AliPHOSReconstructor.h
PHOS/AliPHOSTRURawReader.cxx [new file with mode: 0644]
PHOS/AliPHOSTRURawReader.h [new file with mode: 0644]
PHOS/AliPHOSTriggerRawDigiProducer.cxx [new file with mode: 0644]
PHOS/AliPHOSTriggerRawDigiProducer.h [new file with mode: 0644]
PHOS/AliPHOSTriggerRawDigit.cxx [new file with mode: 0644]
PHOS/AliPHOSTriggerRawDigit.h [new file with mode: 0644]
PHOS/AliPHOSTriggerRawReader.cxx [new file with mode: 0644]
PHOS/AliPHOSTriggerRawReader.h [new file with mode: 0644]
PHOS/CMakelibPHOSrec.pkg
PHOS/PHOSrecLinkDef.h
PHOS/macros/Trigger/triggerClusters.C [new file with mode: 0644]

index 438c600..c3ce258 100644 (file)
@@ -55,6 +55,9 @@
 #include "AliPHOSRawFitterv4.h"
 #include "AliPHOSRawDigiProducer.h"
 #include "AliPHOSPulseGenerator.h"
+#include "AliPHOSTriggerRawDigit.h"
+#include "AliPHOSTriggerRawDigiProducer.h"
+#include "AliPHOSTriggerParameters.h"
 
 ClassImp(AliPHOSReconstructor)
 
@@ -62,7 +65,7 @@ Bool_t AliPHOSReconstructor::fgDebug = kFALSE ;
 TClonesArray*     AliPHOSReconstructor::fgDigitsArray = 0;   // Array of PHOS digits
 TObjArray*        AliPHOSReconstructor::fgEMCRecPoints = 0;   // Array of EMC rec.points
 AliPHOSCalibData * AliPHOSReconstructor::fgCalibData  = 0 ;
-
+TClonesArray*     AliPHOSReconstructor::fgTriggerDigits = 0;   // Array of PHOS trigger digits
 
 //____________________________________________________________________________
 AliPHOSReconstructor::AliPHOSReconstructor() :
@@ -78,7 +81,9 @@ AliPHOSReconstructor::AliPHOSReconstructor() :
   fgEMCRecPoints = new TObjArray(100) ;
   if (!fgCalibData)
     fgCalibData = new AliPHOSCalibData(-1); //use AliCDBManager's run number
-
+  
+  fgTriggerDigits  = new TClonesArray("AliPHOSTriggerRawDigit",100);
+  
   AliInfo(Form("PHOS bad channel map contains %d bad channel(s).\n",
                fgCalibData->GetNumOfEmcBadChannels()));
  
@@ -95,6 +100,7 @@ AliPHOSReconstructor::~AliPHOSReconstructor()
   delete fTmpDigLG;
   delete fgDigitsArray;
   delete fgEMCRecPoints;
+  delete fgTriggerDigits;
 } 
 
 //____________________________________________________________________________
@@ -164,6 +170,38 @@ void AliPHOSReconstructor::FillESD(TTree* digitsTree, TTree* clustersTree,
   emcbranch->SetAddress(&fgEMCRecPoints);
   emcbranch->GetEntry(0);
 
+
+  // Trigger
+
+  TBranch *tbranch = digitsTree->GetBranch("TPHOS");
+  if (!tbranch) { 
+    AliError("can't get the branch with the PHOS trigger digits !");
+    return;
+  }
+
+  tbranch->SetAddress(&fgTriggerDigits);
+  tbranch->GetEntry(0);
+
+  AliESDCaloTrigger* trgESD = esd->GetCaloTrigger("PHOS");
+  
+  if (trgESD) {
+    trgESD->Allocate(fgTriggerDigits->GetEntriesFast());
+
+    for (Int_t i = 0; i < fgTriggerDigits->GetEntriesFast(); i++) {
+      AliPHOSTriggerRawDigit* tdig = (AliPHOSTriggerRawDigit*)fgTriggerDigits->At(i);
+
+      Int_t mod,modX,modZ;
+      tdig->GetModXZ(mod,modX,modZ);
+
+      const Int_t relId[4] = {5-mod,0,modX+1,modZ+1};
+      Int_t absId;
+      
+      fGeom->RelToAbsNumbering(relId,absId);
+      trgESD->Add(mod,absId,tdig->GetAmp(),0.,(Int_t*)NULL,0,0,0);
+    }
+  }
+  
 //   //#########Calculate trigger and set trigger info###########
 
 //   AliPHOSTrigger tr ;
@@ -409,6 +447,21 @@ void  AliPHOSReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digits
 
   delete fitter ;
 
+  TClonesArray *tdigits = new TClonesArray("AliPHOSTriggerRawDigit",1);
+  tdigits->SetName("TDIGITS");
+  digitsTree->Branch("TPHOS", &tdigits, bufsize);  
+
+  rawReader->Reset();
+  AliPHOSTriggerRawDigiProducer tdp(rawReader);
+
+  AliPHOSTriggerParameters* parameters = new AliPHOSTriggerParameters();
+  readTRUParameters(parameters);
+  
+  tdp.SetTriggerParameters(parameters);
+  tdp.ProcessEvent(tdigits);
+  
+  delete parameters;
+  
   if (AliLog::GetGlobalDebugLevel() == 1) {
     Int_t modMax=-111;
     Int_t colMax=-111;
@@ -431,10 +484,14 @@ void  AliPHOSReconstructor::ConvertDigits(AliRawReader* rawReader, TTree* digits
     AliDebug(1,Form("Digit with max. energy:  modMax %d colMax %d rowMax %d  eMax %f\n\n",
                    modMax,colMax,rowMax,eMax));
   }
-
+  
   digitsTree->Fill();
+  
   digits->Delete();
   delete digits;
+  
+  tdigits->Delete();
+  delete tdigits;
 }
 //==================================================================================
 Float_t AliPHOSReconstructor::Calibrate(Float_t amp, Int_t absId)const{
@@ -533,3 +590,97 @@ Float_t AliPHOSReconstructor::CorrectNonlinearity(Float_t en){
   return en ;
 }
 
+void AliPHOSReconstructor::readTRUParameters(AliPHOSTriggerParameters* parameters) const
+{
+  //Read trigger parameters.
+
+  TString path(gSystem->Getenv("ALICE_ROOT"));
+  path += "/PHOS/macros/Trigger/OCDB/";
+  
+  for (Int_t mod = 2; mod < 5; ++mod) { // module
+    for (Int_t tru = 0; tru < 4; tru++) { // tru row
+      for (Int_t branch = 0; branch < 2; branch++) { // branch
+       
+       // Open the Appropriate pedestal file
+       TString fileName = path;
+       fileName += "pedestal_m";
+       fileName = fileName += mod;
+       fileName+="_r";
+       fileName+=tru;
+       fileName+="_b";
+       fileName+=branch;
+       fileName+=".dat";
+       std::ifstream instream;
+       instream.open(fileName.Data());
+       
+       // Read pedestals from file
+       if( ! instream.is_open() )
+         Printf("E-TRUPedestals: could not open %s", fileName.Data());
+       else
+         {
+           Int_t ped[112];
+           
+           char ch_s[35];
+           char *ch_s_p = ch_s;
+           //Int_t nlines = 0;
+           
+           Int_t t_ped_0 =0;
+           Int_t t_ped_1 =0;
+           Int_t t_ped_2 =0;
+           
+           for(Int_t n=0; n<112; n++)
+             {
+               instream.getline(ch_s_p,36);
+               if (ch_s_p[23]<='9' && ch_s_p[23]>='0')
+                 {
+                   t_ped_0 = ch_s_p[23]-'0';
+                 }
+               else if (ch_s_p[23]>='A' && ch_s_p[23]<='Z')
+                 {
+                   t_ped_0 = ch_s_p[23]-'A'+10;
+                   
+                 }
+                 
+               if (ch_s_p[22]<='9' && ch_s_p[22]>='0')
+                 {
+                   t_ped_1 = ch_s_p[22]-'0';
+                 }
+               else if (ch_s_p[22]<='Z' && ch_s_p[22]>='A')
+                 {
+                   t_ped_1 = ch_s_p[22]-'A'+10;
+                 }
+               
+               if (ch_s_p[21]<='9' && ch_s_p[21]>='0')
+                 {
+                   t_ped_2 = ch_s_p[21]-'0';
+                 }
+               else if (ch_s_p[21]<='Z' && ch_s_p[21]>='A')
+                 {
+                   t_ped_2 = ch_s_p[21]-'A'+10;
+                 }
+               
+               ped[n]=t_ped_2*256+t_ped_1*16+t_ped_0;
+               
+               
+             }
+           for (Int_t xrow = 0; xrow < 8; xrow++){
+             for (Int_t zcol = 0; zcol < 14; zcol++){
+               Int_t pedestal = ped[zcol*8+xrow];
+               
+               if( pedestal < 612 && pedestal > 412 ) // resonable
+                 parameters->SetTRUPedestal(pedestal, mod, tru, branch, xrow, zcol);
+               else // unresonable
+                 continue;
+             }
+           }
+         } // Ends read of pedestals from branch from file.
+       instream.close();
+      }// end branch
+    }// end tru
+    
+  }// end for mod
+}
+
+
+
+
index 62e6c6d..cee0716 100644 (file)
@@ -59,6 +59,7 @@ class AliRawReader;
 class AliPHOSRecoParam;
 class AliPHOSGeometry;
 class AliPHOSCalibData ;
+class AliPHOSTriggerParameters;
 
 // --- Standard library ---
 
@@ -91,7 +92,9 @@ public:
   static const AliPHOSRecoParam* GetRecoParam() {
     return dynamic_cast<const AliPHOSRecoParam*>(AliReconstructor::GetRecoParam(4)); }
   static Float_t CorrectNonlinearity(Float_t oldEnergy) ;
-
+  
+  void readTRUParameters(AliPHOSTriggerParameters* parameters) const;
+  
 private:
   AliPHOSReconstructor(const AliPHOSReconstructor & rec); // Not implemented
   AliPHOSReconstructor & operator = (const AliPHOSReconstructor &); // Not implemented
@@ -105,8 +108,9 @@ private:
   static TClonesArray      *fgDigitsArray;   //! Array of PHOS digits
   static TObjArray         *fgEMCRecPoints;  //! Array of EMC rec.points
   static AliPHOSCalibData * fgCalibData ;    //! Calibration database if aval.
+  static TClonesArray      *fgTriggerDigits; //! Array of PHOS trigger digits
 
-  ClassDef(AliPHOSReconstructor,9)  // PHOS Reconstruction class
+  ClassDef(AliPHOSReconstructor,10)  // PHOS Reconstruction class
 
 }; 
 
diff --git a/PHOS/AliPHOSTRURawReader.cxx b/PHOS/AliPHOSTRURawReader.cxx
new file mode 100644 (file)
index 0000000..f138422
--- /dev/null
@@ -0,0 +1,155 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+/* 
+ * Class for reading TRU data from a bunch from a raw datastream.
+ * Author: Henrik Qvigstad <henrik.qvigstad@cern.ch>
+ */
+
+#include "AliPHOSTRURawReader.h"
+
+#include "AliCaloRawStreamV3.h"
+#include <bitset> // std::bitset
+
+ClassImp(AliPHOSTRURawReader)
+
+
+//________________________________________________________________
+AliPHOSTRURawReader::AliPHOSTRURawReader()
+  : TObject(),
+    fSignals(),
+    fFlags(),
+    fActive(0),
+    fActiveTime()
+{
+  // default constructor
+  
+  // fSignals Initialization:
+  for(Int_t row = 0; row < kN2x2XPrTRURow; ++row) {
+    for(Int_t branch = 0; branch < kN2x2ZPrBranch; ++branch) {
+      for(Int_t timeBin = 0; timeBin < kNTimeBins; ++timeBin) {
+       fSignals[row][branch][timeBin] = kDefaultSignalValue;
+      }
+    }
+  }
+      
+  // fFlags Initialization
+  for(Int_t row = 0; row < kN4x4XPrTRURow; ++row){
+    for(Int_t branch = 0; branch < kN4x4ZPrBranch; ++branch){
+      for(Int_t timeBin = 0; timeBin < kNTimeBins; ++timeBin){
+       fFlags[row][branch][timeBin] = kFALSE;
+      }
+    }
+  }
+  
+  // fActiveTime Initialization
+  for(Int_t timeBin = 0; timeBin < kNTimeBins; ++timeBin){
+    fActiveTime[timeBin] = kFALSE;
+  }
+}
+
+
+//________________________________________________________________
+AliPHOSTRURawReader::~AliPHOSTRURawReader()
+{
+  // destructor
+}
+
+//________________________________________________________________
+void AliPHOSTRURawReader::ReadFromStream(AliCaloRawStreamV3* rawStream)
+{
+ // reads the trigger signal amplitudes and trigger flags from the rawStream
+  
+  const UShort_t * const signal = rawStream->GetSignals(); // stream of 10-bit words, buffered as 16-bit words
+  const Int_t signalLength = rawStream->GetBunchLength();
+  const Int_t timeBin = rawStream->GetHWAddress() & 0x7f; // , i.e. & '01111111', strips the first 7 bits ([0:6]) and interprits it as a int
+
+  // TODO: this may need to be an error
+  if(signalLength != 16 && signalLength != 16+112)
+    Warning("ReadFromStream", " signalLength: !16 && !16+112, reader logic may not be valid.");
+  
+
+  fActive = kTRUE;
+  fActiveTime[timeBin] = kTRUE;
+
+  /* There are 91 4x4 Sliding Window signal sum trigger flags.
+   * We read the trigger location information from first 12 10-bit words of the signal
+   * (these are buffered to 12 16-bit words in the rawstream object)
+   * , but only 10 of the 10-bit words are used for trigger location within the TRU.
+   * The flags are found in word_2[0] to word_11[9].
+   * We read the information as following. */
+
+  for(Int_t wIdx = 2; wIdx < 12; ++wIdx) { // words
+    const std::bitset<10> word(signal[wIdx]); // @param word represent a 10-bit word
+    for(Int_t bIdx = 0; bIdx < 10; ++bIdx) { // bits
+      //const Int_t index = 119 - (wIdx*10 + (9-bi)); // index used in TRU documentation,
+      const Int_t index = (110 - wIdx*10) + bIdx; // equivalent
+       if( index < 91 ) { // we are only interrested in these words/bits
+         const Int_t xIdx = index % 7; // x index in TRU internal 2x2 coordinate system
+         const Int_t zIdx = index / 7; // z index in TRU internal 2x2 coordinate system
+         // fFlags[xIdx][zIdx][time] = (signal[wIdx] & (0x01 * 2**i)) != 1;
+         fFlags[xIdx][zIdx][timeBin] = (bool) word[bIdx];
+       }
+    } // end bit loop
+  }// end word loop
+
+
+
+  /* The 2x2 trigger signal sum may follow.
+   * If so, it is found in the following 112 10-bit words
+   * (, 16-bit words in buffer.)
+   * We read the signal as following.
+   */
+
+  if( 16+112 == signalLength) {
+    for (Int_t idx = 0; idx < 112; idx++)
+      {
+       const Int_t xIdx = 7 - idx % 8;  // x index in TRU
+       const Int_t zIdx = 13 - idx / 8; // z index in TRU
+       const Int_t wIdx = idx + 16;     // word index in signal array
+       fSignals[xIdx][zIdx][timeBin] = signal[wIdx];
+      }
+  }
+}
+
+
+//________________________________________________________________
+void AliPHOSTRURawReader::Reset()
+{
+  // Reset to default values
+  
+  if( ! fActive )
+    return;
+
+  for(Int_t timeBin = 0; timeBin < kNTimeBins; ++timeBin) { // loop timeBins
+    if( fActiveTime[timeBin] ) {
+      for(Int_t xIdx = 0; xIdx < kN2x2XPrTRURow; ++xIdx) { // loop 2x2
+       for(Int_t zIdx = 0; zIdx < kN2x2ZPrBranch; ++zIdx) {
+         fSignals[xIdx][zIdx][timeBin] = kDefaultSignalValue;
+       } // zIdx
+      } // xIdx
+      for(Int_t xIdx = 0; xIdx < kN4x4XPrTRURow; ++xIdx) { // loop 4x4
+       for(Int_t zIdx = 0; zIdx < kN4x4ZPrBranch; ++zIdx) {
+         fFlags[xIdx][zIdx][timeBin] = false;
+       } // zIdx
+      } // xIdx
+    }// end if fActiveTime
+    fActiveTime[timeBin] = false;
+  } // timeBin
+
+  fActive = false;
+}
diff --git a/PHOS/AliPHOSTRURawReader.h b/PHOS/AliPHOSTRURawReader.h
new file mode 100644 (file)
index 0000000..ad50e47
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef ALIPHOSTRURAWREADER_H
+#define ALIPHOSTRURAWREADER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+/* $Id$ */
+
+
+class AliCaloRawStreamV3;
+
+#include "TObject.h"
+
+/* 
+ * Class for reading TRU data from a bunch from a raw datastream.
+ * Author: Henrik Qvigstad <henrik.qvigstad@cern.ch>
+ */
+class AliPHOSTRURawReader : public TObject
+{
+ public:
+  AliPHOSTRURawReader();
+  virtual ~AliPHOSTRURawReader();
+
+  Short_t GetTriggerSignal(Int_t xIdx, Int_t zIdx, Int_t timeBin) const {return fSignals[xIdx][zIdx][timeBin];}
+  Bool_t GetTriggerFlag(Int_t xIdx, Int_t zIdx, Int_t timeBin) const {return fFlags[xIdx][zIdx][timeBin];}
+  bool IsActive() {return fActive;}
+  bool IsActive(Int_t timeBin) {return fActiveTime[timeBin];}
+  
+  void ReadFromStream(AliCaloRawStreamV3* );
+  void Reset();
+
+ private:
+  AliPHOSTRURawReader(const AliPHOSTRURawReader &); // not implemented
+  AliPHOSTRURawReader& operator= (const AliPHOSTRURawReader &); // not implemented
+  
+ public:
+  const static Int_t kDefaultSignalValue = 512; // Default/Ideal TRU amplitude pedestal
+  
+ private:  
+  // constants
+  const static Int_t kNTimeBins = 128; // Number of timeBins
+  const static Int_t kN2x2XPrTRURow = 8; // (=64/2/4) Number of 2x2 pr. row
+  const static Int_t kN2x2ZPrBranch = 14; // (=56/2/2) Number of 2x2 pr. branch
+  const static Int_t kN4x4XPrTRURow = 7; // (=64/2/4 -1) Number of 4x4 pr. row
+  const static Int_t kN4x4ZPrBranch = 13; // (=56/2/2) -1 Number of 4x4 pr. branch
+  
+  Short_t fSignals[kN2x2XPrTRURow][kN2x2ZPrBranch][kNTimeBins]; // 2x2 Trigger Signal Sum, [x][z][t]
+  Bool_t  fFlags[kN4x4XPrTRURow][kN4x4ZPrBranch][kNTimeBins]; // 4x4 Trigger Flag, [x][z][t]
+  
+  Bool_t fActive; // Active
+  Bool_t fActiveTime[kNTimeBins]; // Active [t]
+  
+  ClassDef(AliPHOSTRURawReader, 0)
+};
+
+#endif // ALIPHOSTRURAWREADER_H
diff --git a/PHOS/AliPHOSTriggerRawDigiProducer.cxx b/PHOS/AliPHOSTriggerRawDigiProducer.cxx
new file mode 100644 (file)
index 0000000..2a67293
--- /dev/null
@@ -0,0 +1,196 @@
+/**************************************************************************
+ * 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 produces PHOS trigger digits of one event.
+//Authors: Henrik Qvigstad, Boris Polishchuk.
+
+#include "AliPHOSTriggerRawDigiProducer.h"
+#include "AliPHOSTriggerRawReader.h"
+#include "AliPHOSTRURawReader.h"
+#include "AliPHOSTriggerParameters.h"
+#include "AliPHOSTriggerRawDigit.h"
+#include "AliPHOSGeometry.h"
+#include "AliRawReader.h"
+#include "AliCaloRawStreamV3.h"
+
+#include "TH1I.h"
+#include "TH2I.h"
+
+#include <iostream>
+using namespace std;
+
+ClassImp(AliPHOSTriggerRawDigiProducer)
+
+AliPHOSTriggerRawDigiProducer::AliPHOSTriggerRawDigiProducer()
+  :fModules(kNMods, false),
+   fSaturationThreshold(950),
+   fParameters(0),
+   fRawReader(0),
+   fRawStream(0),
+   fTriggerReader(0)
+{}
+
+AliPHOSTriggerRawDigiProducer::AliPHOSTriggerRawDigiProducer(AliRawReader *rawReader)
+  :fModules(kNMods, false),
+   fSaturationThreshold(950),
+   fParameters(0),
+   fRawReader(rawReader),
+   fRawStream(0),
+   fTriggerReader(new AliPHOSTriggerRawReader)
+{
+  SetAnalyseModule(2);
+  SetAnalyseModule(3);
+  SetAnalyseModule(4);
+
+  fRawStream = new AliCaloRawStreamV3(rawReader,"PHOS");
+}
+
+AliPHOSTriggerRawDigiProducer::~AliPHOSTriggerRawDigiProducer()
+{
+  delete fRawStream;
+}
+
+void AliPHOSTriggerRawDigiProducer::ProcessEvent(TClonesArray* tdigits)
+{
+  
+  fTriggerReader->Reset();
+
+  tdigits->Clear();
+  Int_t iDigit=0 ;
+
+  while (fRawStream->NextDDL()) {
+    while (fRawStream->NextChannel()) {
+
+      if (fRawStream->IsTRUData()) {
+       fTriggerReader->ReadFromStream(fRawStream);
+      }// IsTRUData
+    }// NextChannel
+  }//NextDDL
+       
+  // Loop over modules
+  for(unsigned int mod = 0; mod < fModules.size(); ++mod) {
+    if( fModules[mod] ) {
+      
+      // Loop over 4x4 cells
+      for(int TRURow = 0; TRURow < kNTRURows; ++TRURow) {
+       for(int branch = 0; branch < kNBranches; ++branch) {
+         
+         AliPHOSTRURawReader* truReader = fTriggerReader->GetTRU(mod, TRURow, branch);
+         if( truReader->IsActive() ) {
+           
+           for(int xIdx = 0; xIdx < kN4x4XPrTRURow; ++xIdx) {
+             for(int zIdx = 0; zIdx < kN4x4ZPrBranch; ++zIdx) {
+             
+               // Determin if Trigger is flagged for any timeBin
+               bool triggered = false;
+
+               for(int timeBin = 0; timeBin < kNTRUTimeBins; ++timeBin){
+                 if(truReader->IsActive(timeBin)) {
+                   if( fTriggerReader->GetTRU(mod, TRURow, branch)->GetTriggerFlag(xIdx, zIdx, timeBin) ){
+                     triggered = true;
+                   } // end "if TriggerBit"
+                 }
+               }// end TimeBin loop
+               
+               if( triggered ){
+                 // Get peak values
+                 const int TSmax = Get4x4Max(fTriggerReader, fParameters, mod, TRURow, branch, xIdx, zIdx);
+                 new((*tdigits)[iDigit]) AliPHOSTriggerRawDigit(mod,xIdx,zIdx,TRURow,branch,TSmax); 
+                 iDigit++;
+               }// end  "if triggered"
+             
+             } // end zIdx loop
+           } // end xIdx loop
+         } // truReader->IsActive
+       } // end branch loop
+      } // end tru loop
+    } // end "if module"
+  } // end mod loop
+  
+}
+
+int AliPHOSTriggerRawDigiProducer::Get2x2Max(AliPHOSTriggerRawReader* reader, AliPHOSTriggerParameters* params, int mod, int xIdx, int zIdx)
+{
+  int max = 0;
+  for(int timeBin = 0; timeBin < kNTRUTimeBins; ++timeBin) {
+    const int signal = Get2x2Signal(reader, params, mod, xIdx, zIdx, timeBin);
+    if( max < signal ){
+      max = signal;
+    }
+  }
+  return max;
+}
+
+
+int AliPHOSTriggerRawDigiProducer::Get2x2Signal(AliPHOSTriggerRawReader* reader, AliPHOSTriggerParameters* parameters, int mod, int xIdx, int zIdx, int timeBin)
+{
+  const int TRURow = xIdx / kN2x2XPrTRURow;
+  const int branch = zIdx / kN2x2ZPrBranch;
+  const int TRUX = xIdx % kN2x2XPrTRURow; // 2x2 coordinates
+  const int TRUZ = zIdx % kN2x2ZPrBranch; // 2x2 coordinates
+
+  if( reader->GetTRU(mod, TRURow, branch)->IsActive() ){
+    const int signal = reader->GetTRU(mod, TRURow, branch)->GetTriggerSignal( TRUX, TRUZ, timeBin);
+    if( parameters )
+      return signal - parameters->GetTRUPedestal(mod, TRURow, branch, TRUX, TRUZ);
+    else
+      return signal - AliPHOSTRURawReader::kDefaultSignalValue;
+  }
+  else
+    return 0;
+}
+
+int AliPHOSTriggerRawDigiProducer::Get4x4Max(AliPHOSTriggerRawReader* reader, AliPHOSTriggerParameters* params, int mod, int TRURow, int branch, int xIdx, int zIdx)
+{
+  int max = 0;
+  for(int timeBin = 0; timeBin < kNTRUTimeBins; ++timeBin) {
+    const int signal = Get4x4Signal(reader, params, mod, TRURow, branch, xIdx, zIdx, timeBin);
+    if( max < signal ){
+      max = signal;
+    }
+  }
+  return max;
+}
+
+
+int AliPHOSTriggerRawDigiProducer::Get4x4Signal(AliPHOSTriggerRawReader* reader, AliPHOSTriggerParameters* params, int mod, int TRURow, int branch, int xIdx, int zIdx, int timeBin)
+{
+  const int modX = xIdx + TRURow * kN2x2XPrTRURow;
+  const int modZ = zIdx + branch * kN2x2ZPrBranch;
+
+  const int signal
+    = Get2x2Signal(reader, params, mod, modX  , modZ  , timeBin)
+      + Get2x2Signal(reader, params, mod, modX+1, modZ  , timeBin)
+      + Get2x2Signal(reader, params, mod, modX  , modZ+1, timeBin)
+      + Get2x2Signal(reader, params, mod, modX+1, modZ+1, timeBin);
+  return signal;
+}
+
+bool AliPHOSTriggerRawDigiProducer::Is2x2Active(AliPHOSTriggerRawReader* reader, int mod, int xIdx, int zIdx)
+{
+  const int TRURow = xIdx / kN2x2XPrTRURow;
+  const int branch = zIdx / kN2x2ZPrBranch;
+
+  return reader->GetTRU(mod, TRURow, branch)->IsActive();
+}
+
+bool AliPHOSTriggerRawDigiProducer::Is2x2Active(AliPHOSTriggerRawReader* reader, int mod, int xIdx, int zIdx, int timeBin)
+{
+  const int TRURow = xIdx / kN2x2XPrTRURow;
+  const int branch = zIdx / kN2x2ZPrBranch;
+
+  return reader->GetTRU(mod, TRURow, branch)->IsActive(timeBin);
+}
+
+
diff --git a/PHOS/AliPHOSTriggerRawDigiProducer.h b/PHOS/AliPHOSTriggerRawDigiProducer.h
new file mode 100644 (file)
index 0000000..afc877a
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef ALIPHOSTRIGGERRAWDIGIPRODUCER_H
+#define ALIPHOSTRIGGERRAWDIGIPRODUCER_H
+/* Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                          */
+
+class AliPHOSTriggerRawReader;
+class AliPHOSTriggerParameters;
+class AliRawReader;
+class AliCaloRawStreamV3;
+
+#include "TString.h"
+#include "TClonesArray.h"
+
+#include <vector>
+
+class AliPHOSTriggerRawDigiProducer
+{
+ public:
+  
+  AliPHOSTriggerRawDigiProducer();
+  AliPHOSTriggerRawDigiProducer(AliRawReader *rawReader);
+  
+  virtual ~AliPHOSTriggerRawDigiProducer();
+  
+  void ProcessEvent(TClonesArray* tdigits);
+
+  void SetTriggerParameters(AliPHOSTriggerParameters* parameters) {fParameters = parameters;}
+  void SetAnalyseModule(int mod, bool analyse = true) {fModules[mod] = analyse;}
+    
+  static int Get2x2Max(AliPHOSTriggerRawReader*, AliPHOSTriggerParameters*, int mod, int xIdx, int zIdx);
+  static int Get2x2Signal(AliPHOSTriggerRawReader*, AliPHOSTriggerParameters*, int mod, int xIdx, int zIdx, int timeBin);
+  static int Get4x4Max(AliPHOSTriggerRawReader*, AliPHOSTriggerParameters*, int mod, int TRURow, int branch, int xIdx, int zIdx);
+  static int Get4x4Signal(AliPHOSTriggerRawReader*, AliPHOSTriggerParameters*, int mod, int TRURow, int branch, int xIdx, int zIdx, int timeBin);
+  
+  static bool Is2x2Active(AliPHOSTriggerRawReader*, int mod, int xIdx, int zIdx);
+  static bool Is2x2Active(AliPHOSTriggerRawReader*, int mod, int xIdx, int zIdx, int timeBin);
+    
+  const static int kNMods = 5; // number of PHOS modules
+  const static int kNTRURows = 4; // number of TRU rows
+  const static int kNBranches = 2; // number of branches
+  const static int kN2x2X = 32; // (=64/2) Number of 2x2 in X direction
+  const static int kN2x2Z = 28; // (=56/2) Number of 2x2 in Z direction
+  const static Int_t kN2x2XPrTRURow = 8; // (=64/2/4) Number of 2x2 pr. row
+  const static Int_t kN2x2ZPrBranch = 14; // (=56/2/2) Number of 2x2 pr. branch
+  const static Int_t kN4x4XPrTRURow = 7; // (=64/2/4 -1) Number of 4x4 pr. row
+  const static Int_t kN4x4ZPrBranch = 13; // (=56/2/2) -1 Number of 4x4 pr. branch  
+  const static int kNTRUTimeBins = 128; // number of TRU time bins
+  const static int kNDefaultNEMCTimeBins = 62;
+
+ private:  
+  AliPHOSTriggerRawDigiProducer(const AliPHOSTriggerRawDigiProducer &tdp); // not implemented
+  AliPHOSTriggerRawDigiProducer& operator= (const AliPHOSTriggerRawDigiProducer &tdp); // not implemented
+
+ protected:
+  std::vector<bool> fModules; // , per module: should analyser analyse module
+  UShort_t fSaturationThreshold;
+  AliPHOSTriggerParameters* fParameters;
+  
+private:
+  AliRawReader            * fRawReader;       //! Raw data reader
+  AliCaloRawStreamV3      * fRawStream;       //! Calorimeter decoder of ALTRO format
+  AliPHOSTriggerRawReader * fTriggerReader;   //! TriggerRawReader
+
+  ClassDef(AliPHOSTriggerRawDigiProducer,1)
+};
+
+#endif
diff --git a/PHOS/AliPHOSTriggerRawDigit.cxx b/PHOS/AliPHOSTriggerRawDigit.cxx
new file mode 100644 (file)
index 0000000..0082667
--- /dev/null
@@ -0,0 +1,55 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+/* 
+   4x4 TRU represented by position and amplitude.
+   Author: Boris Polishchuk (Boris.Polishchuk@cern.ch)
+*/
+
+// --- AliRoot header files ---
+#include "AliPHOSTriggerRawDigit.h"
+
+ClassImp(AliPHOSTriggerRawDigit)
+
+AliPHOSTriggerRawDigit::AliPHOSTriggerRawDigit() : 
+AliDigitNew(),fMod(-1),fXIdx(-1),fZIdx(-1),fTRURow(-1),fBranch(-1)
+{
+  //Default constructor.
+}
+
+AliPHOSTriggerRawDigit::AliPHOSTriggerRawDigit(Int_t module, Int_t xIdx, Int_t zIdx, Int_t TRURow, Int_t branch, Int_t amp) :
+  AliDigitNew(),fMod(module),fXIdx(xIdx),fZIdx(zIdx),fTRURow(TRURow),fBranch(branch)
+{
+  fAmp = amp;
+}
+
+AliPHOSTriggerRawDigit::AliPHOSTriggerRawDigit(const AliPHOSTriggerRawDigit & tdigit) :
+  AliDigitNew(tdigit),fMod(tdigit.fMod),fXIdx(tdigit.fXIdx),fZIdx(tdigit.fZIdx),
+  fTRURow(tdigit.fTRURow),fBranch(tdigit.fBranch) 
+{
+  fAmp = tdigit.fAmp;
+}
+
+void AliPHOSTriggerRawDigit::GetModXZ(Int_t& mod, Int_t& modX, Int_t& modZ)
+{
+  //Return 4x4 region bottom left cell position.
+
+  Int_t kN2x2XPrTRURow = 8;
+  Int_t kN2x2ZPrBranch = 14;
+  
+  modX = (fXIdx + fTRURow * kN2x2XPrTRURow)*2;
+  modZ = (fZIdx + fBranch * kN2x2ZPrBranch)*2;
+  mod = fMod;
+  
+}
diff --git a/PHOS/AliPHOSTriggerRawDigit.h b/PHOS/AliPHOSTriggerRawDigit.h
new file mode 100644 (file)
index 0000000..a300e3e
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef ALIPHOSTRIGGERRAWDIGIT_H
+#define ALIPHOSTRIGGERRAWDIGIT_H
+
+/* Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                          */
+
+#include "AliDigitNew.h"
+
+class AliPHOSTriggerRawDigit : public AliDigitNew 
+{
+ public:
+
+  AliPHOSTriggerRawDigit();
+  AliPHOSTriggerRawDigit(Int_t module, Int_t xIdx, Int_t zIdx, Int_t TRURow, Int_t branch, Int_t amp);
+  AliPHOSTriggerRawDigit(const AliPHOSTriggerRawDigit & tdigit);
+  virtual ~AliPHOSTriggerRawDigit() {}
+
+  void Get4x4Position(Int_t& module, Int_t& xIdx, Int_t& zIdx, Int_t& TRURow, Int_t& branch) 
+  {module = fMod; xIdx = fXIdx; zIdx = fZIdx; TRURow = fTRURow; branch = fBranch; }
+
+  void GetModXZ(Int_t& mod, Int_t& modX, Int_t& modZ);
+
+ private:
+
+  Int_t fMod;  // module
+  Int_t fXIdx; // 4x4 X 
+  Int_t fZIdx; // 4x4 Z
+  Int_t fTRURow; // TRU row
+  Int_t fBranch; // branch
+
+  ClassDef(AliPHOSTriggerRawDigit,1)
+};
+
+#endif
diff --git a/PHOS/AliPHOSTriggerRawReader.cxx b/PHOS/AliPHOSTriggerRawReader.cxx
new file mode 100644 (file)
index 0000000..b367ab2
--- /dev/null
@@ -0,0 +1,110 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+/*
+ *  Class for reading the Trigger Data Stream from Raw.
+ *   please read documentation for AliPHOSTriggerRawReader::ReadFromStream .
+ */
+
+
+#include "AliPHOSTriggerRawReader.h"
+
+#include "AliCaloRawStreamV3.h"
+#include "AliPHOSTRURawReader.h"
+
+ClassImp(AliPHOSTriggerRawReader)
+
+
+//________________________________________________________________
+AliPHOSTriggerRawReader::AliPHOSTriggerRawReader()
+  : TObject(),
+    fTRUs()
+{
+  // default constructor.
+
+  // Initialise fTRUs
+  for(Int_t mod=0; mod<kNMods; mod++)
+    for(Int_t row=0; row<kNTRURows; ++row)
+      for(Int_t branch=0; branch<kNBranches; ++branch)
+       fTRUs[mod][row][branch] = 0;
+}
+
+    
+//________________________________________________________________
+AliPHOSTriggerRawReader::~AliPHOSTriggerRawReader()
+{
+  // destructor
+  
+  for(Int_t mod = 0; mod < kNMods; ++mod)
+    for(Int_t row = 0; row < kNTRURows; ++row)
+      for(Int_t branch = 0; branch < kNBranches; branch++)
+       delete fTRUs[mod][row][branch];
+}
+
+//________________________________________________________________
+AliPHOSTRURawReader* AliPHOSTriggerRawReader::GetTRU(Int_t mod, Int_t truRow, Int_t branch)
+{
+  // Get TRU Raw Reader.
+
+  if( ! fTRUs[mod][truRow][branch] )
+    fTRUs[mod][truRow][branch] = new AliPHOSTRURawReader();
+  return fTRUs[mod][truRow][branch];
+}
+
+//________________________________________________________________
+void AliPHOSTriggerRawReader::ReadFromStream(AliCaloRawStreamV3* rawStream)
+{
+  // Give a AliCaloRawStreamV3* to an instance of this class.
+  // It will read from the stream. The stream is passed to 'AliPHOSTRURawReader's
+  // which are accesible through 'AliPHOSTriggerRawReader::GetTRU'.
+  // note that @param rawStream will not be left in the same state in terms of
+  // bunch position, i.e. rawStream->NextBunch() will be called.
+  //
+  // It is up to the user to check that
+  // the is at a channel which is tru data, i.e.:
+  //   while (rawStream->NextDDL()) {
+  //     while (rawStream->NextChannel()) {
+  //       if ( rawStream->IsTRUData() ) 
+  //     triggerReader->ReadFromStream(rawStream);
+  //       else
+  //     // do something else
+  //     }
+  //   } 
+  // . Other uses will result in undefined behaviour!
+
+  while (rawStream->NextBunch()) {
+    Int_t module = rawStream->GetModule();
+    Int_t rcuRow = rawStream->GetRow();
+    Int_t branch = 1 - rawStream->GetBranch(); // !!! Found this to be necessary, -Henrik Qvigstad <henrik.qvigstad@cern.ch>
+    
+    GetTRU(module, rcuRow, branch)->ReadFromStream(rawStream);
+  } // end while 
+}
+
+//________________________________________________________________
+void AliPHOSTriggerRawReader::Reset()
+{
+  // Reset
+
+  for(Int_t mod = 0; mod < kNMods; ++mod)
+    for(Int_t truRow = 0; truRow < kNTRURows; ++truRow)
+      for(Int_t branch = 0; branch < kNBranches; branch++)
+       if( fTRUs[mod][truRow][branch] )
+         fTRUs[mod][truRow][branch]->Reset();
+}
diff --git a/PHOS/AliPHOSTriggerRawReader.h b/PHOS/AliPHOSTriggerRawReader.h
new file mode 100644 (file)
index 0000000..2693025
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef ALIPHOSTRIGGERRAWREADER_H
+#define ALIPHOSTRIGGERRAWREADER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+/* $Id$ */
+
+#include "TObject.h"
+
+class AliCaloRawStreamV3;
+class AliPHOSTRURawReader;
+
+/*
+ *  Class for reading the Trigger Data Stream from Raw.
+ */
+class AliPHOSTriggerRawReader : public TObject
+{
+ public:
+  AliPHOSTriggerRawReader();
+ ~AliPHOSTriggerRawReader();
+  
+  AliPHOSTRURawReader* GetTRU(Int_t mod, Int_t truRow, Int_t branch);
+  
+  void ReadFromStream(AliCaloRawStreamV3* );
+  void Reset();
+  
+ private:
+  // constants
+  const static Int_t kNMods = 5; // n. mods
+  const static Int_t kNTRURows = 4; // n. tru rows
+  const static Int_t kNBranches = 2; // n. branches
+
+  AliPHOSTRURawReader* fTRUs[kNMods][kNTRURows][kNBranches]; // TRU raw readers [mod][truRow][branch]
+
+
+  ClassDef(AliPHOSTriggerRawReader, 0)
+};
+
+#endif 
index a539105..ad38ef5 100644 (file)
@@ -46,6 +46,10 @@ set ( SRCS
     AliPHOSAodCluster.cxx 
     AliPHOSQADataMakerRec.cxx 
     AliPHOSReconstructor.cxx
+    AliPHOSTriggerRawReader.cxx
+    AliPHOSTRURawReader.cxx
+    AliPHOSTriggerRawDigiProducer.cxx
+    AliPHOSTriggerRawDigit.cxx
     )
 
 string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
index 169f01d..1ac1a10 100644 (file)
 #pragma link C++ class AliPHOSEsdCluster+;
 #pragma link C++ class AliPHOSAodCluster+;
 #pragma link C++ class AliPHOSQADataMakerRec+;
+#pragma link C++ class AliPHOSTriggerRawReader+;
+#pragma link C++ class AliPHOSTRURawReader+;
+#pragma link C++ class AliPHOSTriggerRawDigiProducer+;
+#pragma link C++ class AliPHOSTriggerRawDigit+;
 
 #pragma link C++ class AliPHOSReconstructor+;
 #endif
diff --git a/PHOS/macros/Trigger/triggerClusters.C b/PHOS/macros/Trigger/triggerClusters.C
new file mode 100644 (file)
index 0000000..295e070
--- /dev/null
@@ -0,0 +1,80 @@
+void triggerClusters(Float_t eClu=2., const char* file="AliESDs.root")
+{
+  //Test macro.
+  //Illustrates how to use trigger info in the ESD.
+
+  //Prints fired 4x4 TRUs and respective PHOS clusters with energy>eClu positions.
+  //For TRU this is bottom-left cell of 4x4 region,
+  //for cluster it is the cell with the max. energy deposition.
+  
+  //Author: Boris Polishchuk (Boris.Polishchuk@cern.ch).
+
+  TChain* esdTree = new TChain("esdTree");
+  esdTree->Add(file);
+
+  AliESDEvent *esd = new AliESDEvent;
+  esd->ReadFromTree(esdTree);
+
+  AliPHOSGeometry* geom = AliPHOSGeometry::GetInstance("IHEP");
+
+  for(Int_t iEvent=0; iEvent<esdTree->GetEntries(); iEvent++){
+    
+    esdTree->GetEvent(iEvent);
+    TString trigClasses = esd->GetFiredTriggerClasses();
+
+    Int_t multClu = esd->GetNumberOfCaloClusters();
+    AliESDCaloCells *phsCells = esd->GetPHOSCells();
+
+    AliESDCaloTrigger* trgESD = esd->GetCaloTrigger("PHOS");
+    trgESD->Reset();
+
+    if(trgESD->GetEntries())
+    printf("\nEvent %d: %d non-zero trigger digits %s\n",
+          iEvent,trgESD->GetEntries(),trigClasses.Data());
+
+    //Loop over 4x4 fired regions
+
+    while(trgESD->Next()) {
+
+      Int_t tmod,tabsId; // "Online" module number, bottom-left 4x4 edge cell absId
+      trgESD->GetPosition(tmod,tabsId);
+
+      Int_t trelid[4] ;
+      geom->AbsToRelNumbering(tabsId,trelid);
+
+      printf("\t4x4 position: (mod,X,Z)=(%d,%d,%d)\n",trelid[0],trelid[2],trelid[3]);
+
+      for (Int_t i=0; i<multClu; i++) {
+       
+       AliESDCaloCluster *c1 = esd->GetCaloCluster(i);
+       if(!c1->IsPHOS()) continue;
+       
+       Int_t maxId, relid[4];
+       MaxEnergyCellPos(phsCells,c1,maxId);
+       
+       geom->AbsToRelNumbering(maxId, relid);
+       if(c1->E()>eClu) printf("\t\tCluster: (mod,X,Z)=(%d,%d,%d), E=%.3f GeV\n",
+              relid[0],relid[2],relid[3],c1->E());
+      }
+
+    }
+    
+    
+    
+  }
+}
+
+void MaxEnergyCellPos(AliESDCaloCells *cells, AliESDCaloCluster* clu, Int_t& maxId)
+{  
+  Double_t eMax = -111;
+  
+  for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
+    Int_t cellAbsId = clu->GetCellAbsId(iDig);
+    Double_t eCell = cells->GetCellAmplitude(cellAbsId)*clu->GetCellAmplitudeFraction(iDig);
+    if(eCell>eMax)  { 
+      eMax = eCell; 
+      maxId = cellAbsId;
+    }
+  }
+
+}