]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - VZERO/AliVZERORawStream.cxx
Adding include path to allow compilation of CleanGeom task
[u/mrichter/AliRoot.git] / VZERO / AliVZERORawStream.cxx
index ace84ad79e187b783377388e72f46b66f46110b3..7d0ed3c51084552fb318a663b21f174fe5ce4e92 100644 (file)
@@ -17,7 +17,7 @@
 ///
 /// This is a class for reading the VZERO DDL raw data
 /// The format of the raw data corresponds to the one
-/// implemented in AliVZEROBuffer class.
+/// implemented in AliVZEROBuffer class. 
 ///
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "AliRawReader.h"
 #include "AliLog.h"
 #include "AliDAQ.h"
-
+#include "AliVZEROCalibData.h"
+#include "AliVZEROTriggerData.h"
 ClassImp(AliVZERORawStream)
 
 //_____________________________________________________________________________
 AliVZERORawStream::AliVZERORawStream(AliRawReader* rawReader) :
-  fCell(-1),
-  fADC(-1),
-  fTime(-1),
+  fTrigger(0),
+  fTriggerMask(0),
   fPosition(-1),
   fRawReader(rawReader),
   fData(NULL)
@@ -44,6 +44,22 @@ AliVZERORawStream::AliVZERORawStream(AliRawReader* rawReader) :
   fRawReader->Reset();
   AliDebug(1,Form("Selecting raw data for detector %d",AliDAQ::DetectorID("VZERO")));
   fRawReader->Select("VZERO");
+
+  // Initalize the containers
+  for(Int_t i = 0; i < kNChannels; i++) {
+    fTime[i] = fWidth[i] = 0;
+    for(Int_t j = 0; j < kNEvOfInt; j++) {
+      fADC[i][j] = 0;
+      fIsInt[i][j] = fIsBB[i][j] = fIsBG[i][j] = kFALSE;
+    }
+    fBBScalers[i] = fBGScalers[i] = 0;
+    for(Int_t j = 0; j < kNBunches; j++) {
+      fChargeMB[i][j] = 0;
+      fIsIntMB[i][j] = fIsBBMB[i][j] = fIsBGMB[i][j] = kFALSE;
+    }
+  }
+  for(Int_t i = 0; i < kNScalers; i++) fScalers[i] = 0;
+  for(Int_t i = 0; i < kNBunches; i++) fBunchNumbers[i] = 0;
 }
 
 //_____________________________________________________________________________
@@ -57,7 +73,25 @@ void AliVZERORawStream::Reset()
 {
   // reset raw stream params
 
-  fCell = fADC = fTime = fPosition = -1;
+  // Reinitalize the containers
+  for(Int_t i = 0; i < kNChannels; i++) {
+    fTime[i] = fWidth[i] = 0;
+    for(Int_t j = 0; j < kNEvOfInt; j++) {
+      fADC[i][j] = 0;
+      fIsInt[i][j] = fIsBB[i][j] = fIsBG[i][j] = kFALSE;
+    }
+    fBBScalers[i] = fBGScalers[i] = 0;
+    for(Int_t j = 0; j < kNBunches; j++) {
+      fChargeMB[i][j] = 0;
+      fIsIntMB[i][j] = fIsBBMB[i][j] = fIsBGMB[i][j] = kFALSE;
+    }
+  }
+  for(Int_t i = 0; i < kNScalers; i++) fScalers[i] = 0;
+  for(Int_t i = 0; i < kNBunches; i++) fBunchNumbers[i] = 0;
+
+  fTrigger = fTriggerMask = 0;
+  fPosition = -1;
+  fData = NULL;
 
   if (fRawReader) fRawReader->Reset();
 }
@@ -68,27 +102,101 @@ Bool_t AliVZERORawStream::Next()
   // read next digit from the VZERO raw data stream
   // return kFALSE in case of error or no digits left
 
