Typo corrected
[u/mrichter/AliRoot.git] / TRD / AliTRDrawData.cxx
CommitLineData
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"
50378239 37
3551db50 38#include "AliTRDcalibDB.h"
5990c064 39
40ClassImp(AliTRDrawData)
41
42//_____________________________________________________________________________
2cb20be6 43AliTRDrawData::AliTRDrawData()
44 :TObject()
bd63bf88 45 ,fRawVersion(2) // Default Raw Data version set here
8c703901 46 ,fGeo(0)
47 ,fNumberOfDDLs(0)
5990c064 48{
b864d801 49 //
50 // Default constructor
51 //
5990c064 52
5990c064 53}
54
55//_____________________________________________________________________________
8c703901 56AliTRDrawData::AliTRDrawData(const AliTRDrawData &r)
57 :TObject(r)
bd63bf88 58 ,fRawVersion(2) // Default Raw Data version set here
8c703901 59 ,fGeo(0)
60 ,fNumberOfDDLs(0)
61{
62 //
63 // Copy constructor
64 //
65
66}
67
68//_____________________________________________________________________________
5990c064 69AliTRDrawData::~AliTRDrawData()
70{
71 //
72 // Destructor
73 //
74
5990c064 75}
76
77//_____________________________________________________________________________
8c703901 78Bool_t AliTRDrawData::SetRawVersion(Int_t v)
5990c064 79{
80 //
7925de54 81 // Set the raw data version (Currently only version 0, 1 and 2 are available)
8c703901 82 //
83
7925de54 84 if ( (v >= 0) && (v <= 2) ) {
8c703901 85 fRawVersion = v;
86 return kTRUE;
87 }
88
89 return kFALSE;
90
91}
92
93//_____________________________________________________________________________
94Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree, TTree *tracks )
95{
96 //
97 // Initialize necessary parameters and call one
98 // of the raw data simulator selected by SetRawVersion.
99 //
100 // Currently tracklet output is not spported yet and it
101 // will be supported in higher version simulator.
102 //
103
104 fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD");
105
106 AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
107
108 if (!digitsManager->ReadDigits(digitsTree)) {
109 delete digitsManager;
110 return kFALSE;
111 }
112
113 if (tracks != NULL) {
114 delete digitsManager;
7925de54 115 AliError("Tracklet input is not supported yet.");
8c703901 116 return kFALSE;
117 }
118
119 fGeo = new AliTRDgeometry();
120
f162af62 121 if (!AliTRDcalibDB::Instance()) {
7925de54 122 AliError("Could not get calibration object");
8c703901 123 delete fGeo;
124 delete digitsManager;
125 return kFALSE;
126 }
127
128 Int_t retval = kTRUE;
129
130 // Call appropriate Raw Simulator
50378239 131 if ( fRawVersion > 0 && fRawVersion <= 2 ) retval = Digits2Raw(digitsManager);
7925de54 132 else {
133 retval = kFALSE;
134 AliWarning(Form("Unsupported raw version (fRawVersion=%d).",fRawVersion));
8c703901 135 }
136
137 // Cleanup
138 delete fGeo;
139 delete digitsManager;
140
141 return retval;
142
143}
144
145//_____________________________________________________________________________
50378239 146Bool_t AliTRDrawData::Digits2Raw(AliTRDdigitsManager *digitsManager)
8c703901 147{
148 //
7925de54 149 // Raw data simulator for all versions > 0. This is prepared for real data.
8c703901 150 // This version simulate only raw data with ADC data and not with tracklet.
8c703901 151 //
152
7925de54 153 const Int_t kMaxHcWords = (fGeo->TBmax()/3)*fGeo->ADCmax()*fGeo->MCMmax()*fGeo->ROBmaxC1()/2 + 100 + 20;
8c703901 154
155 // Buffer to temporary store half chamber data
156 UInt_t *hc_buffer = new UInt_t[kMaxHcWords];
157
158 // sect is same as iDDL, so I use only sect here.
159 for (Int_t sect = 0; sect < fGeo->Nsect(); sect++) {
160
161 char name[1024];
162 sprintf(name,"TRD_%d.ddl",sect + AliTRDRawStream::kDDLOffset);
163
164#ifndef __DECCXX
165 ofstream *of = new ofstream(name, ios::binary);
166#else
167 ofstream *of = new ofstream(name);
168#endif
169
170 // Write a dummy data header
171 AliRawDataHeader header; // the event header
172 UInt_t hpos = of->tellp();
173 of->write((char *) (& header), sizeof(header));
174
175 // Reset payload byte size (payload does not include header).
176 Int_t npayloadbyte = 0;
177
7925de54 178 // GTU common data header (5x4 bytes per super module, shows link mask)
8c703901 179 for( Int_t cham = 0; cham < fGeo->Ncham(); cham++ ) {
777fe13b 180 UInt_t GtuCdh = (UInt_t)(0xe << 28);
7925de54 181 for( Int_t plan = 0; plan < fGeo->Nplan(); plan++) {
182 Int_t iDet = fGeo->GetDetector(plan, cham, sect);
183 // If chamber status is ok, we assume that the optical link is also OK.
184 // This is shown in the GTU link mask.
f162af62 185 if ( AliTRDcalibDB::Instance()->GetChamberStatus(iDet) )
7925de54 186 GtuCdh = GtuCdh | (3 << (2*plan));
187 }
8c703901 188 of->write((char *) (& GtuCdh), sizeof(GtuCdh));
189 npayloadbyte += 4;
190 }
191
192 // Prepare chamber data
193 for( Int_t cham = 0; cham < fGeo->Ncham(); cham++) {
194 for( Int_t plan = 0; plan < fGeo->Nplan(); plan++) {
195
196 Int_t iDet = fGeo->GetDetector(plan,cham,sect);
197
198 // Get the digits array
199 AliTRDdataArrayI *digits = digitsManager->GetDigits(iDet);
200 digits->Expand();
201
7925de54 202 Int_t hcwords = 0;
8c703901 203
204 // Process A side of the chamber
7925de54 205 if ( fRawVersion >= 1 && fRawVersion <= 2 ) hcwords = ProduceHcDataV1andV2(digits,0,iDet,hc_buffer,kMaxHcWords);
8c703901 206 of->write((char *) hc_buffer, hcwords*4);
207 npayloadbyte += hcwords*4;
208
209 // Process B side of the chamber
7925de54 210 if ( fRawVersion >= 1 && fRawVersion <= 2 ) hcwords = ProduceHcDataV1andV2(digits,1,iDet,hc_buffer,kMaxHcWords);
8c703901 211 of->write((char *) hc_buffer, hcwords*4);
212 npayloadbyte += hcwords*4;
213
214 }
215 }
216
217 // Complete header
218 header.fSize = UInt_t(of->tellp()) - hpos;
219 header.SetAttribute(0); // Valid data
220 of->seekp(hpos); // Rewind to header position
221 of->write((char *) (& header), sizeof(header));
222 of->close();
223 delete of;
224
225 }
226
227 delete hc_buffer;
228 return kTRUE;
229
230}
231
232//_____________________________________________________________________________
7925de54 233Int_t AliTRDrawData::ProduceHcDataV1andV2(AliTRDdataArrayI *digits, Int_t side
234 , Int_t det, UInt_t *buf, Int_t maxSize)
8c703901 235{
236 //
7925de54 237 // This function simulates: 1) SM-I commissiong data Oct. 06 (fRawVersion == 1).
238 // 2) Full Raw Production Version (fRawVersion == 2)
239 //
8c703901 240 // Produce half chamber data (= an ORI data) for the given chamber (det) and side (side)
241 // where
7925de54 242 //
8c703901 243 // side=0 means A side with ROB positions 0, 2, 4, 6.
244 // side=1 means B side with ROB positions 1, 3, 5, 7.
245 //
246 // Chamber type (C0 orC1) is determined by "det" automatically.
247 // Appropriate size of buffer (*buf) must be prepared prior to calling this function.
248 // Pointer to the buffer and its size must be given to "buf" and "maxSize".
249 // Return value is the number of valid data filled in the buffer in unit of 32 bits
250 // UInt_t words.
251 // If buffer size if too small, the data is truncated with the buffer size however
252 // the function will finish without crash (this behaviour is similar to the MCM).
253 //
254
255 Int_t nw = 0; // Number of written words
256 Int_t of = 0; // Number of overflowed words
257 Int_t plan = fGeo->GetPlane( det ); // Plane
258 Int_t cham = fGeo->GetChamber( det ); // Chamber
259 Int_t sect = fGeo->GetSector( det ); // Sector (=iDDL)
f162af62 260 Int_t nRow = fGeo->GetRowMax( plan, cham, sect );
261 Int_t nCol = fGeo->GetColMax( plan );
262 const Int_t nTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
8c703901 263 Int_t kCtype = 0; // Chamber type (0:C0, 1:C1)
264 Int_t iEv = 0xA; // Event ID. Now fixed to 10, how do I get event id?
265 UInt_t x = 0; // General used number
266
267 // Check the nCol and nRow.
268 if ((nCol == 144) &&
269 (nRow == 16 || nRow == 12)) {
270 kCtype = (nRow-12) / 4;
271 }
272 else {
7925de54 273 AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d)."
8c703901 274 ,nRow,nCol));
275 return 0;
276 }
277
278 AliDebug(1,Form("Producing raw data for sect=%d plan=%d cham=%d side=%d"
279 ,sect,plan,cham,side));
280
281 // Tracklet should be processed here but not implemented yet
282
283 // Write end of tracklet marker
284 if (nw < maxSize) {
bd63bf88 285 buf[nw++] = kEndoftrackletmarker;
8c703901 286 }
287 else {
288 of++;
289 }
290
291 // Half Chamber header
7925de54 292 if ( fRawVersion == 1 ) {
293 // Now it is the same version as used in SM-I commissioning.
294 Int_t dcs = det+100; // DCS Serial (in simulation, it is meaningless
295 x = (dcs<<20) | (sect<<15) | (plan<<12) | (cham<<9) | (side<<8) | 1;
296 if (nw < maxSize) {
297 buf[nw++] = x;
298 }
299 else {
300 of++;
301 }
302 }
303 else if ( fRawVersion == 2 ) {
bd63bf88 304 // h[0] (there are 3 HC header)
7925de54 305 Int_t minorv = 0; // The minor version number
306 Int_t add = 1; // The number of additional header words to follow
307 x = (1<<31) | (fRawVersion<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (plan<<6) | (cham<<3) | (side<<2) | 1;
308 if (nw < maxSize) {
309 buf[nw++] = x;
310 }
311 else {
312 of++;
313 }
314 // h[1]
315 Int_t bc_ctr = 99; // bunch crossing counter. Here it is set to 99 always for no reason
316 Int_t pt_ctr = 15; // pretrigger counter. Here it is set to 15 always for no reason
317 Int_t pt_phase = 11; // pretrigger phase. Here it is set to 11 always for no reason
318 x = (bc_ctr<<16) | (pt_ctr<<12) | (pt_phase<<8) | ((nTBin-1)<<2) | 1;
319 if (nw < maxSize) {
320 buf[nw++] = x;
321 }
322 else {
323 of++;
324 }
bd63bf88 325 // h[2]
326 Int_t ped_setup = 1; // Pedestal filter setup (0:1). Here it is always 1 for no reason
327 Int_t gain_setup = 1; // Gain filter setup (0:1). Here it is always 1 for no reason
328 Int_t tail_setup = 1; // Tail filter setup (0:1). Here it is always 1 for no reason
329 Int_t xt_setup = 0; // Cross talk filter setup (0:1). Here it is always 0 for no reason
330 Int_t nonlin_setup = 0; // Nonlinearity filter setup (0:1). Here it is always 0 for no reason
331 Int_t bypass_setup = 0; // Filter bypass (for raw data) setup (0:1). Here it is always 0 for no reason
332 Int_t common_additive = 10; // Digital filter common additive (0:63). Here it is always 10 for no reason
333 x = (ped_setup<<31) | (gain_setup<<30) | (tail_setup<<29) | (xt_setup<<28) | (nonlin_setup<<27)
334 | (bypass_setup<<26) | (common_additive<<20) | 1;
335 if (nw < maxSize) {
336 buf[nw++] = x;
337 }
338 else {
339 of++;
340 }
8c703901 341 }
342
343 // Scan for ROB and MCM
344 for (Int_t iRobRow = 0; iRobRow < (kCtype + 3); iRobRow++ ) {
345 Int_t iRob = iRobRow * 2 + side;
7925de54 346 for (Int_t iMcm = 0; iMcm < fGeo->MCMmax(); iMcm++ ) {
8c703901 347 Int_t padrow = iRobRow * 4 + iMcm / 4;
348
349 // MCM header
7925de54 350 x = ((iRob * fGeo->MCMmax() + iMcm) << 24) | ((iEv % 0x100000) << 4) | 0xC;
8c703901 351 if (nw < maxSize) {
352 buf[nw++] = x;
353 }
354 else {
355 of++;
356 }
357
358 // ADC data
359 for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) {
bd63bf88 360 Int_t padcol = fGeo->GetPadColFromADC(iRob, iMcm, iAdc);
7925de54 361 UInt_t aa = !(iAdc & 1) + 2;
8c703901 362 UInt_t *a = new UInt_t[nTBin+2];
363 // 3 timebins are packed into one 32 bits word
364 for (Int_t iT = 0; iT < nTBin; iT+=3) {
7925de54 365 if ((padcol >= 0) && (padcol < nCol)) {
366 a[iT ] = ((iT ) < nTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT ) : 0;
367 a[iT+1] = ((iT + 1) < nTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT + 1) : 0;
368 a[iT+2] = ((iT + 2) < nTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT + 2) : 0;
369 }
370 else {
371 a[iT] = a[iT+1] = a[iT+2] = 0; // This happenes at the edge of chamber (should be pedestal! How?)
8c703901 372 }
7925de54 373 x = (a[iT+2] << 22) | (a[iT+1] << 12) | (a[iT] << 2) | aa;
374 if (nw < maxSize) {
375 buf[nw++] = x;
8c703901 376 }
7925de54 377 else {
378 of++;
8c703901 379 }
7925de54 380 }
8c703901 381 // Diagnostics
382 Float_t avg = 0;
383 Float_t rms = 0;
384 for (Int_t iT = 0; iT < nTBin; iT++) {
385 avg += (Float_t) (a[iT]);
386 }
387 avg /= (Float_t) nTBin;
388 for (Int_t iT = 0; iT < nTBin; iT++) {
389 rms += ((Float_t) (a[iT]) - avg) * ((Float_t) (a[iT]) - avg);
390 }
391 rms = TMath::Sqrt(rms / (Float_t) nTBin);
392 if (rms > 1.7) {
7925de54 393 AliDebug(2,Form("Large RMS (>1.7) (ROB,MCM,ADC)=(%02d,%02d,%02d), avg=%03.1f, rms=%03.1f"
394 ,iRob,iMcm,iAdc,avg,rms));
8c703901 395 }
396 delete a;
397 }
398 }
399 }
400
401 // Write end of raw data marker
402 if (nw < maxSize) {
bd63bf88 403 buf[nw++] = kEndofrawdatamarker;
8c703901 404 }
405 else {
406 of++;
407 }
408 if (of != 0) {
409 AliWarning("Buffer overflow. Data is truncated. Please increase buffer size and recompile.");
410 }
411
412 return nw;
5990c064 413
414}
415
416//_____________________________________________________________________________
7925de54 417AliTRDdigitsManager *AliTRDrawData::Raw2Digits(AliRawReader *rawReader)
5990c064 418{
b864d801 419 //
50378239 420 // Vx of the raw data reading
b864d801 421 //
5990c064 422
2cb20be6 423 AliTRDdataArrayI *digits = 0;
424 AliTRDdataArrayI *track0 = 0;
425 AliTRDdataArrayI *track1 = 0;
426 AliTRDdataArrayI *track2 = 0;
5990c064 427
5990c064 428 // Create the digits manager
b864d801 429 AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager();
b864d801 430 digitsManager->CreateArrays();
5990c064 431
3551db50 432 AliTRDRawStream input(rawReader);
50378239 433 input.SetRawVersion( fRawVersion );
434 input.Init();
5990c064 435
b864d801 436 // Loop through the digits
50378239 437 Int_t lastdet = -1;
438 Int_t det = 0;
439 Int_t it = 0;
440 while (input.Next())
441 {
442
443 det = input.GetDet();
444
445 if (det != lastdet)
446 {
447
448 lastdet = det;
449
450 if (digits) digits->Compress(1,0);
451 if (track0) track0->Compress(1,0);
452 if (track1) track1->Compress(1,0);
453 if (track2) track2->Compress(1,0);
454
455 // Add a container for the digits of this detector
456 digits = digitsManager->GetDigits(det);
457 track0 = digitsManager->GetDictionary(det,0);
458 track1 = digitsManager->GetDictionary(det,1);
459 track2 = digitsManager->GetDictionary(det,2);
460
461 // Allocate memory space for the digits buffer
462 if (digits->GetNtime() == 0)
463 {
464 digits->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
465 track0->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
466 track1->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
467 track2->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins());
468 }
469 }
470
471 for (it = 0; it < 3; it++)
472 {
473 if ( input.GetTimeBin() + it < input.GetNumberOfTimeBins() )
474 {
475 digits->SetDataUnchecked(input.GetRow(), input.GetCol(),
476 input.GetTimeBin() + it, input.GetSignals()[it]);
477 track0->SetDataUnchecked(input.GetRow(), input.GetCol(),
478 input.GetTimeBin() + it, 0);
479 track1->SetDataUnchecked(input.GetRow(), input.GetCol(),
480 input.GetTimeBin() + it, 0);
481 track2->SetDataUnchecked(input.GetRow(), input.GetCol(),
482 input.GetTimeBin() + it, 0);
2cb20be6 483
50378239 484 }
485 }
5990c064 486 }
487
b864d801 488 if (digits) digits->Compress(1,0);
928e9fae 489 if (track0) track0->Compress(1,0);
490 if (track1) track1->Compress(1,0);
491 if (track2) track2->Compress(1,0);
b864d801 492
7925de54 493 return digitsManager;
494
495}