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