1 /**************************************************************************
2 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 // Author: Cvetan Cheshkov 10/10/2005
20 //////////////////////////////////////////////////////////////////////////
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 //
26 //////////////////////////////////////////////////////////////////////////
32 #include <TDataMember.h>
34 #include <TMethodCall.h>
37 #include "AliRawEventHeaderBase.h"
39 #include <Riostream.h>
41 ClassImp(AliRawEventHeaderBase)
43 //______________________________________________________________________________
44 AliRawEventHeaderBase::AliRawEventHeaderBase():
53 // Default constructor
56 //______________________________________________________________________________
57 void *AliRawEventHeaderBase::HeaderBegin()
59 // Returns the pointer to the first data member
60 // beyond the base class data members
62 TList *datalist = IsA()->GetListOfDataMembers();
64 TDataMember *member = (TDataMember *)next();
66 if(!strcmp(member->GetTypeName(),"TClass"))
67 member = (TDataMember *)next();
69 return (void *)((char *)this+member->GetOffset());
72 //______________________________________________________________________________
73 Int_t AliRawEventHeaderBase::HeaderSize() const
75 // Returns the size of the data members list
76 // beyond the base class data members
80 TList *datalist = IsA()->GetListOfDataMembers();
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();
90 for(UInt_t i=0;i<ndim;i++) size += member->GetMaxIndex(i)*unitsize;
96 //______________________________________________________________________________
97 UInt_t AliRawEventHeaderBase::SwapWord(UInt_t x) const
99 // Swap the endianess of the integer value 'x'
101 return (((x & 0x000000ffU) << 24) | ((x & 0x0000ff00U) << 8) |
102 ((x & 0x00ff0000U) >> 8) | ((x & 0xff000000U) >> 24));
105 void AliRawEventHeaderBase::Swap()
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
114 fSize = SwapWord(fSize);
115 fMagic = SwapWord(fMagic);
116 fHeadSize = SwapWord(fHeadSize);
117 fVersion = SwapWord(fVersion);
121 //______________________________________________________________________________
122 const char *AliRawEventHeaderBase::GetTypeName() const
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");
131 return "START_OF_RUN";
136 case kStartOfRunFiles:
137 return "START_OF_RUN_FILES";
140 return "END_OF_RUN_FILES";
143 return "START_OF_BURST";
146 return "END_OF_BURST";
149 return "PHYSICS_EVENT";
151 case kCalibrationEvent:
152 return "CALIBRATION_EVENT";
155 return "EVENT_FORMAT_ERROR";
158 return "START_OF_DATA";
161 return "END_OF_DATA";
163 case kSystemSoftwareTriggerEvent:
164 return "SYSTEM_SOFTWARE_TRIGGER_EVENT";
166 case kDetectorSoftwareTriggerEvent:
167 return "DETECTOR_SOFTWARE_TRIGGER_EVENT";
170 return "UNKNOWN EVENT TYPE NUMBER";
175 //______________________________________________________________________________
176 AliRawEventHeaderBase* AliRawEventHeaderBase::Create(char*& data)
178 // Static method to create AliRawEventHeaderVX object
179 // The actual header class version is taken from the
182 // First create AlirawEVentHeaderBase class object
183 AliRawEventHeaderBase header;
185 // Copy the first common part of the raw data header
186 memcpy(header.HeaderBaseBegin(), data, header.HeaderBaseSize());
188 // Swap header data if needed
189 if (header.IsSwapped())
192 // Is header valid...
193 if (!header.IsValid()) {
194 AliFatalClass("Invalid header format!");
195 // try recovery... how?
199 if (header.GetEventSize() < (UInt_t)header.HeaderBaseSize()) {
200 AliFatalClass("Invalid header base size!");
201 // try recovery... how?
205 // Now check the DATE version and create the corresponding header
207 UInt_t version = header.GetVersion();
208 UInt_t majorversion = (version>>16)&0x0000ffff;
209 UInt_t minorversion = version&0x0000ffff;
211 classname.Form("AliRawEventHeaderV%d_%d",majorversion,minorversion);
213 TClass *tcl = TClass::GetClass(classname.Data());
215 AliFatalClass(Form("Unknown header version (%s)!",classname.Data()));
219 // header.Dump(); tcl->Dump();
221 AliRawEventHeaderBase *hdr = (AliRawEventHeaderBase *)tcl->New();
223 AliFatalClass(Form("Can not create object of class %s",classname.Data()));
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;
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?
240 // Check for the presence of header extension and its size
241 Int_t extsize = (Int_t)hdr->GetHeadSize() - (hdr->HeaderBaseSize() + hdr->HeaderSize());
243 AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
244 hdr->GetHeadSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
245 // try recovery... how?
250 hdr->SetExtendedDataSize(extsize);
251 char *extdata = new char[extsize];
252 memset(extdata,0,extsize);
253 hdr->SetExtendedData(extdata);
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);
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));
272 //______________________________________________________________________________
273 Int_t AliRawEventHeaderBase::ReadHeader(char*& data)
275 // Read header info from DATE data stream.
276 // Returns bytes read
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();
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();
301 return (Int_t)((Long_t)data - start);
304 //______________________________________________________________________________
305 UInt_t AliRawEventHeaderBase::Get(const char *datamember) const
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"
314 strcat(buf,datamember);
316 TDataMember *member = IsA()->GetDataMember(buf);
318 AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
322 if (member->GetArrayDim() != 0) {
323 AliFatal(Form("Member %s is an array! Use the GetP() method!",buf));
327 if (strcmp(member->GetTypeName(),"UInt_t") != 0) {
328 AliFatal(Form("Member %s is not of type UInt_t!",buf));
332 const void *pointer = (char *)this+member->GetOffset();
334 return *((UInt_t *)pointer);
337 //______________________________________________________________________________
338 const UInt_t* AliRawEventHeaderBase::GetP(const char *datamember) const
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"
347 strcat(buf,datamember);
349 TDataMember *member = IsA()->GetDataMember(buf);
351 AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
355 // if (member->GetArrayDim() == 0) {
356 // AliFatal(Form("Member %s is not an array! Use the Get() method!",buf));
360 if (strcmp(member->GetTypeName(),"UInt_t") != 0) {
361 AliFatal(Form("Member %s is not of type UInt_t*!",buf));
365 const void *pointer = (char *)this+member->GetOffset();
367 return (const UInt_t*)pointer;
370 //_____________________________________________________________________________
371 void AliRawEventHeaderBase::Print( const Option_t* opt ) const
373 // Dumps the event or sub-event
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;