-  if (fPosition < 0) {
-    if (!fRawReader->ReadNextData(fData)) return kFALSE;
-    if (fRawReader->GetDataSize()%3 != 0) {
-      fRawReader->AddFatalErrorLog(kRawDataSizeErr,Form("size %d != n*12",fRawReader->GetDataSize()));
-      AliWarning(Form("Wrong VZERO raw data size: %d, expected n*12 bytes!",fRawReader->GetDataSize()));
-      return kFALSE;
-    }
-    fPosition = 0;
+  if (fPosition >= 0) return kFALSE;
+
+  if (!fRawReader->ReadNextData(fData)) return kFALSE;
+  if (fRawReader->GetDataSize() == 0) return kFALSE;
+     
+  if (fRawReader->GetDataSize() != 5936) {
+     fRawReader->AddFatalErrorLog(kRawDataSizeErr,Form("size %d != 5936",fRawReader->GetDataSize()));
+     AliWarning(Form("Wrong VZERO raw data size: %d, expected 5936 bytes!",fRawReader->GetDataSize()));
+     return kFALSE;
   }
 
-  if (fPosition >= fRawReader->GetDataSize()) return kFALSE;
+  fPosition = 0;
+
+  fTrigger = GetNextWord() & 0xffff;
+  fTriggerMask = GetNextWord() & 0xffff;
+
+  for(Int_t iScaler = 0; iScaler < kNScalers; iScaler++)
+     fScalers[iScaler] = GetNextWord();
 
-  fCell = GetNextWord();
-  fADC  = GetNextWord();
-  fTime = GetNextWord();
+  for(Int_t iBunch = 0; iBunch < kNBunches; iBunch++)
+     fBunchNumbers[iBunch] = GetNextWord();
+  for (Int_t  iCIU = 0; iCIU < 8; iCIU++) { 
+  // decoding of one Channel Interface Unit numbered iCIU - there are 8 channels per CIU (and 8 CIUs) :
+  
+    for (Int_t iChannel_Offset = iCIU*8; iChannel_Offset < (iCIU*8)+8; iChannel_Offset=iChannel_Offset+4) { 
+      for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
+        for(Int_t iEvOfInt = 0; iEvOfInt < kNEvOfInt; iEvOfInt++) {
+          UShort_t data = GetNextShort();
+          fADC[iChannel][iEvOfInt] = data & 0x3ff;
+          fIsInt[iChannel][iEvOfInt] = (data >> 10) & 0x1;
+        }
+      }
+      for(Int_t iEvOfInt = 0; iEvOfInt < kNEvOfInt; iEvOfInt=iEvOfInt+2) {
+        UShort_t data = GetNextShort();
+        for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {          
+          fIsBB[iChannel][iEvOfInt] = (data >>  2*(iChannel-iChannel_Offset)) & 0x1;
+          fIsBG[iChannel][iEvOfInt] = (data >> (2*(iChannel-iChannel_Offset)+1)) & 0x1; 
+         if(iEvOfInt < (kNEvOfInt - 1)) {      
+             fIsBB[iChannel][iEvOfInt+1] = (data >> (8+ 2*(iChannel-iChannel_Offset))) & 0x1;
+             fIsBG[iChannel][iEvOfInt+1] = (data >> (8+ 2*(iChannel-iChannel_Offset)+1)) & 0x1;
+         }
+        }
+      }
 
+      GetNextShort();
+
+      for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
+        for(Int_t iBunch = 0; iBunch < kNBunches; iBunch++) {
+          UShort_t data = GetNextShort();
+          fChargeMB[iChannel][iBunch] = data & 0x3ff;
+          fIsIntMB[iChannel][iBunch] = (data >> 10) & 0x1;
+        } 
+      }
+   
+      for(Int_t iBunch = 0; iBunch < kNBunches; iBunch=iBunch+2) {
+        UShort_t data = GetNextShort();
+        for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {  
+          fIsBBMB[iChannel][iBunch] = (data >>  2*iBunch) & 0x1;
+          fIsBGMB[iChannel][iBunch] = (data >> (2*iBunch+1)) & 0x1;
+         if(iBunch < (kNBunches - 1)) {
+             fIsBBMB[iChannel][iBunch+1] = (data >> (8+2*iBunch)) & 0x1;
+             fIsBGMB[iChannel][iBunch+1] = (data >> (8+2*iBunch+1)) & 0x1;
+         }       
+        }
+      }
+  
+      GetNextShort();
+   
+      for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
+        fBBScalers[iChannel] = ((ULong64_t)GetNextWord()) << 32;
+        fBBScalers[iChannel] |= GetNextWord();
+        fBGScalers[iChannel] = ((ULong64_t)GetNextWord()) << 32;
+        fBGScalers[iChannel] |= GetNextWord();
+      }
+
+    } 
+
+    for(Int_t iChannel = (iCIU*8) + 7; iChannel >= iCIU*8; iChannel--) { 
+      UInt_t time = GetNextWord();
+      fTime[iChannel]  = time & 0xfff;
+      fWidth[iChannel] = ((time >> 12) & 0x7f); // HPTDC used in pairing mode
+    }
+    
+    // End of decoding of one CIU card
+    // printf("Number of bytes used at end of reading CIU card number %d %d \n\n", iCIU+1, fPosition); 
+    
+  } // end of decoding the eight CIUs
+    
   return kTRUE;
 }
 
 //_____________________________________________________________________________
