Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PHOS / AliPHOSCpvRawWrite.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 /* History:
19  *
20  * $Log$
21  */
22
23 //_________________________________________________________________________
24 //  Create a raw data stream for the CPV detector
25 //  Input:  AliPHOSDigit or TClonesArray of AliPHOSDigits
26 //  Output: AliFstream, a raw data stream in DDL format
27 //  Number of CPV modules          :  5
28 //  Number of DDL per CPV module   :  1
29 //  Number of rows per DDL         : 16
30 //  Number of Dilogic chips per row: 10
31 //  Number of pads per Dilogic     : 48 (nX,nZ)=(8,6)
32 //--
33 //  Author: Yuri Kharlov
34 //  Reimplemented from AliHMPIDRawStream
35 //  6 July 2008
36 //_________________________________________________________________________
37
38 // --- ROOT system ---
39
40 #include "TObject.h"
41 #include "TClonesArray.h"
42
43 // --- Standard library ---
44 #include <assert.h>
45
46 // --- AliRoot header files ---
47 #include "AliBitPacking.h"
48 #include "AliDAQ.h"
49 #include "AliFstream.h"
50 #include "AliRawDataHeaderSim.h"
51 #include "AliPHOSCpvRawWrite.h"
52 #include "AliPHOSDigit.h"
53 #include "AliPHOSGeometry.h"
54
55 ClassImp(AliPHOSCpvRawWrite)
56
57 //____________________________________________________________________________
58 AliPHOSCpvRawWrite::AliPHOSCpvRawWrite() : 
59   TObject(),
60   fNDDL(5),
61   fNRow(16),
62   fNDilogic(10),
63   fNPad(48)
64 {
65   // ctor
66 }
67
68 //____________________________________________________________________________
69 AliPHOSCpvRawWrite::~AliPHOSCpvRawWrite()
70 {
71   // dtor
72 }
73
74 //____________________________________________________________________________
75 void AliPHOSCpvRawWrite::WriteRaw(const TObjArray *pDigAll)
76 {
77 // Write a list of digits for a given chamber in raw data stream
78 // Arguments: pDigAll- list of digits as TObjArray of 5 TClonesArray's
79 // Returns: none
80
81   AliPHOSGeometry *geom;
82   if (!(geom = AliPHOSGeometry::GetInstance())) 
83         geom = AliPHOSGeometry::GetInstance("IHEP","");
84
85   Int_t  ddl,row,dilogic,address; //32-bits data word 
86   Int_t  cntLpad;
87   Int_t  cntLrow;
88   Int_t  cntL=0;        //data words counters for DDLs
89   Int_t  cntLeoe;
90   UInt_t posL;
91   UInt_t cntLseg;
92   UInt_t cntwInLseg=0;
93   Int_t  cntLdig=0;
94   
95   UInt_t posLmarker;
96   Int_t  digcnt=0;
97
98   Int_t isDigThere[5][16][10][48];
99   
100   Int_t relId[4];
101
102   for(Int_t iCh=0;iCh<fNDDL;iCh++){//chambers loop
103     cntL=0;
104     for(Int_t irow=0; irow<fNRow; irow++){
105       for(Int_t idil=0; idil<fNDilogic; idil++){
106         for(Int_t ipad=0; ipad<fNPad; ipad++){
107           isDigThere[iCh][irow][idil][ipad]=-1;
108         }
109       }
110     }
111     
112     AliFstream* ddlL;                                 //output stream
113     
114     AliRawDataHeaderSim header; header.SetAttribute(0);  //empty DDL header
115     
116     ddlL = new AliFstream(AliDAQ::DdlFileName("CPV",iCh));
117
118     //write dummy header as place holder, actual header
119     //will be rewritten later when total size of DDL is known
120
121     ddlL->WriteBuffer((char*)&header,sizeof(header));
122     
123     UInt_t w32=0;                 //32 bits data word 
124     digcnt=0;
125     
126     TClonesArray *pDigCh=(TClonesArray *)pDigAll->At(iCh); //list of digits for current chamber 
127    
128     for(Int_t iDig=0;iDig<pDigCh->GetEntriesFast();iDig++){//digits loop
129       AliPHOSDigit *pDig1=(AliPHOSDigit*)pDigCh->At(iDig);
130       HWaddress(pDig1,w32,ddl,row,dilogic,address);
131       isDigThere[ddl][row][dilogic][address]=iDig;
132     }  
133     
134     Int_t cntRrow, cntLrow, cntLseg, cntLeoe, cntL, cntwInLseg;
135     for(Int_t row = 0; row < fNRow; row++){ //AliHMPIDRawStream::kNRows=25!
136       cntRrow=0;cntLrow=0;cntLseg=0,cntLeoe=0;
137       posLmarker=ddlL->Tellp(); WriteRowMarker(ddlL,(UInt_t)1);   cntL++; cntLrow++; cntwInLseg++;
138       for(Int_t dil = 0; dil < fNDilogic; dil++){
139         cntLpad=0;
140         for(Int_t pad = 0; pad < fNPad; pad++){
141           if (isDigThere[iCh][row][dil][pad]!=-1) {
142             AliPHOSDigit *pDig=(AliPHOSDigit*)pDigCh->At(isDigThere[iCh][row][dil][pad]);             
143             HWaddress(pDig,w32,iCh,row,dil,pad);
144             if(pDig->GetAmp() < 0 ) continue;  //We can turn of the zero sup for pedestal simulation
145             ddlL->WriteBuffer((char*)&w32,sizeof(w32));   cntL++; cntLpad++; cntLrow++;  cntLdig++; cntwInLseg++;
146           }//isDig
147         }//pad
148         WriteEoE(ddlL,row,dil,cntLpad); cntL++;  cntLrow++;    cntLeoe++;   cntwInLseg++; // write EoE markers
149       }//dil
150       if(row%8==0){  // Why %8 ???
151         WriteSegMarker(ddlL,row,cntwInLseg); cntL++;  cntLseg++; cntwInLseg=0;
152       }
153       // Find the marker position write and  go back to the actual position to continue writing                    
154       posL=ddlL->Tellp();   ddlL->Seekp(posLmarker);    WriteRowMarker(ddlL,(UInt_t)(cntLrow-1)); ddlL->Seekp(posL);
155     }//row
156     //rewrite header with size set to
157     header.fSize=sizeof(header)+cntL*sizeof(w32); ddlL->Seekp(0); ddlL->WriteBuffer((char*)&header,sizeof(header)); delete ddlL;
158     
159   }//chambers loop
160 }//WriteRaw()
161
162 //____________________________________________________________________________
163 void AliPHOSCpvRawWrite::HWaddress(const AliPHOSDigit *digit, 
164                                    UInt_t &w32, Int_t &ddl, Int_t &row, Int_t &dilogic, Int_t &address)
165 {
166 // Convert AliPHOSDigit to raw word format
167 // Arguments: w32,ddl,row,dilogic,address where to write the results
168
169   AliPHOSGeometry *geom;
170   if (!(geom = AliPHOSGeometry::GetInstance())) 
171         geom = AliPHOSGeometry::GetInstance("IHEP","");
172
173   Int_t relid[4] ;
174   geom->AbsToRelNumbering(digit->GetId(), relid) ;
175   if (relid[0]<geom->GetNModules()) Error("HWaddress","Digit does not belong to CPV!");
176
177   Int_t module = relid[0];
178   Int_t cellX  = relid[2];
179   Int_t cellZ  = relid[3];
180   UInt_t charge = (UInt_t)digit->GetAmp();
181
182   ddl     = module-1;                      // DDL# 0..4
183   row     = (cellX-1)/8;                   // row# 0..16
184   dilogic = (cellZ-1)/6;                   // Dilogic# 0..10
185   address = (cellX-1)%6 + 6*((cellZ-1)%8); // Address 0..47
186   
187   w32=0;
188   AliBitPacking::PackWord(charge ,w32, 0,11); // 0000 0rrr rrdd ddaa aaaa qqqq qqqq qqqq  Qdc          bits (00..11) counts (0..4095)
189   assert(0<=address && address<fNPad);
190   AliBitPacking::PackWord(address,w32,12,17); // 3322 2222 2222 1111 1111 1000 0000 0000  DILOGIC addr bits (12..17) counts (0..47)
191   assert(0<=dilogic && dilogic<fNDilogic);
192   AliBitPacking::PackWord(dilogic,w32,18,21); // 1098 7654 3210 9876 5432 1098 7654 3210  DILOGIC No.  bits (18..21) counts (1..10)
193   assert(0<=row && row<fNRow);
194   AliBitPacking::PackWord(row ,w32,22,26); //                                          Row No.   bits (22..26) counts (1..24)
195   AliBitPacking::PackWord((UInt_t)0, w32,27,27);  //To make sure set the 27th bit to Zero so we can distinguish it from the EoE
196 }
197
198 //____________________________________________________________________________
199 void AliPHOSCpvRawWrite::WriteEoE(AliFstream *ddl,UInt_t row,UInt_t dil,UInt_t wordCnt  )
200 {
201   //Writes the EoE word from real data and pedestals into the ddl stream
202   //Arguments:  ddl stream, row number, dilogic number and the number of words before the EoE
203   //Returns:   nothing
204   UInt_t e=1;
205   UInt_t w32=0;
206   assert(0<=row&&row<=fNRow);
207   AliBitPacking::PackWord((UInt_t)row     ,w32,22,26);  // row number (1...24)
208   assert(0<=dil&&dil<=fNDilogic);
209   AliBitPacking::PackWord((UInt_t)dil     ,w32,18,21);  // DILOGIC number (1...10)
210   AliBitPacking::PackWord(          e     ,w32, 7,17);  // event number -- not used
211   AliBitPacking::PackWord((UInt_t)wordCnt ,w32, 0, 6);  // word counter (0...47)
212   AliBitPacking::PackWord((UInt_t)1       ,w32,27,27);  // bit 27 is always 1 by definition of EoE
213   ddl->WriteBuffer((char*)&w32,sizeof(w32));      
214 }
215
216 //____________________________________________________________________________
217 void AliPHOSCpvRawWrite::WriteRowMarker(AliFstream *ddl,UInt_t size)
218 {
219   //Writes the row marker for real data and pedestal into the ddl stream
220   //Arguments: ddl stream and the size of the block of the given row, the siye is at least the 10 EoE words!
221   //Returns:   nothing
222
223   UInt_t w32=0;
224   UInt_t marker=13992;                         //for pedestal=12968  ==  32a8 for zero suppressed 36a8
225   AliBitPacking::PackWord(size,  w32, 16,31);  //number of roaw written after row marker (digits and EoE)
226   AliBitPacking::PackWord(marker,w32,0,15);    //the marker word
227   ddl->WriteBuffer((char*)&w32,sizeof(w32));              
228 }
229
230 //____________________________________________________________________________
231 void AliPHOSCpvRawWrite::WriteSegMarker(AliFstream *ddl,UInt_t row, Int_t nwInSeg)
232 {
233   //Writes the segment marker (after 8 rows) into the ddl stream
234   //Arguments: ddl stream and the segment: row 8 -> 0x5800, row 16 -> 5801, row 24 -> 5802 for pedestal
235   //Returns:   nothing
236   UInt_t w32=0;
237   
238   //Segment marker: 2736 == ab0
239   AliBitPacking::PackWord((UInt_t)2736   ,w32,20,31); //ab0 the segment marker word
240   AliBitPacking::PackWord((UInt_t)nwInSeg,w32, 8,19); //number of words in the segment
241   AliBitPacking::PackWord((UInt_t)(row/8),w32, 0, 7); //segment 0,1,2    
242   ddl->WriteBuffer((char*)&w32,sizeof(w32)); 
243   //Printf("Segment word created is: %x",w32);
244 }