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