]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliRawEventHeaderBase.cxx
alimdc RPM spec file updated
[u/mrichter/AliRoot.git] / RAW / AliRawEventHeaderBase.cxx
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
16 /* $Id$ */
17
18 // Author: Cvetan Cheshkov  10/10/2005
19
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
30 #include <Bytes.h>
31 #include <TClass.h>
32 #include <TDataMember.h>
33 #include <TList.h>
34 #include <TMethodCall.h>
35
36 #include "AliLog.h"
37 #include "AliRawEventHeaderBase.h"
38
39
40 ClassImp(AliRawEventHeaderBase)
41
42 //______________________________________________________________________________
43 AliRawEventHeaderBase::AliRawEventHeaderBase():
44 fSize(0),
45 fMagic(0),
46 fHeadSize(0),
47 fVersion(0),
48 fExtendedDataSize(0),
49 fExtendedData(NULL),
50 fIsSwapped(kFALSE)
51 {
52   // Default constructor
53 }
54
55 //______________________________________________________________________________
56 void *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 //______________________________________________________________________________
72 Int_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 //______________________________________________________________________________
96 UInt_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
104 void 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;
113       fSize         = SwapWord(fSize);
114       fMagic        = SwapWord(fMagic);
115       fHeadSize     = SwapWord(fHeadSize);
116       fVersion      = SwapWord(fVersion);
117    }
118 }
119
120 //______________________________________________________________________________
121 const 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;
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;
168       default:
169          return "UNKNOWN EVENT TYPE NUMBER";
170          break;
171    }
172 }
173
174 //______________________________________________________________________________
175 AliRawEventHeaderBase* 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
259 void 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
271 //______________________________________________________________________________
272 Int_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()) {
280     SwapData(data, HeaderBaseBegin(), HeaderBaseSize());
281     data += HeaderBaseSize();
282     SwapData(data, HeaderBegin(), HeaderSize());
283     data += HeaderSize();
284     if(GetExtendedDataSize()>0) {
285       SwapData(data, GetExtendedData(), GetExtendedDataSize());
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 //______________________________________________________________________________
304 UInt_t AliRawEventHeaderBase::Get(const char *datamember) const
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 //______________________________________________________________________________
337 const UInt_t* AliRawEventHeaderBase::GetP(const char *datamember) const
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
354   //  if (member->GetArrayDim() == 0) {
355   //    AliFatal(Form("Member %s is not an array! Use the Get() method!",buf));
356   //    return 0;
357   //  }
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 }