]> git.uio.no Git - u/mrichter/AliRoot.git/blob - VZERO/AliVZERORawStream.cxx
next50 trigger mask in AliHLTGlobalEsdConverterComponent
[u/mrichter/AliRoot.git] / VZERO / AliVZERORawStream.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 ///////////////////////////////////////////////////////////////////////////////
17 ///
18 /// This is a class for reading the VZERO DDL raw data
19 /// The format of the raw data corresponds to the one
20 /// implemented in AliVZEROBuffer class. 
21 ///
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include "AliVZERORawStream.h"
25 #include "AliRawReader.h"
26 #include "AliLog.h"
27 #include "AliDAQ.h"
28 #include "AliVZEROCalibData.h"
29 #include "AliVZEROTriggerData.h"
30 ClassImp(AliVZERORawStream)
31
32 //_____________________________________________________________________________
33 AliVZERORawStream::AliVZERORawStream(AliRawReader* rawReader) :
34   fTrigger(0),
35   fTriggerMask(0),
36   fPosition(-1),
37   fRawReader(rawReader),
38   fData(NULL)
39 {
40   // create an object to read VZERO raw data
41   //
42   // select the raw data corresponding to
43   // the VZERO detector id
44   fRawReader->Reset();
45   AliDebug(1,Form("Selecting raw data for detector %d",AliDAQ::DetectorID("VZERO")));
46   fRawReader->Select("VZERO");
47
48   // Initalize the containers
49   for(Int_t i = 0; i < kNChannels; i++) {
50     fTime[i] = fWidth[i] = 0;
51     for(Int_t j = 0; j < kNEvOfInt; j++) {
52       fADC[i][j] = 0;
53       fIsInt[i][j] = fIsBB[i][j] = fIsBG[i][j] = kFALSE;
54     }
55     fBBScalers[i] = fBGScalers[i] = 0;
56     for(Int_t j = 0; j < kNBunches; j++) {
57       fChargeMB[i][j] = 0;
58       fIsIntMB[i][j] = fIsBBMB[i][j] = fIsBGMB[i][j] = kFALSE;
59     }
60   }
61   for(Int_t i = 0; i < kNScalers; i++) fScalers[i] = 0;
62   for(Int_t i = 0; i < kNBunches; i++) fBunchNumbers[i] = 0;
63 }
64
65 //_____________________________________________________________________________
66 AliVZERORawStream::~AliVZERORawStream()
67 {
68   // destructor
69 }
70
71 //_____________________________________________________________________________
72 void AliVZERORawStream::Reset()
73 {
74   // reset raw stream params
75
76   // Reinitalize the containers
77   for(Int_t i = 0; i < kNChannels; i++) {
78     fTime[i] = fWidth[i] = 0;
79     for(Int_t j = 0; j < kNEvOfInt; j++) {
80       fADC[i][j] = 0;
81       fIsInt[i][j] = fIsBB[i][j] = fIsBG[i][j] = kFALSE;
82     }
83     fBBScalers[i] = fBGScalers[i] = 0;
84     for(Int_t j = 0; j < kNBunches; j++) {
85       fChargeMB[i][j] = 0;
86       fIsIntMB[i][j] = fIsBBMB[i][j] = fIsBGMB[i][j] = kFALSE;
87     }
88   }
89   for(Int_t i = 0; i < kNScalers; i++) fScalers[i] = 0;
90   for(Int_t i = 0; i < kNBunches; i++) fBunchNumbers[i] = 0;
91
92   fTrigger = fTriggerMask = 0;
93   fPosition = -1;
94   fData = NULL;
95
96   if (fRawReader) fRawReader->Reset();
97 }
98
99 //_____________________________________________________________________________
100 Bool_t AliVZERORawStream::Next()
101 {
102   // read next digit from the VZERO raw data stream
103   // return kFALSE in case of error or no digits left
104
105   if (fPosition >= 0) return kFALSE;
106
107   if (!fRawReader->ReadNextData(fData)) return kFALSE;
108   if (fRawReader->GetDataSize() == 0) return kFALSE;
109      
110   if (fRawReader->GetDataSize() != 5936) {
111      fRawReader->AddFatalErrorLog(kRawDataSizeErr,Form("size %d != 5936",fRawReader->GetDataSize()));
112      AliWarning(Form("Wrong VZERO raw data size: %d, expected 5936 bytes!",fRawReader->GetDataSize()));
113      return kFALSE;
114   }
115
116   fPosition = 0;
117
118   fTrigger = GetNextWord() & 0xffff;
119   fTriggerMask = GetNextWord() & 0xffff;
120
121   for(Int_t iScaler = 0; iScaler < kNScalers; iScaler++)
122      fScalers[iScaler] = GetNextWord();
123
124   for(Int_t iBunch = 0; iBunch < kNBunches; iBunch++)
125      fBunchNumbers[iBunch] = GetNextWord();
126  
127   for (Int_t  iCIU = 0; iCIU < 8; iCIU++) { 
128  
129   // decoding of one Channel Interface Unit numbered iCIU - there are 8 channels per CIU (and 8 CIUs) :
130   
131     for (Int_t iChannel_Offset = iCIU*8; iChannel_Offset < (iCIU*8)+8; iChannel_Offset=iChannel_Offset+4) { 
132       for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
133         for(Int_t iEvOfInt = 0; iEvOfInt < kNEvOfInt; iEvOfInt++) {
134           UShort_t data = GetNextShort();
135           fADC[iChannel][iEvOfInt] = data & 0x3ff;
136           fIsInt[iChannel][iEvOfInt] = (data >> 10) & 0x1;
137         }
138       }
139       for(Int_t iEvOfInt = 0; iEvOfInt < kNEvOfInt; iEvOfInt=iEvOfInt+2) {
140         UShort_t data = GetNextShort();
141         for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {          
142           fIsBB[iChannel][iEvOfInt] = (data >>  2*(iChannel-iChannel_Offset)) & 0x1;
143           fIsBG[iChannel][iEvOfInt] = (data >> (2*(iChannel-iChannel_Offset)+1)) & 0x1; 
144           if(iEvOfInt < (kNEvOfInt - 1)) {      
145              fIsBB[iChannel][iEvOfInt+1] = (data >> (8+ 2*(iChannel-iChannel_Offset))) & 0x1;
146              fIsBG[iChannel][iEvOfInt+1] = (data >> (8+ 2*(iChannel-iChannel_Offset)+1)) & 0x1;
147           }
148         }
149       }
150
151       GetNextShort();
152
153       for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
154         for(Int_t iBunch = 0; iBunch < kNBunches; iBunch++) {
155           UShort_t data = GetNextShort();
156           fChargeMB[iChannel][iBunch] = data & 0x3ff;
157           fIsIntMB[iChannel][iBunch] = (data >> 10) & 0x1;
158         } 
159       }
160    
161       for(Int_t iBunch = 0; iBunch < kNBunches; iBunch=iBunch+2) {
162         UShort_t data = GetNextShort();
163         for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {  
164           fIsBBMB[iChannel][iBunch] = (data >>  2*iBunch) & 0x1;
165           fIsBGMB[iChannel][iBunch] = (data >> (2*iBunch+1)) & 0x1;
166           if(iBunch < (kNBunches - 1)) {
167              fIsBBMB[iChannel][iBunch+1] = (data >> (8+2*iBunch)) & 0x1;
168              fIsBGMB[iChannel][iBunch+1] = (data >> (8+2*iBunch+1)) & 0x1;
169           }       
170         }
171       }
172   
173       GetNextShort();
174    
175       for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
176         fBBScalers[iChannel] = ((ULong64_t)GetNextWord()) << 32;
177         fBBScalers[iChannel] |= GetNextWord();
178         fBGScalers[iChannel] = ((ULong64_t)GetNextWord()) << 32;
179         fBGScalers[iChannel] |= GetNextWord();
180       }
181
182     } 
183
184     for(Int_t iChannel = (iCIU*8) + 7; iChannel >= iCIU*8; iChannel--) { 
185       UInt_t time = GetNextWord();
186       fTime[iChannel]  = time & 0xfff;
187       fWidth[iChannel] = ((time >> 12) & 0x7f); // HPTDC used in pairing mode
188     }
189     
190     // End of decoding of one CIU card
191     // printf("Number of bytes used at end of reading CIU card number %d %d \n\n", iCIU+1, fPosition); 
192     
193   } // end of decoding the eight CIUs
194     
195   return kTRUE;
196 }
197
198 //_____________________________________________________________________________
199 UInt_t AliVZERORawStream::GetNextWord()
200 {
201   // This method returns the next 32 bit word
202   // inside the raw data payload.
203   // The method is supposed to be endian (platform)
204   // independent.
205   if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
206
207   UInt_t word = 0;
208   word |= fData[fPosition++];
209   word |= fData[fPosition++] << 8;
210   word |= fData[fPosition++] << 16;
211   word |= fData[fPosition++] << 24;
212
213   return word;
214 }
215
216 //_____________________________________________________________________________
217 UShort_t AliVZERORawStream::GetNextShort()
218 {
219   // This method returns the next 16 bit word
220   // inside the raw data payload.
221   // The method is supposed to be endian (platform)
222   // independent.
223   if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
224
225   UShort_t word = 0;
226   word |= fData[fPosition++];
227   word |= fData[fPosition++] << 8;
228
229   return word;
230 }
231
232 //_____________________________________________________________________________
233 void AliVZERORawStream::CalculateChargeForCentrTriggers(AliVZEROTriggerData *triggerData,
234                                                         UShort_t &chargeA, UShort_t &chargeC) const
235 {
236   // Use the raw-data payload
237   // in order to calculate the total
238   // charge (which is used in the
239   // centrality triggers) on each side of V0
240   if (!triggerData) {
241     AliFatal("Trigger configuration data is not provided. Exiting...");
242     return;
243   }
244   chargeA = chargeC = 0;
245   for(Int_t iChannel=0; iChannel<64; iChannel++) {
246     Int_t offlineCh = GetOfflineChannel(iChannel);
247     Int_t board = AliVZEROCalibData::GetBoardNumber(offlineCh);
248     Int_t feeChannel = AliVZEROCalibData::GetFEEChannelNumber(offlineCh);
249     if (triggerData->GetEnableCharge(board,feeChannel)) {
250       Bool_t integ10 = GetIntegratorFlag(iChannel,10);
251       UShort_t ch10 = (UShort_t)GetPedestal(iChannel,10);
252       UShort_t trPed = (integ10 == kFALSE) ? triggerData->GetPedestal(0,board,feeChannel) : triggerData->GetPedestal(1,board,feeChannel);
253       UShort_t trPedCut = (integ10 == kFALSE) ? triggerData->GetPedestalCut(0,board,feeChannel) : triggerData->GetPedestalCut(1,board,feeChannel);
254       if (!triggerData->GetPedestalSubtraction(board)) trPed = trPedCut = 0;
255       if (ch10 > trPedCut) {
256         if (offlineCh < 32) {
257           chargeC += (ch10 - trPed);
258         }
259         else {
260           chargeA += (ch10 - trPed);
261         }
262       }
263     }
264   }
265 }
266
267 //_____________________________________________________________________________
268 void AliVZERORawStream::CalculateBBandBGFlags(AliVZEROTriggerData *triggerData,
269                                               UChar_t &nBBA, UChar_t &nBBC,
270                                               UChar_t &nBGA, UChar_t &nBGC) const
271 {
272   // Use the raw-data payload
273   // in order to calculate the total
274   // number of beam-beam and beam-gas flags
275   // (which is used in the centrality and
276   // multiplicity triggers) on each side of V0
277   if (!triggerData) {
278     AliFatal("Trigger configuration data is not provided. Exiting...");
279     return;
280   }
281   nBBA = nBBC = nBGA = nBGC = 0;
282   for(Int_t iChannel=0; iChannel<64; iChannel++) {
283     Int_t offlineCh = GetOfflineChannel(iChannel);
284     Int_t board = AliVZEROCalibData::GetBoardNumber(offlineCh);
285     Int_t feeChannel = AliVZEROCalibData::GetFEEChannelNumber(offlineCh);
286     if (triggerData->GetEnableTiming(board,feeChannel)) {
287       if (offlineCh < 32) {
288         if (GetBBFlag(iChannel,10)) nBBC++;
289         if (GetBGFlag(iChannel,10)) nBGC++;
290       }
291       else {
292         if (GetBBFlag(iChannel,10)) nBBA++;
293         if (GetBGFlag(iChannel,10)) nBGA++;
294       }
295     }
296   }
297 }
298
299 //_____________________________________________________________________________
300 void AliVZERORawStream::FillTriggerBits(AliVZEROTriggerData *triggerData)
301 {
302   // Calculate the charge sums and
303   // number of trigger flags and then
304   // fill the V0 trigger bits word
305   // following the trigger logic implemented
306   // in the firmware
307   UShort_t chargeA,chargeC;
308   CalculateChargeForCentrTriggers(triggerData,chargeA,chargeC);
309   UChar_t nBBA,nBBC,nBGA,nBGC;
310   CalculateBBandBGFlags(triggerData,
311                         nBBA,nBBC,
312                         nBGA,nBGC);
313
314   fTrigger = 0;
315   //BBA and BBC
316   if((nBBC >= triggerData->GetBBCThreshold()) && (nBBA >= triggerData->GetBBAThreshold())) fTrigger |= 1;
317   //BBA or BBC
318   if((nBBC >= triggerData->GetBBCThreshold()) || (nBBA >= triggerData->GetBBAThreshold())) fTrigger |= (1<<1);
319   //BGA and BBC
320   if((nBBC >= triggerData->GetBBCForBGThreshold()) && (nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<2);
321   //BGA 
322   if((nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<3);
323   //BGC and BBA
324   if((nBGC >= triggerData->GetBGCThreshold()) && (nBBA >= triggerData->GetBBAForBGThreshold())) fTrigger |= (1<<4);
325   //BGC 
326   if((nBGC >= triggerData->GetBGCThreshold())) fTrigger |= (1<<5);
327   //CTA1 and CTC1
328   if((chargeC >= triggerData->GetCentralityV0CThrLow()) && (chargeA >= triggerData->GetCentralityV0AThrLow())) fTrigger |= (1<<6);
329   //CTA1 or CTC1
330   if((chargeC >= triggerData->GetCentralityV0CThrLow()) || (chargeA >= triggerData->GetCentralityV0AThrLow())) fTrigger |= (1<<7);
331   //CTA2 and CTC2
332   if((chargeC >= triggerData->GetCentralityV0CThrHigh()) && (chargeA >= triggerData->GetCentralityV0AThrHigh())) fTrigger |= (1<<8);
333   //CTA2 or CTC2
334   if((chargeC >= triggerData->GetCentralityV0CThrHigh()) || (chargeA >= triggerData->GetCentralityV0AThrHigh())) fTrigger |= (1<<9);
335   //MTA and MTC
336   if(((nBBC >= triggerData->GetMultV0CThrLow()) && (nBBC <= triggerData->GetMultV0CThrHigh())) &&
337      ((nBBA >= triggerData->GetMultV0AThrLow()) && (nBBA <= triggerData->GetMultV0AThrHigh()))) 
338     fTrigger |= (1<<10);
339   //MTA or MTC
340   if(((nBBC >= triggerData->GetMultV0CThrLow()) && (nBBC <= triggerData->GetMultV0CThrHigh())) ||
341      ((nBBA >= triggerData->GetMultV0AThrLow()) && (nBBA <= triggerData->GetMultV0AThrHigh()))) 
342     fTrigger |= (1<<11);
343   //BBA 
344   if((nBBA >= triggerData->GetBBAThreshold())) fTrigger |= (1<<12);
345   //BBC
346   if((nBBC >= triggerData->GetBBCThreshold())) fTrigger |= (1<<13);
347   //BGA or BGC 
348   if((nBGC >= triggerData->GetBGCThreshold()) || (nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<14);
349   //(BGA and BBC) or (BGC and BBA) 
350   if(((nBBC >= triggerData->GetBBCForBGThreshold()) && (nBGA >= triggerData->GetBGAThreshold())) ||
351      ((nBGC >= triggerData->GetBGCThreshold()) && (nBBA >= triggerData->GetBBAForBGThreshold()))) fTrigger |= (1<<15);
352
353 }