]>
Commit | Line | Data |
---|---|---|
5990c064 | 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 | ||
88cb7938 | 16 | /* $Id$ */ |
5990c064 | 17 | |
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | // // | |
20 | // TRD raw data conversion class // | |
21 | // // | |
22 | /////////////////////////////////////////////////////////////////////////////// | |
23 | ||
a2cb5b3d | 24 | #include <Riostream.h> |
5990c064 | 25 | |
2745a409 | 26 | #include "AliDAQ.h" |
27 | #include "AliRawDataHeader.h" | |
28 | #include "AliRawReader.h" | |
29 | #include "AliLog.h" | |
30 | ||
5990c064 | 31 | #include "AliTRDrawData.h" |
32 | #include "AliTRDdigitsManager.h" | |
bd0f8685 | 33 | #include "AliTRDgeometry.h" |
5990c064 | 34 | #include "AliTRDdataArrayI.h" |
b864d801 | 35 | #include "AliTRDRawStream.h" |
3551db50 | 36 | #include "AliTRDCommonParam.h" |
37 | #include "AliTRDcalibDB.h" | |
5990c064 | 38 | |
39 | ClassImp(AliTRDrawData) | |
40 | ||
41 | //_____________________________________________________________________________ | |
2cb20be6 | 42 | AliTRDrawData::AliTRDrawData() |
43 | :TObject() | |
8c703901 | 44 | ,fRawVersion(1) |
45 | ,fCommonParam(0) | |
46 | ,fCalibration(0) | |
47 | ,fGeo(0) | |
48 | ,fNumberOfDDLs(0) | |
5990c064 | 49 | { |
b864d801 | 50 | // |
51 | // Default constructor | |
52 | // | |
5990c064 | 53 | |
5990c064 | 54 | } |
55 | ||
8c703901 | 56 | //_____________________________________________________________________________ |
57 | AliTRDrawData::AliTRDrawData(const AliTRDrawData &r) | |
58 | :TObject(r) | |
59 | ,fRawVersion(1) | |
60 | ,fCommonParam(0) | |
61 | ,fCalibration(0) | |
62 | ,fGeo(0) | |
63 | ,fNumberOfDDLs(0) | |
64 | { | |
65 | // | |
66 | // Copy constructor | |
67 | // | |
68 | ||
69 | } | |
70 | ||
5990c064 | 71 | //_____________________________________________________________________________ |
72 | AliTRDrawData::~AliTRDrawData() | |
73 | { | |
74 | // | |
75 | // Destructor | |
76 | // | |
77 | ||
5990c064 | 78 | } |
79 | ||
5990c064 | 80 | //_____________________________________________________________________________ |
8c703901 | 81 | Bool_t AliTRDrawData::SetRawVersion(Int_t v) |
5990c064 | 82 | { |
8c703901 | 83 | // |
84 | // Set the raw data version | |
85 | // Currently only version 0 and 1 are available. | |
86 | // | |
87 | ||
88 | if ((v == 0) || | |
89 | (v == 1)) { | |
90 | fRawVersion = v; | |
91 | return kTRUE; | |
92 | } | |
93 | ||
94 | return kFALSE; | |
95 | ||
96 | } | |
97 | ||
98 | //_____________________________________________________________________________ | |
99 | Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree, TTree *tracks ) | |
100 | { | |
101 | // | |
102 | // Initialize necessary parameters and call one | |
103 | // of the raw data simulator selected by SetRawVersion. | |
104 | // | |
105 | // Currently tracklet output is not spported yet and it | |
106 | // will be supported in higher version simulator. | |
107 | // | |
108 | ||
109 | fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD"); | |
110 | ||
111 | AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager(); | |
112 | ||
113 | if (!digitsManager->ReadDigits(digitsTree)) { | |
114 | delete digitsManager; | |
115 | return kFALSE; | |
116 | } | |
117 | ||
118 | if (tracks != NULL) { | |
119 | delete digitsManager; | |
120 | printf("<AliTRDrawData::Digits2Raw> Tracklet input is not supported yet.\n"); | |
121 | return kFALSE; | |
122 | } | |
123 | ||
124 | fGeo = new AliTRDgeometry(); | |
125 | ||
126 | fCommonParam = AliTRDCommonParam::Instance(); | |
127 | if (!fCommonParam) { | |
128 | AliError("Could not get common params\n"); | |
129 | delete fGeo; | |
130 | delete digitsManager; | |
131 | return kFALSE; | |
132 | } | |
133 | ||
134 | fCalibration = AliTRDcalibDB::Instance(); | |
135 | if (!fCalibration) { | |
136 | AliError("Could not get calibration object\n"); | |
137 | delete fGeo; | |
138 | delete digitsManager; | |
139 | return kFALSE; | |
140 | } | |
141 | ||
142 | Int_t retval = kTRUE; | |
143 | ||
144 | // Call appropriate Raw Simulator | |
145 | switch( fRawVersion ) { | |
146 | case 0 : | |
147 | retval = Digits2RawV0(digitsManager); | |
148 | break; | |
149 | case 1 : | |
150 | retval = Digits2RawV1(digitsManager); | |
151 | break; | |
152 | default: | |
153 | retval = kFALSE; | |
154 | AliWarning(Form("Unsupported raw version (fRawVersion=%d).\n",fRawVersion)); | |
155 | break; | |
156 | } | |
157 | ||
158 | // Cleanup | |
159 | delete fGeo; | |
160 | delete digitsManager; | |
161 | ||
162 | return retval; | |
163 | ||
164 | } | |
165 | ||
166 | //_____________________________________________________________________________ | |
167 | Bool_t AliTRDrawData::Digits2RawV0(AliTRDdigitsManager* digitsManager) | |
168 | { | |
169 | // | |
170 | // Bogdan's raw simulator (offline use only) | |
5990c064 | 171 | // |
172 | // Convert the digits to raw data byte stream. The output is written | |
b864d801 | 173 | // into the the binary files TRD_<DDL number>.ddl. |
5990c064 | 174 | // |
175 | // The pseudo raw data format is currently defined like this: | |
176 | // | |
b864d801 | 177 | // DDL data header |
5990c064 | 178 | // |
179 | // Subevent (= single chamber) header (8 bytes) | |
180 | // FLAG | |
181 | // Detector number (2 bytes) | |
182 | // Number of data bytes (2 bytes) | |
183 | // Number of pads with data (2 bytes) | |
184 | // 1 empty byte | |
185 | // | |
186 | // Data bank | |
187 | // | |
188 | ||
5990c064 | 189 | const Int_t kSubeventHeaderLength = 8; |
5990c064 | 190 | const Int_t kSubeventDummyFlag = 0xBB; |
e3e1266c | 191 | Int_t headerSubevent[3]; |
5990c064 | 192 | |
8c703901 | 193 | ofstream **outputFile = new ofstream* [fNumberOfDDLs]; |
194 | UInt_t *bHPosition = new UInt_t [fNumberOfDDLs]; | |
195 | Int_t *ntotalbyte = new Int_t [fNumberOfDDLs]; | |
5990c064 | 196 | Int_t nbyte = 0; |
197 | Int_t npads = 0; | |
b864d801 | 198 | unsigned char *bytePtr; |
199 | unsigned char *headerPtr; | |
5990c064 | 200 | |
8c703901 | 201 | AliTRDdataArrayI *digits; |
202 | AliRawDataHeader header; // The event header | |
5990c064 | 203 | |
b864d801 | 204 | // Open the output files |
8c703901 | 205 | for (Int_t iDDL = 0; iDDL < fNumberOfDDLs; iDDL++) { |
2cb20be6 | 206 | |
b864d801 | 207 | char name[20]; |
8c703901 | 208 | sprintf(name, "TRD_%d.ddl", iDDL + AliTRDRawStream::kDDLOffset); |
b864d801 | 209 | #ifndef __DECCXX |
210 | outputFile[iDDL] = new ofstream(name, ios::binary); | |
211 | #else | |
212 | outputFile[iDDL] = new ofstream(name); | |
213 | #endif | |
214 | ||
215 | // Write a dummy data header | |
216 | bHPosition[iDDL] = outputFile[iDDL]->tellp(); | |
8c703901 | 217 | outputFile[iDDL]->write((char *) (& header),sizeof(header)); |
b864d801 | 218 | ntotalbyte[iDDL] = 0; |
2cb20be6 | 219 | |
5990c064 | 220 | } |
221 | ||
222 | // Loop through all detectors | |
223 | for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) { | |
224 | ||
8c703901 | 225 | Int_t cham = fGeo->GetChamber(det); |
226 | Int_t plan = fGeo->GetPlane(det); | |
227 | Int_t sect = fGeo->GetSector(det); | |
228 | Int_t rowMax = fCommonParam->GetRowMax(plan,cham,sect); | |
229 | Int_t colMax = fCommonParam->GetColMax(plan); | |
230 | Int_t timeTotal = fCalibration->GetNumberOfTimeBins(); | |
231 | Int_t bufferMax = rowMax * colMax * timeTotal; | |
e3e1266c | 232 | Int_t *buffer = new Int_t[bufferMax]; |
5990c064 | 233 | |
b864d801 | 234 | npads = 0; |
235 | nbyte = 0; | |
236 | bytePtr = (unsigned char *) buffer; | |
5990c064 | 237 | |
b864d801 | 238 | Int_t iDDL = sect; |
5990c064 | 239 | |
240 | // Get the digits array | |
b864d801 | 241 | digits = digitsManager->GetDigits(det); |
5990c064 | 242 | digits->Expand(); |
2cb20be6 | 243 | // This is to take care of switched off super modules |
244 | if (digits->GetNtime() == 0) { | |
245 | continue; | |
246 | } | |
5990c064 | 247 | |
248 | // Loop through the detector pixel | |
249 | for (Int_t col = 0; col < colMax; col++) { | |
250 | for (Int_t row = 0; row < rowMax; row++) { | |
251 | ||
252 | // Check whether data exists for this pad | |
253 | Bool_t dataflag = kFALSE; | |
928e9fae | 254 | for (Int_t time = 0; time < timeTotal; time++) { |
5990c064 | 255 | Int_t data = digits->GetDataUnchecked(row,col,time); |
256 | if (data) { | |
257 | dataflag = kTRUE; | |
258 | break; | |
259 | } | |
260 | } | |
261 | ||
262 | if (dataflag) { | |
263 | ||
264 | npads++; | |
265 | ||
266 | // The pad row number | |
b864d801 | 267 | *bytePtr++ = row + 1; |
5990c064 | 268 | // The pad column number |
b864d801 | 269 | *bytePtr++ = col + 1; |
5990c064 | 270 | nbyte += 2; |
271 | ||
272 | Int_t nzero = 0; | |
928e9fae | 273 | for (Int_t time = 0; time < timeTotal; time++) { |
5990c064 | 274 | |
275 | Int_t data = digits->GetDataUnchecked(row,col,time); | |
276 | ||
277 | if (!data) { | |
278 | nzero++; | |
279 | if ((nzero == 256) || | |
928e9fae | 280 | (time == timeTotal-1)) { |
b864d801 | 281 | *bytePtr++ = 0; |
282 | *bytePtr++ = nzero-1; | |
5990c064 | 283 | nbyte += 2; |
284 | nzero = 0; | |
285 | } | |
286 | } | |
287 | else { | |
288 | if (nzero) { | |
b864d801 | 289 | *bytePtr++ = 0; |
290 | *bytePtr++ = nzero-1; | |
5990c064 | 291 | nbyte += 2; |
292 | nzero = 0; | |
293 | } | |
294 | // High byte (MSB always set) | |
b864d801 | 295 | *bytePtr++ = ((data >> 8) | 128); |
5990c064 | 296 | // Low byte |
b864d801 | 297 | *bytePtr++ = (data & 0xff); |
5990c064 | 298 | nbyte += 2; |
299 | } | |
300 | ||
301 | } | |
302 | ||
303 | } | |
304 | ||
305 | } | |
306 | ||
307 | } | |
308 | ||
309 | // Fill the end of the buffer with zeros | |
310 | while (nbyte % 4) { | |
b864d801 | 311 | *bytePtr++ = 0; |
5990c064 | 312 | nbyte++; |
313 | } | |
314 | ||
2745a409 | 315 | AliDebug(1,Form("det = %d, nbyte = %d (%d)",det,nbyte,bufferMax)); |
5990c064 | 316 | |
317 | // Write the subevent header | |
b864d801 | 318 | bytePtr = (unsigned char *) headerSubevent; |
319 | headerPtr = bytePtr; | |
320 | *bytePtr++ = kSubeventDummyFlag; | |
321 | *bytePtr++ = (det & 0xff); | |
322 | *bytePtr++ = (det >> 8); | |
323 | *bytePtr++ = (nbyte & 0xff); | |
324 | *bytePtr++ = (nbyte >> 8); | |
928e9fae | 325 | *bytePtr++ = (nbyte >> 16); |
b864d801 | 326 | *bytePtr++ = (npads & 0xff); |
327 | *bytePtr++ = (npads >> 8); | |
2cb20be6 | 328 | outputFile[iDDL]->write((char *) headerPtr,kSubeventHeaderLength); |
5990c064 | 329 | |
330 | // Write the buffer to the file | |
b864d801 | 331 | bytePtr = (unsigned char *) buffer; |
2cb20be6 | 332 | outputFile[iDDL]->write((char *) bytePtr,nbyte); |
5990c064 | 333 | |
b864d801 | 334 | ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength; |
5990c064 | 335 | |
336 | delete buffer; | |
337 | ||
338 | } | |
339 | ||
b864d801 | 340 | // Update the data headers and close the output files |
8c703901 | 341 | for (Int_t iDDL = 0; iDDL < fNumberOfDDLs; iDDL++) { |
2745a409 | 342 | |
b864d801 | 343 | header.fSize = UInt_t(outputFile[iDDL]->tellp()) - bHPosition[iDDL]; |
344 | header.SetAttribute(0); // valid data | |
345 | outputFile[iDDL]->seekp(bHPosition[iDDL]); | |
2cb20be6 | 346 | outputFile[iDDL]->write((char *) (&header),sizeof(header)); |
b864d801 | 347 | |
348 | outputFile[iDDL]->close(); | |
349 | delete outputFile[iDDL]; | |
2745a409 | 350 | |
b864d801 | 351 | } |
5990c064 | 352 | |
bc33499b | 353 | delete [] outputFile; |
354 | delete [] bHPosition; | |
355 | delete [] ntotalbyte; | |
356 | ||
5990c064 | 357 | return kTRUE; |
8c703901 | 358 | } |
359 | ||
360 | //_____________________________________________________________________________ | |
361 | Bool_t AliTRDrawData::Digits2RawV1(AliTRDdigitsManager *digitsManager) | |
362 | { | |
363 | // | |
364 | // Raw data simulator version 1. | |
365 | // This version simulate only raw data with ADC data and not with tracklet. | |
366 | // This is close to the SM-I commissiong data format in Oct.2006. | |
367 | // | |
368 | ||
369 | // (timebin/3)*nADC*nMCM*nROB + header + tracklet(max 20) | |
370 | const Int_t kMaxHcWords = (60/3)*21*16*4 + 100 + 20; | |
371 | ||
372 | // Buffer to temporary store half chamber data | |
373 | UInt_t *hc_buffer = new UInt_t[kMaxHcWords]; | |
374 | ||
375 | // sect is same as iDDL, so I use only sect here. | |
376 | for (Int_t sect = 0; sect < fGeo->Nsect(); sect++) { | |
377 | ||
378 | char name[1024]; | |
379 | sprintf(name,"TRD_%d.ddl",sect + AliTRDRawStream::kDDLOffset); | |
380 | ||
381 | #ifndef __DECCXX | |
382 | ofstream *of = new ofstream(name, ios::binary); | |
383 | #else | |
384 | ofstream *of = new ofstream(name); | |
385 | #endif | |
386 | ||
387 | // Write a dummy data header | |
388 | AliRawDataHeader header; // the event header | |
389 | UInt_t hpos = of->tellp(); | |
390 | of->write((char *) (& header), sizeof(header)); | |
391 | ||
392 | // Reset payload byte size (payload does not include header). | |
393 | Int_t npayloadbyte = 0; | |
394 | ||
395 | // GTU common data header (5x4 bytes shows link mask) | |
396 | for( Int_t cham = 0; cham < fGeo->Ncham(); cham++ ) { | |
397 | UInt_t GtuCdh; | |
398 | GtuCdh = 0x00000FFF; // Assume all ORI links (12 per stack) are always up | |
399 | of->write((char *) (& GtuCdh), sizeof(GtuCdh)); | |
400 | npayloadbyte += 4; | |
401 | } | |
402 | ||
403 | // Prepare chamber data | |
404 | for( Int_t cham = 0; cham < fGeo->Ncham(); cham++) { | |
405 | for( Int_t plan = 0; plan < fGeo->Nplan(); plan++) { | |
406 | ||
407 | Int_t iDet = fGeo->GetDetector(plan,cham,sect); | |
408 | ||
409 | // Get the digits array | |
410 | AliTRDdataArrayI *digits = digitsManager->GetDigits(iDet); | |
411 | digits->Expand(); | |
412 | ||
413 | Int_t hcwords; | |
414 | ||
415 | // Process A side of the chamber | |
416 | hcwords = ProduceHcDataV1(digits,0,iDet,hc_buffer,kMaxHcWords); | |
417 | of->write((char *) hc_buffer, hcwords*4); | |
418 | npayloadbyte += hcwords*4; | |
419 | ||
420 | // Process B side of the chamber | |
421 | hcwords = ProduceHcDataV1(digits,1,iDet,hc_buffer,kMaxHcWords); | |
422 | of->write((char *) hc_buffer, hcwords*4); | |
423 | npayloadbyte += hcwords*4; | |
424 | ||
425 | } | |
426 | } | |
427 | ||
428 | // Complete header | |
429 | header.fSize = UInt_t(of->tellp()) - hpos; | |
430 | header.SetAttribute(0); // Valid data | |
431 | of->seekp(hpos); // Rewind to header position | |
432 | of->write((char *) (& header), sizeof(header)); | |
433 | of->close(); | |
434 | delete of; | |
435 | ||
436 | } | |
437 | ||
438 | delete hc_buffer; | |
439 | return kTRUE; | |
440 | ||
441 | } | |
442 | ||
443 | //_____________________________________________________________________________ | |
444 | Int_t AliTRDrawData::ProduceHcDataV1(AliTRDdataArrayI *digits, Int_t side | |
445 | , Int_t det, UInt_t *buf, Int_t maxSize) | |
446 | { | |
447 | // | |
448 | // Produce half chamber data (= an ORI data) for the given chamber (det) and side (side) | |
449 | // where | |
450 | // side=0 means A side with ROB positions 0, 2, 4, 6. | |
451 | // side=1 means B side with ROB positions 1, 3, 5, 7. | |
452 | // | |
453 | // Chamber type (C0 orC1) is determined by "det" automatically. | |
454 | // Appropriate size of buffer (*buf) must be prepared prior to calling this function. | |
455 | // Pointer to the buffer and its size must be given to "buf" and "maxSize". | |
456 | // Return value is the number of valid data filled in the buffer in unit of 32 bits | |
457 | // UInt_t words. | |
458 | // If buffer size if too small, the data is truncated with the buffer size however | |
459 | // the function will finish without crash (this behaviour is similar to the MCM). | |
460 | // | |
461 | ||
462 | Int_t nw = 0; // Number of written words | |
463 | Int_t of = 0; // Number of overflowed words | |
464 | Int_t plan = fGeo->GetPlane( det ); // Plane | |
465 | Int_t cham = fGeo->GetChamber( det ); // Chamber | |
466 | Int_t sect = fGeo->GetSector( det ); // Sector (=iDDL) | |
467 | Int_t nRow = fCommonParam->GetRowMax( plan, cham, sect ); | |
468 | Int_t nCol = fCommonParam->GetColMax( plan ); | |
469 | const Int_t nMcm = 16; // Number of MCMs per ROB (fixed) | |
470 | const Int_t nTBin = fCalibration->GetNumberOfTimeBins(); | |
471 | Int_t dcs = det+100; // DCS Serial (in simulation, it's always | |
472 | // chamber ID+1000 without any reason | |
473 | Int_t kCtype = 0; // Chamber type (0:C0, 1:C1) | |
474 | Int_t iEv = 0xA; // Event ID. Now fixed to 10, how do I get event id? | |
475 | UInt_t x = 0; // General used number | |
476 | ||
477 | // Check the nCol and nRow. | |
478 | if ((nCol == 144) && | |
479 | (nRow == 16 || nRow == 12)) { | |
480 | kCtype = (nRow-12) / 4; | |
481 | } | |
482 | else { | |
483 | AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d).\n" | |
484 | ,nRow,nCol)); | |
485 | return 0; | |
486 | } | |
487 | ||
488 | AliDebug(1,Form("Producing raw data for sect=%d plan=%d cham=%d side=%d" | |
489 | ,sect,plan,cham,side)); | |
490 | ||
491 | // Tracklet should be processed here but not implemented yet | |
492 | ||
493 | // Write end of tracklet marker | |
494 | if (nw < maxSize) { | |
495 | buf[nw++] = 0xAAAAAAAA; | |
496 | } | |
497 | else { | |
498 | of++; | |
499 | } | |
500 | ||
501 | // Half Chamber header | |
502 | // Now it is the same version as used in SM-I commissioning. | |
503 | // It is: (dcs << 20) | (sect << 15) | (plan << 12) | (cham << 9) | (side << 8) | |
504 | x = (dcs << 20) | (sect << 15) | (plan << 12) | (cham << 9) | (side << 8); | |
505 | if (nw < maxSize) { | |
506 | buf[nw++] = x; | |
507 | } | |
508 | else { | |
509 | of++; | |
510 | } | |
511 | ||
512 | // Scan for ROB and MCM | |
513 | for (Int_t iRobRow = 0; iRobRow < (kCtype + 3); iRobRow++ ) { | |
514 | Int_t iRob = iRobRow * 2 + side; | |
515 | for (Int_t iMcm = 0; iMcm < nMcm; iMcm++ ) { | |
516 | Int_t padrow = iRobRow * 4 + iMcm / 4; | |
517 | ||
518 | // MCM header | |
519 | x = ((iRob * nMcm + iMcm) << 24) | ((iEv % 0x100000) << 4) | 0xC; | |
520 | if (nw < maxSize) { | |
521 | buf[nw++] = x; | |
522 | } | |
523 | else { | |
524 | of++; | |
525 | } | |
526 | ||
527 | // ADC data | |
528 | for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) { | |
529 | Int_t padcol = (17-(iAdc-2)) + (iMcm % 4)*18 + side*72; | |
530 | UInt_t aa = 2; | |
531 | UInt_t *a = new UInt_t[nTBin+2]; | |
532 | // 3 timebins are packed into one 32 bits word | |
533 | for (Int_t iT = 0; iT < nTBin; iT+=3) { | |
534 | if ((padcol >= 0) && | |
535 | (padcol < nCol)) { | |
536 | if ((iT ) < nTBin ) { | |
537 | a[iT ] = digits->GetDataUnchecked(padrow,padcol,iT); | |
538 | } | |
539 | else { | |
540 | a[iT ] = 0; | |
541 | } | |
542 | if ((iT + 1) < nTBin ) { | |
543 | a[iT+1] = digits->GetDataUnchecked(padrow,padcol,iT + 1); | |
544 | } | |
545 | else { | |
546 | a[iT+1] = 0; | |
547 | } | |
548 | if ((iT + 2) < nTBin ) { | |
549 | a[iT+2] = digits->GetDataUnchecked(padrow,padcol,iT + 2); | |
550 | } | |
551 | else { | |
552 | a[iT+2] = 0; | |
553 | } | |
554 | } | |
555 | else { | |
556 | a[iT] = a[iT+1] = a[iT+2] = 0; // This happenes at the edge of chamber | |
557 | } | |
558 | x = (a[iT+2] << 22) | (a[iT+1] << 12) | (a[iT] << 2) | aa; | |
559 | if (nw < maxSize) { | |
560 | buf[nw++] = x; | |
561 | } | |
562 | else { | |
563 | of++; | |
564 | } | |
565 | if (aa == 2) { | |
566 | aa = 3; | |
567 | } | |
568 | else { | |
569 | aa = 2; // aa alternatively changes between 10b and 11b | |
570 | } | |
571 | } | |
572 | // Diagnostics | |
573 | Float_t avg = 0; | |
574 | Float_t rms = 0; | |
575 | for (Int_t iT = 0; iT < nTBin; iT++) { | |
576 | avg += (Float_t) (a[iT]); | |
577 | } | |
578 | avg /= (Float_t) nTBin; | |
579 | for (Int_t iT = 0; iT < nTBin; iT++) { | |
580 | rms += ((Float_t) (a[iT]) - avg) * ((Float_t) (a[iT]) - avg); | |
581 | } | |
582 | rms = TMath::Sqrt(rms / (Float_t) nTBin); | |
583 | if (rms > 1.7) { | |
584 | AliDebug(1,Form("Large RMS (>1.7) (ROB,MCM,ADC)=(%02d,%02d,%02d), avg=%03.1f, rms=%03.1f\n" | |
585 | ,iRob,iMcm,iAdc,avg,rms)); | |
586 | } | |
587 | delete a; | |
588 | } | |
589 | } | |
590 | } | |
591 | ||
592 | // Write end of raw data marker | |
593 | if (nw < maxSize) { | |
594 | buf[nw++] = 0x00000000; | |
595 | } | |
596 | else { | |
597 | of++; | |
598 | } | |
599 | if (of != 0) { | |
600 | AliWarning("Buffer overflow. Data is truncated. Please increase buffer size and recompile."); | |
601 | } | |
602 | ||
603 | return nw; | |
5990c064 | 604 | |
605 | } | |
606 | ||
607 | //_____________________________________________________________________________ | |
8c703901 | 608 | AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader *rawReader) |
5990c064 | 609 | { |
b864d801 | 610 | // |
611 | // Read the raw data digits and put them into the returned digits manager | |
612 | // | |
5990c064 | 613 | |
2cb20be6 | 614 | AliTRDdataArrayI *digits = 0; |
615 | AliTRDdataArrayI *track0 = 0; | |
616 | AliTRDdataArrayI *track1 = 0; | |
617 | AliTRDdataArrayI *track2 = 0; | |
5990c064 | 618 | |
bd0f8685 | 619 | AliTRDgeometry *geo = new AliTRDgeometry(); |
3551db50 | 620 | |
621 | AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance(); | |
2745a409 | 622 | if (!commonParam) { |
623 | AliError("Could not get common parameters\n"); | |
3551db50 | 624 | return 0; |
625 | } | |
626 | ||
627 | AliTRDcalibDB* calibration = AliTRDcalibDB::Instance(); | |
2745a409 | 628 | if (!calibration) { |
629 | AliError("Could not get calibration object\n"); | |
3551db50 | 630 | return 0; |
631 | } | |
5990c064 | 632 | |
633 | // Create the digits manager | |
b864d801 | 634 | AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager(); |
b864d801 | 635 | digitsManager->CreateArrays(); |
5990c064 | 636 | |
3551db50 | 637 | AliTRDRawStream input(rawReader); |
5990c064 | 638 | |
b864d801 | 639 | // Loop through the digits |
640 | while (input.Next()) { | |
5990c064 | 641 | |
b864d801 | 642 | Int_t det = input.GetDetector(); |
643 | Int_t npads = input.GetNPads(); | |
5990c064 | 644 | |
b864d801 | 645 | if (input.IsNewDetector()) { |
646 | ||
647 | if (digits) digits->Compress(1,0); | |
928e9fae | 648 | if (track0) track0->Compress(1,0); |
649 | if (track1) track1->Compress(1,0); | |
650 | if (track2) track2->Compress(1,0); | |
5990c064 | 651 | |
2745a409 | 652 | AliDebug(2,"Subevent header:"); |
653 | AliDebug(2,Form("\tdet = %d",det)); | |
654 | AliDebug(2,Form("\tnpads = %d",npads)); | |
5990c064 | 655 | |
656 | // Create the data buffer | |
657 | Int_t cham = geo->GetChamber(det); | |
658 | Int_t plan = geo->GetPlane(det); | |
659 | Int_t sect = geo->GetSector(det); | |
3551db50 | 660 | Int_t rowMax = commonParam->GetRowMax(plan,cham,sect); |
661 | Int_t colMax = commonParam->GetColMax(plan); | |
662 | Int_t timeTotal = calibration->GetNumberOfTimeBins(); | |
5990c064 | 663 | |
664 | // Add a container for the digits of this detector | |
b864d801 | 665 | digits = digitsManager->GetDigits(det); |
928e9fae | 666 | track0 = digitsManager->GetDictionary(det,0); |
667 | track1 = digitsManager->GetDictionary(det,1); | |
668 | track2 = digitsManager->GetDictionary(det,2); | |
5990c064 | 669 | // Allocate memory space for the digits buffer |
670 | if (digits->GetNtime() == 0) { | |
928e9fae | 671 | digits->Allocate(rowMax,colMax,timeTotal); |
672 | track0->Allocate(rowMax,colMax,timeTotal); | |
673 | track1->Allocate(rowMax,colMax,timeTotal); | |
674 | track2->Allocate(rowMax,colMax,timeTotal); | |
5990c064 | 675 | } |
676 | ||
5990c064 | 677 | } |
928e9fae | 678 | |
b864d801 | 679 | digits->SetDataUnchecked(input.GetRow(),input.GetColumn(), |
680 | input.GetTime(),input.GetSignal()); | |
928e9fae | 681 | track0->SetDataUnchecked(input.GetRow(),input.GetColumn(), |
2cb20be6 | 682 | input.GetTime(), 0); |
928e9fae | 683 | track1->SetDataUnchecked(input.GetRow(),input.GetColumn(), |
2cb20be6 | 684 | input.GetTime(), 0); |
928e9fae | 685 | track2->SetDataUnchecked(input.GetRow(),input.GetColumn(), |
2cb20be6 | 686 | input.GetTime(), 0); |
687 | ||
5990c064 | 688 | } |
689 | ||
b864d801 | 690 | if (digits) digits->Compress(1,0); |
928e9fae | 691 | if (track0) track0->Compress(1,0); |
692 | if (track1) track1->Compress(1,0); | |
693 | if (track2) track2->Compress(1,0); | |
b864d801 | 694 | |
5990c064 | 695 | delete geo; |
5990c064 | 696 | |
b864d801 | 697 | return digitsManager; |
5990c064 | 698 | |
699 | } |