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