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