Added new classes for CPV raw data reconstruction
[u/mrichter/AliRoot.git] / PHOS / PHOSbase / AliPHOSCpvRawStream.h
1 #ifndef ALICPVRAWSTREAM_H
2 #define ALICPVRAWSTREAM_H
3 ///////////////////////////////////////////////////////////////////////////////
4 ///
5 /// This is a class for reading raw data of CPV.
6 /// Author: Mikhail Stolpovskiy, IHEP Protvino (2013)
7 ///
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include <TObject.h>
11 #include <TClonesArray.h>
12 #include <TFile.h>
13 #include "AliPHOSCpvParam.h"
14 #include <AliBitPacking.h>
15 #include <AliFstream.h>
16 #include "AliDAQ.h"
17 #include "AliRawDataHeaderSim.h"
18 #include "AliLog.h"
19
20 #include <assert.h>
21
22 class AliRawReader;
23
24 class AliPHOSCpvRawStream: public TObject {
25  public :
26   AliPHOSCpvRawStream(AliRawReader* rawReader);
27   AliPHOSCpvRawStream();
28   
29   virtual ~AliPHOSCpvRawStream();
30   
31   virtual void     Reset();   // reset raw stream params, reinitalize the containers
32   virtual Bool_t   Next();    // read next DDL raw data from the CPV raw data stream 
33   void     InitVars(Int_t n); // initialise containers
34   void     DelVars();         // delete containers
35   
36    static Int_t GetNErrors() { return kSumErr;} // return the number of max # of Error Types
37
38    Int_t   GetNPads()         const { return fNPads;}         //Get number of pads present in the stream
39    Int_t*  GetPadArray()      const { return fPad;}           //Get pad array from stream decoded
40    Int_t*  GetChargeArray()   const { return fCharge;}        //Get the charge of the pads from dedcoded stream 
41    Int_t*  GetnDDLInStream()  const { return fnDDLInStream;}  //Get the DDL input check array
42    Int_t*  GetnDDLOutStream() const { return fnDDLOutStream;} //Get the DDL output check array
43
44    static inline const Char_t* GetErrName(Int_t eType);
45    inline  Int_t  GetErrors(Int_t ddl,Int_t eType) const;  //Get errors and occurance
46    inline  void   SetZeroSup (Bool_t isSup) {fZeroSup = isSup;}
47    inline  Bool_t GetZeroSup () const       {return fZeroSup;}
48
49    Int_t  GetDDLNumber() const{ return fDDLNumber;} //return the number of DDL actually being decoded
50    UInt_t GetLDCNumber() const{ return fLDCNumber;} //return the number of LDC actually being decoded
51    UInt_t GetTimeStamp() const{ return fTimeStamp;} //return the time stamp of the event actually being decoded
52
53    void   SetTurbo (Bool_t isTurbo) {fTurbo=isTurbo;} // Enable/Disable Turbo
54    Bool_t GetTurbo () { return fTurbo;}
55    Bool_t Turbo();                                    // Read CPV Raw data withour error check
56    Bool_t ReadCPVRawData();                           // Read CPV Raw data
57    Bool_t ReadSegment(Int_t &cntSegment);             // Read Segment (we have one segment per DDL in CPV)
58    Bool_t ReadRow(Int_t &cntRow);                     // Read Row (Row = column controler)
59    Bool_t Read3G(Int_t &cnt3G);                       // Read 3Gassiplex
60
61    Bool_t CheckRow(UInt_t row);                         // Check Row
62    Bool_t Check3G (UInt_t _3G);                         // Check 3Gassiplex
63    Bool_t CheckPad(UInt_t pad);                         // Check pad
64    Bool_t CheckEoE(Int_t &n3G);                         // Check EoE
65    Bool_t CheckRowMarker();                             // Check RowMarker
66    Bool_t CheckSegment();                               // Check Segment
67    void   DumpData(Int_t nw);                           // Dump Data
68    void   StorePosition();                              // Debug purpose
69     
70    Double_t GetDdlDataSize() {return 4.0*fRawDataSize;} //returns the data size for the DDL which is decoded in Next(); fRawDataSize = Bytes/4  
71
72    /*
73    // These methods were in AliHMPIDRawStream and I have not yet re-written them for CPV 
74    inline void WriteRaw           (TObjArray *pDigLst);                                   //write as raw stream     
75    inline void WriteRowMarker     (AliFstream *ddl,UInt_t size);                          //write row marker in simulation
76    inline void WriteEoE           (AliFstream *ddl,UInt_t row,UInt_t dil,UInt_t wordCnt); //write Enf Of Event word in simulation
77    inline void WriteSegMarker     (AliFstream *ddl,UInt_t row, Int_t nwInSeg);            //write Segment Marker word in simulation
78    inline void Write5FirmwareWords(AliFstream *ddl);                                      //write the firmware control words in simulation
79    */
80     
81    enum EDirection {kFwd,kBwd};
82    enum Ebits {kbit0 ,kbit1 ,kbit2 ,kbit3 ,kbit4 ,kbit5 ,kbit6 ,kbit7 , kbit8,
83                kbit9 ,kbit10,kbit11,kbit12,kbit13,kbit14,kbit15,kbit16,
84                kbit17,kbit18,kbit19,kbit20,kbit21,kbit22,kbit23,kbit24,
85                kbit25,kbit26,kbit27,kbit28,kbit29,kbit30,kbit31,kbit32};
86     
87    enum ECPVRawStreamError { kRawDataSizeErr   = 0,  kRowMarkerErr     = 1,  kWrongRowErr      = 2,  kWrong3GErr  = 3,
88                              kWrongPadErr      = 4,  kEoEFlagErr       = 5,  kEoESizeErr       = 6,  kEoE3GErr    = 7,
89                              kEoERowErr        = 8,  kBadSegWordErr    = 9,  kWrongSegErr      = 10, kRowMarkerSizeErr = 11,
90                              kPedQZero         =12,  kSumErr           = 13  //This is always the last one, to retreive the number of errors
91    };                        //Always check the updated list of names in the .cxx file for print-out!
92    
93    enum ECPVRawError {
94      kInvalidRawDataWord = 1
95    };
96
97  private :
98     Bool_t         GetWord(Int_t n=0,EDirection dir=kFwd); // Get n-th word
99     UInt_t         GetNextWord();                          // Get next word
100     Int_t          fNPads;                                 // counter of pads in one DDL
101     Int_t         *fCharge;                                // Array for charge values for all channels in one DDL
102     Int_t         *fPad;                                   // Array for abs pad values for all channels in one DDL
103     Int_t          fDDLNumber;                             // index of current DDL number
104     Int_t         *fnDDLInStream;                          // if the DDL is in the raw data
105     Int_t         *fnDDLOutStream;                         // if the DDL is in the raw data
106     UInt_t         fLDCNumber;                             // index of current LDC number
107     UInt_t         fTimeStamp;                             // TimeStamp
108     AliRawReader  *fRawReader;                             // object for reading the raw data
109     UChar_t       *fData;                                  // raw data
110     Int_t        **fNumOfErr;                              // Store the numner of errors for a given error type and a given DDL
111     Int_t          fPosition;                              // current word
112     UInt_t         fWord;                                  // current position in fData
113     Bool_t         fZeroSup;                               // set if zero suppression is applied
114     Int_t         *fPos;                                   // for debug purposes
115     Int_t          fiPos;                                  // counter for debug
116     Bool_t         fTurbo;                                 // kTRUE = Turbo decoding is called. DEFAULT: kFALSE = normal decoding is called
117     Int_t          fRawDataSize;
118     ClassDef(AliPHOSCpvRawStream, 1) ;  // base class for reading CPV raw digits
119 };
120
121 /*
122 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
123 void AliPHOSCpvRawStream::WriteRowMarker(AliFstream *ddl,UInt_t size)
124 {
125   //Writes the row marker for real data and pedestal into the ddl stream
126   //Arguments: ddl stream and the size of the block of the given row, the size is at least the 10 EoE words!
127   //Returns:   nothing
128   UInt_t w32=0;
129   UInt_t marker=13992;                                   //for pedestal=12968  ==  32a8 for zero suppressed 36a8
130   AliBitPacking::PackWord(size,  w32, 16,31);            //number of roaw written after row marker (digits and EoE)
131   AliBitPacking::PackWord(marker,w32,0,15);              //the marker word
132   ddl->WriteBuffer((char*)&w32,sizeof(w32));              
133 } // WriteRowMarker
134 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
135 void AliPHOSCpvRawStream::WriteEoE(AliFstream *ddl,UInt_t row,UInt_t dil,UInt_t wordCnt  )
136 {
137   //Writes the EoE word from real data and pedestals into the ddl stream
138   //Arguments:  ddl stream, row number, dilogic number and the number of words before the EoE
139   //Retursns:   nothing
140   UInt_t e=1;
141   UInt_t w32=0;
142   assert(1<=row&&row<=24);      AliBitPacking::PackWord((UInt_t)row     ,w32,22,26);    // row number (1...24)
143   assert(1<=dil&&dil<=10);      AliBitPacking::PackWord((UInt_t)dil     ,w32,18,21);    // DILOGIC number (1...10)
144                                 AliBitPacking::PackWord(          e     ,w32, 7,17);   // event number -- not used
145                                 AliBitPacking::PackWord((UInt_t)wordCnt ,w32, 0, 6);  // word counter (0...47)                                                                  AliBitPacking::PackWord((UInt_t)1       ,w32,27,27);  // bit 27 is always 1 by definition of EoE
146                                 AliBitPacking::PackWord((UInt_t)1       ,w32,27,27);  // bit 27 is always 1 by definition of EoE    
147   ddl->WriteBuffer((char*)&w32,sizeof(w32));      
148 } // WriteEoE
149 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++     
150 void AliPHOSCpvRawStream::WriteSegMarker(AliFstream *ddl,UInt_t row, Int_t nwInSeg)
151 {
152   //Writes the segment marker (after 8 rows) into the ddl stream
153   //Arguments: ddl stream and the segment: row 8 -> 0x5800, row 16 -> 5801, row 24 -> 5802 for pedestal
154   //Retruns:   nothing
155     UInt_t w32=0;
156
157       //Segment marker: 2736 == ab0
158       //AliBitPacking::PackWord((UInt_t)0   ,w32,27,31);          //zero out the rest of the bits, since they are not needed
159       AliBitPacking::PackWord((UInt_t)2736   ,w32,20,31);       //ab0 the segment marker word
160       AliBitPacking::PackWord((UInt_t)nwInSeg,w32, 8,19);       //number of words in the segment
161       AliBitPacking::PackWord((UInt_t)(row/8),w32, 0, 7);       //segment 0,1,2    
162       ddl->WriteBuffer((char*)&w32,sizeof(w32)); 
163       //Printf("Segment word created is: %x",w32);
164 }      
165 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++     
166 void AliPHOSCpvRawStream::Write5FirmwareWords(AliFstream *ddl)
167 {
168   //Before each DDL payload 5 words are written: 
169   // 1.) Firmware version,              for sim = 999
170   // 2.) Status and error bits from CD, for sim = 0
171   // 3.) # FEE RESET received         , for sim = 0
172   // 4.) # TTC READY                  , for sim = 0  
173   // 5.) Spare/Reserved               , for sim = 0
174   //Returns:   nothing
175   UInt_t w32=0;
176   AliBitPacking::PackWord((UInt_t)999,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));              
177   AliBitPacking::PackWord((UInt_t) 10,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));              
178   AliBitPacking::PackWord((UInt_t) 11,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));              
179   AliBitPacking::PackWord((UInt_t) 12,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));              
180   AliBitPacking::PackWord((UInt_t) 13,w32,0,31); ddl->WriteBuffer((char*)&w32,sizeof(w32));              
181 } // Write5FirmwareWords
182 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++     
183 void AliPHOSCpvRawStream::WriteRaw(TObjArray *pDigAll)
184 {
185 // Write a list of digits for a given chamber in raw data stream
186 // Arguments: pDigAll- list of digits 
187 // Returns: none      
188   Int_t  ddl,r,d,a;            //32 bits data word 
189   Int_t  cntLpad,cntRpad;
190   Int_t  cntLrow,cntRrow;
191   Int_t  cntL=0,cntR=0;                           //data words counters for DDLs
192   Int_t  cntLeoe,cntReoe;
193   UInt_t posL,posR;
194   UInt_t cntLseg,cntRseg;
195   UInt_t cntwInLseg=0,cntwInRseg=0;
196   Int_t  cntRdig=0,cntLdig=0;
197   
198   UInt_t posLmarker,posRmarker;
199   //  Int_t digcnt=0;
200
201   Int_t isDigThere[14][25][11][48];
202   
203   for(Int_t iCh=AliPHOSCpvParam::kMinCh;iCh<=AliPHOSCpvParam::kMaxCh;iCh++){//chambers loop
204     cntL=0;cntR=0;   
205     for(Int_t iddl=0;iddl<14;iddl++){
206       for(Int_t irow=1;irow<=24;irow++){
207         for(Int_t idil=1;idil<=10;idil++){
208           for(Int_t ipad=0;ipad<48;ipad++){
209             isDigThere[iddl][irow][idil][ipad]=-1;
210           }
211         }
212       }
213     }
214     
215     AliFstream* ddlL;                                 //output streams, 2 per chamber
216     AliFstream* ddlR;                          
217     
218     AliRawDataHeaderSim header; header.SetAttribute(0);  //empty DDL header
219     
220     ddlL = new AliFstream(AliDAQ::DdlFileName("CPV",2*iCh+1)); //left and right looking at the IP
221     ddlR = new AliFstream(AliDAQ::DdlFileName("CPV",2*iCh));   //open both DDL of this chamber in parallel
222     
223     ddlL->WriteBuffer((char*)&header,sizeof(header));            //write dummy header as place holder, actual 
224     ddlR->WriteBuffer((char*)&header,sizeof(header));            //will be rewritten later when total size of DDL is known
225     
226     UInt_t w32=0;                 //32 bits data word 
227     //    digcnt=0;
228     
229     //added frimware control words
230     Write5FirmwareWords(ddlL);  cntL+=5;
231     Write5FirmwareWords(ddlR);  cntR+=5;
232    
233     
234     TClonesArray *pDigCh=(TClonesArray *)pDigAll->At(iCh); //list of digits for current chamber 
235    
236     for(Int_t iDig=0;iDig<pDigCh->GetEntriesFast();iDig++){//digits loop
237       AliHMPIDDigit *pDig1=(AliHMPIDDigit*)pDigCh->At(iDig);
238       pDig1->Raw(w32,ddl,r,d,a);  //??????????
239       isDigThere[ddl][r][d][a]=iDig;
240     }  
241     
242     for(Int_t row = 1; row <= AliPHOSCpvRawStream::kNRows; row++){ //AliPHOSCpvRawStream::kNRows=25!
243       cntRrow=0;cntLrow=0;cntLseg=0;cntRseg=0;// 
244       cntLeoe=0;cntReoe=0;
245       posLmarker=ddlL->Tellp(); WriteRowMarker(ddlL,(UInt_t)1);   cntL++; cntRrow++; cntwInRseg++;
246       posRmarker=ddlR->Tellp(); WriteRowMarker(ddlR,(UInt_t)1);   cntR++; cntLrow++; cntwInLseg++;
247       for(Int_t dil = 1; dil <= AliPHOSCpvRawStream::kNDILOGICAdd; dil++){ //AliPHOSCpvRawStream::kNDILOGICAdd = 11!
248         cntLpad=0;cntRpad=0;
249         for(Int_t pad = 0; pad < AliPHOSCpvRawStream::kNPadAdd; pad++){   //AliPHOSCpvRawStream::kNPadAdd     = 48
250           for ( Int_t iddl=2*iCh; iddl<=2*iCh+1;iddl++){
251             if (isDigThere[iddl][row][dil][pad]!=-1) {
252               AliHMPIDDigit *pDig=(AliHMPIDDigit*)pDigCh->At(isDigThere[iddl][row][dil][pad]);             
253               pDig->Raw(w32,ddl,r,d,a);  
254               if(pDig->Q() < 0 ) continue;                                                 //We can turn of the zero sup for pedestal simulation
255                 if(ddl%2){                                                                               //write raw digit selecting on DDL
256                 ddlL->WriteBuffer((char*)&w32,sizeof(w32));   cntL++; cntLpad++; cntLrow++;  cntLdig++; cntwInLseg++;//Printf(" WL: %x isDig: %d",w32,isDigThere[iddl][row][dil][pad]);
257               }else{
258                 ddlR->WriteBuffer((char*)&w32,sizeof(w32));   cntR++; cntRpad++; cntRrow++;   cntRdig++;cntwInRseg++;//Printf(" WR: %x isDig: %d",w32,isDigThere[iddl][row][dil][pad]);
259               }
260             }//ddl 
261           }//isDig
262         }//pad
263         WriteEoE(ddlL,row,dil,cntLpad); cntL++;  cntLrow++;    cntLeoe++;   cntwInLseg++;                              //molnarl: write EoE markers
264         WriteEoE(ddlR,row,dil,cntRpad); cntR++;  cntRrow++;    cntReoe++;   cntwInRseg++;
265       }//dil
266       if(row%8==0){                                               
267         WriteSegMarker(ddlL,row,cntwInLseg); cntL++;  cntLseg++; cntwInLseg=0;
268         WriteSegMarker(ddlR,row,cntwInRseg); cntR++;  cntRseg++;  cntwInRseg=0; 
269       }
270       posL=ddlL->Tellp();   ddlL->Seekp(posLmarker);    WriteRowMarker(ddlL,(UInt_t)(cntLrow-1)); ddlL->Seekp(posL);      //find the marker position write and  go back to the actual position to continue writing                    
271       posR=ddlR->Tellp();   ddlR->Seekp(posRmarker);    WriteRowMarker(ddlR,(UInt_t)(cntRrow-1)); ddlR->Seekp(posR);                           
272     }//row
273     header.fSize=sizeof(header)+cntL*sizeof(w32); ddlL->Seekp(0); ddlL->WriteBuffer((char*)&header,sizeof(header)); delete ddlL; //rewrite header with size set to
274     header.fSize=sizeof(header)+cntR*sizeof(w32); ddlR->Seekp(0); ddlR->WriteBuffer((char*)&header,sizeof(header)); delete ddlR; //number of bytes and close file
275     
276     //Printf("In Ch %d # digits written to LDD %d RDDL %d",iCh,cntLdig,cntRdig);
277     
278   }//chambers loop
279 }//WriteRaw()
280 */
281
282
283
284 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
285 Int_t AliPHOSCpvRawStream::GetErrors(Int_t ddl,Int_t eType)const
286 {
287 // Return the number of errors for a given error type during raw data reading
288 // Arguments: errorType
289 // Returns: error or -999 if error Type does not exist
290   if(eType < 0 || eType> kSumErr ||  ddl < 0 || ddl > AliPHOSCpvParam::kNDDL-1 ) return -999;
291   else return fNumOfErr[ddl][eType];
292 } //GetErrors()     
293 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
294 const Char_t* AliPHOSCpvRawStream::GetErrName(Int_t eType)
295 {
296   // Return the name of the error for a given error tye during raw data reading
297   // Arguments: errorType
298   // Returns: error or -999 if error Type does not exist
299   const Char_t *eName[]={ "Raw data size = 0",  "Wrong row marker" , "Wrong row index" , "Wrong 3G index",
300                     "Wrong pad index","Missing end-of-event flag","Wrong end-of-event word-count","kEoE3GErr",
301                     "kEoERowErr"     ,  "kBadSegWordErr", "Segment error" , "Number of words in a row exceeds the expected value",
302                     "Ped = 0"      ,  "kSumErr"        };                       
303   const Char_t *eNoErr="NotDefinedErrorType";
304   if(eType<0 || eType>kSumErr) return eNoErr;
305   else                         return eName[eType];
306 }//GetErrName()
307 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
308     
309 #endif