-Int_t AliVZERORawStream::GetNextWord()
+UInt_t AliVZERORawStream::GetNextWord()
 {
   // This method returns the next 32 bit word
   // inside the raw data payload.
@@ -96,7 +204,7 @@ Int_t AliVZERORawStream::GetNextWord()
   // independent.
   if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
 
-  Int_t word = 0;
+  UInt_t word = 0;
   word |= fData[fPosition++];
   word |= fData[fPosition++] << 8;
   word |= fData[fPosition++] << 16;
@@ -104,3 +212,142 @@ Int_t AliVZERORawStream::GetNextWord()
 
   return word;
 }
+
+//_____________________________________________________________________________
+UShort_t AliVZERORawStream::GetNextShort()
+{
+  // This method returns the next 16 bit word
+  // inside the raw data payload.
+  // The method is supposed to be endian (platform)
+  // independent.
+  if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
+
+  UShort_t word = 0;
+  word |= fData[fPosition++];
+  word |= fData[fPosition++] << 8;
+
+  return word;
+}
+
+//_____________________________________________________________________________
+void AliVZERORawStream::CalculateChargeForCentrTriggers(AliVZEROTriggerData *triggerData,
+                                                       UShort_t &chargeA, UShort_t &chargeC) const
+{
+  // Use the raw-data payload
+  // in order to calculate the total
+  // charge (which is used in the
+  // centrality triggers) on each side of V0
+  if (!triggerData) {
+    AliFatal("Trigger configuration data is not provided. Exiting...");
+    return;
+  }
+  chargeA = chargeC = 0;
+  for(Int_t iChannel=0; iChannel<64; iChannel++) {
+    Int_t offlineCh = GetOfflineChannel(iChannel);
+    Int_t board = AliVZEROCalibData::GetBoardNumber(offlineCh);
+    Int_t feeChannel = AliVZEROCalibData::GetFEEChannelNumber(offlineCh);
+    if (triggerData->GetEnableCharge(board,feeChannel)) {
+      Bool_t integ10 = GetIntegratorFlag(iChannel,10);
+      UShort_t ch10 = (UShort_t)GetPedestal(iChannel,10);
+      UShort_t trPed = (integ10 == kFALSE) ? triggerData->GetPedestal(0,board,feeChannel) : triggerData->GetPedestal(1,board,feeChannel);
+      UShort_t trPedCut = (integ10 == kFALSE) ? triggerData->GetPedestalCut(0,board,feeChannel) : triggerData->GetPedestalCut(1,board,feeChannel);
+      if (!triggerData->GetPedestalSubtraction(board)) trPed = trPedCut = 0;
+      if (ch10 > trPedCut) {
+       if (offlineCh < 32) {
+         chargeC += (ch10 - trPed);
+       }
+       else {
+         chargeA += (ch10 - trPed);
+       }
+      }
+    }
+  }
+}
+
+//_____________________________________________________________________________
+void AliVZERORawStream::CalculateBBandBGFlags(AliVZEROTriggerData *triggerData,
+                                             UChar_t &nBBA, UChar_t &nBBC,
+                                             UChar_t &nBGA, UChar_t &nBGC) const
+{
+  // Use the raw-data payload
+  // in order to calculate the total
+  // number of beam-beam and beam-gas flags
+  // (which is used in the centrality and
+  // multiplicity triggers) on each side of V0
+  if (!triggerData) {
+    AliFatal("Trigger configuration data is not provided. Exiting...");
+    return;
+  }
+  nBBA = nBBC = nBGA = nBGC = 0;
+  for(Int_t iChannel=0; iChannel<64; iChannel++) {
+    Int_t offlineCh = GetOfflineChannel(iChannel);
+    Int_t board = AliVZEROCalibData::GetBoardNumber(offlineCh);
+    Int_t feeChannel = AliVZEROCalibData::GetFEEChannelNumber(offlineCh);
+    if (triggerData->GetEnableTiming(board,feeChannel)) {
+      if (offlineCh < 32) {
+       if (GetBBFlag(iChannel,10)) nBBC++;
+       if (GetBGFlag(iChannel,10)) nBGC++;
+      }
+      else {
+       if (GetBBFlag(iChannel,10)) nBBA++;
+       if (GetBGFlag(iChannel,10)) nBGA++;
+      }
+    }
+  }
+}
+
+//_____________________________________________________________________________
+void AliVZERORawStream::FillTriggerBits(AliVZEROTriggerData *triggerData)
+{
+  // Calculate the charge sums and
+  // number of trigger flags and then
+  // fill the V0 trigger bits word
+  // following the trigger logic implemented
+  // in the firmware
+  UShort_t chargeA,chargeC;
+  CalculateChargeForCentrTriggers(triggerData,chargeA,chargeC);
+  UChar_t nBBA,nBBC,nBGA,nBGC;
+  CalculateBBandBGFlags(triggerData,
+                       nBBA,nBBC,
+                       nBGA,nBGC);
+
+  fTrigger = 0;
+  //BBA and BBC
+  if((nBBC >= triggerData->GetBBCThreshold()) && (nBBA >= triggerData->GetBBAThreshold())) fTrigger |= 1;
+  //BBA or BBC
+  if((nBBC >= triggerData->GetBBCThreshold()) || (nBBA >= triggerData->GetBBAThreshold())) fTrigger |= (1<<1);
+  //BGA and BBC
+  if((nBBC >= triggerData->GetBBCForBGThreshold()) && (nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<2);
+  //BGA 
+  if((nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<3);
+  //BGC and BBA
+  if((nBGC >= triggerData->GetBGCThreshold()) && (nBBA >= triggerData->GetBBAForBGThreshold())) fTrigger |= (1<<4);
+  //BGC 
+  if((nBGC >= triggerData->GetBGCThreshold())) fTrigger |= (1<<5);
+  //CTA1 and CTC1
+  if((chargeC >= triggerData->GetCentralityV0CThrLow()) && (chargeA >= triggerData->GetCentralityV0AThrLow())) fTrigger |= (1<<6);
+  //CTA1 or CTC1
+  if((chargeC >= triggerData->GetCentralityV0CThrLow()) || (chargeA >= triggerData->GetCentralityV0AThrLow())) fTrigger |= (1<<7);
+  //CTA2 and CTC2
+  if((chargeC >= triggerData->GetCentralityV0CThrHigh()) && (chargeA >= triggerData->GetCentralityV0AThrHigh())) fTrigger |= (1<<8);
+  //CTA2 or CTC2
+  if((chargeC >= triggerData->GetCentralityV0CThrHigh()) || (chargeA >= triggerData->GetCentralityV0AThrHigh())) fTrigger |= (1<<9);
+  //MTA and MTC
+  if(((nBBC >= triggerData->GetMultV0CThrLow()) && (nBBC <= triggerData->GetMultV0CThrHigh())) &&
+     ((nBBA >= triggerData->GetMultV0AThrLow()) && (nBBA <= triggerData->GetMultV0AThrHigh()))) 
+    fTrigger |= (1<<10);
+  //MTA or MTC
+  if(((nBBC >= triggerData->GetMultV0CThrLow()) && (nBBC <= triggerData->GetMultV0CThrHigh())) ||
+     ((nBBA >= triggerData->GetMultV0AThrLow()) && (nBBA <= triggerData->GetMultV0AThrHigh()))) 
+    fTrigger |= (1<<11);
+  //BBA 
+  if((nBBA >= triggerData->GetBBAThreshold())) fTrigger |= (1<<12);
+  //BBC
+  if((nBBC >= triggerData->GetBBCThreshold())) fTrigger |= (1<<13);
+  //BGA or BGC 
+  if((nBGC >= triggerData->GetBGCThreshold()) || (nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<14);
+  //(BGA and BBC) or (BGC and BBA) 
+  if(((nBBC >= triggerData->GetBBCForBGThreshold()) && (nBGA >= triggerData->GetBGAThreshold())) ||
+     ((nBGC >= triggerData->GetBGCThreshold()) && (nBBA >= triggerData->GetBBAForBGThreshold()))) fTrigger |= (1<<15);
+
+}