Bug fixes
[u/mrichter/AliRoot.git] / PMD / AliPMDDDLRawData.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 #include <Riostream.h>
17 #include <TClonesArray.h>
18 #include <TTree.h>
19 #include <TBranch.h>
20 #include <TMath.h>
21
22 #include "AliPMDdigit.h"
23 #include "AliPMDDDLRawData.h"
24
25
26 ClassImp(AliPMDDDLRawData)
27
28 AliPMDDDLRawData::AliPMDDDLRawData():
29   fDigits(new TClonesArray("AliPMDdigit", 1000))
30 {
31   // Default Constructor
32   //
33 }
34 //____________________________________________________________________________
35
36 AliPMDDDLRawData::~AliPMDDDLRawData()
37 {
38   // Default Destructor
39   //
40
41 }
42
43 //____________________________________________________________________________
44 void AliPMDDDLRawData::WritePMDRawData(TTree *treeD, Int_t evtno)
45 {
46   // write digits into raw data format
47
48   ofstream outfile;
49
50   TBranch *branch = treeD->GetBranch("PMDDigit");
51   if (!branch) return;
52   branch->SetAddress(&fDigits);  
53   
54   Int_t   nmodules = (Int_t) treeD->GetEntries();
55   //  cout << " nmodules = " << nmodules << endl;
56
57   const Int_t kSize         = 4608;
58   const Int_t kDDL          = 6;
59   Int_t modulePerDDL        = 0;
60
61
62   UInt_t sizeRawData = 0;
63   UInt_t magicWord   = 0x123456;
64   UInt_t detectorID  = 0;
65   UInt_t ddlID       = 0;
66   Int_t  flag        = 0;
67   Int_t  version     = 1;
68   UInt_t mHSize      = 3*sizeof(UInt_t);
69   Int_t  totword     = 0;
70
71   UInt_t miniHeader[3];
72   UInt_t buffer[kSize];
73
74   Char_t filename[80];
75
76   Int_t mmodule = 0;
77   for(Int_t iddl = 0; iddl < kDDL; iddl++)
78     {
79       sprintf(filename,"Ev%dPMDddl%d.dat",evtno,iddl);
80 #ifndef __DECCXX
81       outfile.open(filename,ios::binary);
82 #else
83       outfile.open(filename);
84 #endif
85       
86       if (iddl < 4)
87         {
88           modulePerDDL = 6;
89           mmodule = 6*iddl;
90           detectorID = 0;
91         }
92       else if (iddl == 4)
93         {
94           modulePerDDL = 12;
95           mmodule = 24;
96           detectorID = 1;
97         }
98       else if (iddl == 5)
99         {
100           modulePerDDL = 12;
101           mmodule = 36;
102           detectorID = 1;
103         }
104
105       miniHeader[0] = sizeRawData;
106       PackWord(0,23,magicWord,miniHeader[1]);
107       PackWord(24,31,detectorID,miniHeader[1]);
108       ddlID = iddl;
109       PackWord(0,15,ddlID,miniHeader[2]);
110       PackWord(16,23,flag,miniHeader[2]);
111       PackWord(24,31,version,miniHeader[2]);
112
113
114       // Write the Dummy Mini Header into the file
115       Int_t bHPosition = outfile.tellp();
116       outfile.write((char*)(miniHeader),mHSize);
117
118
119       for(Int_t ium = 0; ium < modulePerDDL; ium++)
120         {
121           
122           for (Int_t i = 0; i < kSize; i++)
123             {
124               buffer[i] = 0;
125             }
126           // Extract energy deposition per cell and pack it
127           // in a 32-bit word and returns all the total words
128           // per one unit-module
129           
130           GetUMDigitsData(treeD, mmodule, ium, iddl, totword, buffer);
131           
132           outfile.write((char*)buffer,totword*sizeof(UInt_t));
133
134           mmodule++;
135
136         }
137
138       // Write real mini header
139       // take the pointer to the beginning of the mini header
140       // write the total number of words per ddl and bring the
141       // pointer to the current file position and close it
142       UInt_t cFPosition = outfile.tellp();
143       sizeRawData = cFPosition - bHPosition - mHSize;
144       outfile.seekp(bHPosition);
145       outfile.write((char*)(&sizeRawData),sizeof(UInt_t));
146       outfile.seekp(cFPosition);
147
148       outfile.close();
149     } // DDL Loop over
150
151
152 }
153 //____________________________________________________________________________
154
155 void AliPMDDDLRawData::ReadPMDRawData(Int_t evtno)
156 {
157   // reads the raw data
158   ifstream infile;
159
160   Char_t filename[80];
161
162   const Int_t kDDL = 6;
163   Int_t imodule = 0;
164
165   for(Int_t iddl = 0; iddl < kDDL; iddl++)
166     {
167       sprintf(filename,"Ev%dPMDddl%d.dat",evtno,iddl);
168 #ifndef __DECCXX
169       infile.open(filename,ios::binary);
170 #else
171       infile.open(filename);
172 #endif
173       
174       Int_t  ium;
175       Int_t  irow;
176       Int_t  icol;
177       UInt_t baseword;
178       UInt_t miniHeader[3];
179       UInt_t sizeRawData;
180       UInt_t mHSize = 3*sizeof(UInt_t);
181
182       infile.read((char*)(miniHeader), mHSize);
183       
184       sizeRawData = miniHeader[0];
185       Int_t totword = sizeRawData/4;
186       
187       UInt_t adc;
188       UInt_t chno;
189       UInt_t mcmno;
190       
191       for (Int_t iword = 0; iword < totword; iword++)
192         {
193           infile.read((char*)(&baseword),sizeof(UInt_t));
194           
195           UnpackWord(0,11,adc,baseword);
196           UnpackWord(12,17,chno,baseword);
197           UnpackWord(18,28,mcmno,baseword);
198           
199           GetRowCol(iddl, mcmno, chno, ium, irow, icol);
200           if (iddl < 4)
201             {
202               imodule = iddl*6 + ium;
203             }
204           else if (iddl == 4)
205             {
206               imodule = 24 + ium;
207             }
208           else if (iddl == 5)
209             {
210               imodule = 36 + ium;
211             }
212
213           
214         }
215
216     } // ddl loop
217 }
218 //____________________________________________________________________________
219 void AliPMDDDLRawData::GetUMDigitsData(TTree *treeD, Int_t imodule, Int_t ium,
220                                        Int_t ddlno, Int_t & totword,
221                                        UInt_t *buffer)
222 {
223
224   UInt_t dataword, baseword;
225
226   UInt_t mcmno, chno;
227   UInt_t adc;
228   Int_t  irownew = 0;
229   Int_t  icolnew = 0;
230   Int_t  det, smn, irow, icol;
231
232
233   treeD->GetEntry(imodule); 
234   Int_t nentries = fDigits->GetLast();
235   totword = nentries+1;
236
237   for (Int_t ient = 0; ient < totword; ient++)
238     {
239       fPMDdigit = (AliPMDdigit*)fDigits->UncheckedAt(ient);
240       
241       det    = fPMDdigit->GetDetector();
242       smn    = fPMDdigit->GetSMNumber();
243       irow   = fPMDdigit->GetRow();
244       icol   = fPMDdigit->GetColumn();
245       adc    = (UInt_t) fPMDdigit->GetADC();
246
247       if(smn < 12)
248         {
249           irownew = icol;
250           icolnew = irow;
251         }
252       else if( smn >= 12 && smn < 24)
253         {
254           irownew = irow;
255           icolnew = icol;
256         }
257
258
259
260       GetMCMCh(ddlno, ium, irownew, icolnew, mcmno, chno);
261
262
263       baseword = 0;
264       dataword = adc;
265       PackWord(0, 11,dataword,baseword);
266       dataword = chno;
267       PackWord(12,17,dataword,baseword);
268       dataword = mcmno;
269       PackWord(18,28,dataword,baseword);
270       dataword = 0;
271       PackWord(29,29,dataword,baseword);
272       dataword = 0;
273       PackWord(30,30,dataword,baseword);
274       dataword = 1;
275       PackWord(31,31,dataword,baseword);
276       
277       buffer[ient] = baseword;
278       
279
280
281       
282     }
283
284
285 }
286 //____________________________________________________________________________
287 void AliPMDDDLRawData::GetMCMCh(Int_t ddlno, Int_t um,
288                                 Int_t row, Int_t col,
289                                 UInt_t &mcmno, UInt_t &chno)
290 {
291   // This part will be modified once the final track layout on the PCB is
292   // designed. This will only change the coordinate of the individual cell
293   UInt_t ch[16][4] = { {3, 2, 29, 28},
294                        {5, 1, 31, 27},
295                        {6, 0, 30, 26},
296                        {7, 4, 25, 24},
297                        {8, 9, 20, 23},
298                        {10, 14, 16, 22},
299                        {11, 15, 17, 21},
300                        {12, 13, 18, 19},
301                        {35, 34, 61, 60},
302                        {37, 33, 63, 59},
303                        {38, 32, 62, 58},
304                        {39, 36, 57, 56},
305                        {40, 41, 52, 55},
306                        {42, 46, 48, 54},
307                        {43, 47, 49, 53},
308                        {44, 45, 50, 51} };
309   
310   if (ddlno == 0 || ddlno == 1)
311     {
312       // PRE plane, SU Mod = 1, 2
313       Int_t irownew = row%16;
314       Int_t icolnew = col%4;
315       Int_t irowdiv = row/16;
316       Int_t icoldiv = col/4;
317
318       mcmno = 72*um + 6*icoldiv + irowdiv;
319       chno  = ch[irownew][icolnew];
320     }
321   else if (ddlno == 2 || ddlno == 3)
322     {
323       // PRE plane,  SU Mod = 3, 4
324       Int_t irownew = row%16;
325       Int_t icolnew = col%4;
326       Int_t irowdiv = row/16;
327       Int_t icoldiv = col/4;
328       
329       mcmno = 72*um + 3*icoldiv + irowdiv;
330       chno  = ch[irownew][icolnew];
331     }
332   else if (ddlno == 4)
333     {
334       // CPV plane,  SU Mod = 1, 2
335       Int_t irownew = row%16;
336       Int_t icolnew = col%4;
337       Int_t irowdiv = row/16;
338       Int_t icoldiv = col/4;
339
340       mcmno = 72*um + 6*icoldiv + irowdiv;
341       chno  = ch[irownew][icolnew];
342     }
343   else if (ddlno == 5)
344     {
345       // CPV plane,  SU Mod = 3, 4
346       Int_t irownew = row%16;
347       Int_t icolnew = col%4;
348       Int_t irowdiv = row/16;
349       Int_t icoldiv = col/4;
350       
351       mcmno = 72*um + 3*icoldiv + irowdiv;
352       chno  = ch[irownew][icolnew];
353     }
354
355 }
356 //____________________________________________________________________________
357
358 void AliPMDDDLRawData::GetRowCol(Int_t ddlno, UInt_t mcmno, UInt_t chno,
359                                  Int_t &um, Int_t &row, Int_t &col)
360 {
361   UInt_t ch[64] = { 9, 5, 1, 0, 13, 4, 8, 12,
362                     16, 17, 20, 24, 28, 29, 21, 25,
363                     22, 26, 30, 31, 18, 27, 23, 19,
364                     15, 14, 11, 7, 3, 2, 10, 6,
365                     41, 37, 33, 32, 45, 36, 40, 44,
366                     48, 49, 52, 56, 60, 61, 53, 57,
367                     54, 58, 62, 63, 50, 59, 55, 51,
368                     47, 46, 43, 39, 35, 34, 42, 38 };
369
370   if (ddlno == 1 || ddlno == 2)
371     {
372       um  = mcmno/72;
373       Int_t mcmnonew = mcmno - 72*um;
374       Int_t rowcol  = ch[chno];
375       Int_t irownew = rowcol/4;
376       Int_t icolnew = rowcol%4;
377       
378       Int_t remmcm  = mcmnonew%6;
379       Int_t divmcm  = mcmnonew/6;
380       
381       row = 16*remmcm + irownew;
382       col =  4*divmcm + icolnew;
383     }
384   else   if (ddlno == 3 || ddlno == 4)
385     {
386       um  = mcmno/72;
387       Int_t mcmnonew = mcmno - 72*um;
388       Int_t rowcol  = ch[chno];
389       Int_t irownew = rowcol/4;
390       Int_t icolnew = rowcol%4;
391       
392       Int_t remmcm  = mcmnonew%3;
393       Int_t divmcm  = mcmnonew/3;
394       
395       row = 16*remmcm + irownew;
396       col =  4*divmcm + icolnew;
397     }
398   else if (ddlno == 4)
399     {
400       um  = mcmno/144;
401       Int_t mcmnonew = mcmno - 72*um;
402       Int_t rowcol  = ch[chno];
403       Int_t irownew = rowcol/4;
404       Int_t icolnew = rowcol%4;
405       
406       Int_t remmcm  = mcmnonew%6;
407       Int_t divmcm  = mcmnonew/6;
408       
409       row = 16*remmcm + irownew;
410       col =  4*divmcm + icolnew;
411     }
412   else if (ddlno == 5)
413     {
414       um  = mcmno/144;
415       Int_t mcmnonew = mcmno - 72*um;
416       Int_t rowcol  = ch[chno];
417       Int_t irownew = rowcol/4;
418       Int_t icolnew = rowcol%4;
419       
420       Int_t remmcm  = mcmnonew%3;
421       Int_t divmcm  = mcmnonew/3;
422       
423       row = 16*remmcm + irownew;
424       col =  4*divmcm + icolnew;
425     }
426
427
428 }
429 //____________________________________________________________________________
430
431 void AliPMDDDLRawData::PackWord(UInt_t startbit, UInt_t stopbit, 
432                                 UInt_t dataword, UInt_t &packedword)
433 {
434   UInt_t bitLength  = stopbit - startbit + 1;
435   UInt_t bitContent = (UInt_t) (TMath::Power(2,bitLength) - 1);
436   if(bitContent < dataword)
437     {
438       cout << " *** ERROR *** bitContent is less than the dataword" << endl;
439       return;
440     }
441   UInt_t packedBits = 0;
442   if (packedword != 0)
443     packedBits = (UInt_t) (TMath::Log(packedword)/TMath::Log(2));
444
445   UInt_t counter;
446   if (packedBits <= stopbit)
447     {
448       counter   = 31 - stopbit;
449     }
450   else
451     {
452       counter   = 31 - packedBits;
453     }
454   UInt_t dummyword = 0xFFFFFFFF;
455   dummyword >>= counter;
456   UInt_t lword = dataword << startbit;
457   UInt_t nword = lword | packedword;
458   packedword = dummyword & nword;
459
460
461 }
462 //____________________________________________________________________________
463 void AliPMDDDLRawData::UnpackWord(UInt_t startbit, UInt_t stopbit, 
464                                 UInt_t &dataword, UInt_t packedword)
465 {
466   UInt_t bitLength  = stopbit - startbit + 1;
467   UInt_t bitContent = (UInt_t) (TMath::Power(2,bitLength) - 1);
468   bitContent <<= startbit;
469   dataword = packedword & bitContent;
470   dataword >>= startbit;
471
472 }
473 //____________________________________________________________________________
474