Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 2007-2009, 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 : /* $Id$ */
17 :
18 : ///////////////////////////////////////////////////////////////////////////////
19 : ///
20 : /// This class provides access to ITS SPD digits in raw data.
21 : ///
22 : ///////////////////////////////////////////////////////////////////////////////
23 :
24 : #include "AliITSRawStreamSPD.h"
25 : #include "AliRawReader.h"
26 : #include "AliLog.h"
27 :
28 118 : ClassImp(AliITSRawStreamSPD)
29 :
30 : const Int_t AliITSRawStreamSPD::fgkDDLModuleMap[kDDLsNumber][kModulesPerDDL] = {
31 : { 4, 5, 0, 1, 80, 81, 84, 85, 88, 89, 92, 93},
32 : {12,13, 8, 9, 96, 97,100,101,104,105,108,109},
33 : {20,21,16,17,112,113,116,117,120,121,124,125},
34 : {28,29,24,25,128,129,132,133,136,137,140,141},
35 : {36,37,32,33,144,145,148,149,152,153,156,157},
36 : {44,45,40,41,160,161,164,165,168,169,172,173},
37 : {52,53,48,49,176,177,180,181,184,185,188,189},
38 : {60,61,56,57,192,193,196,197,200,201,204,205},
39 : {68,69,64,65,208,209,212,213,216,217,220,221},
40 : {76,77,72,73,224,225,228,229,232,233,236,237},
41 : { 7, 6, 3, 2, 83, 82, 87, 86, 91, 90, 95, 94},
42 : {15,14,11,10, 99, 98,103,102,107,106,111,110},
43 : {23,22,19,18,115,114,119,118,123,122,127,126},
44 : {31,30,27,26,131,130,135,134,139,138,143,142},
45 : {39,38,35,34,147,146,151,150,155,154,159,158},
46 : {47,46,43,42,163,162,167,166,171,170,175,174},
47 : {55,54,51,50,179,178,183,182,187,186,191,190},
48 : {63,62,59,58,195,194,199,198,203,202,207,206},
49 : {71,70,67,66,211,210,215,214,219,218,223,222},
50 : {79,78,75,74,227,226,231,230,235,234,239,238}
51 : };
52 : //__________________________________________________________________________
53 : AliITSRawStreamSPD::AliITSRawStreamSPD(AliRawReader* rawReader) :
54 4 : AliITSRawStream(rawReader),
55 4 : fEventCounter(-1),fChipAddr(0),fHalfStaveNr(0),fCol(0),fRow(0),fCalHeadLen(0),
56 4 : fData(0),fOffset(0),fHitCount(0),
57 4 : fDataChar1(0),fDataChar2(0),fDataChar3(0),fDataChar4(0),
58 4 : fFirstWord(kTRUE),fPrevEventId(0xffffffff),
59 4 : fEqPLBytesRead(0),fEqPLChipHeadersRead(0),fEqPLChipTrailersRead(0),
60 4 : fHeaderOrTrailerReadLast(kFALSE),fExpectedHeaderTrailerCount(0),
61 4 : fFillOutOfSynch(kFALSE),fDDLID(-1),fLastDDLID(-1),fAdvancedErrorLog(kFALSE),
62 4 : fAdvLogger(NULL)
63 20 : {
64 : // create an object to read ITS SPD raw digits
65 4 : fRawReader->Reset();
66 4 : fRawReader->Select("ITSSPD");
67 : // reset calib header words
68 520 : for (UInt_t iword=0; iword<kCalHeadLenMax; iword++) {
69 256 : fCalHeadWord[iword]=0xffffffff;
70 : }
71 168 : for (UInt_t eq=0; eq<20; eq++) {
72 80 : fActiveEq[eq]=kFALSE;
73 1120 : for (UInt_t hs=0; hs<6; hs++) {
74 480 : fActiveHS[eq][hs]=kFALSE;
75 10560 : for (UInt_t chip=0; chip<10; chip++) {
76 4800 : fActiveChip[eq][hs][chip]=kFALSE;
77 4800 : fEventCounterFull[eq][hs][chip] = -1;
78 : }
79 : }
80 : }
81 4 : NewEvent();
82 8 : }
83 : //__________________________________________________________________________
84 : AliITSRawStreamSPD::AliITSRawStreamSPD(const AliITSRawStreamSPD& rstream) :
85 0 : AliITSRawStream(rstream.fRawReader),
86 0 : fEventCounter(-1),fChipAddr(0),fHalfStaveNr(0),fCol(0),fRow(0),fCalHeadLen(0),
87 0 : fData(0),fOffset(0),fHitCount(0),
88 0 : fDataChar1(0),fDataChar2(0),fDataChar3(0),fDataChar4(0),
89 0 : fFirstWord(kTRUE),fPrevEventId(0xffffffff),
90 0 : fEqPLBytesRead(0),fEqPLChipHeadersRead(0),fEqPLChipTrailersRead(0),
91 0 : fHeaderOrTrailerReadLast(kFALSE),fExpectedHeaderTrailerCount(0),
92 0 : fFillOutOfSynch(kFALSE),fDDLID(-1),fLastDDLID(-1),fAdvancedErrorLog(kFALSE),
93 0 : fAdvLogger(NULL)
94 0 : {
95 : // copy constructor
96 0 : AliError("Copy constructor should not be used.");
97 0 : }
98 : //__________________________________________________________________________
99 : AliITSRawStreamSPD& AliITSRawStreamSPD::operator=(const AliITSRawStreamSPD& rstream) {
100 : // assignment operator
101 : if (this!=&rstream) {}
102 0 : AliError("Assignment opertator should not be used.");
103 0 : return *this;
104 : }
105 : //__________________________________________________________________________
106 : Bool_t AliITSRawStreamSPD::ReadNextShort() {
107 : // read next 16 bit word into fData
108 19576 : if (fFirstWord) {
109 4896 : Bool_t b1 = fRawReader->ReadNextChar(fDataChar1);
110 4900 : if (!b1) return kFALSE;
111 : Bool_t b2, b3, b4;
112 4892 : b2 = fRawReader->ReadNextChar(fDataChar2);
113 4892 : b3 = fRawReader->ReadNextChar(fDataChar3);
114 4892 : b4 = fRawReader->ReadNextChar(fDataChar4);
115 14676 : if (!(b2 && b3 && b4)) {
116 0 : return kFALSE;
117 : }
118 4892 : fData = fDataChar3+(fDataChar4<<8);
119 4892 : const UInt_t *intPtr = fRawReader->GetEventId();
120 4892 : if (intPtr!=0) {
121 4892 : if (*intPtr!=fPrevEventId) { // if new event...
122 4 : NewEvent();
123 4 : fPrevEventId=*intPtr;
124 4 : }
125 : }
126 4892 : fFirstWord=kFALSE;
127 4892 : }
128 : else {
129 4892 : fFirstWord=kTRUE;
130 4892 : fData = fDataChar1+(fDataChar2<<8);
131 : }
132 9784 : fEqPLBytesRead+=2;
133 :
134 9784 : return kTRUE;
135 9788 : }
136 : //__________________________________________________________________________
137 : Bool_t AliITSRawStreamSPD::ReadNextInt() {
138 : // reads next 32 bit into fDataChar1..4
139 : // (if first 16 bits read already, just completes the present word)
140 0 : if (fFirstWord) {
141 0 : if (ReadNextShort() && ReadNextShort()) {
142 0 : return kTRUE;
143 : }
144 : }
145 : else {
146 0 : if (ReadNextShort()) {
147 0 : return kTRUE;
148 : }
149 : }
150 0 : return kFALSE;
151 0 : }
152 : //__________________________________________________________________________
153 : void AliITSRawStreamSPD::NewEvent() {
154 : // call this to reset flags for a new event
155 344 : for (UInt_t eqId=0; eqId<20; eqId++) {
156 160 : fCalHeadRead[eqId]=kFALSE;
157 : }
158 8 : fEventCounter = -1;
159 8 : fDDLID = -1;
160 8 : fLastDDLID = -1;
161 336 : for (UInt_t eq=0; eq<20; eq++) {
162 2240 : for (UInt_t hs=0; hs<6; hs++) {
163 21120 : for (UInt_t chip=0; chip<10; chip++) {
164 9600 : fFastOrSignal[eq][hs][chip] = kFALSE;
165 : }
166 : }
167 : }
168 8 : }
169 : //__________________________________________________________________________
170 : Int_t AliITSRawStreamSPD::ReadCalibHeader() {
171 : // needs to be called in the beginning of each equipment data
172 : // read the extra calibration header
173 : // returns the length of the header if it is present, -1 otherwise
174 :
175 160 : Int_t ddlID = fRawReader->GetDDLID();
176 80 : if (ddlID==-1) { // we may need to read one word to get the blockAttr
177 0 : if (!ReadNextShort()) return -1;
178 0 : ddlID = fRawReader->GetDDLID();
179 0 : if(ddlID<0){
180 0 : AliError("fRawReader->GetDDLID() returns a negative value");
181 : ddlID=0;
182 0 : }
183 : }
184 : // reset flags and counters
185 80 : fEqPLBytesRead = 2;
186 80 : fEqPLChipHeadersRead = 0;
187 80 : fEqPLChipTrailersRead = 0;
188 80 : fHeaderOrTrailerReadLast = kFALSE;
189 80 : fFillOutOfSynch = kFALSE;
190 :
191 : // check router error bits:
192 80 : UInt_t statusBits = fRawReader->GetStatusBits();
193 80 : if ((statusBits >> 5) & 1) { // linkrx/detector fatal error bit
194 0 : TString errMess = "LinkRx Error Bit Set";
195 0 : AliError(errMess.Data());
196 0 : fRawReader->AddMajorErrorLog(kLinkRxDetectorFatalErr,errMess.Data());
197 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kLinkRxDetectorFatalErr,ddlID,-1,-1,errMess.Data());
198 0 : }
199 80 : if ((statusBits >> 12) & 1) { // trigger sequence monitor error bit
200 0 : TString errMess = "TSM Trigger Error Bit Set";
201 0 : AliError(errMess.Data());
202 0 : fRawReader->AddMajorErrorLog(kTSMtriggerErr,errMess.Data());
203 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kTSMtriggerErr,ddlID,-1,-1,errMess.Data());
204 0 : }
205 80 : if (fRawReader->TestBlockAttribute(7)) { // bunch crossing difference error bit
206 0 : TString errMess = "High Multiplicity Event Flag Set";
207 0 : static bool show_info = !(getenv("HLT_ONLINE_MODE") && strcmp(getenv("HLT_ONLINE_MODE"), "on") == 0);
208 : static int nErrors = 0;
209 0 : if (show_info || nErrors++ < 10)
210 : {
211 0 : AliError(errMess.Data());
212 : }
213 0 : fRawReader->AddMajorErrorLog(kHighMultiplicityFlag,errMess.Data());
214 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHighMultiplicityFlag,ddlID,-1,-1,errMess.Data());
215 0 : }
216 :
217 : // set eq active and the participating half-staves (for access from outside this class),
218 : // set what number of chip headers/trailers to expect (for the moment not used)
219 80 : fActiveEq[ddlID]=kTRUE;
220 80 : fExpectedHeaderTrailerCount = 0;
221 1120 : for (UInt_t hs=0; hs<6; hs++) {
222 960 : if (!fRawReader->TestBlockAttribute(hs)) {
223 480 : fActiveHS[ddlID][hs]=kTRUE;
224 480 : fExpectedHeaderTrailerCount+=10;
225 480 : }
226 : else {
227 480 : fActiveHS[ddlID][hs]=kFALSE;
228 : }
229 : }
230 :
231 160 : if (ddlID>=0 && ddlID<20) fCalHeadRead[ddlID]=kTRUE;
232 80 : if (fRawReader->TestBlockAttribute(6)) { // is the calib header present?
233 0 : if (ReadNextInt()) {
234 : // length of cal header:
235 0 : fCalHeadLen = fDataChar1+(fDataChar2<<8)+(fDataChar3<<16)+(fDataChar4<<24);
236 0 : if (fCalHeadLen>kCalHeadLenMax) {
237 0 : TString errMess = Form("Header length %d > max = %d",fCalHeadLen,kCalHeadLenMax);
238 0 : AliError(errMess.Data());
239 0 : fRawReader->AddMajorErrorLog(kCalHeaderLengthErr,errMess.Data());
240 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kCalHeaderLengthErr,ddlID,-1,-1,errMess.Data());
241 : return -1;
242 0 : }
243 : else {
244 0 : for (UInt_t iword=0; iword<fCalHeadLen; iword++) {
245 0 : if (ReadNextInt()) {
246 0 : fCalHeadWord[iword] = fDataChar1+(fDataChar2<<8)+(fDataChar3<<16)+(fDataChar4<<24);
247 : }
248 : else {
249 0 : TString errMess = "Header length problem";
250 0 : AliError(errMess.Data());
251 0 : fRawReader->AddMajorErrorLog(kCalHeaderLengthErr,errMess.Data());
252 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kCalHeaderLengthErr,ddlID,-1,-1,errMess.Data());
253 : return -1;
254 0 : }
255 : }
256 0 : return fCalHeadLen;
257 : }
258 : }
259 : }
260 :
261 80 : return -1;
262 80 : }
263 : //__________________________________________________________________________
264 : Bool_t AliITSRawStreamSPD::Next() {
265 : // read the next raw digit
266 : // returns kFALSE if there is no digit left
267 :
268 304 : fPrevModuleID = fModuleID;
269 :
270 19728 : while (ReadNextShort()) {
271 :
272 19572 : fLastDDLID = fDDLID;
273 9784 : fDDLID = fRawReader->GetDDLID();
274 19568 : if (fDDLID>=0 && fDDLID<20) {
275 9784 : if (!fCalHeadRead[fDDLID]) {
276 80 : if (fLastDDLID!=-1) { // if not the first equipment for this event
277 76 : fEqPLBytesRead -= 2;
278 : // The next line is commented, since we do not have the information how many chips to expect
279 : // CheckHeaderAndTrailerCount(fLastDDLID);
280 76 : }
281 80 : if (ReadCalibHeader()>=0) continue; // skip to next word if we found a calib header, otherwise parse this word as regular data (go on with this while loop)
282 : }
283 : }
284 : else {
285 0 : TString errMess = Form("Error in DDL number (=%d) , setting it to 19",fDDLID);
286 0 : AliError(errMess.Data());
287 0 : fRawReader->AddMajorErrorLog(kDDLNumberErr,errMess.Data());
288 0 : if (fAdvancedErrorLog) fAdvLogger->AddMessage(errMess.Data());
289 0 : fDDLID=19;
290 0 : }
291 :
292 9784 : Short_t hs = ((fData & 0x3800)>>11) ; Short_t chip=(fData & 0x000F); // -> for printouts
293 :
294 9784 : if ((fData & 0xC000) == 0x4000) { // header
295 4800 : if (fHeaderOrTrailerReadLast) {
296 0 : TString errMess = Form("Chip trailer missing - (eq,hs,chip) = (%d,%d,%d)",fDDLID,hs,chip);
297 0 : AliError(errMess.Data());
298 0 : fRawReader->AddMajorErrorLog(kTrailerMissingErr,errMess.Data());
299 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kTrailerMissingErr,fLastDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
300 0 : }
301 4800 : fHeaderOrTrailerReadLast = kTRUE;
302 4800 : fEqPLChipHeadersRead++;
303 4800 : fHitCount = 0;
304 4800 : UShort_t eventCounter = (fData >> 4) & 0x007F;
305 9600 : if (fEventCounter < 0) {
306 4804 : fEventCounter = eventCounter;
307 4 : }
308 4796 : else if (eventCounter != fEventCounter) {
309 0 : TString errMess;
310 0 : if (fEqPLChipHeadersRead==1) {
311 0 : errMess = Form("Mismatching event counters between this equipment and the previous: %d != %d - (eq,hs,chip) = (%d,%d,%d)",
312 0 : eventCounter,fEventCounter,fDDLID,hs,chip);
313 : }
314 : else {
315 0 : errMess = Form("Mismatching event counters between this chip header and the previous: %d != %d - (eq,hs,chip) = (%d,%d,%d)",
316 : eventCounter,fEventCounter,fDDLID,hs,chip);
317 : }
318 0 : fEventCounter = eventCounter;
319 0 : AliError(errMess.Data());
320 0 : fRawReader->AddMajorErrorLog(kEventCounterErr,errMess.Data());
321 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kEventCounterErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
322 0 : }
323 4800 : fChipAddr = fData & 0x000F;
324 4800 : if (fChipAddr>9) {
325 0 : TString errMess = Form("Overflow chip address %d - set to 0 (eq,hs) = (%d,%d)",fChipAddr,fDDLID,hs);
326 0 : AliError(errMess.Data());
327 0 : fRawReader->AddMajorErrorLog(kChipAddrErr,errMess.Data());
328 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kChipAddrErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
329 0 : fChipAddr=0;
330 0 : }
331 4800 : fHalfStaveNr = (fData & 0x3800)>>11;
332 9600 : if (fHalfStaveNr>5 || fRawReader->TestBlockAttribute(fHalfStaveNr)) {
333 0 : TString errMess = Form("Half stave number error: %d - set to 0 - eq %d",fHalfStaveNr,fDDLID);
334 0 : AliError(errMess.Data());
335 0 : fRawReader->AddMajorErrorLog(kHSNumberErr,errMess.Data());
336 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHSNumberErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
337 0 : fHalfStaveNr=0;
338 0 : }
339 4800 : fActiveChip[fDDLID][fHalfStaveNr][fChipAddr]=kTRUE;
340 4800 : fEventCounterFull[fDDLID][fHalfStaveNr][fChipAddr] = eventCounter;
341 : // translate ("online") ddl, hs, chip nr to ("offline") module id :
342 4800 : fModuleID = GetOfflineModuleFromOnline(fDDLID,fHalfStaveNr,fChipAddr);
343 4800 : }
344 :
345 4984 : else if ((fData & 0xC000) == 0x0000) { // trailer
346 4800 : if ( (fEqPLBytesRead+fFillOutOfSynch*2)%4 != 0 ) {
347 0 : TString errMess = Form("Fill word is missing - (eq,hs,chip) = (%d,%d,%d)",fDDLID,fHalfStaveNr,fChipAddr);
348 0 : AliError(errMess.Data());
349 0 : fRawReader->AddMajorErrorLog(kFillMissingErr,errMess.Data());
350 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kFillMissingErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
351 0 : if (fFillOutOfSynch) fFillOutOfSynch = kFALSE;
352 0 : else fFillOutOfSynch = kTRUE;
353 0 : }
354 4800 : if (!fHeaderOrTrailerReadLast) {
355 0 : TString errMess = Form("Trailer without previous header - (eq,hs,chip) = (%d,%d,%d)",fDDLID,fHalfStaveNr,fChipAddr);
356 0 : AliError(errMess.Data());
357 0 : fRawReader->AddMajorErrorLog(kTrailerWithoutHeaderErr,errMess.Data());
358 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kTrailerWithoutHeaderErr,fLastDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
359 0 : }
360 4800 : fHeaderOrTrailerReadLast = kFALSE;
361 4800 : fEqPLChipTrailersRead++;
362 4800 : UShort_t hitCount = fData & 0x0FFF;
363 4800 : if (hitCount != fHitCount){
364 0 : TString errMess = Form("Number of hits %d, while %d expected - (eq,hs,chip) = (%d,%d,%d)",fHitCount,hitCount,fDDLID,fHalfStaveNr,fChipAddr);
365 0 : AliError(errMess.Data());
366 0 : fRawReader->AddMajorErrorLog(kNumberHitsErr,errMess.Data());
367 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kNumberHitsErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
368 0 : }
369 4800 : Bool_t errorBit = fData & 0x1000;
370 4800 : if (errorBit) {
371 0 : TString errMess = Form("Trailer error bit set for chip (eq,hs,chip) = (%d,%d,%d)",fDDLID,fHalfStaveNr,fChipAddr);
372 0 : static bool show_info = !(getenv("HLT_ONLINE_MODE") && strcmp(getenv("HLT_ONLINE_MODE"), "on") == 0);
373 : static int nErrors = 0;
374 0 : if (show_info || nErrors++ < 10)
375 : {
376 0 : AliError(errMess.Data());
377 : }
378 0 : fRawReader->AddMajorErrorLog(kTrailerErrorBitErr,errMess.Data());
379 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kTrailerErrorBitErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
380 0 : }
381 4800 : Bool_t fastorBit = fData & 0x2000;
382 4800 : fFastOrSignal[fDDLID][fHalfStaveNr][fChipAddr] = fastorBit;
383 4800 : }
384 :
385 184 : else if ((fData & 0xC000) == 0x8000) { // pixel hit
386 148 : if (!fHeaderOrTrailerReadLast) {
387 0 : TString errMess = Form("Chip header missing - (eq,hs,chip) = (%d,%d,%d)",fDDLID,fHalfStaveNr,fChipAddr);
388 0 : AliError(errMess.Data());
389 0 : fRawReader->AddMajorErrorLog(kHeaderMissingErr,errMess.Data());
390 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHeaderMissingErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
391 0 : fHeaderOrTrailerReadLast = kTRUE;
392 0 : }
393 148 : fHitCount++;
394 148 : fCol = (fData & 0x001F);
395 148 : fRow = (fData >> 5) & 0x00FF;
396 :
397 148 : fCoord1 = GetOfflineColFromOnline(fDDLID,fHalfStaveNr,fChipAddr,fCol);
398 148 : fCoord2 = GetOfflineRowFromOnline(fDDLID,fHalfStaveNr,fChipAddr,fRow);
399 :
400 148 : return kTRUE;
401 : }
402 :
403 : else { // fill word
404 36 : if ((fData & 0xC000) != 0xC000) {
405 0 : TString errMess = Form("Wrong fill word! - (eq,hs,chip) = (%d,%d,%d)",fDDLID,fHalfStaveNr,fChipAddr);
406 0 : AliError(errMess.Data());
407 0 : fRawReader->AddMajorErrorLog(kWrongFillWordErr,errMess.Data());
408 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kWrongFillWordErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
409 0 : }
410 36 : if ( (fEqPLBytesRead+fFillOutOfSynch*2)%4 != 2 ) {
411 0 : TString errMess = Form("Fill word is unexpected - (eq,hs,chip) = (%d,%d,%d)",fDDLID,fHalfStaveNr,fChipAddr);
412 0 : AliError(errMess.Data());
413 0 : fRawReader->AddMajorErrorLog(kFillUnexpectErr,errMess.Data());
414 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kFillUnexpectErr,fDDLID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
415 0 : if (fFillOutOfSynch) fFillOutOfSynch = kFALSE;
416 0 : else fFillOutOfSynch = kTRUE;
417 0 : }
418 : }
419 :
420 9636 : }
421 : if (fDDLID>=0 && fDDLID<20) {
422 : // The next line is commented, since we do not have the information how many chips to expect
423 : // CheckHeaderAndTrailerCount(fDDLID);
424 : }
425 4 : return kFALSE;
426 152 : }
427 : //__________________________________________________________________________
428 : void AliITSRawStreamSPD::CheckHeaderAndTrailerCount(Int_t ddlID) {
429 : // Checks that the number of header and trailers found for the ddl are as expected
430 0 : if (fEqPLChipHeadersRead != fExpectedHeaderTrailerCount) {
431 0 : TString errMess = Form("Chip header count inconsistent %d != %d (expected) for ddl %d",
432 0 : fEqPLChipHeadersRead,fExpectedHeaderTrailerCount,ddlID);
433 0 : AliError(errMess.Data());
434 0 : fRawReader->AddMajorErrorLog(kHeaderCountErr,errMess.Data());
435 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHeaderCountErr,ddlID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
436 0 : }
437 0 : if (fEqPLChipTrailersRead != fExpectedHeaderTrailerCount) {
438 0 : TString errMess = Form("Chip trailer count inconsistent %d != %d (expected) for ddl %d",
439 0 : fEqPLChipTrailersRead,fExpectedHeaderTrailerCount,ddlID);
440 0 : AliError(errMess.Data());
441 0 : fRawReader->AddMajorErrorLog(kHeaderCountErr,errMess.Data());
442 : // if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHeaderCountErr,ddlID,fEqPLBytesRead,fEqPLChipHeadersRead,errMess.Data());
443 0 : if (fAdvancedErrorLog) fAdvLogger->ProcessError(kHeaderCountErr,ddlID,fEqPLBytesRead,fEqPLChipTrailersRead,errMess.Data());
444 0 : }
445 0 : }
446 : //__________________________________________________________________________
447 : void AliITSRawStreamSPD::ActivateAdvancedErrorLog(Bool_t activate, AliITSRawStreamSPDErrorLog* advLogger) {
448 : // Activate the advanced error logging.
449 : // Logger object has to be created elsewhere and a pointer sent here.
450 0 : fAdvancedErrorLog=activate;
451 0 : if (activate && advLogger!=NULL) {
452 0 : fAdvLogger = advLogger;
453 0 : }
454 0 : if (fAdvLogger==NULL) {
455 0 : fAdvancedErrorLog=kFALSE;
456 0 : }
457 0 : }
458 : //__________________________________________________________________________
459 : const Char_t* AliITSRawStreamSPD::GetErrorName(UInt_t errorCode) {
460 : // Returns a string for each error code
461 0 : if (errorCode==kTotal) return "All Errors";
462 0 : else if (errorCode==kHeaderMissingErr) return "Header Missing";
463 0 : else if (errorCode==kTrailerMissingErr) return "Trailer Missing";
464 0 : else if (errorCode==kTrailerWithoutHeaderErr) return "Trailer Unexpected";
465 0 : else if (errorCode==kHeaderCountErr) return "Header Count Wrong";
466 0 : else if (errorCode==kTrailerCountErr) return "Trailer Count Wrong";
467 0 : else if (errorCode==kFillUnexpectErr) return "Fill Unexpected";
468 0 : else if (errorCode==kFillMissingErr) return "Fill Missing";
469 0 : else if (errorCode==kWrongFillWordErr) return "Fill Word Wrong";
470 0 : else if (errorCode==kNumberHitsErr) return "Hit Count Wrong";
471 0 : else if (errorCode==kEventCounterErr) return "Event Counter Error";
472 0 : else if (errorCode==kDDLNumberErr) return "DDL Number Error";
473 0 : else if (errorCode==kHSNumberErr) return "HS Number Error";
474 0 : else if (errorCode==kChipAddrErr) return "Chip Address Error";
475 0 : else if (errorCode==kCalHeaderLengthErr) return "Calib Header Length Error";
476 0 : else if (errorCode==kAdvEventCounterErr) return "Event Counter Error (Adv)";
477 0 : else if (errorCode==kAdvEventCounterOrderErr) return "Event Counter Jump Error (Adv)";
478 0 : else if (errorCode==kTrailerErrorBitErr) return "Trailer Error Bit Set";
479 0 : else if (errorCode==kLinkRxDetectorFatalErr) return "LinkRx/Detector Fatal Error Bit Set";
480 0 : else if (errorCode==kTSMtriggerErr) return "TSM Trigger Error Bit Set";
481 0 : else if (errorCode==kHighMultiplicityFlag) return "High Multiplicity Event Flag Set";
482 0 : else return "";
483 0 : }
484 : //__________________________________________________________________________
485 : Bool_t AliITSRawStreamSPD::GetFastOrSignal(UInt_t eq, UInt_t hs, UInt_t chip) {
486 : // returns if there was a fastor signal from this chip
487 9600 : if (eq>=20 || hs>=6 || chip>=10) {
488 0 : TString errMess = Form("eq,hs,chip = %d,%d,%d out of bounds. Return kFALSE.",eq,hs,chip);
489 0 : AliError(errMess.Data());
490 : return kFALSE;
491 0 : }
492 4800 : return fFastOrSignal[eq][hs][chip];
493 4800 : }
494 : //__________________________________________________________________________
495 : Bool_t AliITSRawStreamSPD::IsActiveEq(UInt_t eq) const {
496 : // returns if the eq is active (seen in data)
497 0 : if (eq>=20) {
498 0 : TString errMess = Form("eq = %d out of bounds. Return kFALSE.",eq);
499 0 : AliError(errMess.Data());
500 : return kFALSE;
501 0 : }
502 0 : return fActiveEq[eq];
503 0 : }
504 : //__________________________________________________________________________
505 : Bool_t AliITSRawStreamSPD::IsActiveHS(UInt_t eq, UInt_t hs) const {
506 : // returns if the hs is active (info from block attr)
507 0 : if (eq>=20 || hs>=6) {
508 0 : TString errMess = Form("eq,hs = %d,%d out of bounds. Return kFALSE.",eq,hs);
509 0 : AliError(errMess.Data());
510 : return kFALSE;
511 0 : }
512 0 : return fActiveHS[eq][hs];
513 0 : }
514 : //__________________________________________________________________________
515 : Bool_t AliITSRawStreamSPD::IsActiveChip(UInt_t eq, UInt_t hs, UInt_t chip) const {
516 : // returns if the chip is active (seen in data)
517 0 : if (eq>=20 || hs>=6 || chip>=10) {
518 0 : TString errMess = Form("eq,hs,chip = %d,%d,%d out of bounds. Return kFALSE.",eq,hs,chip);
519 0 : AliError(errMess.Data());
520 : return kFALSE;
521 0 : }
522 0 : return fActiveChip[eq][hs][chip];
523 0 : }
524 : //__________________________________________________________________________
525 : Bool_t AliITSRawStreamSPD::GetHalfStavePresent(UInt_t hs) {
526 : // Reads the half stave present status from the block attributes
527 : // This is not really needed anymore (kept for now in case it is still used somewhere).
528 : // The same information can be reached through the "IsActiveHS" method instead.
529 0 : Int_t ddlID = fRawReader->GetDDLID();
530 0 : if (ddlID==-1) {
531 0 : AliWarning("DDL ID = -1. Cannot read block attributes. Return kFALSE.");
532 0 : return kFALSE;
533 : }
534 : else {
535 0 : if (hs>=6) {
536 0 : AliWarning(Form("HS >= 6 requested (%d). Return kFALSE.",hs));
537 0 : return kFALSE;
538 : }
539 0 : UChar_t attr = fRawReader->GetBlockAttributes();
540 0 : if (((attr>>hs) & 0x01) == 0x01) { // bit set means not present
541 0 : return kFALSE;
542 : }
543 : else {
544 0 : return kTRUE;
545 : }
546 : }
547 0 : }
548 : //__________________________________________________________________________
549 : Bool_t AliITSRawStreamSPD::IsEventCounterFullConsistent() const {
550 : // checks if the event counter values are consistent within the event
551 : Short_t reference = -1;
552 0 : for (UInt_t eq=0; eq<20; eq++) {
553 0 : if (IsActiveEq(eq)) {
554 0 : for (UInt_t hs=0; hs<6; hs++) {
555 0 : if (IsActiveHS(eq,hs)) {
556 0 : for (UInt_t chip=0; chip<10; chip++) {
557 0 : if (fEventCounterFull[eq][hs][chip]!=-1) {
558 0 : if (reference==-1) reference = fEventCounterFull[eq][hs][chip];
559 0 : if (fEventCounterFull[eq][hs][chip] != reference) return kFALSE;
560 : }
561 : }
562 : }
563 : }
564 : }
565 : }
566 0 : return kTRUE;
567 0 : }
568 : //__________________________________________________________________________
569 : Short_t AliITSRawStreamSPD::GetEventCounterFullEq(UInt_t eq) const {
570 : // if the eq is active; returns the event counter value
571 0 : if (eq>=20) {
572 0 : TString errMess = Form("eq (%d) out of bounds",eq);
573 0 : AliError(errMess.Data());
574 : return -1;
575 0 : }
576 0 : if (IsActiveEq(eq)) {
577 0 : for (UInt_t hs=0; hs<6; hs++) {
578 0 : if (IsActiveHS(eq,hs)) {
579 0 : for (UInt_t chip=0; chip<10; chip++) {
580 0 : if (fEventCounterFull[eq][hs][chip]!=-1) {
581 0 : return fEventCounterFull[eq][hs][chip];
582 : }
583 : }
584 : }
585 : }
586 : }
587 0 : return -1;
588 0 : }
589 : //__________________________________________________________________________
590 : Short_t AliITSRawStreamSPD::GetEventCounterFullHS(UInt_t eq, UInt_t hs) const {
591 : // if the eq,hs is active; returns the event counter value
592 0 : if (eq>=20 || hs>=6) {
593 0 : TString errMess = Form("eq,hs (%d,%d) out of bounds",eq,hs);
594 0 : AliError(errMess.Data());
595 : return -1;
596 0 : }
597 0 : if (IsActiveEq(eq)) {
598 0 : if (IsActiveHS(eq,hs)) {
599 0 : for (UInt_t chip=0; chip<10; chip++) {
600 0 : if (fEventCounterFull[eq][hs][chip]!=-1) {
601 0 : return fEventCounterFull[eq][hs][chip];
602 : }
603 : }
604 : }
605 : }
606 0 : return -1;
607 0 : }
608 : //__________________________________________________________________________
609 : Short_t AliITSRawStreamSPD::GetEventCounterFullChip(UInt_t eq, UInt_t hs, UInt_t chip) const {
610 : // if the eq,hs,chip is active; returns the event counter value
611 0 : if (eq>=20 || hs>=6 || chip>=10) {
612 0 : TString errMess = Form("eq,hs,chip (%d,%d,%d) out of bounds",eq,hs,chip);
613 0 : AliError(errMess.Data());
614 : return -1;
615 0 : }
616 0 : if (IsActiveEq(eq)) {
617 0 : if (IsActiveHS(eq,hs)) {
618 0 : if (IsActiveChip(eq,hs,chip)) {
619 0 : return fEventCounterFull[eq][hs][chip];
620 : }
621 : }
622 : }
623 0 : return -1;
624 0 : }
625 : //__________________________________________________________________________
626 : Int_t AliITSRawStreamSPD::GetHword(UInt_t index) {
627 0 : if (index<kCalHeadLenMax) return fCalHeadWord[index];
628 0 : else return 0;
629 0 : }
630 : Bool_t AliITSRawStreamSPD::GetHhalfStaveScanned(UInt_t hs) const {
631 0 : if (hs<6) return (Bool_t)((fCalHeadWord[0]>>(6+hs)) & (0x00000001));
632 0 : else return kFALSE;
633 0 : }
634 : Bool_t AliITSRawStreamSPD::GetHchipPresent(UInt_t hs, UInt_t chip) const {
635 0 : if (hs<6 && chip<10) return ((( fCalHeadWord[hs/3+3]>>((hs%3)*10+chip)) & 0x00000001) == 1);
636 0 : else return kFALSE;
637 0 : }
638 : UInt_t AliITSRawStreamSPD::GetHdacHigh(UInt_t hs) const {
639 0 : if (hs<6) return (fCalHeadWord[hs/2+7]>>(24-16*(hs%2)) & 0x000000ff);
640 0 : else return 0;
641 0 : }
642 : UInt_t AliITSRawStreamSPD::GetHdacLow(UInt_t hs) const {
643 0 : if (hs<6) return (fCalHeadWord[hs/2+7]>>(16-16*(hs%2)) & 0x000000ff);
644 0 : else return 0;
645 0 : }
646 : UInt_t AliITSRawStreamSPD::GetHTPAmp(UInt_t hs) const {
647 0 : if (hs<6) return fCalHeadWord[hs+10];
648 0 : else return 0;
649 0 : }
650 : Bool_t AliITSRawStreamSPD::GetHminTHchipPresent(UInt_t chip) const {
651 0 : if (chip<10) return ((( fCalHeadWord[7]>>(16+chip)) & 0x00000001) == 1);
652 0 : else return kFALSE;
653 0 : }
654 : UInt_t AliITSRawStreamSPD::GetFOHnumDacs() const {
655 0 : return (fCalHeadLen-37)/2;
656 : }
657 : UInt_t AliITSRawStreamSPD::GetFOHdacIndex(UInt_t index) const {
658 0 : if (index>=GetFOHnumDacs()) {
659 0 : TString errMess = Form("Only %d DACs in this run, returning 0",GetFOHnumDacs());
660 0 : AliError(errMess.Data());
661 : return 0;
662 0 : }
663 0 : return fCalHeadWord[7+index*2];
664 0 : }
665 : UInt_t AliITSRawStreamSPD::GetFOHdacValue(UInt_t index) const {
666 0 : if (index>=GetFOHnumDacs()) {
667 0 : TString errMess = Form("Only %d DACs in this run, returning 0",GetFOHnumDacs());
668 0 : AliError(errMess.Data());
669 : return 0;
670 0 : }
671 0 : return fCalHeadWord[7+1+index*2];
672 0 : }
673 : UInt_t AliITSRawStreamSPD::GetFOHchipCount(UInt_t hs, UInt_t chip) const {
674 0 : if (hs<6 && chip<10) {
675 0 : if (chip%2==0) {
676 0 : return ((fCalHeadWord[7 + GetFOHnumDacs()*2 + (hs*10 + chip)/2] >> 16) & 0x0000ffff);
677 : }
678 : else {
679 0 : return (fCalHeadWord[7 + GetFOHnumDacs()*2 + (hs*10 + chip)/2] & 0x0000ffff);
680 : }
681 : }
682 0 : else return 0;
683 0 : }
684 : //__________________________________________________________________________
685 : Int_t AliITSRawStreamSPD::GetModuleNumber(UInt_t iDDL, UInt_t iModule) {
686 4323438 : if (iDDL<20 && iModule<12) return fgkDDLModuleMap[iDDL][iModule];
687 0 : else return 240;
688 1441146 : }
689 : //__________________________________________________________________________
690 : Bool_t AliITSRawStreamSPD::OfflineToOnline(UInt_t module, UInt_t colM, UInt_t rowM, UInt_t& eq, UInt_t& hs, UInt_t& chip, UInt_t& col, UInt_t& row) {
691 : // converts offline coordinates to online
692 592 : eq = GetOnlineEqIdFromOffline(module);
693 296 : hs = GetOnlineHSFromOffline(module);
694 296 : chip = GetOnlineChipFromOffline(module,colM);
695 296 : col = GetOnlineColFromOffline(module,colM);
696 296 : row = GetOnlineRowFromOffline(module,rowM);
697 1480 : if (eq>=20 || hs>=6 || chip>=10 || col>=32 || row>=256) return kFALSE;
698 296 : else return kTRUE;
699 296 : }
700 : //__________________________________________________________________________
701 : Bool_t AliITSRawStreamSPD::OnlineToOffline(UInt_t eq, UInt_t hs, UInt_t chip, UInt_t col, UInt_t row, UInt_t& module, UInt_t& colM, UInt_t& rowM) {
702 : // converts online coordinates to offline
703 0 : module = GetOfflineModuleFromOnline(eq,hs,chip);
704 0 : colM = GetOfflineColFromOnline(eq,hs,chip,col);
705 0 : rowM = GetOfflineRowFromOnline(eq,hs,chip,row);
706 0 : if (module>=240 || colM>=160 || rowM>=256) return kFALSE;
707 0 : else return kTRUE;
708 0 : }
709 : //__________________________________________________________________________
710 : UInt_t AliITSRawStreamSPD::GetOnlineEqIdFromOffline(UInt_t module) {
711 : // offline->online (eq)
712 52631 : for (UInt_t eqId=0; eqId<20; eqId++) {
713 642513 : for (UInt_t iModule=0; iModule<12; iModule++) {
714 289697 : if (GetModuleNumber(eqId,iModule)==(Int_t)module) return eqId;
715 : }
716 : }
717 0 : return 20; // error
718 2435 : }
719 : //__________________________________________________________________________
720 : UInt_t AliITSRawStreamSPD::GetOnlineHSFromOffline(UInt_t module) {
721 : // offline->online (hs)
722 52631 : for (UInt_t eqId=0; eqId<20; eqId++) {
723 642513 : for (UInt_t iModule=0; iModule<12; iModule++) {
724 289697 : if (GetModuleNumber(eqId,iModule)==(Int_t)module) return iModule/2;
725 : }
726 : }
727 0 : return 6; // error
728 2435 : }
729 : //__________________________________________________________________________
730 : UInt_t AliITSRawStreamSPD::GetOnlineChipFromOffline(UInt_t module, UInt_t colM) {
731 : // offline->online (chip)
732 158231 : for (UInt_t eq=0; eq<20; eq++) {
733 1936113 : for (UInt_t iModule=0; iModule<12; iModule++) {
734 865662 : if (GetModuleNumber(eq,iModule)==(Int_t)module) {
735 7235 : if (module<80) {
736 2510 : if (eq<10) { // side A
737 1204 : return (159-colM)/32 + 5*(iModule%2);
738 : }
739 : else { // side C
740 1306 : return colM/32 + 5*(iModule%2);
741 : }
742 : }
743 4725 : else if (module<240) {
744 4725 : if (eq<10) { // side A
745 2334 : return colM/32 + 5*(iModule%2);
746 : }
747 : else { // side C
748 2391 : return (159-colM)/32 + 5*(iModule%2);
749 : }
750 : }
751 : }
752 : }
753 : }
754 0 : return 10; // error
755 7235 : }
756 : //__________________________________________________________________________
757 : UInt_t AliITSRawStreamSPD::GetOnlineColFromOffline(UInt_t module, UInt_t colM) {
758 : // offline->online (col)
759 592 : if (module<80) { // inner layer
760 138 : return colM%32;
761 : }
762 158 : else if (module<240) { // outer layer
763 158 : return colM%32;
764 : }
765 0 : return 32; // error
766 296 : }
767 : //__________________________________________________________________________
768 : UInt_t AliITSRawStreamSPD::GetOnlineRowFromOffline(UInt_t module, UInt_t rowM) {
769 : // offline->online (row)
770 592 : if (module<80) { // inner layer
771 138 : return (255-rowM);
772 : }
773 158 : else if (module<240) { // outer layer
774 158 : return (255-rowM);
775 : }
776 0 : return 256; // error
777 296 : }
778 : //__________________________________________________________________________
779 : UInt_t AliITSRawStreamSPD::GetOfflineModuleFromOnline(UInt_t eqId, UInt_t hs, UInt_t chip) {
780 : // online->offline (module)
781 19077 : if (eqId<20 && hs<6 && chip<10) return fgkDDLModuleMap[eqId][hs*2+chip/5];
782 0 : else return 240;
783 6359 : }
784 : //__________________________________________________________________________
785 : UInt_t AliITSRawStreamSPD::GetOfflineChipKeyFromOnline(UInt_t eqId, UInt_t hs, UInt_t chip) {
786 : // online->offline (chip key: 0-1199)
787 3118 : if (eqId<20 && hs<6 && chip<10) {
788 1559 : UInt_t module = GetOfflineModuleFromOnline(eqId,hs,chip);
789 1559 : UInt_t chipInModule = ( chip>4 ? chip-5 : chip );
790 2406 : if(eqId>9) chipInModule = 4 - chipInModule; // side C only
791 1559 : return (module*5 + chipInModule);
792 0 : } else return 1200;
793 1559 : }
794 : //__________________________________________________________________________
795 : UInt_t AliITSRawStreamSPD::GetOfflineColFromOnline(UInt_t eqId, UInt_t hs, UInt_t chip, UInt_t col) {
796 : // online->offline (col)
797 296 : if (eqId>=20 || hs>=6 || chip>=10 || col>=32) return 160; // error
798 148 : UInt_t offset = 32 * (chip % 5);
799 296 : if (hs<2) {
800 217 : if (eqId<10) {
801 24 : return 159 - (31-col + offset); // inner layer, side A
802 : }
803 : else {
804 45 : return col + offset; // inner layer, side C
805 : }
806 : }
807 : else {
808 79 : if (eqId<10) {
809 29 : return (col + offset); // outer layer, side A
810 : }
811 : else {
812 50 : return 159 - (31-col + offset); // outer layer, side C
813 : }
814 : }
815 148 : }
816 : //__________________________________________________________________________
817 : UInt_t AliITSRawStreamSPD::GetOfflineRowFromOnline(UInt_t eqId, UInt_t hs, UInt_t chip, UInt_t row) {
818 : // online->offline (row)
819 296 : if (eqId>=20 || hs>=6 || chip>=10 || row>=256) return 256; // error
820 148 : return 255-row;
821 148 : }
822 :
|