Line data Source code
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 128 : ClassImp(AliRawEventHeaderBase)
45 :
46 : //______________________________________________________________________________
47 724 : AliRawEventHeaderBase::AliRawEventHeaderBase():
48 724 : fSize(0),
49 724 : fMagic(0),
50 724 : fHeadSize(0),
51 724 : fVersion(0),
52 724 : fExtendedDataSize(0),
53 724 : fExtendedAllocSize(0),
54 724 : fExtendedData(NULL),
55 724 : fIsSwapped(kFALSE),
56 724 : fHeaderSize(0),
57 724 : fHeaderBegin(NULL),
58 724 : fFirstEqIndex(-1),
59 724 : fLastEqIndex(-1)
60 2178 : {
61 : // Default constructor
62 727 : }
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 1341 : if (fHeaderBegin) return fHeaderBegin;
71 :
72 123 : TList *datalist = IsA()->GetListOfDataMembers();
73 123 : TIter next(datalist);
74 246 : TDataMember *member = (TDataMember *)next();
75 :
76 369 : if(strstr(member->GetTypeName(),"TClass"))
77 0 : member = (TDataMember *)next();
78 :
79 246 : void *ptr = (void *)((char *)this+member->GetOffset());
80 123 : const_cast<AliRawEventHeaderBase*>(this)->fHeaderBegin = ptr;
81 :
82 : return ptr;
83 611 : }
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 4233 : if (fHeaderSize) return fHeaderSize;
92 :
93 : Int_t size = 0;
94 :
95 123 : TList *datalist = IsA()->GetListOfDataMembers();
96 123 : TIter next(datalist);
97 : TDataMember *member;
98 4305 : while ((member=(TDataMember *)next()) != 0x0) {
99 4059 : if (strstr(member->GetTypeName(),"TClass")) continue;
100 1230 : UInt_t unitsize = member->GetUnitSize();
101 1230 : UInt_t ndim = member->GetArrayDim();
102 1230 : if (ndim == 0)
103 861 : size += unitsize;
104 : else
105 1845 : for(UInt_t i=0;i<ndim;i++) size += member->GetMaxIndex(i)*unitsize;
106 : }
107 :
108 123 : const_cast<AliRawEventHeaderBase*>(this)->fHeaderSize = size;
109 :
110 : return size;
111 1575 : }
112 :
113 : //______________________________________________________________________________
114 : UInt_t AliRawEventHeaderBase::SwapWord(UInt_t x) const
115 : {
116 : // Swap the endianess of the integer value 'x'
117 :
118 0 : return (((x & 0x000000ffU) << 24) | ((x & 0x0000ff00U) << 8) |
119 0 : ((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 0 : if (IsSwapped()) {
130 0 : fIsSwapped = kTRUE;
131 0 : fSize = SwapWord(fSize);
132 0 : fMagic = SwapWord(fMagic);
133 0 : fHeadSize = SwapWord(fHeadSize);
134 0 : fVersion = SwapWord(fVersion);
135 0 : }
136 0 : }
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 0 : UInt_t eventType = Get("Type");
145 :
146 0 : 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 0 : switch (eventType) {
157 : case kStartOfRun:
158 0 : return "START_OF_RUN";
159 : break;
160 : case kEndOfRun:
161 0 : return "END_OF_RUN";
162 : break;
163 : case kStartOfRunFiles:
164 0 : return "START_OF_RUN_FILES";
165 : break;
166 : case kEndOfRunFiles:
167 0 : return "END_OF_RUN_FILES";
168 : break;
169 : case kStartOfBurst:
170 0 : return "START_OF_BURST";
171 : break;
172 : case kEndOfBurst:
173 0 : return "END_OF_BURST";
174 : break;
175 : case kPhysicsEvent:
176 0 : return "PHYSICS_EVENT";
177 : break;
178 : case kCalibrationEvent:
179 0 : return "CALIBRATION_EVENT";
180 : break;
181 : case kFormatError:
182 0 : return "EVENT_FORMAT_ERROR";
183 : break;
184 : case kStartOfData:
185 0 : return "START_OF_DATA";
186 : break;
187 : case kEndOfData:
188 0 : return "END_OF_DATA";
189 : break;
190 : case kSystemSoftwareTriggerEvent:
191 0 : return "SYSTEM_SOFTWARE_TRIGGER_EVENT";
192 : break;
193 : case kDetectorSoftwareTriggerEvent:
194 0 : return "DETECTOR_SOFTWARE_TRIGGER_EVENT";
195 : break;
196 : default:
197 0 : return "UNKNOWN EVENT TYPE NUMBER";
198 : break;
199 : }
200 0 : }
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 4 : AliRawEventHeaderBase header;
211 :
212 : // Copy the first common part of the raw data header
213 2 : memcpy(header.HeaderBaseBegin(), data, header.HeaderBaseSize());
214 :
215 : // Swap header data if needed
216 2 : if (header.IsSwapped())
217 0 : header.Swap();
218 :
219 : // Is header valid...
220 2 : if (!header.IsValid()) {
221 0 : AliFatalClass("Invalid header format!");
222 : // try recovery... how?
223 0 : return 0x0;
224 : }
225 :
226 2 : if (header.GetEventSize() < (UInt_t)header.HeaderBaseSize()) {
227 0 : AliFatalClass("Invalid header base size!");
228 : // try recovery... how?
229 0 : return 0x0;
230 : }
231 :
232 : // Now check the DATE version and create the corresponding header
233 : // class object
234 2 : UInt_t version = header.GetVersion();
235 2 : UInt_t majorversion = (version>>16)&0x0000ffff;
236 2 : UInt_t minorversion = version&0x0000ffff;
237 2 : TString classname;
238 2 : classname.Form("AliRawEventHeaderV%d_%d",majorversion,minorversion);
239 :
240 4 : TClass *tcl = TClass::GetClass(classname.Data());
241 2 : if (!tcl) {
242 0 : AliFatalClass(Form("Unknown header version (%s)!",classname.Data()));
243 0 : return 0x0;
244 : }
245 :
246 : // header.Dump(); tcl->Dump();
247 :
248 4 : AliRawEventHeaderBase *hdr = (AliRawEventHeaderBase *)tcl->New();
249 2 : if (!hdr) {
250 0 : AliFatalClass(Form("Can not create object of class %s",classname.Data()));
251 0 : return 0x0;
252 : }
253 :
254 : // Copy the base header data members and initialize other data members
255 2 : memcpy(hdr->HeaderBaseBegin(),header.HeaderBaseBegin(), header.HeaderBaseSize());
256 6 : memset(hdr->HeaderBegin(),0, hdr->HeaderSize());
257 2 : hdr->fIsSwapped = header.fIsSwapped;
258 :
259 : // Consistency check
260 4 : if (hdr->GetEventSize() < ((UInt_t)hdr->HeaderBaseSize() + (UInt_t)hdr->HeaderSize())) {
261 0 : AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
262 : hdr->GetEventSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
263 : // try recovery... how?
264 0 : return 0x0;
265 : }
266 :
267 : // Check for the presence of header extension and its size
268 4 : Int_t extsize = (Int_t)hdr->GetHeadSize() - (hdr->HeaderBaseSize() + hdr->HeaderSize());
269 2 : if (extsize < 0) {
270 0 : AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
271 : hdr->GetHeadSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
272 : // try recovery... how?
273 0 : return 0x0;
274 : }
275 : else {
276 2 : if (extsize > 0) {
277 0 : hdr->AllocateExtendedData(extsize);
278 : }
279 : }
280 :
281 2 : return hdr;
282 4 : }
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 0 : UInt_t intCount = size/sizeof(UInt_t);
288 :
289 0 : UInt_t* buf = (UInt_t*) inbuf; // temporary integers buffer
290 0 : for (UInt_t i=0; i<intCount; i++, buf++) {
291 0 : UInt_t value = SwapWord(*buf);
292 0 : memcpy((UInt_t*)outbuf+i, &value, sizeof(UInt_t));
293 : }
294 0 : }
295 :
296 : //______________________________________________________________________________
297 : Int_t AliRawEventHeaderBase::ReadHeader(char*& data)
298 : {
299 : // Read header info from DATE data stream.
300 : // Returns bytes read
301 :
302 956 : Long_t start = (Long_t)data;
303 : // Swap header data if needed
304 478 : if (DataIsSwapped()) {
305 0 : SwapData(data, HeaderBaseBegin(), HeaderBaseSize());
306 0 : data += HeaderBaseSize();
307 0 : SwapData(data, HeaderBegin(), HeaderSize());
308 0 : data += HeaderSize();
309 0 : }
310 : else {
311 478 : memcpy(HeaderBaseBegin(), data, HeaderBaseSize());
312 478 : data += HeaderBaseSize();
313 478 : memcpy(HeaderBegin(), data, HeaderSize());
314 478 : data += HeaderSize();
315 : }
316 478 : data += ReadExtendedData(data);
317 :
318 478 : 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 0 : if (fExtendedData) delete [] fExtendedData;
327 :
328 0 : fExtendedDataSize = fExtendedAllocSize = extsize;
329 0 : fExtendedData = new char[fExtendedAllocSize];
330 0 : memset(fExtendedData,0,fExtendedAllocSize);
331 0 : }
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 956 : Int_t extsize = (Int_t)GetHeadSize() - (HeaderBaseSize() + HeaderSize());
340 :
341 478 : if (extsize == 0) {
342 478 : fExtendedDataSize = 0;
343 478 : return 0;
344 : }
345 :
346 0 : if (extsize < 0) {
347 0 : AliFatal(Form("Invalid header size (%d < %d +%d)!",
348 : GetHeadSize(),HeaderBaseSize(),HeaderSize()));
349 : // try recovery... how?
350 0 : return 0;
351 : }
352 :
353 0 : fExtendedDataSize = extsize;
354 0 : if (fExtendedDataSize > fExtendedAllocSize)
355 0 : AllocateExtendedData(fExtendedDataSize);
356 :
357 0 : if (DataIsSwapped())
358 0 : SwapData(data, fExtendedData, fExtendedDataSize);
359 : else
360 0 : memcpy(fExtendedData, data, fExtendedDataSize);
361 :
362 0 : return fExtendedDataSize;
363 478 : }
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 1686 : char buf[256] = "f";
375 843 : strncat(buf,datamember,sizeof(buf)-2);
376 :
377 843 : TDataMember *member = IsA()->GetDataMember(buf);
378 843 : if (!member) {
379 0 : AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
380 0 : return 0;
381 : }
382 :
383 843 : if (member->GetArrayDim() != 0) {
384 0 : AliFatal(Form("Member %s is an array! Use the GetP() method!",buf));
385 0 : return 0;
386 : }
387 :
388 843 : TDataType * dataType = member->GetDataType();
389 1686 : if (!dataType || dataType->GetType() != kUInt_t) {
390 0 : AliFatal(Form("Member %s is not of type UInt_t!",buf));
391 0 : return 0;
392 : }
393 :
394 843 : const void *pointer = (char *)this+member->GetOffset();
395 :
396 843 : return *((UInt_t *)pointer);
397 843 : }
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 9926 : char buf[256] = "f";
409 4963 : strncat(buf,datamember,sizeof(buf)-2);
410 :
411 4963 : TDataMember *member = IsA()->GetDataMember(buf);
412 4963 : if (!member) {
413 0 : AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
414 0 : 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 4963 : TDataType * dataType = member->GetDataType();
423 9926 : if (!dataType || dataType->GetType() != kUInt_t) {
424 0 : AliFatal(Form("Member %s is not of type UInt_t*!",buf));
425 0 : return 0;
426 : }
427 :
428 4963 : const void *pointer = (char *)this+member->GetOffset();
429 :
430 4963 : return (const UInt_t*)pointer;
431 4963 : }
432 :
433 : //_____________________________________________________________________________
434 : void AliRawEventHeaderBase::Print( const Option_t* opt ) const
435 : {
436 : // Dumps the event or sub-event
437 : // header fields
438 :
439 0 : cout << opt << " Event size: " << GetEventSize() << endl;
440 0 : cout << opt << " Event header size: " << GetHeadSize() << endl;
441 0 : cout << opt << " Event header version: " << GetMajorVersion() << "." << GetMinorVersion() << endl;
442 0 : cout << opt << " Event type: " << Get("Type") << "( " << GetTypeName() << " )" << endl;
443 0 : cout << opt << " Run Number: " << Get("RunNb") << endl;
444 0 : const UInt_t *id = GetP("Id");
445 0 : cout << opt << " Period: " << (((id)[0]>>4)&0x0fffffff) << " Orbit: " << ((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff)) << " Bunch-crossing: " << ((id)[1]&0x00000fff) << endl;
446 0 : cout << opt << " Trigger pattern: " << GetP("TriggerPattern")[0] << "-" << GetP("TriggerPattern")[1] << endl;
447 0 : cout << opt << " Detector pattern: " << Get("DetectorPattern") << endl;
448 0 : cout << opt << " Type attribute: " << GetP("TypeAttribute")[0] << "-" << GetP("TypeAttribute")[1] << "-" << GetP("TypeAttribute")[2] << endl;
449 0 : cout << opt << " GDC: " << Get("GdcId") << " LDC: " << Get("LdcId") << endl;
450 0 : }
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 3716 : if (fFirstEqIndex < 0) fFirstEqIndex = index;
458 3242 : if (index > fLastEqIndex) fLastEqIndex = index;
459 1621 : }
460 :
461 : //_____________________________________________________________________________
462 : void AliRawEventHeaderBase::Reset()
463 : {
464 956 : fFirstEqIndex = fLastEqIndex = -1;
465 478 : }
|