Line data Source code
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 44 : ClassImp(AliVZERORawStream)
31 :
32 : //_____________________________________________________________________________
33 4 : AliVZERORawStream::AliVZERORawStream(AliRawReader* rawReader) :
34 4 : fTrigger(0),
35 4 : fTriggerMask(0),
36 4 : fPosition(-1),
37 4 : fRawReader(rawReader),
38 4 : fData(NULL)
39 20 : {
40 : // create an object to read VZERO raw data
41 : //
42 : // select the raw data corresponding to
43 : // the VZERO detector id
44 4 : fRawReader->Reset();
45 20 : AliDebug(1,Form("Selecting raw data for detector %d",AliDAQ::DetectorID("VZERO")));
46 4 : fRawReader->Select("VZERO");
47 :
48 : // Initalize the containers
49 520 : for(Int_t i = 0; i < kNChannels; i++) {
50 256 : fTime[i] = fWidth[i] = 0;
51 11264 : for(Int_t j = 0; j < kNEvOfInt; j++) {
52 5376 : fADC[i][j] = 0;
53 5376 : fIsInt[i][j] = fIsBB[i][j] = fIsBG[i][j] = kFALSE;
54 : }
55 256 : fBBScalers[i] = fBGScalers[i] = 0;
56 5632 : for(Int_t j = 0; j < kNBunches; j++) {
57 2560 : fChargeMB[i][j] = 0;
58 2560 : fIsIntMB[i][j] = fIsBBMB[i][j] = fIsBGMB[i][j] = kFALSE;
59 : }
60 : }
61 136 : for(Int_t i = 0; i < kNScalers; i++) fScalers[i] = 0;
62 88 : for(Int_t i = 0; i < kNBunches; i++) fBunchNumbers[i] = 0;
63 8 : }
64 :
65 : //_____________________________________________________________________________
66 : AliVZERORawStream::~AliVZERORawStream()
67 8 : {
68 : // destructor
69 12 : }
70 :
71 : //_____________________________________________________________________________
72 : void AliVZERORawStream::Reset()
73 : {
74 : // reset raw stream params
75 :
76 : // Reinitalize the containers
77 0 : for(Int_t i = 0; i < kNChannels; i++) {
78 0 : fTime[i] = fWidth[i] = 0;
79 0 : for(Int_t j = 0; j < kNEvOfInt; j++) {
80 0 : fADC[i][j] = 0;
81 0 : fIsInt[i][j] = fIsBB[i][j] = fIsBG[i][j] = kFALSE;
82 : }
83 0 : fBBScalers[i] = fBGScalers[i] = 0;
84 0 : for(Int_t j = 0; j < kNBunches; j++) {
85 0 : fChargeMB[i][j] = 0;
86 0 : fIsIntMB[i][j] = fIsBBMB[i][j] = fIsBGMB[i][j] = kFALSE;
87 : }
88 : }
89 0 : for(Int_t i = 0; i < kNScalers; i++) fScalers[i] = 0;
90 0 : for(Int_t i = 0; i < kNBunches; i++) fBunchNumbers[i] = 0;
91 :
92 0 : fTrigger = fTriggerMask = 0;
93 0 : fPosition = -1;
94 0 : fData = NULL;
95 :
96 0 : if (fRawReader) fRawReader->Reset();
97 0 : }
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 8 : if (fPosition >= 0) return kFALSE;
106 :
107 4 : if (!fRawReader->ReadNextData(fData)) return kFALSE;
108 4 : if (fRawReader->GetDataSize() == 0) return kFALSE;
109 :
110 4 : if (fRawReader->GetDataSize() != 5936) {
111 0 : fRawReader->AddFatalErrorLog(kRawDataSizeErr,Form("size %d != 5936",fRawReader->GetDataSize()));
112 0 : AliWarning(Form("Wrong VZERO raw data size: %d, expected 5936 bytes!",fRawReader->GetDataSize()));
113 0 : return kFALSE;
114 : }
115 :
116 4 : fPosition = 0;
117 :
118 4 : fTrigger = GetNextWord() & 0xffff;
119 4 : fTriggerMask = GetNextWord() & 0xffff;
120 :
121 136 : for(Int_t iScaler = 0; iScaler < kNScalers; iScaler++)
122 64 : fScalers[iScaler] = GetNextWord();
123 :
124 88 : for(Int_t iBunch = 0; iBunch < kNBunches; iBunch++)
125 40 : fBunchNumbers[iBunch] = GetNextWord();
126 :
127 72 : 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 192 : for (Int_t iChannel_Offset = iCIU*8; iChannel_Offset < (iCIU*8)+8; iChannel_Offset=iChannel_Offset+4) {
132 640 : for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
133 11264 : for(Int_t iEvOfInt = 0; iEvOfInt < kNEvOfInt; iEvOfInt++) {
134 5376 : UShort_t data = GetNextShort();
135 5376 : fADC[iChannel][iEvOfInt] = data & 0x3ff;
136 5376 : fIsInt[iChannel][iEvOfInt] = (data >> 10) & 0x1;
137 : }
138 : }
139 1536 : for(Int_t iEvOfInt = 0; iEvOfInt < kNEvOfInt; iEvOfInt=iEvOfInt+2) {
140 704 : UShort_t data = GetNextShort();
141 7040 : for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
142 2816 : fIsBB[iChannel][iEvOfInt] = (data >> 2*(iChannel-iChannel_Offset)) & 0x1;
143 2816 : fIsBG[iChannel][iEvOfInt] = (data >> (2*(iChannel-iChannel_Offset)+1)) & 0x1;
144 2816 : if(iEvOfInt < (kNEvOfInt - 1)) {
145 2560 : fIsBB[iChannel][iEvOfInt+1] = (data >> (8+ 2*(iChannel-iChannel_Offset))) & 0x1;
146 2560 : fIsBG[iChannel][iEvOfInt+1] = (data >> (8+ 2*(iChannel-iChannel_Offset)+1)) & 0x1;
147 2560 : }
148 : }
149 : }
150 :
151 64 : GetNextShort();
152 :
153 640 : for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
154 5632 : for(Int_t iBunch = 0; iBunch < kNBunches; iBunch++) {
155 2560 : UShort_t data = GetNextShort();
156 2560 : fChargeMB[iChannel][iBunch] = data & 0x3ff;
157 2560 : fIsIntMB[iChannel][iBunch] = (data >> 10) & 0x1;
158 : }
159 : }
160 :
161 768 : for(Int_t iBunch = 0; iBunch < kNBunches; iBunch=iBunch+2) {
162 320 : UShort_t data = GetNextShort();
163 3200 : for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
164 1280 : fIsBBMB[iChannel][iBunch] = (data >> 2*iBunch) & 0x1;
165 1280 : fIsBGMB[iChannel][iBunch] = (data >> (2*iBunch+1)) & 0x1;
166 1280 : if(iBunch < (kNBunches - 1)) {
167 1280 : fIsBBMB[iChannel][iBunch+1] = (data >> (8+2*iBunch)) & 0x1;
168 1280 : fIsBGMB[iChannel][iBunch+1] = (data >> (8+2*iBunch+1)) & 0x1;
169 1280 : }
170 : }
171 : }
172 :
173 64 : GetNextShort();
174 :
175 640 : for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) {
176 256 : fBBScalers[iChannel] = ((ULong64_t)GetNextWord()) << 32;
177 256 : fBBScalers[iChannel] |= GetNextWord();
178 256 : fBGScalers[iChannel] = ((ULong64_t)GetNextWord()) << 32;
179 256 : fBGScalers[iChannel] |= GetNextWord();
180 : }
181 :
182 : }
183 :
184 576 : for(Int_t iChannel = (iCIU*8) + 7; iChannel >= iCIU*8; iChannel--) {
185 256 : UInt_t time = GetNextWord();
186 256 : fTime[iChannel] = time & 0xfff;
187 256 : 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 4 : return kTRUE;
196 4 : }
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 4176 : if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
206 :
207 : UInt_t word = 0;
208 1392 : word |= fData[fPosition++];
209 1392 : word |= fData[fPosition++] << 8;
210 1392 : word |= fData[fPosition++] << 16;
211 1392 : word |= fData[fPosition++] << 24;
212 :
213 1392 : 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 27264 : if (!fData || fPosition < 0) AliFatal("Raw data payload buffer is not yet initialized !");
224 :
225 : UShort_t word = 0;
226 9088 : word |= fData[fPosition++];
227 9088 : word |= fData[fPosition++] << 8;
228 :
229 9088 : 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 16 : if (!triggerData) {
241 0 : AliFatal("Trigger configuration data is not provided. Exiting...");
242 0 : return;
243 : }
244 8 : chargeA = chargeC = 0;
245 1040 : for(Int_t iChannel=0; iChannel<64; iChannel++) {
246 512 : Int_t offlineCh = GetOfflineChannel(iChannel);
247 512 : Int_t board = AliVZEROCalibData::GetBoardNumber(offlineCh);
248 512 : Int_t feeChannel = AliVZEROCalibData::GetFEEChannelNumber(offlineCh);
249 512 : if (triggerData->GetEnableCharge(board,feeChannel)) {
250 512 : Bool_t integ10 = GetIntegratorFlag(iChannel,10);
251 512 : UShort_t ch10 = (UShort_t)GetPedestal(iChannel,10);
252 1536 : UShort_t trPed = (integ10 == kFALSE) ? triggerData->GetPedestal(0,board,feeChannel) : triggerData->GetPedestal(1,board,feeChannel);
253 1536 : UShort_t trPedCut = (integ10 == kFALSE) ? triggerData->GetPedestalCut(0,board,feeChannel) : triggerData->GetPedestalCut(1,board,feeChannel);
254 512 : if (!triggerData->GetPedestalSubtraction(board)) trPed = trPedCut = 0;
255 512 : if (ch10 > trPedCut) {
256 120 : if (offlineCh < 32) {
257 84 : chargeC += (ch10 - trPed);
258 24 : }
259 : else {
260 36 : chargeA += (ch10 - trPed);
261 : }
262 : }
263 512 : }
264 : }
265 8 : }
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 8 : if (!triggerData) {
278 0 : AliFatal("Trigger configuration data is not provided. Exiting...");
279 0 : return;
280 : }
281 4 : nBBA = nBBC = nBGA = nBGC = 0;
282 520 : for(Int_t iChannel=0; iChannel<64; iChannel++) {
283 256 : Int_t offlineCh = GetOfflineChannel(iChannel);
284 256 : Int_t board = AliVZEROCalibData::GetBoardNumber(offlineCh);
285 256 : Int_t feeChannel = AliVZEROCalibData::GetFEEChannelNumber(offlineCh);
286 256 : if (triggerData->GetEnableTiming(board,feeChannel)) {
287 512 : if (offlineCh < 32) {
288 400 : if (GetBBFlag(iChannel,10)) nBBC++;
289 144 : if (GetBGFlag(iChannel,10)) nBGC++;
290 : }
291 : else {
292 148 : if (GetBBFlag(iChannel,10)) nBBA++;
293 148 : if (GetBGFlag(iChannel,10)) nBGA++;
294 : }
295 : }
296 : }
297 4 : }
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 8 : UShort_t chargeA,chargeC;
308 4 : CalculateChargeForCentrTriggers(triggerData,chargeA,chargeC);
309 4 : UChar_t nBBA,nBBC,nBGA,nBGC;
310 4 : CalculateBBandBGFlags(triggerData,
311 : nBBA,nBBC,
312 : nBGA,nBGC);
313 :
314 4 : fTrigger = 0;
315 : //BBA and BBC
316 12 : if((nBBC >= triggerData->GetBBCThreshold()) && (nBBA >= triggerData->GetBBAThreshold())) fTrigger |= 1;
317 : //BBA or BBC
318 8 : if((nBBC >= triggerData->GetBBCThreshold()) || (nBBA >= triggerData->GetBBAThreshold())) fTrigger |= (1<<1);
319 : //BGA and BBC
320 12 : if((nBBC >= triggerData->GetBBCForBGThreshold()) && (nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<2);
321 : //BGA
322 8 : if((nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<3);
323 : //BGC and BBA
324 12 : if((nBGC >= triggerData->GetBGCThreshold()) && (nBBA >= triggerData->GetBBAForBGThreshold())) fTrigger |= (1<<4);
325 : //BGC
326 8 : if((nBGC >= triggerData->GetBGCThreshold())) fTrigger |= (1<<5);
327 : //CTA1 and CTC1
328 12 : if((chargeC >= triggerData->GetCentralityV0CThrLow()) && (chargeA >= triggerData->GetCentralityV0AThrLow())) fTrigger |= (1<<6);
329 : //CTA1 or CTC1
330 8 : if((chargeC >= triggerData->GetCentralityV0CThrLow()) || (chargeA >= triggerData->GetCentralityV0AThrLow())) fTrigger |= (1<<7);
331 : //CTA2 and CTC2
332 10 : if((chargeC >= triggerData->GetCentralityV0CThrHigh()) && (chargeA >= triggerData->GetCentralityV0AThrHigh())) fTrigger |= (1<<8);
333 : //CTA2 or CTC2
334 9 : if((chargeC >= triggerData->GetCentralityV0CThrHigh()) || (chargeA >= triggerData->GetCentralityV0AThrHigh())) fTrigger |= (1<<9);
335 : //MTA and MTC
336 12 : if(((nBBC >= triggerData->GetMultV0CThrLow()) && (nBBC <= triggerData->GetMultV0CThrHigh())) &&
337 8 : ((nBBA >= triggerData->GetMultV0AThrLow()) && (nBBA <= triggerData->GetMultV0AThrHigh())))
338 4 : fTrigger |= (1<<10);
339 : //MTA or MTC
340 8 : if(((nBBC >= triggerData->GetMultV0CThrLow()) && (nBBC <= triggerData->GetMultV0CThrHigh())) ||
341 0 : ((nBBA >= triggerData->GetMultV0AThrLow()) && (nBBA <= triggerData->GetMultV0AThrHigh())))
342 4 : fTrigger |= (1<<11);
343 : //BBA
344 8 : if((nBBA >= triggerData->GetBBAThreshold())) fTrigger |= (1<<12);
345 : //BBC
346 8 : if((nBBC >= triggerData->GetBBCThreshold())) fTrigger |= (1<<13);
347 : //BGA or BGC
348 8 : if((nBGC >= triggerData->GetBGCThreshold()) || (nBGA >= triggerData->GetBGAThreshold())) fTrigger |= (1<<14);
349 : //(BGA and BBC) or (BGC and BBA)
350 8 : if(((nBBC >= triggerData->GetBBCForBGThreshold()) && (nBGA >= triggerData->GetBGAThreshold())) ||
351 4 : ((nBGC >= triggerData->GetBGCThreshold()) && (nBBA >= triggerData->GetBBAForBGThreshold()))) fTrigger |= (1<<15);
352 :
353 4 : }
|