]>
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() | |
5990c064 | 44 | { |
b864d801 | 45 | // |
46 | // Default constructor | |
47 | // | |
5990c064 | 48 | |
5990c064 | 49 | } |
50 | ||
51 | //_____________________________________________________________________________ | |
52 | AliTRDrawData::~AliTRDrawData() | |
53 | { | |
54 | // | |
55 | // Destructor | |
56 | // | |
57 | ||
5990c064 | 58 | } |
59 | ||
5990c064 | 60 | //_____________________________________________________________________________ |
b864d801 | 61 | Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree) |
5990c064 | 62 | { |
63 | // | |
64 | // Convert the digits to raw data byte stream. The output is written | |
b864d801 | 65 | // into the the binary files TRD_<DDL number>.ddl. |
5990c064 | 66 | // |
67 | // The pseudo raw data format is currently defined like this: | |
68 | // | |
b864d801 | 69 | // DDL data header |
5990c064 | 70 | // |
71 | // Subevent (= single chamber) header (8 bytes) | |
72 | // FLAG | |
73 | // Detector number (2 bytes) | |
74 | // Number of data bytes (2 bytes) | |
75 | // Number of pads with data (2 bytes) | |
76 | // 1 empty byte | |
77 | // | |
78 | // Data bank | |
79 | // | |
80 | ||
362c9d61 | 81 | const Int_t kNumberOfDDLs = AliDAQ::NumberOfDdls("TRD"); |
5990c064 | 82 | const Int_t kSubeventHeaderLength = 8; |
5990c064 | 83 | const Int_t kSubeventDummyFlag = 0xBB; |
e3e1266c | 84 | Int_t headerSubevent[3]; |
5990c064 | 85 | |
bc33499b | 86 | ofstream **outputFile = new ofstream* [kNumberOfDDLs]; |
87 | UInt_t *bHPosition = new UInt_t [kNumberOfDDLs]; | |
88 | Int_t *ntotalbyte = new Int_t [kNumberOfDDLs]; | |
5990c064 | 89 | Int_t nbyte = 0; |
90 | Int_t npads = 0; | |
b864d801 | 91 | unsigned char *bytePtr; |
92 | unsigned char *headerPtr; | |
5990c064 | 93 | |
2cb20be6 | 94 | AliTRDdigitsManager *digitsManager = new AliTRDdigitsManager(); |
5990c064 | 95 | |
96 | // Read in the digit arrays | |
b864d801 | 97 | if (!digitsManager->ReadDigits(digitsTree)) { |
98 | delete digitsManager; | |
5990c064 | 99 | return kFALSE; |
100 | } | |
101 | ||
2cb20be6 | 102 | AliTRDgeometry *geo = new AliTRDgeometry(); |
103 | AliTRDdataArrayI *digits; | |
5990c064 | 104 | |
2cb20be6 | 105 | AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance(); |
2745a409 | 106 | if (!commonParam) { |
107 | AliError("Could not get common parameters\n"); | |
3551db50 | 108 | return 0; |
109 | } | |
110 | ||
2cb20be6 | 111 | AliTRDcalibDB *calibration = AliTRDcalibDB::Instance(); |
3551db50 | 112 | if (!calibration) |
113 | { | |
2745a409 | 114 | AliError("Could not get calibration object\n"); |
3551db50 | 115 | return kFALSE; |
116 | } | |
117 | ||
2cb20be6 | 118 | // The event header |
b864d801 | 119 | AliRawDataHeader header; |
5990c064 | 120 | |
b864d801 | 121 | // Open the output files |
122 | for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) { | |
2cb20be6 | 123 | |
b864d801 | 124 | char name[20]; |
362c9d61 | 125 | strcpy(name,AliDAQ::DdlFileName("TRD",iDDL)); |
b864d801 | 126 | #ifndef __DECCXX |
127 | outputFile[iDDL] = new ofstream(name, ios::binary); | |
128 | #else | |
129 | outputFile[iDDL] = new ofstream(name); | |
130 | #endif | |
131 | ||
132 | // Write a dummy data header | |
133 | bHPosition[iDDL] = outputFile[iDDL]->tellp(); | |
134 | outputFile[iDDL]->write((char*)(&header),sizeof(header)); | |
135 | ntotalbyte[iDDL] = 0; | |
2cb20be6 | 136 | |
5990c064 | 137 | } |
138 | ||
139 | // Loop through all detectors | |
140 | for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) { | |
141 | ||
142 | Int_t cham = geo->GetChamber(det); | |
143 | Int_t plan = geo->GetPlane(det); | |
144 | Int_t sect = geo->GetSector(det); | |
3551db50 | 145 | Int_t rowMax = commonParam->GetRowMax(plan,cham,sect); |
146 | Int_t colMax = commonParam->GetColMax(plan); | |
147 | Int_t timeTotal = calibration->GetNumberOfTimeBins(); | |
928e9fae | 148 | Int_t bufferMax = rowMax*colMax*timeTotal; |
e3e1266c | 149 | Int_t *buffer = new Int_t[bufferMax]; |
5990c064 | 150 | |
b864d801 | 151 | npads = 0; |
152 | nbyte = 0; | |
153 | bytePtr = (unsigned char *) buffer; | |
5990c064 | 154 | |
b864d801 | 155 | Int_t iDDL = sect; |
5990c064 | 156 | |
157 | // Get the digits array | |
b864d801 | 158 | digits = digitsManager->GetDigits(det); |
5990c064 | 159 | digits->Expand(); |
2cb20be6 | 160 | // This is to take care of switched off super modules |
161 | if (digits->GetNtime() == 0) { | |
162 | continue; | |
163 | } | |
5990c064 | 164 | |
165 | // Loop through the detector pixel | |
166 | for (Int_t col = 0; col < colMax; col++) { | |
167 | for (Int_t row = 0; row < rowMax; row++) { | |
168 | ||
169 | // Check whether data exists for this pad | |
170 | Bool_t dataflag = kFALSE; | |
928e9fae | 171 | for (Int_t time = 0; time < timeTotal; time++) { |
5990c064 | 172 | Int_t data = digits->GetDataUnchecked(row,col,time); |
173 | if (data) { | |
174 | dataflag = kTRUE; | |
175 | break; | |
176 | } | |
177 | } | |
178 | ||
179 | if (dataflag) { | |
180 | ||
181 | npads++; | |
182 | ||
183 | // The pad row number | |
b864d801 | 184 | *bytePtr++ = row + 1; |
5990c064 | 185 | // The pad column number |
b864d801 | 186 | *bytePtr++ = col + 1; |
5990c064 | 187 | nbyte += 2; |
188 | ||
189 | Int_t nzero = 0; | |
928e9fae | 190 | for (Int_t time = 0; time < timeTotal; time++) { |
5990c064 | 191 | |
192 | Int_t data = digits->GetDataUnchecked(row,col,time); | |
193 | ||
194 | if (!data) { | |
195 | nzero++; | |
196 | if ((nzero == 256) || | |
928e9fae | 197 | (time == timeTotal-1)) { |
b864d801 | 198 | *bytePtr++ = 0; |
199 | *bytePtr++ = nzero-1; | |
5990c064 | 200 | nbyte += 2; |
201 | nzero = 0; | |
202 | } | |
203 | } | |
204 | else { | |
205 | if (nzero) { | |
b864d801 | 206 | *bytePtr++ = 0; |
207 | *bytePtr++ = nzero-1; | |
5990c064 | 208 | nbyte += 2; |
209 | nzero = 0; | |
210 | } | |
211 | // High byte (MSB always set) | |
b864d801 | 212 | *bytePtr++ = ((data >> 8) | 128); |
5990c064 | 213 | // Low byte |
b864d801 | 214 | *bytePtr++ = (data & 0xff); |
5990c064 | 215 | nbyte += 2; |
216 | } | |
217 | ||
218 | } | |
219 | ||
220 | } | |
221 | ||
222 | } | |
223 | ||
224 | } | |
225 | ||
226 | // Fill the end of the buffer with zeros | |
227 | while (nbyte % 4) { | |
b864d801 | 228 | *bytePtr++ = 0; |
5990c064 | 229 | nbyte++; |
230 | } | |
231 | ||
2745a409 | 232 | AliDebug(1,Form("det = %d, nbyte = %d (%d)",det,nbyte,bufferMax)); |
5990c064 | 233 | |
234 | // Write the subevent header | |
b864d801 | 235 | bytePtr = (unsigned char *) headerSubevent; |
236 | headerPtr = bytePtr; | |
237 | *bytePtr++ = kSubeventDummyFlag; | |
238 | *bytePtr++ = (det & 0xff); | |
239 | *bytePtr++ = (det >> 8); | |
240 | *bytePtr++ = (nbyte & 0xff); | |
241 | *bytePtr++ = (nbyte >> 8); | |
928e9fae | 242 | *bytePtr++ = (nbyte >> 16); |
b864d801 | 243 | *bytePtr++ = (npads & 0xff); |
244 | *bytePtr++ = (npads >> 8); | |
2cb20be6 | 245 | outputFile[iDDL]->write((char *) headerPtr,kSubeventHeaderLength); |
5990c064 | 246 | |
247 | // Write the buffer to the file | |
b864d801 | 248 | bytePtr = (unsigned char *) buffer; |
2cb20be6 | 249 | outputFile[iDDL]->write((char *) bytePtr,nbyte); |
5990c064 | 250 | |
b864d801 | 251 | ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength; |
5990c064 | 252 | |
253 | delete buffer; | |
254 | ||
255 | } | |
256 | ||
b864d801 | 257 | // Update the data headers and close the output files |
258 | for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) { | |
2745a409 | 259 | |
b864d801 | 260 | header.fSize = UInt_t(outputFile[iDDL]->tellp()) - bHPosition[iDDL]; |
261 | header.SetAttribute(0); // valid data | |
262 | outputFile[iDDL]->seekp(bHPosition[iDDL]); | |
2cb20be6 | 263 | outputFile[iDDL]->write((char *) (&header),sizeof(header)); |
b864d801 | 264 | |
265 | outputFile[iDDL]->close(); | |
266 | delete outputFile[iDDL]; | |
2745a409 | 267 | |
b864d801 | 268 | } |
5990c064 | 269 | |
270 | delete geo; | |
b864d801 | 271 | delete digitsManager; |
5990c064 | 272 | |
bc33499b | 273 | delete [] outputFile; |
274 | delete [] bHPosition; | |
275 | delete [] ntotalbyte; | |
276 | ||
5990c064 | 277 | return kTRUE; |
278 | ||
279 | } | |
280 | ||
281 | //_____________________________________________________________________________ | |
b864d801 | 282 | AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader* rawReader) |
5990c064 | 283 | { |
b864d801 | 284 | // |
285 | // Read the raw data digits and put them into the returned digits manager | |
286 | // | |
5990c064 | 287 | |
2cb20be6 | 288 | AliTRDdataArrayI *digits = 0; |
289 | AliTRDdataArrayI *track0 = 0; | |
290 | AliTRDdataArrayI *track1 = 0; | |
291 | AliTRDdataArrayI *track2 = 0; | |
5990c064 | 292 | |
bd0f8685 | 293 | AliTRDgeometry *geo = new AliTRDgeometry(); |
3551db50 | 294 | |
295 | AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance(); | |
2745a409 | 296 | if (!commonParam) { |
297 | AliError("Could not get common parameters\n"); | |
3551db50 | 298 | return 0; |
299 | } | |
300 | ||
301 | AliTRDcalibDB* calibration = AliTRDcalibDB::Instance(); | |
2745a409 | 302 | if (!calibration) { |
303 | AliError("Could not get calibration object\n"); | |
3551db50 | 304 | return 0; |
305 | } | |
5990c064 | 306 | |
307 | // Create the digits manager | |
b864d801 | 308 | AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager(); |
b864d801 | 309 | digitsManager->CreateArrays(); |
5990c064 | 310 | |
3551db50 | 311 | AliTRDRawStream input(rawReader); |
5990c064 | 312 | |
b864d801 | 313 | // Loop through the digits |
314 | while (input.Next()) { | |
5990c064 | 315 | |
b864d801 | 316 | Int_t det = input.GetDetector(); |
317 | Int_t npads = input.GetNPads(); | |
5990c064 | 318 | |
b864d801 | 319 | if (input.IsNewDetector()) { |
320 | ||
321 | if (digits) digits->Compress(1,0); | |
928e9fae | 322 | if (track0) track0->Compress(1,0); |
323 | if (track1) track1->Compress(1,0); | |
324 | if (track2) track2->Compress(1,0); | |
5990c064 | 325 | |
2745a409 | 326 | AliDebug(2,"Subevent header:"); |
327 | AliDebug(2,Form("\tdet = %d",det)); | |
328 | AliDebug(2,Form("\tnpads = %d",npads)); | |
5990c064 | 329 | |
330 | // Create the data buffer | |
331 | Int_t cham = geo->GetChamber(det); | |
332 | Int_t plan = geo->GetPlane(det); | |
333 | Int_t sect = geo->GetSector(det); | |
3551db50 | 334 | Int_t rowMax = commonParam->GetRowMax(plan,cham,sect); |
335 | Int_t colMax = commonParam->GetColMax(plan); | |
336 | Int_t timeTotal = calibration->GetNumberOfTimeBins(); | |
5990c064 | 337 | |
338 | // Add a container for the digits of this detector | |
b864d801 | 339 | digits = digitsManager->GetDigits(det); |
928e9fae | 340 | track0 = digitsManager->GetDictionary(det,0); |
341 | track1 = digitsManager->GetDictionary(det,1); | |
342 | track2 = digitsManager->GetDictionary(det,2); | |
5990c064 | 343 | // Allocate memory space for the digits buffer |
344 | if (digits->GetNtime() == 0) { | |
928e9fae | 345 | digits->Allocate(rowMax,colMax,timeTotal); |
346 | track0->Allocate(rowMax,colMax,timeTotal); | |
347 | track1->Allocate(rowMax,colMax,timeTotal); | |
348 | track2->Allocate(rowMax,colMax,timeTotal); | |
5990c064 | 349 | } |
350 | ||
5990c064 | 351 | } |
928e9fae | 352 | |
b864d801 | 353 | digits->SetDataUnchecked(input.GetRow(),input.GetColumn(), |
354 | input.GetTime(),input.GetSignal()); | |
928e9fae | 355 | track0->SetDataUnchecked(input.GetRow(),input.GetColumn(), |
2cb20be6 | 356 | input.GetTime(), 0); |
928e9fae | 357 | track1->SetDataUnchecked(input.GetRow(),input.GetColumn(), |
2cb20be6 | 358 | input.GetTime(), 0); |
928e9fae | 359 | track2->SetDataUnchecked(input.GetRow(),input.GetColumn(), |
2cb20be6 | 360 | input.GetTime(), 0); |
361 | ||
5990c064 | 362 | } |
363 | ||
b864d801 | 364 | if (digits) digits->Compress(1,0); |
928e9fae | 365 | if (track0) track0->Compress(1,0); |
366 | if (track1) track1->Compress(1,0); | |
367 | if (track2) track2->Compress(1,0); | |
b864d801 | 368 | |
5990c064 | 369 | delete geo; |
5990c064 | 370 | |
b864d801 | 371 | return digitsManager; |
5990c064 | 372 | |
373 | } |