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