5dfe3dd37bc09ddca5983edea795433c992a1a0b
[u/mrichter/AliRoot.git] / ZDC / AliZDCRawStream.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // This class provides access to ZDC digits in raw data.                     //
21 //                                                                           //
22 // It loops over all ZDC digits in the raw data given by the AliRawReader.   //
23 // The Next method goes to the next digit. If there are no digits left       //
24 // it returns kFALSE.                                                        //
25 // Getters provide information about the current digit.                      //
26 //                                                                           //
27 ///////////////////////////////////////////////////////////////////////////////
28
29 #include "AliZDCRawStream.h"
30 #include "AliRawReader.h"
31 #include "AliRawDataHeader.h"
32 #include "AliRawEventHeaderBase.h"
33 #include "AliLog.h"
34
35 ClassImp(AliZDCRawStream)
36
37
38 //_____________________________________________________________________________
39 AliZDCRawStream::AliZDCRawStream(AliRawReader* rawReader) :
40   fRawReader(rawReader),
41   fBuffer(0),
42   fEvType(0),
43   fPosition(0),
44   fIsCalib(kFALSE),
45   fIsDARCHeader(kFALSE),
46   fIsChMapping(kFALSE),
47   fIsADCDataWord(kFALSE),
48   fIsADCHeader(kFALSE),
49   fIsADCEOB(kFALSE),
50   fDARCEvBlockLenght(0),  
51   fDARCBlockAttributes(0),
52   fDeadfaceOffset(0),
53   fDeadbeefOffset(0),
54   fDataOffset(0),
55   fModType(-1),
56   fADCModule(-1),
57   fADCNChannels(-1),     
58   fADCChannel(-1),       
59   fADCValue(-1),         
60   fADCGain(-1),
61   fNConnCh(-1),
62   fCabledSignal(-1)
63 {
64   // Create an object to read ZDC raw digits
65   fRawReader->Reset();
66   fRawReader->Select("ZDC");
67   //
68   for(Int_t i=0; i<48; i++){
69     for(Int_t j=0; j<3; j++) fMapADC[i][j]=-1;
70   }
71
72 }
73
74 //_____________________________________________________________________________
75 AliZDCRawStream::AliZDCRawStream(const AliZDCRawStream& stream) :
76   TObject(stream),
77   fRawReader(stream.fRawReader),
78   fBuffer(stream.GetRawBuffer()),
79   fEvType(stream.fEvType),
80   fPosition(stream.fPosition),
81   fIsCalib(stream.fIsCalib),
82   fIsDARCHeader(stream.fIsDARCHeader), 
83   fIsChMapping(stream.fIsChMapping),
84   fIsADCDataWord(stream.fIsADCDataWord), 
85   fIsADCHeader(stream.fIsADCHeader), 
86   fIsADCEOB(stream.fIsADCEOB), 
87   fDARCEvBlockLenght(stream.fDARCEvBlockLenght),  
88   fDARCBlockAttributes(stream.fDARCBlockAttributes),
89   fDeadfaceOffset(stream.GetDeadfaceOffset()),
90   fDeadbeefOffset(stream.GetDeadbeefOffset()),
91   fDataOffset(stream.GetDataOffset()),
92   fModType(stream.GetModType()),
93   fADCModule(stream.GetADCModule()),     
94   fADCNChannels(stream.GetADCNChannels()),       
95   fADCChannel(stream.GetADCChannel()),   
96   fADCValue(stream.GetADCValue()),       
97   fADCGain(stream.GetADCGain()),
98   fNConnCh(stream.fNConnCh),
99   fCabledSignal(stream.GetCabledSignal())
100 {
101   // Copy constructor
102   for(Int_t j=0; j<2; j++) fSector[j] = stream.GetSector(j);     
103   for(Int_t i=0; i<48; i++){
104     for(Int_t j=0; j<3; j++) fMapADC[i][j] = stream.fMapADC[i][j];
105   }
106 }
107
108 //_____________________________________________________________________________
109 AliZDCRawStream& AliZDCRawStream::operator = (const AliZDCRawStream& 
110                                               /* stream */)
111 {
112   // Assignment operator
113   Fatal("operator =", "assignment operator not implemented");
114   return *this;
115 }
116
117 //_____________________________________________________________________________
118 AliZDCRawStream::~AliZDCRawStream()
119 {
120 // Destructor
121
122 }
123
124 //_____________________________________________________________________________
125 void AliZDCRawStream::ReadCDHHeader()
126 {
127   // Reading CDH 
128   const AliRawDataHeader* header = fRawReader->GetDataHeader();
129   if(!header) {
130       AliError("\t No CDH in raw data streaming\n");
131       fRawReader->AddMajorErrorLog(kCDHError);
132       //
133       // For the moment to debug the classe the event is read
134       // also if the CDH is not present in the data buffer
135       // ******* TO BE CHANGED!!! ***************************
136       //return;
137   }
138   else{
139     //printf("\t AliZDCRawStream::ReadCDHHeader -> Data Size = %d\n",fRawReader->GetDataSize());
140
141     fDARCEvBlockLenght = header->fSize;
142     //printf("\t AliZDCRawStream::ReadCDHHeader -> fDARCEvBlockLenght = %d\n",fDARCEvBlockLenght);
143     
144     //UChar_t message = header->GetAttributes();
145     //printf("\t AliZDCRawStream::ReadCDHHeader -> Attributes %x\n",message);
146     
147     /*if(message & 0x10){ // COSMIC RUN
148        printf("\t STANDALONE_COSMIC RUN raw data found\n");
149     }
150     else if(message & 0x20){ // PEDESTAL RUN
151        printf("\t STANDALONE_PEDESTAL RUN raw data found\n");
152     }
153     else if(message & 0x30){ // LASER RUN
154        printf("\t STANDALONE_LASER RUN raw data found\n");
155     }*/
156     
157     if(header->GetL1TriggerMessage() & 0x1){ // Calibration bit set in CDH
158       fIsCalib = kTRUE;
159     }
160     //printf("\t AliZDCRawStream::ReadCDHHeader -> L1TriggerMessage %x\n",header->GetL1TriggerMessage());
161     printf("\t AliZDCRawStream::ReadCDHHeader -> Calibration bit = %d\n",fIsCalib);
162     
163     
164     UInt_t status = header->GetStatus();
165     //printf("\t AliZDCRawStream::ReadCDHHeader -> status = %d\n",status);
166     if(status & 0x000f == 0x0001){
167       AliWarning("CDH -> DARC trg0 overlap error\n");
168       fRawReader->AddMajorErrorLog(kDARCError);
169     }
170     if(status & 0x000f == 0x0002){
171       AliWarning("CDH -> DARC trg0 missing error\n");
172       fRawReader->AddMajorErrorLog(kDARCError);
173     }
174     if(status & 0x000f == 0x0004){
175       AliWarning("CDH -> DARC data parity error\n");
176       fRawReader->AddMajorErrorLog(kDARCError);
177     }
178     if(status & 0x000f == 0x0008){
179       AliWarning("CDH -> DARC ctrl parity error\n");
180       fRawReader->AddMajorErrorLog(kDARCError);
181     }
182     //
183     if(status & 0x00f0 == 0x0010){
184       AliWarning("CDH -> DARC trg unavailable\n");
185       fRawReader->AddMajorErrorLog(kDARCError);
186     }
187     if(status & 0x00f0 == 0x0020){
188       AliWarning("CDH -> DARC FEE error\n");
189       fRawReader->AddMajorErrorLog(kDARCError);
190     }
191     //
192     if(status & 0x0f00 == 0x0200){
193       AliWarning("CDH -> DARC L1 time violation\n");
194       fRawReader->AddMajorErrorLog(kDARCError);
195     }
196     if(status & 0x0f00 == 0x0400){
197       AliWarning("CDH -> DARC L2 time-out\n");
198       fRawReader->AddMajorErrorLog(kDARCError);
199     }
200     if(status & 0x0f00 == 0x0800){
201       AliWarning("CDH -> DARC prepulse time violation\n");
202       fRawReader->AddMajorErrorLog(kDARCError);
203     }
204     //
205     if(status & 0xf000 == 0x1000){
206       AliWarning("CDH -> DARC other error\n");
207       fRawReader->AddMajorErrorLog(kDARCError);
208     }
209   }
210   //
211   fIsDARCHeader = kTRUE;
212 }
213
214
215 //_____________________________________________________________________________
216 Bool_t AliZDCRawStream::Next()
217 {
218   // Read the next raw digit
219   // Returns kFALSE if there is no digit left
220
221   if(!fRawReader->ReadNextInt((UInt_t&) fBuffer)) return kFALSE;
222   fIsChMapping = kFALSE; fIsADCHeader = kFALSE; 
223   fIsADCDataWord = kFALSE; fIsADCEOB = kFALSE;
224   
225   fEvType = fRawReader->GetType();
226   //printf("\n\t AliZDCRawStream::Next() -> ev. type %d\n",fEvType);
227   
228   if(fPosition==0){
229     //if(fEvType==7 || fEvType ==8){ //Physics or calibration event
230       //ReadEventHeader();
231       ReadCDHHeader();
232     //}
233     fNConnCh=0;
234   }
235   //printf("\n  AliZDCRawStream::Next() - fBuffer[%d] = %x\n",fPosition, fBuffer);
236   
237   // -------------------------------------------
238   // --- DARC header
239   // -------------------------------------------
240   if(fIsDARCHeader){
241     //printf("\t ---- DARC header ----\n");
242     if(fIsCalib){
243       fDeadfaceOffset = 9;
244       fDeadbeefOffset = 25;
245     }
246     else{
247       fDeadfaceOffset = 1;
248       fDeadbeefOffset = 7;
249     }
250     fDataOffset = 1+fDeadbeefOffset;
251     fIsDARCHeader = kFALSE;
252   }
253   
254     
255   // -------------------------------------------
256   // --- Start of data event
257   // --- decoding mapping of connected ADC ch.
258   // -------------------------------------------
259   if(fEvType==10){
260     if(fPosition>fDataOffset){
261       if((fBuffer&0xff000000) == 0xff000000){
262         if(fPosition==(fDataOffset+1)){ 
263            printf("\n\n\t Reading ZDC mapping from StartOfData event\n");
264            fNConnCh=0;  
265         }
266         else{
267           //printf("\n\t End of StartOfData event\n\n");
268           return kTRUE;
269         }
270       }
271       else if((fBuffer&0x80000000)>>31 == 1){
272         // Mapping identification
273         fADCModule = ((fBuffer & 0x7f000000)>>24);
274         fModType = ((fBuffer & 0xfff000)>>8);
275         fADCNChannels = (fBuffer & 0xff);
276         //
277         //printf("\tGEO %d, mod. type %d, #ch. %d\n",fADCModule,fModType,fADCNChannels);
278       }
279       else if(fModType==0 && (fBuffer&0x80000000)>>31 == 0){
280         // Channel signal
281         if((fBuffer&0x40000000)>>30==0){ // high range chain ADC
282           fIsChMapping = kTRUE;
283           fADCChannel = ((fBuffer & 0x3fff0000)>>16);
284           fCabledSignal = (fBuffer&0xffff);
285           fMapADC[fNConnCh][0] = fADCModule;
286           fMapADC[fNConnCh][1] = fADCChannel;
287           fMapADC[fNConnCh][2] = fCabledSignal;
288           //printf("  RawData%d mod. %d ch. %d signal %d\n",fNConnCh,fADCModule,
289            // fADCChannel, fBuffer&0xffff);
290           //
291           fNConnCh++;
292           if(fNConnCh>48){
293             // Protection manually set since it returns:
294             // RawData48 mod. 3 ch. 2048 signal 515
295             // to be checked with Pietro!!!!!!!!!!!!!!!!!!!!!!!
296             AliWarning("\t AliZDCRawStream -> ERROR: no. of cabled channels > 48!!!\n");
297             return kFALSE;
298           }
299         }
300       }
301     }
302     fPosition++;
303     return kTRUE;
304   }
305   
306   // -------------------------------------------
307   // --- DARC data
308   // -------------------------------------------
309   if(fPosition<fDeadfaceOffset){
310     fPosition++;
311     return kTRUE;
312   }
313   else if(fPosition==fDeadfaceOffset){
314     if(fBuffer != 0xdeadface){
315       AliWarning("AliZDCRawStream -> NO deadface after DARC data\n");
316       fRawReader->AddMajorErrorLog(kDARCError);  
317     }
318     else{
319       fPosition++;
320       return kTRUE;
321     }
322   }
323   
324   // -------------------------------------------
325   // --- DARC global data
326   // -------------------------------------------
327   else if(fPosition>fDeadfaceOffset && fPosition<fDeadbeefOffset){
328     fPosition++;
329     return kTRUE;
330   }
331   else if(fPosition==fDeadbeefOffset){
332     if(fBuffer != 0xdeadbeef){
333       AliWarning("AliZDCRawStream -> NO deadbeef after DARC global data\n");
334       fRawReader->AddMajorErrorLog(kDARCError);  
335     }
336     else{
337       fPosition++;
338       return kTRUE;
339     }
340   }
341
342   // -------------------------------------------
343   // --- ZDC data
344   // --- ADC buffer + scaler
345   // -------------------------------------------
346   else if(fPosition>=fDataOffset){
347   
348     // Not valid datum before the event 
349     // there MUST be a NOT valid datum before the event!!!
350     if(fPosition==fDataOffset){
351       //printf("\t **** ZDC data begin ****\n");
352       if((fBuffer & 0x07000000) == 0x06000000){
353         //printf("    AliZDCRawStream -> Not valid datum in ADC %d,"
354         //       "position %d in word data buffer\n",fADCModule,fPosition);
355       }
356       else fRawReader->AddMajorErrorLog(kZDCDataError);
357     }
358     
359     // If the not valid datum isn't followed by the 1st ADC header
360     // the event is corrupted (i.e., 2 gates arrived before trigger)
361     else if(fPosition==fDataOffset+1){
362       if((fBuffer & 0x07000000) != 0x02000000){
363         AliWarning("ZDC ADC -> The not valid datum is NOT followed by an ADC header!\n");
364         fRawReader->AddMajorErrorLog(kZDCDataError);
365       }
366     }
367      
368     // Get geo address of current word to determine
369     // if it is a scaler word (geo address == kScalerAddress)
370     // if it is an ADC word (geo address != 8)
371     Int_t kScalerAddress=8;
372     fADCModule = ((fBuffer & 0xf8000000)>>27);
373     if(fADCModule == kScalerAddress){
374       DecodeScaler();
375     }
376     else{//ADC module
377       // *** End of event
378       if(fBuffer == 0xcafefade){
379         //printf("  AliZDCRawStream ->  End of ZDC event!\n");
380       }
381       // *** ADC header
382       else if((fBuffer & 0x07000000) == 0x02000000){
383         fIsADCHeader = kTRUE;
384         fADCNChannels = ((fBuffer & 0x00003f00)>>8);
385         //printf("  AliZDCRawStream -> HEADER: ADC mod.%d has %d ch. \n",fADCModule,fADCNChannels);
386       }
387       // *** ADC data word
388       else if((fBuffer & 0x07000000) == 0x00000000){
389         fIsADCDataWord = kTRUE;
390         fADCChannel = ((fBuffer & 0x1e0000) >> 17);
391         fADCGain = ((fBuffer & 0x10000) >> 16);       
392         fADCValue = (fBuffer & 0xfff);  
393         
394         //printf("  AliZDCRawStream -> DATA: ADC mod. %d ch. %d gain %d value %d\n",
395         //  fADCModule,fADCChannel,fADCGain,fADCValue);
396
397         // Valid ADC data (not underflow nor overflow)
398         if(!(fBuffer & 0x1000) && !(fBuffer & 0x2000)){ 
399           Int_t indSig = -1;
400           for(Int_t k=0; k<48; k++){
401              if(fMapADC[k][0]==fADCModule && fMapADC[k][1]==fADCChannel){
402                //
403                for(Int_t ci=0; ci<48; ci++)
404                 //printf("  %d mod. %d ch. %d signal %d\n",ci,fMapADC[ci][0],
405                 //fMapADC[ci][1], fMapADC[ci][2]);
406
407                indSig=k;
408                break;
409              } 
410           }
411           // ++++++++++++++++++++++++++++++++++++++++++++++++++++++
412           //    To understand the assignment of fSector[i]
413           //   have a look at the enum in AliZDCRawStream.h
414           //   fSector[0] = 1(ZNC+PMRefC), 2(ZPC), 3(ZEM), 
415           //                4(ZNA+PMRefA), 5(ZPA)
416           // ++++++++++++++++++++++++++++++++++++++++++++++++++++++
417           if((fMapADC[indSig][2]>=2 && fMapADC[indSig][2]<=6) || (fMapADC[indSig][2]>=26 && fMapADC[indSig][2]<=30) 
418             || fMapADC[indSig][2]==24 || fMapADC[indSig][2]==48){
419             fSector[0] = 4; 
420             //
421             if(fMapADC[indSig][2]==2 || fMapADC[indSig][2]==26) fSector[1]=0;
422             else if(fMapADC[indSig][2]==3 || fMapADC[indSig][2]==27) fSector[1]=1;
423             else if(fMapADC[indSig][2]==4 || fMapADC[indSig][2]==28) fSector[1]=2;
424             else if(fMapADC[indSig][2]==5 || fMapADC[indSig][2]==29) fSector[1]=3;
425             else if(fMapADC[indSig][2]==6 || fMapADC[indSig][2]==30) fSector[1]=4;
426             else if(fMapADC[indSig][2]==24 || fMapADC[indSig][2]==48) fSector[1]=5;
427           }
428           else if((fMapADC[indSig][2]>=7 && fMapADC[indSig][2]<=11) || (fMapADC[indSig][2]>=31 && fMapADC[indSig][2]<=35)){
429             fSector[0] = 5; 
430             //
431             if(fMapADC[indSig][2]==7 || fMapADC[indSig][2]==31) fSector[1]=0;
432             else if(fMapADC[indSig][2]==8 || fMapADC[indSig][2]==32) fSector[1]=1;
433             else if(fMapADC[indSig][2]==9 || fMapADC[indSig][2]==33) fSector[1]=2;
434             else if(fMapADC[indSig][2]==10 || fMapADC[indSig][2]==34) fSector[1]=3;
435             else if(fMapADC[indSig][2]==11 || fMapADC[indSig][2]==35) fSector[1]=4;
436           }
437           else if((fMapADC[indSig][2]>=12 && fMapADC[indSig][2]<=16) || (fMapADC[indSig][2]>=36 && fMapADC[indSig][2]<=40) 
438             || fMapADC[indSig][2]==25 || fMapADC[indSig][2]==49){
439             fSector[0] = 1; 
440             //
441             if(fMapADC[indSig][2]==12 || fMapADC[indSig][2]==36) fSector[1]=0;
442             else if(fMapADC[indSig][2]==13 || fMapADC[indSig][2]==37) fSector[1]=1;
443             else if(fMapADC[indSig][2]==14 || fMapADC[indSig][2]==38) fSector[1]=2;
444             else if(fMapADC[indSig][2]==15 || fMapADC[indSig][2]==39) fSector[1]=3;
445             else if(fMapADC[indSig][2]==16 || fMapADC[indSig][2]==40) fSector[1]=4;
446             else if(fMapADC[indSig][2]==25 || fMapADC[indSig][2]==49) fSector[1]=5;
447           }
448           else if((fMapADC[indSig][2]>=17 && fMapADC[indSig][2]<=21) || (fMapADC[indSig][2]>=41 && fMapADC[indSig][2]<=45)){
449             fSector[0] = 2; 
450             //
451             if(fMapADC[indSig][2]==17 || fMapADC[indSig][2]==41) fSector[1]=0;
452             else if(fMapADC[indSig][2]==18 || fMapADC[indSig][2]==42) fSector[1]=1;
453             else if(fMapADC[indSig][2]==19 || fMapADC[indSig][2]==43) fSector[1]=2;
454             else if(fMapADC[indSig][2]==20 || fMapADC[indSig][2]==44) fSector[1]=3;
455             else if(fMapADC[indSig][2]==21 || fMapADC[indSig][2]==45) fSector[1]=4;
456           }
457           else if(fMapADC[indSig][2]==22 || fMapADC[indSig][2]==23 || fMapADC[indSig][2]==46 || fMapADC[indSig][2]==47){
458             fSector[0] = 3; 
459             //
460             if(fMapADC[indSig][2]==22 || fMapADC[indSig][2]==46) fSector[1]=1;
461             else if(fMapADC[indSig][2]==23 || fMapADC[indSig][2]==49) fSector[1]=2;
462           }
463           //
464           //printf("\t Signal %d -> fSector[0] %d, fSector[1] %d\n", fMapADC[indSig][2], fSector[0], fSector[1]);
465           
466           if(fADCModule<0 || fADCModule>3){
467             AliWarning(Form("    AliZDCRawStream -> No valid ADC module: %d\n",fADCModule));
468             fRawReader->AddMajorErrorLog(kInvalidADCModule);
469           }
470
471         }//No underflow nor overflow    
472       }//ADC data word
473       // *** ADC EOB
474       else if((fBuffer & 0x07000000) == 0x04000000){
475         fIsADCEOB = kTRUE;
476         //printf("  AliZDCRawStream -> EOB --------------------------\n");
477       }
478      }//ADC module
479         
480     
481   }
482   fPosition++;
483
484   return kTRUE;
485 }