START_OF_RUN events are added to the root-ification procedure. Will be checked with...
[u/mrichter/AliRoot.git] / RAW / AliRawEventHeaderBase.cxx
1 // Author: Cvetan Cheshkov  10/10/2005
2
3 /**************************************************************************
4  * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Author: The ALICE Off-line Project.                                    *
7  * Contributors are mentioned in the code where appropriate.              *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          *
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 //////////////////////////////////////////////////////////////////////////
19 //                                                                      //
20 // AliRawEventHeaderBase                                                //
21 // This a new versioning scheme for raw data root-ification and reading //
22 // For details look at offline weekly meeting 20/10/2005                //
23 //                                                                      //
24 //////////////////////////////////////////////////////////////////////////
25
26 #include <unistd.h>
27
28 #include <TClass.h>
29 #include <TDataMember.h>
30 #include <TMethodCall.h>
31
32 #include "AliLog.h"
33 #include "AliRawEventHeaderBase.h"
34
35
36 ClassImp(AliRawEventHeaderBase)
37
38
39 //______________________________________________________________________________
40 void *AliRawEventHeaderBase::HeaderBegin()
41 {
42   // Returns the pointer to the first data member
43   // beyond the base class data members
44
45   TList *datalist = IsA()->GetListOfDataMembers();
46   TIter next(datalist);                           
47   TDataMember *member = (TDataMember *)next();
48
49   if(!strcmp(member->GetTypeName(),"TClass"))
50     member = (TDataMember *)next();
51
52   return (void *)((char *)this+member->GetOffset());
53 }
54
55 //______________________________________________________________________________
56 Int_t AliRawEventHeaderBase::HeaderSize() const
57 {
58   // Returns the size of the data members list
59   // beyond the base class data members
60
61   Int_t size = 0;
62
63   TList *datalist = IsA()->GetListOfDataMembers();
64   TIter next(datalist);                           
65   TDataMember *member;
66   while ((member=(TDataMember *)next()) != 0x0) {
67     if (!strcmp(member->GetTypeName(),"TClass")) continue;
68     UInt_t unitsize = member->GetUnitSize();
69     UInt_t ndim = member->GetArrayDim();
70     if (ndim == 0)
71       size += unitsize;
72     else
73       for(UInt_t i=0;i<ndim;i++) size += member->GetMaxIndex(i)*unitsize;
74   }
75
76   return size;
77 }
78
79 //______________________________________________________________________________
80 void AliRawEventHeaderBase::Swap()
81 {
82    // Swap base header data.
83    // Update the fIsSwapped flag which
84    // is then use to copy in an appropriate way
85    // the rest of the header data from the raw data stream
86
87    if (IsSwapped()) {
88       fIsSwapped    = kTRUE;
89       fSize         = net2host(fSize);
90       fMagic        = net2host(fMagic);
91       fHeadSize     = net2host(fHeadSize);
92       fVersion      = net2host(fVersion);
93    }
94 }
95
96 //______________________________________________________________________________
97 const char *AliRawEventHeaderBase::GetTypeName()
98 {
99    // Get event type as a string.
100    // Will fail in case data header
101    // does not contain eventType field
102    Int_t eventType = Get("Type");
103
104    switch (eventType) {
105       case kStartOfRun:
106          return "START_OF_RUN";
107          break;
108       case kEndOfRun:
109          return "END_OF_RUN";
110          break;
111       case kStartOfRunFiles:
112          return "START_OF_RUN_FILES";
113          break;
114       case kEndOfRunFiles:
115          return "END_OF_RUN_FILES";
116          break;
117       case kStartOfBurst:
118          return "START_OF_BURST";
119          break;
120       case kEndOfBurst:
121          return "END_OF_BURST";
122          break;
123       case kPhysicsEvent:
124          return "PHYSICS_EVENT";
125          break;
126       case kCalibrationEvent:
127          return "CALIBRATION_EVENT";
128          break;
129       case kFormatError:
130          return "EVENT_FORMAT_ERROR";
131          break;
132       case kStartOfData:
133          return "START_OF_DATA";
134          break;
135       case kEndOfData:
136          return "END_OF_DATA";
137          break;
138       case kSystemSoftwareTriggerEvent:
139          return "SYSTEM_SOFTWARE_TRIGGER_EVENT";
140          break;
141       case kDetectorSoftwareTriggerEvent:
142          return "DETECTOR_SOFTWARE_TRIGGER_EVENT";
143          break;
144       default:
145          return "UNKNOWN EVENT TYPE NUMBER";
146          break;
147    }
148 }
149
150 //______________________________________________________________________________
151 AliRawEventHeaderBase* AliRawEventHeaderBase::Create(char*& data)
152 {
153   // Static method to create AliRawEventHeaderVX object
154   // The actual header class version is taken from the
155   // raw data
156
157   // First create AlirawEVentHeaderBase class object
158   AliRawEventHeaderBase header;
159
160   // Copy the first common part of the raw data header
161   memcpy(header.HeaderBaseBegin(), data, header.HeaderBaseSize());
162  
163     // Swap header data if needed
164   if (header.IsSwapped())
165     header.Swap();
166
167   // Is header valid...
168   if (!header.IsValid()) {
169     AliFatalClass("Invalid header format!");
170     // try recovery... how?
171     return 0x0;
172   }
173
174   if (header.GetEventSize() < (UInt_t)header.HeaderBaseSize()) {
175     AliFatalClass("Invalid header base size!");
176     // try recovery... how?
177     return 0x0;
178   }
179
180   // Now check the DATE version and create the corresponding header
181   // class object
182   UInt_t version = header.GetVersion();
183   UInt_t majorversion = (version>>16)&0x0000ffff;
184   UInt_t minorversion = version&0x0000ffff;
185   TString classname;
186   classname.Form("AliRawEventHeaderV%d_%d",majorversion,minorversion);
187     
188   TClass *tcl = TClass::GetClass(classname.Data());
189   if (!tcl) {
190     AliFatalClass(Form("Unknown header version (%s)!",classname.Data()));
191     return 0x0;
192   }
193
194   //  header.Dump(); tcl->Dump();
195
196   AliRawEventHeaderBase *hdr = (AliRawEventHeaderBase *)tcl->New();
197   if (!hdr) {
198     AliFatalClass(Form("Can not create object of class %s",classname.Data()));
199     return 0x0;
200   }
201
202   // Copy the base header data members and initialize other data members
203   memcpy(hdr->HeaderBaseBegin(),header.HeaderBaseBegin(), header.HeaderBaseSize());
204   memset(hdr->HeaderBegin(),0, hdr->HeaderSize());
205   hdr->fIsSwapped = header.fIsSwapped;
206
207   // Consistency check
208   if (hdr->GetEventSize() < ((UInt_t)hdr->HeaderBaseSize() + (UInt_t)hdr->HeaderSize())) {
209     AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
210                        hdr->GetEventSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
211     // try recovery... how?
212     return 0x0;
213   }
214
215   // Check for the presence of header extension and its size
216   Int_t extsize = (Int_t)hdr->GetHeadSize() - (hdr->HeaderBaseSize() + hdr->HeaderSize());
217   if (extsize < 0) {
218     AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
219                        hdr->GetHeadSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
220     // try recovery... how?
221     return 0x0;
222   }
223   else {
224     if (extsize > 0) {
225       hdr->SetExtendedDataSize(extsize);
226       char *extdata = new char[extsize];
227       memset(extdata,0,extsize);
228       hdr->SetExtendedData(extdata);
229     }
230   }
231
232   return hdr;
233 }
234
235 //______________________________________________________________________________
236 Int_t AliRawEventHeaderBase::ReadHeader(char*& data)
237 {
238   // Read header info from DATE data stream.
239   // Returns bytes read
240
241   Long_t start = (Long_t)data;
242   // Swap header data if needed
243   if (DataIsSwapped()) {
244     swab(data,HeaderBaseBegin(), HeaderBaseSize());
245     data += HeaderBaseSize();
246     swab(data, HeaderBegin(), HeaderSize());
247     data += HeaderSize();
248     if(GetExtendedDataSize()>0) {
249       swab(data, GetExtendedData(), GetExtendedDataSize());
250       data += GetExtendedDataSize();
251     }
252   }
253   else {
254     memcpy(HeaderBaseBegin(), data, HeaderBaseSize());
255     data += HeaderBaseSize();
256     memcpy(HeaderBegin(), data, HeaderSize());
257     data += HeaderSize();
258     if(GetExtendedDataSize()>0) {
259       memcpy(GetExtendedData(), data, GetExtendedDataSize());
260       data += GetExtendedDataSize();
261     }
262   }
263
264   return (Int_t)((Long_t)data - start);
265 }
266
267 //______________________________________________________________________________
268 UInt_t AliRawEventHeaderBase::Get(const char *datamember)
269 {
270   // The method to get a data member from the header object
271   // Except for the data members of the base class, all the
272   // other header data should be retrieved ONLY by this method
273   // The name of the data member should be supplied without "f"
274   // in front
275
276   char buf[256] = "f";
277   strcat(buf,datamember);
278
279   TDataMember *member = IsA()->GetDataMember(buf);
280   if (!member) {
281     AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
282     return 0;
283   }
284
285   if (member->GetArrayDim() != 0) {
286     AliFatal(Form("Member %s is an array! Use the GetP() method!",buf));
287     return 0;
288   }
289
290   if (strcmp(member->GetTypeName(),"UInt_t") != 0) {
291     AliFatal(Form("Member %s is not of type UInt_t!",buf));
292     return 0;
293   }
294
295   const void *pointer = (char *)this+member->GetOffset();
296
297   return *((UInt_t *)pointer);
298 }
299
300 //______________________________________________________________________________
301 const UInt_t* AliRawEventHeaderBase::GetP(const char *datamember)
302 {
303   // The method to get a data member from the header object
304   // Except for the data members of the base class, all the
305   // other header data should be retrieved ONLY by this method
306   // The name of the data member should be supplied without "f"
307   // in front
308
309   char buf[256] = "f";
310   strcat(buf,datamember);
311
312   TDataMember *member = IsA()->GetDataMember(buf);
313   if (!member) {
314     AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
315     return 0;
316   }
317
318   //  if (member->GetArrayDim() == 0) {
319   //    AliFatal(Form("Member %s is not an array! Use the Get() method!",buf));
320   //    return 0;
321   //  }
322
323   if (strcmp(member->GetTypeName(),"UInt_t") != 0) {
324     AliFatal(Form("Member %s is not of type UInt_t*!",buf));
325     return 0;
326   }
327
328   const void *pointer = (char *)this+member->GetOffset();
329
330   return (const UInt_t*)pointer;
331 }