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