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