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