Replacing string comparison by coparison of enums
[u/mrichter/AliRoot.git] / RAW / AliRawEventHeaderBase.cxx
CommitLineData
f2dc6b20 1/**************************************************************************
2 * Copyright(c) 1998-2003, 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
9edefa04 16/* $Id$ */
17
18// Author: Cvetan Cheshkov 10/10/2005
19
f2dc6b20 20//////////////////////////////////////////////////////////////////////////
21// //
22// AliRawEventHeaderBase //
23// This a new versioning scheme for raw data root-ification and reading //
24// For details look at offline weekly meeting 20/10/2005 //
25// //
26//////////////////////////////////////////////////////////////////////////
27
28#include <unistd.h>
29
9edefa04 30#include <Bytes.h>
f2dc6b20 31#include <TClass.h>
32#include <TDataMember.h>
7ca4655f 33#include <TList.h>
f2dc6b20 34#include <TMethodCall.h>
57aaba19 35#include <TDataType.h>
f2dc6b20 36
37#include "AliLog.h"
38#include "AliRawEventHeaderBase.h"
39
12e921cc 40#include <Riostream.h>
f2dc6b20 41
714281ef 42using std::cout;
43using std::endl;
f2dc6b20 44ClassImp(AliRawEventHeaderBase)
45
f3c1e83c 46//______________________________________________________________________________
47AliRawEventHeaderBase::AliRawEventHeaderBase():
48fSize(0),
49fMagic(0),
50fHeadSize(0),
51fVersion(0),
52fExtendedDataSize(0),
33778962 53fExtendedAllocSize(0),
f3c1e83c 54fExtendedData(NULL),
936875a4 55fIsSwapped(kFALSE),
33314186 56fHeaderSize(0),
57fHeaderBegin(NULL),
58fFirstEqIndex(-1),
59fLastEqIndex(-1)
f3c1e83c 60{
61 // Default constructor
62}
f2dc6b20 63
64//______________________________________________________________________________
33314186 65void *AliRawEventHeaderBase::HeaderBegin() const
f2dc6b20 66{
67 // Returns the pointer to the first data member
68 // beyond the base class data members
69
33314186 70 if (fHeaderBegin) return fHeaderBegin;
71
f2dc6b20 72 TList *datalist = IsA()->GetListOfDataMembers();
73 TIter next(datalist);
74 TDataMember *member = (TDataMember *)next();
75
76 if(!strcmp(member->GetTypeName(),"TClass"))
77 member = (TDataMember *)next();
78
33314186 79 void *ptr = (void *)((char *)this+member->GetOffset());
80 const_cast<AliRawEventHeaderBase*>(this)->fHeaderBegin = ptr;
81
82 return ptr;
f2dc6b20 83}
84
85//______________________________________________________________________________
86Int_t AliRawEventHeaderBase::HeaderSize() const
87{
88 // Returns the size of the data members list
89 // beyond the base class data members
90
936875a4 91 if (fHeaderSize) return fHeaderSize;
92
f2dc6b20 93 Int_t size = 0;
94
95 TList *datalist = IsA()->GetListOfDataMembers();
96 TIter next(datalist);
97 TDataMember *member;
98 while ((member=(TDataMember *)next()) != 0x0) {
99 if (!strcmp(member->GetTypeName(),"TClass")) continue;
100 UInt_t unitsize = member->GetUnitSize();
101 UInt_t ndim = member->GetArrayDim();
102 if (ndim == 0)
103 size += unitsize;
104 else
105 for(UInt_t i=0;i<ndim;i++) size += member->GetMaxIndex(i)*unitsize;
106 }
107
936875a4 108 const_cast<AliRawEventHeaderBase*>(this)->fHeaderSize = size;
109
f2dc6b20 110 return size;
111}
112
113//______________________________________________________________________________
e653e3e1 114UInt_t AliRawEventHeaderBase::SwapWord(UInt_t x) const
115{
116 // Swap the endianess of the integer value 'x'
117
118 return (((x & 0x000000ffU) << 24) | ((x & 0x0000ff00U) << 8) |
119 ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
120}
121
f2dc6b20 122void AliRawEventHeaderBase::Swap()
123{
124 // Swap base header data.
125 // Update the fIsSwapped flag which
126 // is then use to copy in an appropriate way
127 // the rest of the header data from the raw data stream
128
129 if (IsSwapped()) {
130 fIsSwapped = kTRUE;
e653e3e1 131 fSize = SwapWord(fSize);
132 fMagic = SwapWord(fMagic);
133 fHeadSize = SwapWord(fHeadSize);
134 fVersion = SwapWord(fVersion);
f2dc6b20 135 }
136}
137
138//______________________________________________________________________________
12e921cc 139const char *AliRawEventHeaderBase::GetTypeName() const
f2dc6b20 140{
141 // Get event type as a string.
142 // Will fail in case data header
143 // does not contain eventType field
ec835ab5 144 UInt_t eventType = Get("Type");
145
146 return GetTypeName(eventType);
147}
148
149//______________________________________________________________________________
150const char *AliRawEventHeaderBase::GetTypeName(UInt_t eventType)
151{
152 // Get event type as a string.
153 // Static method that could be used
154 // from everywhere inside aliroot
f2dc6b20 155
156 switch (eventType) {
157 case kStartOfRun:
158 return "START_OF_RUN";
159 break;
160 case kEndOfRun:
161 return "END_OF_RUN";
162 break;
163 case kStartOfRunFiles:
164 return "START_OF_RUN_FILES";
165 break;
166 case kEndOfRunFiles:
167 return "END_OF_RUN_FILES";
168 break;
169 case kStartOfBurst:
170 return "START_OF_BURST";
171 break;
172 case kEndOfBurst:
173 return "END_OF_BURST";
174 break;
175 case kPhysicsEvent:
176 return "PHYSICS_EVENT";
177 break;
178 case kCalibrationEvent:
179 return "CALIBRATION_EVENT";
180 break;
181 case kFormatError:
182 return "EVENT_FORMAT_ERROR";
183 break;
cce65444 184 case kStartOfData:
185 return "START_OF_DATA";
186 break;
187 case kEndOfData:
188 return "END_OF_DATA";
189 break;
190 case kSystemSoftwareTriggerEvent:
191 return "SYSTEM_SOFTWARE_TRIGGER_EVENT";
192 break;
193 case kDetectorSoftwareTriggerEvent:
194 return "DETECTOR_SOFTWARE_TRIGGER_EVENT";
195 break;
f2dc6b20 196 default:
197 return "UNKNOWN EVENT TYPE NUMBER";
198 break;
199 }
200}
201
202//______________________________________________________________________________
203AliRawEventHeaderBase* AliRawEventHeaderBase::Create(char*& data)
204{
205 // Static method to create AliRawEventHeaderVX object
206 // The actual header class version is taken from the
207 // raw data
208
209 // First create AlirawEVentHeaderBase class object
210 AliRawEventHeaderBase header;
211
212 // Copy the first common part of the raw data header
213 memcpy(header.HeaderBaseBegin(), data, header.HeaderBaseSize());
214
215 // Swap header data if needed
216 if (header.IsSwapped())
217 header.Swap();
218
219 // Is header valid...
220 if (!header.IsValid()) {
221 AliFatalClass("Invalid header format!");
222 // try recovery... how?
223 return 0x0;
224 }
225
226 if (header.GetEventSize() < (UInt_t)header.HeaderBaseSize()) {
227 AliFatalClass("Invalid header base size!");
228 // try recovery... how?
229 return 0x0;
230 }
231
232 // Now check the DATE version and create the corresponding header
233 // class object
234 UInt_t version = header.GetVersion();
235 UInt_t majorversion = (version>>16)&0x0000ffff;
236 UInt_t minorversion = version&0x0000ffff;
237 TString classname;
238 classname.Form("AliRawEventHeaderV%d_%d",majorversion,minorversion);
239
240 TClass *tcl = TClass::GetClass(classname.Data());
241 if (!tcl) {
242 AliFatalClass(Form("Unknown header version (%s)!",classname.Data()));
243 return 0x0;
244 }
245
246 // header.Dump(); tcl->Dump();
247
248 AliRawEventHeaderBase *hdr = (AliRawEventHeaderBase *)tcl->New();
249 if (!hdr) {
250 AliFatalClass(Form("Can not create object of class %s",classname.Data()));
251 return 0x0;
252 }
253
254 // Copy the base header data members and initialize other data members
255 memcpy(hdr->HeaderBaseBegin(),header.HeaderBaseBegin(), header.HeaderBaseSize());
256 memset(hdr->HeaderBegin(),0, hdr->HeaderSize());
257 hdr->fIsSwapped = header.fIsSwapped;
258
259 // Consistency check
260 if (hdr->GetEventSize() < ((UInt_t)hdr->HeaderBaseSize() + (UInt_t)hdr->HeaderSize())) {
261 AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
262 hdr->GetEventSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
263 // try recovery... how?
264 return 0x0;
265 }
266
267 // Check for the presence of header extension and its size
268 Int_t extsize = (Int_t)hdr->GetHeadSize() - (hdr->HeaderBaseSize() + hdr->HeaderSize());
269 if (extsize < 0) {
270 AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
271 hdr->GetHeadSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
272 // try recovery... how?
273 return 0x0;
274 }
275 else {
276 if (extsize > 0) {
33778962 277 hdr->AllocateExtendedData(extsize);
f2dc6b20 278 }
279 }
280
281 return hdr;
282}
283
e653e3e1 284void AliRawEventHeaderBase::SwapData(const void* inbuf, const void* outbuf, UInt_t size) {
285 // The method swaps the contents of the
286 // raw-data event header
287 UInt_t intCount = size/sizeof(UInt_t);
288
289 UInt_t* buf = (UInt_t*) inbuf; // temporary integers buffer
290 for (UInt_t i=0; i<intCount; i++, buf++) {
291 UInt_t value = SwapWord(*buf);
292 memcpy((UInt_t*)outbuf+i, &value, sizeof(UInt_t));
293 }
294}
295
f2dc6b20 296//______________________________________________________________________________
297Int_t AliRawEventHeaderBase::ReadHeader(char*& data)
298{
299 // Read header info from DATE data stream.
300 // Returns bytes read
301
302 Long_t start = (Long_t)data;
303 // Swap header data if needed
304 if (DataIsSwapped()) {
e653e3e1 305 SwapData(data, HeaderBaseBegin(), HeaderBaseSize());
f2dc6b20 306 data += HeaderBaseSize();
e653e3e1 307 SwapData(data, HeaderBegin(), HeaderSize());
f2dc6b20 308 data += HeaderSize();
f2dc6b20 309 }
310 else {
311 memcpy(HeaderBaseBegin(), data, HeaderBaseSize());
312 data += HeaderBaseSize();
313 memcpy(HeaderBegin(), data, HeaderSize());
314 data += HeaderSize();
f2dc6b20 315 }
33778962 316 data += ReadExtendedData(data);
f2dc6b20 317
318 return (Int_t)((Long_t)data - start);
319}
320
321//______________________________________________________________________________
33778962 322void AliRawEventHeaderBase::AllocateExtendedData(Int_t extsize)
323{
324 // Allocate the space for the header
325 // extended data
326 if (fExtendedData) delete [] fExtendedData;
327
328 fExtendedDataSize = fExtendedAllocSize = extsize;
329 fExtendedData = new char[fExtendedAllocSize];
330 memset(fExtendedData,0,fExtendedAllocSize);
331}
332
333//______________________________________________________________________________
334Int_t AliRawEventHeaderBase::ReadExtendedData(char*& data)
335{
336 // Read extended header data
337 // Reallocates memory if the present
338 // buffer is insufficient
339 Int_t extsize = (Int_t)GetHeadSize() - (HeaderBaseSize() + HeaderSize());
340
341 if (extsize == 0) {
342 fExtendedDataSize = 0;
343 return 0;
344 }
345
346 if (extsize < 0) {
347 AliFatal(Form("Invalid header size (%d < %d +%d)!",
348 GetHeadSize(),HeaderBaseSize(),HeaderSize()));
349 // try recovery... how?
350 return 0;
351 }
352
353 fExtendedDataSize = extsize;
354 if (fExtendedDataSize > fExtendedAllocSize)
355 AllocateExtendedData(fExtendedDataSize);
356
357 if (DataIsSwapped())
358 SwapData(data, fExtendedData, fExtendedDataSize);
359 else
360 memcpy(fExtendedData, data, fExtendedDataSize);
361
362 return fExtendedDataSize;
363}
364
365//______________________________________________________________________________
11d31ad9 366UInt_t AliRawEventHeaderBase::Get(const char *datamember) const
f2dc6b20 367{
368 // The method to get a data member from the header object
369 // Except for the data members of the base class, all the
370 // other header data should be retrieved ONLY by this method
371 // The name of the data member should be supplied without "f"
372 // in front
373
374 char buf[256] = "f";
0f772864 375 strncat(buf,datamember,sizeof(buf)-2);
f2dc6b20 376
377 TDataMember *member = IsA()->GetDataMember(buf);
378 if (!member) {
379 AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
380 return 0;
381 }
382
383 if (member->GetArrayDim() != 0) {
384 AliFatal(Form("Member %s is an array! Use the GetP() method!",buf));
385 return 0;
386 }
387
57aaba19 388 TDataType * dataType = member->GetDataType();
389 if (!dataType || dataType->GetType() != kUInt_t) {
f2dc6b20 390 AliFatal(Form("Member %s is not of type UInt_t!",buf));
391 return 0;
392 }
393
394 const void *pointer = (char *)this+member->GetOffset();
395
396 return *((UInt_t *)pointer);
397}
398
399//______________________________________________________________________________
11d31ad9 400const UInt_t* AliRawEventHeaderBase::GetP(const char *datamember) const
f2dc6b20 401{
402 // The method to get a data member from the header object
403 // Except for the data members of the base class, all the
404 // other header data should be retrieved ONLY by this method
405 // The name of the data member should be supplied without "f"
406 // in front
407
408 char buf[256] = "f";
0f772864 409 strncat(buf,datamember,sizeof(buf)-2);
f2dc6b20 410
411 TDataMember *member = IsA()->GetDataMember(buf);
412 if (!member) {
413 AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
414 return 0;
415 }
416
39848565 417 // if (member->GetArrayDim() == 0) {
418 // AliFatal(Form("Member %s is not an array! Use the Get() method!",buf));
419 // return 0;
420 // }
f2dc6b20 421
57aaba19 422 TDataType * dataType = member->GetDataType();
423 if (!dataType || dataType->GetType() != kUInt_t) {
f2dc6b20 424 AliFatal(Form("Member %s is not of type UInt_t*!",buf));
425 return 0;
426 }
427
428 const void *pointer = (char *)this+member->GetOffset();
429
430 return (const UInt_t*)pointer;
431}
12e921cc 432
433//_____________________________________________________________________________
434void AliRawEventHeaderBase::Print( const Option_t* opt ) const
435{
436 // Dumps the event or sub-event
437 // header fields
438
439 cout << opt << " Event size: " << GetEventSize() << endl;
440 cout << opt << " Event header size: " << GetHeadSize() << endl;
441 cout << opt << " Event header version: " << GetMajorVersion() << "." << GetMinorVersion() << endl;
442 cout << opt << " Event type: " << Get("Type") << "( " << GetTypeName() << " )" << endl;
443 cout << opt << " Run Number: " << Get("RunNb") << endl;
444 const UInt_t *id = GetP("Id");
445 cout << opt << " Period: " << (((id)[0]>>4)&0x0fffffff) << " Orbit: " << ((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff)) << " Bunch-crossing: " << ((id)[1]&0x00000fff) << endl;
446 cout << opt << " Trigger pattern: " << GetP("TriggerPattern")[0] << "-" << GetP("TriggerPattern")[1] << endl;
447 cout << opt << " Detector pattern: " << Get("DetectorPattern") << endl;
448 cout << opt << " Type attribute: " << GetP("TypeAttribute")[0] << "-" << GetP("TypeAttribute")[1] << "-" << GetP("TypeAttribute")[2] << endl;
449 cout << opt << " GDC: " << Get("GdcId") << " LDC: " << Get("LdcId") << endl;
450}
33314186 451
452//_____________________________________________________________________________
453void AliRawEventHeaderBase::AddEqIndex(Int_t index)
454{
455 // Adds an equipment by changing properly
456 // the first and last equipment indexes
457 if (fFirstEqIndex < 0) fFirstEqIndex = index;
458 if (index > fLastEqIndex) fLastEqIndex = index;
459}
460
461//_____________________________________________________________________________
462void AliRawEventHeaderBase::Reset()
463{
464 fFirstEqIndex = fLastEqIndex = -1;
465}
466
467//______________________________________________________________________________
468void AliRawEventHeaderBase::Streamer(TBuffer &R__b)
469{
470 // Stream an object of class AliRawEventHeaderBase.
471
472 if (R__b.IsReading()) {
473 UInt_t R__s, R__c;
474 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
475 if (R__v > 3) {
476 R__b.ReadClassBuffer(AliRawEventHeaderBase::Class(),this,R__v,R__s,R__c);
477 return;
478 }
479 TObject::Streamer(R__b);
480 R__b >> fSize;
481 R__b >> fMagic;
482 R__b >> fHeadSize;
483 R__b >> fVersion;
484 R__b >> fExtendedDataSize;
485 delete [] fExtendedData;
486 fExtendedData = new char[fExtendedDataSize];
487 R__b.ReadFastArray(fExtendedData,fExtendedDataSize);
488 R__b >> fIsSwapped;
489 R__b.CheckByteCount(R__s, R__c, AliRawEventHeaderBase::IsA());
490 } else {
491 R__b.WriteClassBuffer(AliRawEventHeaderBase::Class(),this);
492 }
493}