- add new classes
[u/mrichter/AliRoot.git] / VZERO / AliVZERORawStream.cxx
CommitLineData
2eb38194 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
e6bc1a67 20/// implemented in AliVZEROBuffer class.
2eb38194 21///
22///////////////////////////////////////////////////////////////////////////////
23
24#include "AliVZERORawStream.h"
25#include "AliRawReader.h"
26#include "AliLog.h"
27#include "AliDAQ.h"
cc12572f 28#include "AliVZEROCalibData.h"
29#include "AliVZEROTriggerData.h"
2eb38194 30ClassImp(AliVZERORawStream)
31
32//_____________________________________________________________________________
33AliVZERORawStream::AliVZERORawStream(AliRawReader* rawReader) :
726d762c 34 fTrigger(0),
35 fTriggerMask(0),
2eb38194 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");
726d762c 47
48 // Initalize the containers
49 for(Int_t i = 0; i < kNChannels; i++) {
1d51e5e5 50 fTime[i] = fWidth[i] = 0;
726d762c 51 for(Int_t j = 0; j < kNEvOfInt; j++) {
1d51e5e5 52 fADC[i][j] = 0;
726d762c 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;
2eb38194 63}
64
65//_____________________________________________________________________________
66AliVZERORawStream::~AliVZERORawStream()
67{
68 // destructor
69}
70
71//_____________________________________________________________________________
72void AliVZERORawStream::Reset()
73{
74 // reset raw stream params
75
726d762c 76 // Reinitalize the containers
77 for(Int_t i = 0; i < kNChannels; i++) {
1d51e5e5 78 fTime[i] = fWidth[i] = 0;
726d762c 79 for(Int_t j = 0; j < kNEvOfInt; j++) {
1d51e5e5 80 fADC[i][j] = 0;
726d762c 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;
2eb38194 95
96 if (fRawReader) fRawReader->Reset();
97}
98
99//_____________________________________________________________________________
100Bool_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
726d762c 105 if (fPosition >= 0) return kFALSE;
106
107 if (!fRawReader->ReadNextData(fData)) return kFALSE;
108 if (fRawReader->GetDataSize() == 0) return kFALSE;
e6bc1a67 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;
726d762c 114 }
115
116 fPosition = 0;
117
118 fTrigger = GetNextWord() & 0xffff;
119 fTriggerMask = GetNextWord() & 0xffff;
120
726d762c 121 for(Int_t iScaler = 0; iScaler < kNScalers; iScaler++)
e6bc1a67 122 fScalers[iScaler] = GetNextWord();
726d762c 123
124 for(Int_t iBunch = 0; iBunch < kNBunches; iBunch++)
e6bc1a67 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) :
726d762c 130
e6bc1a67 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();
1d51e5e5 135 fADC[iChannel][iEvOfInt] = data & 0x3ff;
e6bc1a67 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++) {
6f27a54e 142 fIsBB[iChannel][iEvOfInt] = (data >> 2*(iChannel-iChannel_Offset)) & 0x1;
143 fIsBG[iChannel][iEvOfInt] = (data >> (2*(iChannel-iChannel_Offset)+1)) & 0x1;
a346d69a 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 }
e6bc1a67 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++) {
6f27a54e 164 fIsBBMB[iChannel][iBunch] = (data >> 2*iBunch) & 0x1;
165 fIsBGMB[iChannel][iBunch] = (data >> (2*iBunch+1)) & 0x1;
a346d69a 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 }
e6bc1a67 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
b6fd9c4a 184 for(Int_t iChannel = (iCIU*8) + 7; iChannel >= iCIU*8; iChannel--) {
185 UInt_t time = GetNextWord();
1d51e5e5 186 fTime[iChannel] = time & 0xfff;
187 fWidth[iChannel] = ((time >> 12) & 0x7f); // HPTDC used in pairing mode
e6bc1a67 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
2eb38194 195 return kTRUE;
196}
197
198//_____________________________________________________________________________
726d762c 199UInt_t AliVZERORawStream::GetNextWord()
2eb38194 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
726d762c 207 UInt_t word = 0;
2eb38194 208 word |= fData[fPosition++];
209 word |= fData[fPosition++] << 8;
210 word |= fData[fPosition++] << 16;
211 word |= fData[fPosition++] << 24;
212
213 return word;
214}
726d762c 215
216//_____________________________________________________________________________
217UShort_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}
cc12572f 231
232//_____________________________________________________________________________
233void 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}
9a7352cc 266
267//_____________________________________________________________________________
268void 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//_____________________________________________________________________________
300void 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}