28328eeb |
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 | |
9e76520d |
54 | // Int_t nmodules = (Int_t) treeD->GetEntries(); |
28328eeb |
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 | |
28328eeb |
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 | |
28328eeb |
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 | |
28328eeb |
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 | |