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():TObject()
45 // Default constructor
50 //_____________________________________________________________________________
51 AliTRDrawData::~AliTRDrawData()
59 //_____________________________________________________________________________
60 Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree)
63 // Convert the digits to raw data byte stream. The output is written
64 // into the the binary files TRD_<DDL number>.ddl.
66 // The pseudo raw data format is currently defined like this:
70 // Subevent (= single chamber) header (8 bytes)
72 // Detector number (2 bytes)
73 // Number of data bytes (2 bytes)
74 // Number of pads with data (2 bytes)
80 const Int_t kNumberOfDDLs = AliDAQ::NumberOfDdls("TRD");
81 const Int_t kSubeventHeaderLength = 8;
82 const Int_t kSubeventDummyFlag = 0xBB;
83 Int_t headerSubevent[3];
85 ofstream **outputFile = new ofstream* [kNumberOfDDLs];
86 UInt_t *bHPosition = new UInt_t [kNumberOfDDLs];
87 Int_t *ntotalbyte = new Int_t [kNumberOfDDLs];
90 unsigned char *bytePtr;
91 unsigned char *headerPtr;
93 AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
95 // Read in the digit arrays
96 if (!digitsManager->ReadDigits(digitsTree)) {
101 AliTRDgeometry *geo = new AliTRDgeometry();
102 AliTRDdataArrayI *digits;
104 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
106 AliError("Could not get common parameters\n");
110 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
113 AliError("Could not get calibration object\n");
118 AliRawDataHeader header;
120 // Open the output files
121 for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
123 strcpy(name,AliDAQ::DdlFileName("TRD",iDDL));
125 outputFile[iDDL] = new ofstream(name, ios::binary);
127 outputFile[iDDL] = new ofstream(name);
130 // Write a dummy data header
131 bHPosition[iDDL] = outputFile[iDDL]->tellp();
132 outputFile[iDDL]->write((char*)(&header),sizeof(header));
133 ntotalbyte[iDDL] = 0;
136 // Loop through all detectors
137 for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
139 Int_t cham = geo->GetChamber(det);
140 Int_t plan = geo->GetPlane(det);
141 Int_t sect = geo->GetSector(det);
142 Int_t rowMax = commonParam->GetRowMax(plan,cham,sect);
143 Int_t colMax = commonParam->GetColMax(plan);
144 Int_t timeTotal = calibration->GetNumberOfTimeBins();
145 Int_t bufferMax = rowMax*colMax*timeTotal;
146 Int_t *buffer = new Int_t[bufferMax];
150 bytePtr = (unsigned char *) buffer;
154 // Get the digits array
155 digits = digitsManager->GetDigits(det);
158 // Loop through the detector pixel
159 for (Int_t col = 0; col < colMax; col++) {
160 for (Int_t row = 0; row < rowMax; row++) {
162 // Check whether data exists for this pad
163 Bool_t dataflag = kFALSE;
164 for (Int_t time = 0; time < timeTotal; time++) {
165 Int_t data = digits->GetDataUnchecked(row,col,time);
176 // The pad row number
177 *bytePtr++ = row + 1;
178 // The pad column number
179 *bytePtr++ = col + 1;
183 for (Int_t time = 0; time < timeTotal; time++) {
185 Int_t data = digits->GetDataUnchecked(row,col,time);
189 if ((nzero == 256) ||
190 (time == timeTotal-1)) {
192 *bytePtr++ = nzero-1;
200 *bytePtr++ = nzero-1;
204 // High byte (MSB always set)
205 *bytePtr++ = ((data >> 8) | 128);
207 *bytePtr++ = (data & 0xff);
219 // Fill the end of the buffer with zeros
225 AliDebug(1,Form("det = %d, nbyte = %d (%d)",det,nbyte,bufferMax));
227 // Write the subevent header
228 bytePtr = (unsigned char *) headerSubevent;
230 *bytePtr++ = kSubeventDummyFlag;
231 *bytePtr++ = (det & 0xff);
232 *bytePtr++ = (det >> 8);
233 *bytePtr++ = (nbyte & 0xff);
234 *bytePtr++ = (nbyte >> 8);
235 *bytePtr++ = (nbyte >> 16);
236 *bytePtr++ = (npads & 0xff);
237 *bytePtr++ = (npads >> 8);
238 outputFile[iDDL]->write((char*)headerPtr,kSubeventHeaderLength);
240 // Write the buffer to the file
241 bytePtr = (unsigned char *) buffer;
242 outputFile[iDDL]->write((char*)bytePtr,nbyte);
244 ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength;
250 // Update the data headers and close the output files
251 for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) {
253 header.fSize = UInt_t(outputFile[iDDL]->tellp()) - bHPosition[iDDL];
254 header.SetAttribute(0); // valid data
255 outputFile[iDDL]->seekp(bHPosition[iDDL]);
256 outputFile[iDDL]->write((char*)(&header),sizeof(header));
258 outputFile[iDDL]->close();
259 delete outputFile[iDDL];
264 delete digitsManager;
266 delete [] outputFile;
267 delete [] bHPosition;
268 delete [] ntotalbyte;
274 //_____________________________________________________________________________
275 AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader* rawReader)
278 // Read the raw data digits and put them into the returned digits manager
281 AliTRDdataArrayI *digits = 0;
282 AliTRDdataArrayI *track0 = 0;
283 AliTRDdataArrayI *track1 = 0;
284 AliTRDdataArrayI *track2 = 0;
286 AliTRDgeometry *geo = new AliTRDgeometry();
288 AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
290 AliError("Could not get common parameters\n");
294 AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
296 AliError("Could not get calibration object\n");
300 // Create the digits manager
301 AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
302 digitsManager->CreateArrays();
304 AliTRDRawStream input(rawReader);
306 // Loop through the digits
307 while (input.Next()) {
309 Int_t det = input.GetDetector();
310 Int_t npads = input.GetNPads();
312 if (input.IsNewDetector()) {
314 if (digits) digits->Compress(1,0);
315 if (track0) track0->Compress(1,0);
316 if (track1) track1->Compress(1,0);
317 if (track2) track2->Compress(1,0);
319 AliDebug(2,"Subevent header:");
320 AliDebug(2,Form("\tdet = %d",det));
321 AliDebug(2,Form("\tnpads = %d",npads));
323 // Create the data buffer
324 Int_t cham = geo->GetChamber(det);
325 Int_t plan = geo->GetPlane(det);
326 Int_t sect = geo->GetSector(det);
327 Int_t rowMax = commonParam->GetRowMax(plan,cham,sect);
328 Int_t colMax = commonParam->GetColMax(plan);
329 Int_t timeTotal = calibration->GetNumberOfTimeBins();
331 // Add a container for the digits of this detector
332 digits = digitsManager->GetDigits(det);
333 track0 = digitsManager->GetDictionary(det,0);
334 track1 = digitsManager->GetDictionary(det,1);
335 track2 = digitsManager->GetDictionary(det,2);
336 // Allocate memory space for the digits buffer
337 if (digits->GetNtime() == 0) {
338 digits->Allocate(rowMax,colMax,timeTotal);
339 track0->Allocate(rowMax,colMax,timeTotal);
340 track1->Allocate(rowMax,colMax,timeTotal);
341 track2->Allocate(rowMax,colMax,timeTotal);
346 digits->SetDataUnchecked(input.GetRow(),input.GetColumn(),
347 input.GetTime(),input.GetSignal());
348 track0->SetDataUnchecked(input.GetRow(),input.GetColumn(),
349 input.GetTime(), -1);
350 track1->SetDataUnchecked(input.GetRow(),input.GetColumn(),
351 input.GetTime(), -1);
352 track2->SetDataUnchecked(input.GetRow(),input.GetColumn(),
353 input.GetTime(), -1);
356 if (digits) digits->Compress(1,0);
357 if (track0) track0->Compress(1,0);
358 if (track1) track1->Compress(1,0);
359 if (track2) track2->Compress(1,0);
363 return digitsManager;