]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TRD/TRDsim/AliTRDptrgFEB.cxx
TRD module
[u/mrichter/AliRoot.git] / TRD / TRDsim / AliTRDptrgFEB.cxx
diff --git a/TRD/TRDsim/AliTRDptrgFEB.cxx b/TRD/TRDsim/AliTRDptrgFEB.cxx
new file mode 100644 (file)
index 0000000..b1254b1
--- /dev/null
@@ -0,0 +1,425 @@
+/**************************************************************************
+ * 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$ */
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        
+//  Pre-Trigger simulation                                                
+//                                                                        
+//  Authors: F. Reidt (Felix.Reidt@cern.ch)                               
+//               
+//  This class is used to simulate the front end box behavior of the 
+//  pretrigger system. Digits of T0 and V0 are used as input. A threshold
+//  discrimination, masking and first processing with look up tables  is 
+//  done during the simulation process
+//                                                                  
+////////////////////////////////////////////////////////////////////////////
+
+#include <TClonesArray.h> 
+#include <TTree.h>
+
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+#include "AliLog.h"
+
+#include "AliVZEROdigit.h" 
+#include "AliVZEROCalibData.h"
+#include "AliT0digit.h"
+
+#include "AliTRDptrgParam.h"
+#include "AliTRDptrgLUT.h"
+#include "AliTRDptrgFEB.h"
+
+ClassImp(AliTRDptrgFEB)
+
+//______________________________________________________________________________
+AliTRDptrgFEB::AliTRDptrgFEB(AliRunLoader *rl) 
+  : TObject(),
+  fRunLoader(rl),
+  fParam(0),
+  fLUTArray(0),
+  fType(AliTRDptrgParam::kUndefined),
+  fOperatingMode(AliTRDptrgParam::kDigits),
+  fInputChannelCount(0),
+  fPosition(AliTRDptrgParam::kUnknown),  
+  fID(0),
+  fThreshold(0)
+{
+  // default constructor
+  AliError("default ctor - not recommended");
+}
+
+//______________________________________________________________________________
+AliTRDptrgFEB::AliTRDptrgFEB(AliRunLoader *rl, AliTRDptrgParam::AliTRDptrgFEBType_t febType, 
+                             AliTRDptrgParam::AliTRDptrgOperatingMode_t operatingMode,
+                             AliTRDptrgParam::AliTRDptrgFEBPosition_t position, Int_t id, 
+                             AliTRDptrgParam *param)
+  : TObject(),
+  fRunLoader(rl),
+  fParam(param),
+  fLUTArray(0),
+  fType(febType),
+  fOperatingMode(operatingMode),
+  fInputChannelCount(0),
+  fPosition(position),
+  fID(id),
+  fThreshold(0x0) 
+{
+  // prefered constructor
+  
+  this->LoadParams(); // load configuration parameters
+
+}
+
+//______________________________________________________________________________
+AliTRDptrgFEB::~AliTRDptrgFEB() 
+{
+  // destructor
+  if (this->fParam == 0x0) {  
+    if (this->fThreshold != 0x0) {
+      delete[] this->fThreshold;
+      this->fThreshold = 0x0;
+   }
+  }
+  // delete LUTArray
+  this->fLUTArray.Delete();
+}
+
+//______________________________________________________________________________
+Int_t AliTRDptrgFEB::LoadDigits()
+{
+  // loads T0 or V0 digits and discriminates them automatically
+  if (this->fType == AliTRDptrgParam::kVZERO) {
+    // load V0's digits --------------------------------------------------------
+    // behavior adapted for AliVZERODigitizer.cxx 40613 2010-04-22 09:57:15Z   
+    // get V0 run loader
+    AliLoader* loader = this->fRunLoader->GetLoader( "VZEROLoader" );
+
+    if (!loader) {
+      AliError("Cannot get VZERO loader");
+      return -1;
+    }
+    loader->LoadDigits("READ");
+    TTree* vzeroDigitsTree = loader->TreeD();
+
+    if (!vzeroDigitsTree) {
+      AliError("Cannot get the VZERO digit tree");
+      return -1;
+    }
+    
+               
+    TClonesArray* vzeroDigits = NULL;
+    TBranch* digitBranch = vzeroDigitsTree->GetBranch("VZERODigit");
+    digitBranch->SetAddress(&vzeroDigits);
+    vzeroDigitsTree->GetEvent(0);      
+    
+  
+    Int_t nDigits = vzeroDigits->GetEntriesFast(); // get digit count
+               
+    AliDebug(5, Form("Found a whole of %d digits", nDigits));    
+               
+    Int_t inputVector = 0x0; // Vector which is feed into the LUT
+               
+    for (Int_t iDigit=0; iDigit<nDigits; iDigit++) {
+      // loop over all digits
+      AliDebug(5, "Looping over digit");
+      AliVZEROdigit* digit = (AliVZEROdigit*)vzeroDigits->At(iDigit);
+                             
+      Int_t pmNumber   = digit->PMNumber();
+      //      Int_t board   = pmNumber / 8; // changed in Version 40613
+      Int_t feeBoard = AliVZEROCalibData::GetBoardNumber(pmNumber);
+      Int_t board = feeBoard % 4; // feeBoard V0-A: 1-4; V0-C: 5-8 => board: 1-4
+
+      Int_t channel = pmNumber % 8;
+
+      Int_t position = -1;
+      if ((pmNumber >= 32) && (pmNumber <= 63)) { // V0-A (matched v40613)
+        position = 1; // AliTRDptrgParam::kA
+      } 
+      else if ((pmNumber >= 0) && (pmNumber <= 31)) { // V0-C (matched v40613)
+        position = 2; // kB
+      }
+
+      AliDebug(5, 
+        Form("pmNumber: %d; feeBoard: %d; board: %d; channel: %d; position %d",
+             pmNumber, feeBoard, board, channel, position));  
+
+      if (position == -1)   {
+        AliError("Wrong VZERO pmt position found");
+       loader->UnloadDigits();
+        return -1;
+      }
+
+      // check whether the digits belongs to the current FEB, otherwise omit it
+      if ((position == this->fPosition) && (board == this->fID)) {
+        AliDebug(5, "Found an digit corresponding to the current FEB");
+        Float_t value = digit->ADC();
+        AliDebug(5, Form("ADC value: %f\n", value));
+        Int_t channelBitMask = 0x01; 
+        // channel0 => 0x01; channel1=> 0x02;  2^(channel number)
+        channelBitMask <<= channel;
+        if (value >= this->fThreshold[channel]) {
+          inputVector |= channelBitMask;
+          AliDebug(5,
+            Form("Threshold exceeded in channel %d, new inputVector 0x%x", 
+                 channel, inputVector));
+        }
+      }
+    }
+
+    AliDebug(5, Form("inputVector: 0x%x", inputVector));
+    loader->UnloadDigits();
+    return inputVector;
+  }
+  else if (this->fType == AliTRDptrgParam::kTZERO) {
+    // load T0's digits --------------------------------------------------------
+    AliLoader * fT0Loader = this->fRunLoader->GetLoader("T0Loader");
+    //   AliT0digit *fDigits; 
+    if (!fT0Loader) {
+      AliError("Cannot get T0 loader");
+      return -1;
+    }
+      
+    fT0Loader->LoadDigits("READ");
+    // Creating T0 data container
+
+    TTree* treeD = fT0Loader->TreeD();
+    if (!treeD) {
+      AliError("no digits tree");
+      return -1;
+    }
+    AliT0digit* digits = new AliT0digit();
+    TBranch *brDigits = treeD->GetBranch("T0");
+
+    if (brDigits) {
+      brDigits->SetAddress(&digits);
+    }
+    else {
+      AliError("Branch T0 DIGIT not found");
+      return -1;
+    }     
+    brDigits->GetEntry(0);             
+
+    TArrayI qtc0(24); // Array must have 24 entries!
+    TArrayI qtc1(24); // Array must have 24 entries!
+    
+    digits->GetQT0(qtc0); // baseline (reference level)
+    digits->GetQT1(qtc1); // measurement value
+
+    Int_t inputVector = 0x0; // vector to be fed into the look up table
+    
+    // PMT Positions
+    // C: 0  to 11
+    // A: 12 to 23
+    // positions according to AliT0Digitizer.cxx Revision 37491
+    Int_t nStart = 0;
+    if (this->fPosition == AliTRDptrgParam::kC) { // C
+      nStart = 0;
+    }
+    else if (this->fPosition == AliTRDptrgParam::kA) { // A
+      nStart = 12;
+    }
+
+    Int_t channelBitMask = 0x01;
+    for (Int_t i = 0 + nStart; i < nStart + 12; i++) {
+      //Int_t channelBitMask = 0x01;
+      AliDebug(5, Form("channel: %d", i));
+
+      Int_t value = qtc1[i] - qtc0[i]; // calculate correct measurement value
+
+      if (value > (Int_t)this->fThreshold[i - nStart]) {
+        inputVector |= channelBitMask;    // Add bit
+          
+        AliDebug(5, Form("Threshold exceeded in channel %d,", i));
+        AliDebug(5, Form("new inputVector 0x%x", inputVector));       
+        AliDebug(5, Form("channelBitMask 0x%x", channelBitMask));
+      }
+      channelBitMask <<= 1; // go on to the next channel
+    }
+    
+    delete digits;
+    return inputVector;
+  }
+  return -1;
+}
+
+//______________________________________________________________________________
+Int_t AliTRDptrgFEB::LoadAndProcessHits()
+{
+  // loads TO or VO hits and converts them to digits optimized for ptrg  
+  // afterwards the digits will be discriminated
+  AliError("LoadAndProcessHits() - not yet implemented!\n");
+  if (this->fType == AliTRDptrgParam::kVZERO) {                
+    return 0;
+  }
+  else if (this->fType == AliTRDptrgParam::kTZERO) {
+    return 0;
+  }
+  return -1;
+}
+
+//______________________________________________________________________________
+Bool_t AliTRDptrgFEB::LoadParams()
+{
+  // Load Parameters
+
+  if (this->fParam == 0x0) {
+    AliWarning("No paramater object specified - start loading defaults\n");
+    if (this->fType == AliTRDptrgParam::kVZERO) {              
+      // initialize threshold
+      this->fThreshold = new UInt_t[8]; 
+      for (Int_t i = 0; i < 8; i++) {
+        this->fThreshold[i] = 10; 
+      }
+      // initialize LUTsoutputWidth=<value optimized out>
+      AliTRDptrgLUT* lut = new AliTRDptrgLUT();
+      this->fLUTArray.AddLast(lut);
+      lut = new AliTRDptrgLUT(); 
+      this->fLUTArray.AddLast(lut);
+                       // the following lines are only needed for test reasons
+      Int_t* initData = new Int_t[256]; // 2^8
+      lut = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray.At(0));
+      if (lut) {
+        for (Int_t i = 0; i < 256; i++ ) {
+          initData[i] = i;
+        }
+        lut->InitTable(8, 8, initData, kTRUE); // make copy of initData
+      }
+      lut = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray.At(1));
+      if (lut) {
+        for (Int_t i = 255; i >= 0; i--) {
+          initData[255 - i] = i;  // inverse ramp
+        }
+        lut->InitTable(8, 8, initData, kTRUE);
+      }
+      delete [] initData;
+    }
+    else {
+      // initialize threshold
+      this->fThreshold = new UInt_t[12];
+      for (Int_t i = 0; i < 12; i++) {
+        this->fThreshold[i] = 10; 
+      }
+      
+      // initialize LUTsoutputWidth=<value optimized out>
+      AliTRDptrgLUT* lut = new AliTRDptrgLUT();
+      this->fLUTArray.AddLast(lut);
+      lut = new AliTRDptrgLUT(); // this->fRunLoader
+      this->fLUTArray.AddLast(lut);
+      // the following lines are only needed for test reasons
+      lut = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray.At(0));
+      Int_t* initData = new Int_t[4096]; // 2^12
+      if (lut) {
+        for (Int_t i = 0; i < 4096; i++ ) {
+          initData[i] = i;
+        }
+        lut->InitTable(12, 12, initData, kTRUE); // make a copy of the table
+      }
+      lut = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray.At(1));
+      if (lut) {
+        //for (Int_t i = 4095; i >= 0; i--) {
+        for (Int_t i = 4096; i > 0; i--) {
+          initData[4096 - i] = i;  // inverse ramp
+        }
+        lut->InitTable(12, 12, initData, kTRUE); // make a copy of the table
+      }
+      delete [] initData;    
+    }
+    return false;
+  }
+  else {
+    // load parameters from object
+    if (this->fType == AliTRDptrgParam::kVZERO) {              
+      // threshold
+      this->fThreshold = 
+        this->fParam->GetFEBV0Thresholds(this->fPosition, (this->fID - 1));
+
+      // look up tables
+      // 1
+      AliTRDptrgLUT* LUT = new AliTRDptrgLUT();
+      LUT->InitTable(8, 8, this->fParam->GetFEBV0LUT(this->fPosition, 
+                                                     (this->fID - 1),
+                                                     0), kFALSE);
+      // do not make a copy of the table due to performance reasons
+      this->fLUTArray.AddLast(LUT);
+      // 2
+      LUT = new AliTRDptrgLUT(); 
+      LUT->InitTable(8, 8, this->fParam->GetFEBV0LUT(this->fPosition, 
+                                                     (this->fID - 1),
+                                                     1), kFALSE);
+      // do not make a copy of the table due to performance reasons
+      this->fLUTArray.AddLast(LUT);
+    }
+    else {             
+      // threshold
+      this->fThreshold =
+        this->fParam->GetFEBT0Thresholds(this->fPosition);
+
+      // look up tables
+      // 1
+      AliTRDptrgLUT* LUT = new AliTRDptrgLUT();
+      LUT->InitTable(12, 12, fParam->GetFEBT0LUT(this->fPosition, 0), kFALSE); 
+      // do not make a copy of the table due to performance reasosn
+      this->fLUTArray.AddLast(LUT);
+
+      // 2
+      LUT = new AliTRDptrgLUT(); 
+      LUT->InitTable(12, 12, fParam->GetFEBT0LUT(this->fPosition, 1), kFALSE); 
+      // do not make a copy of the table due to performance reasosn      
+      this->fLUTArray.AddLast(LUT);
+    }
+    return true;
+  }
+  
+  return false;
+}
+
+//______________________________________________________________________________
+Int_t* AliTRDptrgFEB::Simulate()
+{
+  // simulates the FEB behavior and returns a 2 bit ouput 
+  // (least significant bits)
+  
+  Int_t *result = new Int_t;
+  (*result) = -1; 
+  if (this->fOperatingMode == AliTRDptrgParam::kDigits) {
+    Int_t inputVector = this->LoadDigits();
+    delete result; // delete error return value
+
+    // perform look up
+    Int_t nLUTs = this->fLUTArray.GetEntriesFast();  // get LUT count
+    result = new Int_t[nLUTs + 1]; // generate new return array
+    result[0] = nLUTs; // storage array length in the first array value
+    for (Int_t iLUT = 0; iLUT < nLUTs; iLUT++) { 
+      // process the return value for each LUT and store the result in the array
+      AliDebug(4, Form("FEB: (pos=%d,id=%d,lut=%d,vector=0x%x)", 
+                       this->fPosition, this->fID, iLUT, inputVector));
+
+      AliTRDptrgLUT *lutTmp = dynamic_cast<AliTRDptrgLUT*>(this->fLUTArray[iLUT]);
+      if (lutTmp) {
+        result[iLUT + 1] =  lutTmp->LookUp(inputVector);
+      }
+      AliDebug(4, Form("FEB result[%d] = 0x%x",(iLUT + 1),result[iLUT + 1])); 
+    }
+  }
+  else if (this->fOperatingMode == AliTRDptrgParam::kHits) {
+    return result;
+  }
+  return result;
+}