1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // TRD raw data conversion class //
22 ///////////////////////////////////////////////////////////////////////////////
24 #include <Riostream.h>
27 #include "AliRawDataHeader.h"
28 #include "AliRawReader.h"
31 #include "AliTRDrawData.h"
32 #include "AliTRDdigitsManager.h"
33 #include "AliTRDgeometry.h"
34 #include "AliTRDdataArrayI.h"
35 #include "AliTRDRawStream.h"
36 #include "AliTRDCommonParam.h"
37 #include "AliTRDcalibDB.h"
39 ClassImp(AliTRDrawData)
41 //_____________________________________________________________________________
42 AliTRDrawData::AliTRDrawData()
46 // Default constructor
51 //_____________________________________________________________________________
52 AliTRDrawData::~AliTRDrawData()
60 //_____________________________________________________________________________
61 Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree)
64 // Convert the digits to raw data byte stream. The output is written
65 // into the the binary files TRD_<DDL number>.ddl.
67 // The pseudo raw data format is currently defined like this:
71 // Subevent (= single chamber) header (8 bytes)
73 // Detector number (2 bytes)
74 // Number of data bytes (2 bytes)
75 // Number of pads with data (2 bytes)
81 const Int_t kNumberOfDDLs = AliDAQ::NumberOfDdls("TRD");
82 const Int_t kSubeventHeaderLength = 8;
83 const Int_t kSubeventDummyFlag = 0xBB;
84 Int_t headerSubevent[3];
86 ofstream **outputFile = new ofstream* [kNumberOfDDLs];
87 UInt_t *bHPosition = new UInt_t [kNumberOfDDLs];
88 Int_t *ntotalbyte = new Int_t [kNumberOfDDLs];
91 unsigned char *bytePtr;
92 unsigned char *headerPtr;
94 AliTRDdigitsManager *digitsManager = new AliTRDdigitsManager();
96 // Read in the digit arrays
97 if (!digitsManager->ReadDigits(digitsTree)) {
102 AliTRDgeometry *geo = new AliTRDgeometry();
103 AliTRDdataArrayI *digits;
105 AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
107 AliError("Could not get common parameters\n");
111 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
114 AliError("Could not get calibration object\n");
119 AliRawDataHeader header;
121 // Open the output files
122 for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
125 strcpy(name,AliDAQ::DdlFileName("TRD",iDDL));
127 outputFile[iDDL] = new ofstream(name, ios::binary);
129 outputFile[iDDL] = new ofstream(name);
132 // Write a dummy data header
133 bHPosition[iDDL] = outputFile[iDDL]->tellp();
134 outputFile[iDDL]->write((char*)(&header),sizeof(header));
135 ntotalbyte[iDDL] = 0;
139 // Loop through all detectors
140 for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
142 Int_t cham = geo->GetChamber(det);
143 Int_t plan = geo->GetPlane(det);
144 Int_t sect = geo->GetSector(det);
145 Int_t rowMax = commonParam->GetRowMax(plan,cham,sect);
146 Int_t colMax = commonParam->GetColMax(plan);
147 Int_t timeTotal = calibration->GetNumberOfTimeBins();
148 Int_t bufferMax = rowMax*colMax*timeTotal;
149 Int_t *buffer = new Int_t[bufferMax];
153 bytePtr = (unsigned char *) buffer;
157 // Get the digits array
158 digits = digitsManager->GetDigits(det);
160 // This is to take care of switched off super modules
161 if (digits->GetNtime() == 0) {
165 // Loop through the detector pixel
166 for (Int_t col = 0; col < colMax; col++) {
167 for (Int_t row = 0; row < rowMax; row++) {
169 // Check whether data exists for this pad
170 Bool_t dataflag = kFALSE;
171 for (Int_t time = 0; time < timeTotal; time++) {
172 Int_t data = digits->GetDataUnchecked(row,col,time);
183 // The pad row number
184 *bytePtr++ = row + 1;
185 // The pad column number
186 *bytePtr++ = col + 1;
190 for (Int_t time = 0; time < timeTotal; time++) {
192 Int_t data = digits->GetDataUnchecked(row,col,time);
196 if ((nzero == 256) ||
197 (time == timeTotal-1)) {
199 *bytePtr++ = nzero-1;
207 *bytePtr++ = nzero-1;
211 // High byte (MSB always set)
212 *bytePtr++ = ((data >> 8) | 128);
214 *bytePtr++ = (data & 0xff);
226 // Fill the end of the buffer with zeros
232 AliDebug(1,Form("det = %d, nbyte = %d (%d)",det,nbyte,bufferMax));
234 // Write the subevent header
235 bytePtr = (unsigned char *) headerSubevent;
237 *bytePtr++ = kSubeventDummyFlag;
238 *bytePtr++ = (det & 0xff);
239 *bytePtr++ = (det >> 8);
240 *bytePtr++ = (nbyte & 0xff);
241 *bytePtr++ = (nbyte >> 8);
242 *bytePtr++ = (nbyte >> 16);
243 *bytePtr++ = (npads & 0xff);
244 *bytePtr++ = (npads >> 8);
245 outputFile[iDDL]->write((char *) headerPtr,kSubeventHeaderLength);
247 // Write the buffer to the file
248 bytePtr = (unsigned char *) buffer;
249 outputFile[iDDL]->write((char *) bytePtr,nbyte);
251 ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength;
257 // Update the data headers and close the output files
258 for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
260 header.fSize = UInt_t(outputFile[iDDL]->tellp()) - bHPosition[iDDL];
261 header.SetAttribute(0); // valid data
262 outputFile[iDDL]->seekp(bHPosition[iDDL]);
263 outputFile[iDDL]->write((char *) (&header),sizeof(header));
265 outputFile[iDDL]->close();
266 delete outputFile[iDDL];
271 delete digitsManager;
273 delete [] outputFile;
274 delete [] bHPosition;
275 delete [] ntotalbyte;
281 //_____________________________________________________________________________
282 AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader* rawReader)
285 // Read the raw data digits and put them into the returned digits manager
288 AliTRDdataArrayI *digits = 0;
289 AliTRDdataArrayI *track0 = 0;
290 AliTRDdataArrayI *track1 = 0;
291 AliTRDdataArrayI *track2 = 0;
293 AliTRDgeometry *geo = new AliTRDgeometry();
295 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
297 AliError("Could not get common parameters\n");
301 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
303 AliError("Could not get calibration object\n");
307 // Create the digits manager
308 AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
309 digitsManager->CreateArrays();
311 AliTRDRawStream input(rawReader);
313 // Loop through the digits
314 while (input.Next()) {
316 Int_t det = input.GetDetector();
317 Int_t npads = input.GetNPads();
319 if (input.IsNewDetector()) {
321 if (digits) digits->Compress(1,0);
322 if (track0) track0->Compress(1,0);
323 if (track1) track1->Compress(1,0);
324 if (track2) track2->Compress(1,0);
326 AliDebug(2,"Subevent header:");
327 AliDebug(2,Form("\tdet = %d",det));
328 AliDebug(2,Form("\tnpads = %d",npads));
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);
334 Int_t rowMax = commonParam->GetRowMax(plan,cham,sect);
335 Int_t colMax = commonParam->GetColMax(plan);
336 Int_t timeTotal = calibration->GetNumberOfTimeBins();
338 // Add a container for the digits of this detector
339 digits = digitsManager->GetDigits(det);
340 track0 = digitsManager->GetDictionary(det,0);
341 track1 = digitsManager->GetDictionary(det,1);
342 track2 = digitsManager->GetDictionary(det,2);
343 // Allocate memory space for the digits buffer
344 if (digits->GetNtime() == 0) {
345 digits->Allocate(rowMax,colMax,timeTotal);
346 track0->Allocate(rowMax,colMax,timeTotal);
347 track1->Allocate(rowMax,colMax,timeTotal);
348 track2->Allocate(rowMax,colMax,timeTotal);
353 digits->SetDataUnchecked(input.GetRow(),input.GetColumn(),
354 input.GetTime(),input.GetSignal());
355 track0->SetDataUnchecked(input.GetRow(),input.GetColumn(),
357 track1->SetDataUnchecked(input.GetRow(),input.GetColumn(),
359 track2->SetDataUnchecked(input.GetRow(),input.GetColumn(),
364 if (digits) digits->Compress(1,0);
365 if (track0) track0->Compress(1,0);
366 if (track1) track1->Compress(1,0);
367 if (track2) track2->Compress(1,0);
371 return digitsManager;