]>
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 | ||
39 | ||
40 | ClassImp(AliRawEventHeaderBase) | |
41 | ||
f3c1e83c | 42 | //______________________________________________________________________________ |
43 | AliRawEventHeaderBase::AliRawEventHeaderBase(): | |
44 | fSize(0), | |
45 | fMagic(0), | |
46 | fHeadSize(0), | |
47 | fVersion(0), | |
48 | fExtendedDataSize(0), | |
49 | fExtendedData(NULL), | |
50 | fIsSwapped(kFALSE) | |
51 | { | |
52 | // Default constructor | |
53 | } | |
f2dc6b20 | 54 | |
55 | //______________________________________________________________________________ | |
56 | void *AliRawEventHeaderBase::HeaderBegin() | |
57 | { | |
58 | // Returns the pointer to the first data member | |
59 | // beyond the base class data members | |
60 | ||
61 | TList *datalist = IsA()->GetListOfDataMembers(); | |
62 | TIter next(datalist); | |
63 | TDataMember *member = (TDataMember *)next(); | |
64 | ||
65 | if(!strcmp(member->GetTypeName(),"TClass")) | |
66 | member = (TDataMember *)next(); | |
67 | ||
68 | return (void *)((char *)this+member->GetOffset()); | |
69 | } | |
70 | ||
71 | //______________________________________________________________________________ | |
72 | Int_t AliRawEventHeaderBase::HeaderSize() const | |
73 | { | |
74 | // Returns the size of the data members list | |
75 | // beyond the base class data members | |
76 | ||
77 | Int_t size = 0; | |
78 | ||
79 | TList *datalist = IsA()->GetListOfDataMembers(); | |
80 | TIter next(datalist); | |
81 | TDataMember *member; | |
82 | while ((member=(TDataMember *)next()) != 0x0) { | |
83 | if (!strcmp(member->GetTypeName(),"TClass")) continue; | |
84 | UInt_t unitsize = member->GetUnitSize(); | |
85 | UInt_t ndim = member->GetArrayDim(); | |
86 | if (ndim == 0) | |
87 | size += unitsize; | |
88 | else | |
89 | for(UInt_t i=0;i<ndim;i++) size += member->GetMaxIndex(i)*unitsize; | |
90 | } | |
91 | ||
92 | return size; | |
93 | } | |
94 | ||
95 | //______________________________________________________________________________ | |
96 | void AliRawEventHeaderBase::Swap() | |
97 | { | |
98 | // Swap base header data. | |
99 | // Update the fIsSwapped flag which | |
100 | // is then use to copy in an appropriate way | |
101 | // the rest of the header data from the raw data stream | |
102 | ||
103 | if (IsSwapped()) { | |
104 | fIsSwapped = kTRUE; | |
105 | fSize = net2host(fSize); | |
106 | fMagic = net2host(fMagic); | |
107 | fHeadSize = net2host(fHeadSize); | |
108 | fVersion = net2host(fVersion); | |
109 | } | |
110 | } | |
111 | ||
112 | //______________________________________________________________________________ | |
113 | const char *AliRawEventHeaderBase::GetTypeName() | |
114 | { | |
115 | // Get event type as a string. | |
116 | // Will fail in case data header | |
117 | // does not contain eventType field | |
118 | Int_t eventType = Get("Type"); | |
119 | ||
120 | switch (eventType) { | |
121 | case kStartOfRun: | |
122 | return "START_OF_RUN"; | |
123 | break; | |
124 | case kEndOfRun: | |
125 | return "END_OF_RUN"; | |
126 | break; | |
127 | case kStartOfRunFiles: | |
128 | return "START_OF_RUN_FILES"; | |
129 | break; | |
130 | case kEndOfRunFiles: | |
131 | return "END_OF_RUN_FILES"; | |
132 | break; | |
133 | case kStartOfBurst: | |
134 | return "START_OF_BURST"; | |
135 | break; | |
136 | case kEndOfBurst: | |
137 | return "END_OF_BURST"; | |
138 | break; | |
139 | case kPhysicsEvent: | |
140 | return "PHYSICS_EVENT"; | |
141 | break; | |
142 | case kCalibrationEvent: | |
143 | return "CALIBRATION_EVENT"; | |
144 | break; | |
145 | case kFormatError: | |
146 | return "EVENT_FORMAT_ERROR"; | |
147 | break; | |
cce65444 | 148 | case kStartOfData: |
149 | return "START_OF_DATA"; | |
150 | break; | |
151 | case kEndOfData: | |
152 | return "END_OF_DATA"; | |
153 | break; | |
154 | case kSystemSoftwareTriggerEvent: | |
155 | return "SYSTEM_SOFTWARE_TRIGGER_EVENT"; | |
156 | break; | |
157 | case kDetectorSoftwareTriggerEvent: | |
158 | return "DETECTOR_SOFTWARE_TRIGGER_EVENT"; | |
159 | break; | |
f2dc6b20 | 160 | default: |
161 | return "UNKNOWN EVENT TYPE NUMBER"; | |
162 | break; | |
163 | } | |
164 | } | |
165 | ||
166 | //______________________________________________________________________________ | |
167 | AliRawEventHeaderBase* AliRawEventHeaderBase::Create(char*& data) | |
168 | { | |
169 | // Static method to create AliRawEventHeaderVX object | |
170 | // The actual header class version is taken from the | |
171 | // raw data | |
172 | ||
173 | // First create AlirawEVentHeaderBase class object | |
174 | AliRawEventHeaderBase header; | |
175 | ||
176 | // Copy the first common part of the raw data header | |
177 | memcpy(header.HeaderBaseBegin(), data, header.HeaderBaseSize()); | |
178 | ||
179 | // Swap header data if needed | |
180 | if (header.IsSwapped()) | |
181 | header.Swap(); | |
182 | ||
183 | // Is header valid... | |
184 | if (!header.IsValid()) { | |
185 | AliFatalClass("Invalid header format!"); | |
186 | // try recovery... how? | |
187 | return 0x0; | |
188 | } | |
189 | ||
190 | if (header.GetEventSize() < (UInt_t)header.HeaderBaseSize()) { | |
191 | AliFatalClass("Invalid header base size!"); | |
192 | // try recovery... how? | |
193 | return 0x0; | |
194 | } | |
195 | ||
196 | // Now check the DATE version and create the corresponding header | |
197 | // class object | |
198 | UInt_t version = header.GetVersion(); | |
199 | UInt_t majorversion = (version>>16)&0x0000ffff; | |
200 | UInt_t minorversion = version&0x0000ffff; | |
201 | TString classname; | |
202 | classname.Form("AliRawEventHeaderV%d_%d",majorversion,minorversion); | |
203 | ||
204 | TClass *tcl = TClass::GetClass(classname.Data()); | |
205 | if (!tcl) { | |
206 | AliFatalClass(Form("Unknown header version (%s)!",classname.Data())); | |
207 | return 0x0; | |
208 | } | |
209 | ||
210 | // header.Dump(); tcl->Dump(); | |
211 | ||
212 | AliRawEventHeaderBase *hdr = (AliRawEventHeaderBase *)tcl->New(); | |
213 | if (!hdr) { | |
214 | AliFatalClass(Form("Can not create object of class %s",classname.Data())); | |
215 | return 0x0; | |
216 | } | |
217 | ||
218 | // Copy the base header data members and initialize other data members | |
219 | memcpy(hdr->HeaderBaseBegin(),header.HeaderBaseBegin(), header.HeaderBaseSize()); | |
220 | memset(hdr->HeaderBegin(),0, hdr->HeaderSize()); | |
221 | hdr->fIsSwapped = header.fIsSwapped; | |
222 | ||
223 | // Consistency check | |
224 | if (hdr->GetEventSize() < ((UInt_t)hdr->HeaderBaseSize() + (UInt_t)hdr->HeaderSize())) { | |
225 | AliFatalClass(Form("Invalid header size (%d < %d +%d)!", | |
226 | hdr->GetEventSize(),hdr->HeaderBaseSize(),hdr->HeaderSize())); | |
227 | // try recovery... how? | |
228 | return 0x0; | |
229 | } | |
230 | ||
231 | // Check for the presence of header extension and its size | |
232 | Int_t extsize = (Int_t)hdr->GetHeadSize() - (hdr->HeaderBaseSize() + hdr->HeaderSize()); | |
233 | if (extsize < 0) { | |
234 | AliFatalClass(Form("Invalid header size (%d < %d +%d)!", | |
235 | hdr->GetHeadSize(),hdr->HeaderBaseSize(),hdr->HeaderSize())); | |
236 | // try recovery... how? | |
237 | return 0x0; | |
238 | } | |
239 | else { | |
240 | if (extsize > 0) { | |
241 | hdr->SetExtendedDataSize(extsize); | |
242 | char *extdata = new char[extsize]; | |
243 | memset(extdata,0,extsize); | |
244 | hdr->SetExtendedData(extdata); | |
245 | } | |
246 | } | |
247 | ||
248 | return hdr; | |
249 | } | |
250 | ||
251 | //______________________________________________________________________________ | |
252 | Int_t AliRawEventHeaderBase::ReadHeader(char*& data) | |
253 | { | |
254 | // Read header info from DATE data stream. | |
255 | // Returns bytes read | |
256 | ||
257 | Long_t start = (Long_t)data; | |
258 | // Swap header data if needed | |
259 | if (DataIsSwapped()) { | |
260 | swab(data,HeaderBaseBegin(), HeaderBaseSize()); | |
261 | data += HeaderBaseSize(); | |
262 | swab(data, HeaderBegin(), HeaderSize()); | |
263 | data += HeaderSize(); | |
264 | if(GetExtendedDataSize()>0) { | |
265 | swab(data, GetExtendedData(), GetExtendedDataSize()); | |
266 | data += GetExtendedDataSize(); | |
267 | } | |
268 | } | |
269 | else { | |
270 | memcpy(HeaderBaseBegin(), data, HeaderBaseSize()); | |
271 | data += HeaderBaseSize(); | |
272 | memcpy(HeaderBegin(), data, HeaderSize()); | |
273 | data += HeaderSize(); | |
274 | if(GetExtendedDataSize()>0) { | |
275 | memcpy(GetExtendedData(), data, GetExtendedDataSize()); | |
276 | data += GetExtendedDataSize(); | |
277 | } | |
278 | } | |
279 | ||
280 | return (Int_t)((Long_t)data - start); | |
281 | } | |
282 | ||
283 | //______________________________________________________________________________ | |
11d31ad9 | 284 | UInt_t AliRawEventHeaderBase::Get(const char *datamember) const |
f2dc6b20 | 285 | { |
286 | // The method to get a data member from the header object | |
287 | // Except for the data members of the base class, all the | |
288 | // other header data should be retrieved ONLY by this method | |
289 | // The name of the data member should be supplied without "f" | |
290 | // in front | |
291 | ||
292 | char buf[256] = "f"; | |
293 | strcat(buf,datamember); | |
294 | ||
295 | TDataMember *member = IsA()->GetDataMember(buf); | |
296 | if (!member) { | |
297 | AliFatal(Form("No data member %s is found! Check the raw data version!",buf)); | |
298 | return 0; | |
299 | } | |
300 | ||
301 | if (member->GetArrayDim() != 0) { | |
302 | AliFatal(Form("Member %s is an array! Use the GetP() method!",buf)); | |
303 | return 0; | |
304 | } | |
305 | ||
306 | if (strcmp(member->GetTypeName(),"UInt_t") != 0) { | |
307 | AliFatal(Form("Member %s is not of type UInt_t!",buf)); | |
308 | return 0; | |
309 | } | |
310 | ||
311 | const void *pointer = (char *)this+member->GetOffset(); | |
312 | ||
313 | return *((UInt_t *)pointer); | |
314 | } | |
315 | ||
316 | //______________________________________________________________________________ | |
11d31ad9 | 317 | const UInt_t* AliRawEventHeaderBase::GetP(const char *datamember) const |
f2dc6b20 | 318 | { |
319 | // The method to get a data member from the header object | |
320 | // Except for the data members of the base class, all the | |
321 | // other header data should be retrieved ONLY by this method | |
322 | // The name of the data member should be supplied without "f" | |
323 | // in front | |
324 | ||
325 | char buf[256] = "f"; | |
326 | strcat(buf,datamember); | |
327 | ||
328 | TDataMember *member = IsA()->GetDataMember(buf); | |
329 | if (!member) { | |
330 | AliFatal(Form("No data member %s is found! Check the raw data version!",buf)); | |
331 | return 0; | |
332 | } | |
333 | ||
39848565 | 334 | // if (member->GetArrayDim() == 0) { |
335 | // AliFatal(Form("Member %s is not an array! Use the Get() method!",buf)); | |
336 | // return 0; | |
337 | // } | |
f2dc6b20 | 338 | |
339 | if (strcmp(member->GetTypeName(),"UInt_t") != 0) { | |
340 | AliFatal(Form("Member %s is not of type UInt_t*!",buf)); | |
341 | return 0; | |
342 | } | |
343 | ||
344 | const void *pointer = (char *)this+member->GetOffset(); | |
345 | ||
346 | return (const UInt_t*)pointer; | |
347 | } |