7e914051 |
1 | // $Id$ |
9c7b5023 |
2 | |
3 | /************************************************************************** |
4 | * This file is property of and copyright by the ALICE HLT Project * |
5 | * ALICE Experiment at CERN, All rights reserved. * |
6 | * * |
7 | * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * |
8 | * for The ALICE HLT Project. * |
9 | * * |
10 | * Permission to use, copy, modify and distribute this software and its * |
11 | * documentation strictly for non-commercial purposes is hereby granted * |
12 | * without fee, provided that the above copyright notice appears in all * |
13 | * copies and that both the copyright notice and this permission notice * |
14 | * appear in the supporting documentation. The authors make no claims * |
15 | * about the suitability of this software for any purpose. It is * |
16 | * provided "as is" without express or implied warranty. * |
17 | **************************************************************************/ |
18 | |
19 | /** @file AliRawReaderHLT.cxx |
20 | @author Matthias Richter |
21 | @date |
22 | @brief AliRawReader implementation which replaces original input of |
23 | detectors with the appropriate HLT output. */ |
24 | |
25 | // see header file for class documentation |
26 | // or |
27 | // refer to README to build package |
28 | // or |
29 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt |
30 | |
31 | #include "AliRawReaderHLT.h" |
13b78f4c |
32 | #include "AliHLTOUTRawReader.h" |
33 | #include "AliHLTModuleAgent.h" |
e3917543 |
34 | #include "AliLog.h" |
13b78f4c |
35 | #include "AliDAQ.h" // RAW, for detector names and equipment ids |
36 | #include "TObjString.h" |
37 | #include <cassert> |
9c7b5023 |
38 | |
39 | /** ROOT macro for the implementation of ROOT specific class methods */ |
40 | ClassImp(AliRawReaderHLT) |
41 | |
42 | AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options) |
43 | : |
44 | AliRawReader(), |
45 | fpParentReader(pRawreader), |
13b78f4c |
46 | fOptions(), |
47 | fpData(NULL), |
48 | fDataSize(0), |
49 | fOffset(0), |
50 | fEquipmentId(-1), |
51 | fbHaveHLTData(false), |
52 | fDetectors(), |
53 | fpHLTOUT(NULL) |
9c7b5023 |
54 | { |
55 | // see header file for class documentation |
56 | // or |
57 | // refer to README to build package |
58 | // or |
59 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt |
60 | fOptions=options; |
13b78f4c |
61 | ScanOptions(options); |
9c7b5023 |
62 | } |
63 | |
64 | AliRawReaderHLT::~AliRawReaderHLT() |
65 | { |
66 | // see header file for class documentation |
67 | } |
68 | |
69 | UInt_t AliRawReaderHLT::GetType() const |
70 | { |
71 | // see header file for class documentation |
72 | return fpParentReader->GetType(); |
73 | } |
74 | |
75 | UInt_t AliRawReaderHLT::GetRunNumber() const |
76 | { |
77 | // see header file for class documentation |
78 | return fpParentReader->GetRunNumber(); |
79 | } |
80 | |
81 | const UInt_t* AliRawReaderHLT::GetEventId() const |
82 | { |
83 | // see header file for class documentation |
84 | return fpParentReader->GetEventId(); |
85 | } |
86 | |
87 | const UInt_t* AliRawReaderHLT::GetTriggerPattern() const |
88 | { |
89 | // see header file for class documentation |
90 | return fpParentReader->GetTriggerPattern(); |
91 | } |
92 | |
93 | const UInt_t* AliRawReaderHLT::GetDetectorPattern() const |
94 | { |
95 | // see header file for class documentation |
96 | return fpParentReader->GetDetectorPattern(); |
97 | } |
98 | |
99 | const UInt_t* AliRawReaderHLT::GetAttributes() const |
100 | { |
101 | // see header file for class documentation |
102 | return fpParentReader->GetAttributes(); |
103 | } |
104 | |
105 | const UInt_t* AliRawReaderHLT::GetSubEventAttributes() const |
106 | { |
107 | // see header file for class documentation |
108 | return fpParentReader->GetSubEventAttributes(); |
109 | } |
110 | |
111 | UInt_t AliRawReaderHLT::GetLDCId() const |
112 | { |
113 | // see header file for class documentation |
114 | return fpParentReader->GetLDCId(); |
115 | } |
116 | |
117 | UInt_t AliRawReaderHLT::GetGDCId() const |
118 | { |
119 | // see header file for class documentation |
120 | return fpParentReader->GetGDCId(); |
121 | } |
122 | |
123 | UInt_t AliRawReaderHLT::GetTimestamp() const |
124 | { |
125 | // see header file for class documentation |
126 | return fpParentReader->GetTimestamp(); |
127 | } |
128 | |
129 | const UInt_t* AliRawReaderHLT::GetEquipmentAttributes() const |
130 | { |
131 | // see header file for class documentation |
132 | return fpParentReader->GetEquipmentAttributes(); |
133 | } |
134 | |
135 | Int_t AliRawReaderHLT::GetEquipmentElementSize() const |
136 | { |
137 | // see header file for class documentation |
13b78f4c |
138 | // don't know what it really means, bu the AliRawReaderFile |
139 | // just sets it to 0 |
140 | // do the same if we have a valid equipment data set from |
141 | // the HLT stream |
142 | if (fEquipmentId>=0) return 0; |
9c7b5023 |
143 | return fpParentReader->GetEquipmentElementSize(); |
144 | } |
145 | |
146 | Int_t AliRawReaderHLT::GetEquipmentHeaderSize() const |
147 | { |
148 | // see header file for class documentation |
13b78f4c |
149 | |
150 | // equipment header means the additional data header? |
151 | // if we have a valid equipment data set from the HLT stream |
152 | // there is no additional header |
153 | if (fEquipmentId>=0) return 0; |
9c7b5023 |
154 | return fpParentReader->GetEquipmentHeaderSize(); |
155 | } |
156 | |
157 | Int_t AliRawReaderHLT::GetEquipmentSize() const |
158 | { |
159 | // see header file for class documentation |
13b78f4c |
160 | if (fEquipmentId>=0) return fDataSize+sizeof(AliRawDataHeader); |
9c7b5023 |
161 | return fpParentReader->GetEquipmentSize(); |
162 | } |
163 | |
164 | Int_t AliRawReaderHLT::GetEquipmentType() const |
165 | { |
166 | // see header file for class documentation |
167 | return fpParentReader->GetEquipmentType(); |
168 | } |
169 | |
170 | Int_t AliRawReaderHLT::GetEquipmentId() const |
171 | { |
172 | // see header file for class documentation |
13b78f4c |
173 | Int_t id=-1; |
174 | if (fEquipmentId>=0) id=fEquipmentId; |
175 | else id=fpParentReader->GetEquipmentId(); |
e3917543 |
176 | return id; |
9c7b5023 |
177 | } |
178 | |
179 | Bool_t AliRawReaderHLT::ReadHeader() |
180 | { |
181 | // see header file for class documentation |
e3917543 |
182 | Bool_t result=fpParentReader->ReadHeader(); |
093f4dba |
183 | fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader()); |
e3917543 |
184 | return result; |
9c7b5023 |
185 | } |
186 | |
187 | Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data) |
188 | { |
189 | // see header file for class documentation |
13b78f4c |
190 | |
191 | // this function is the backbone of the ReadNext functions, it gets the |
192 | // whole data block either from the HLT stream or the parent raw reader. |
193 | // Each call of ReadNextData directly jumps to the next data set. |
194 | Bool_t result=kFALSE; |
195 | if (fbHaveHLTData&=ReadNextHLTData()) { |
196 | // all internal data variables set |
197 | assert(fpData!=NULL); |
198 | data=const_cast<AliHLTUInt8_t*>(fpData); |
199 | result=kTRUE; |
200 | } |
201 | if (!result) { |
202 | // no data in the HLT stream, read real data |
203 | //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId)); |
204 | |
205 | // first set the selection back to the original one |
206 | fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId); |
207 | |
208 | // read data |
209 | while (result=fpParentReader->ReadNextData(data)) { |
210 | // continue if the Equipment Id is supposed to be replaced by the HLT stream |
211 | // in that case we do not want to read it from the parent raw reader |
212 | if (!IsHLTInput(fpParentReader->GetEquipmentId())) break; |
213 | } |
214 | |
215 | // set the header of this reader from the parent reader. |
216 | // This is necessary because of a few base class methods working directly |
217 | // on the header |
218 | fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader()); |
219 | if (result) { |
220 | fpData=data; |
221 | fDataSize=fpParentReader->GetDataSize(); |
222 | } else { |
223 | fpData=NULL; |
224 | fDataSize=0; |
225 | } |
226 | fOffset=0; |
227 | fEquipmentId=-1; |
228 | } |
e3917543 |
229 | return result; |
9c7b5023 |
230 | } |
231 | |
232 | Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data) |
233 | { |
234 | // see header file for class documentation |
13b78f4c |
235 | int iCopy=sizeof(UInt_t); |
236 | UChar_t* dummy=NULL; |
237 | do { |
238 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
239 | data=*reinterpret_cast<const UInt_t*>(fpData+fOffset); |
240 | fOffset+=iCopy; |
241 | return kTRUE; |
242 | } |
243 | } while (ReadNextData(dummy)); |
244 | return kFALSE; |
9c7b5023 |
245 | } |
246 | |
247 | Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data) |
248 | { |
249 | // see header file for class documentation |
13b78f4c |
250 | int iCopy=sizeof(UShort_t); |
251 | UChar_t* dummy=NULL; |
252 | do { |
253 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
254 | data=*reinterpret_cast<const UShort_t*>(fpData+fOffset); |
255 | fOffset+=iCopy; |
256 | return kTRUE; |
257 | } |
258 | } while (ReadNextData(dummy)); |
259 | return kFALSE; |
9c7b5023 |
260 | } |
261 | |
262 | Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data) |
263 | { |
264 | // see header file for class documentation |
13b78f4c |
265 | int iCopy=sizeof(UChar_t); |
266 | UChar_t* dummy=NULL; |
267 | do { |
268 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
269 | data=*reinterpret_cast<const UChar_t*>(fpData+fOffset); |
270 | fOffset+=iCopy; |
271 | return kTRUE; |
272 | } |
273 | } while (ReadNextData(dummy)); |
274 | return kFALSE; |
9c7b5023 |
275 | } |
276 | |
277 | Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size) |
278 | { |
279 | // see header file for class documentation |
13b78f4c |
280 | UChar_t* dummy=NULL; |
281 | do { |
282 | if (fpData && (fDataSize-fOffset)>=size) { |
283 | // copy remaining data |
284 | int iCopy=fDataSize-fOffset; |
285 | if (iCopy>size) iCopy=size; |
286 | memcpy(data, fpData+fOffset, iCopy); |
287 | fOffset+=iCopy; |
288 | return kTRUE; |
289 | } |
290 | } while (ReadNextData(dummy)); |
291 | return kFALSE; |
9c7b5023 |
292 | } |
293 | |
294 | Bool_t AliRawReaderHLT::Reset() |
295 | { |
296 | // see header file for class documentation |
13b78f4c |
297 | Bool_t result=fpParentReader->Reset(); |
298 | fpData=NULL; |
299 | fDataSize=0; |
300 | fOffset=0; |
301 | fEquipmentId=-1; |
302 | if (fbHaveHLTData=(fDetectors.size()>0)) { |
303 | vector<int>::iterator detector=fDetectors.begin(); |
304 | for (; detector!=fDetectors.end(); detector++) { |
305 | int ddlOffset=AliDAQ::DdlIDOffset(*detector); |
306 | int nofDDLs=AliDAQ::NumberOfDdls(*detector); |
307 | if ((fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>ddlOffset+nofDDLs) || |
308 | (fSelectMinEquipmentId>=0 && fSelectMaxEquipmentId<ddlOffset)) |
309 | continue; |
310 | break; |
311 | } |
312 | fbHaveHLTData=detector!=fDetectors.end(); |
313 | } |
314 | return result; |
9c7b5023 |
315 | } |
316 | |
317 | Bool_t AliRawReaderHLT::NextEvent() |
318 | { |
319 | // see header file for class documentation |
e3917543 |
320 | Bool_t result=fpParentReader->NextEvent(); |
13b78f4c |
321 | if (result) { |
322 | fEventNumber++; |
323 | Reset(); |
324 | } |
e3917543 |
325 | return result; |
9c7b5023 |
326 | } |
327 | |
328 | Bool_t AliRawReaderHLT::RewindEvents() |
329 | { |
330 | // see header file for class documentation |
e3917543 |
331 | fEventNumber=-1; |
13b78f4c |
332 | Reset(); |
9c7b5023 |
333 | return fpParentReader->RewindEvents(); |
334 | } |
335 | |
e3917543 |
336 | void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID) |
337 | { |
13b78f4c |
338 | // see header file for class documentation |
e3917543 |
339 | AliRawReader::Select(detectorID, minDDLID, maxDDLID); |
340 | fpParentReader->Select(detectorID, minDDLID, maxDDLID); |
341 | } |
342 | |
343 | // most likely we do not need this method since the base class directly forwards |
344 | // to this method |
345 | // void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID) |
346 | // { |
347 | // AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID)); |
348 | // AliRawReader::Select(detectorName, minDDLID, maxDDLID); |
349 | // fpParentReader->Select(detectorName, minDDLID, maxDDLID); |
350 | // } |
351 | |
352 | void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId) |
353 | { |
13b78f4c |
354 | // see header file for class documentation |
355 | |
093f4dba |
356 | //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId)); |
e3917543 |
357 | AliRawReader::Select(equipmentType, minEquipmentId, maxEquipmentId); |
358 | fpParentReader->Select(equipmentType, minEquipmentId, maxEquipmentId); |
359 | } |
360 | |
361 | void AliRawReaderHLT::SkipInvalid(Bool_t skip) |
362 | { |
13b78f4c |
363 | // see header file for class documentation |
364 | |
e3917543 |
365 | AliRawReader::SkipInvalid(skip); |
366 | fpParentReader->SkipInvalid(skip); |
367 | } |
368 | |
369 | void AliRawReaderHLT::SelectEvents(Int_t type) |
370 | { |
13b78f4c |
371 | // see header file for class documentation |
372 | |
093f4dba |
373 | //AliInfo(Form("type=%d", type)); |
e3917543 |
374 | AliRawReader::SelectEvents(type); |
375 | fpParentReader->SelectEvents(type); |
376 | } |
377 | |
13b78f4c |
378 | int AliRawReaderHLT::ScanOptions(const char* options) |
379 | { |
380 | // see header file for class documentation |
381 | int iResult=0; |
382 | TString optString(options); |
383 | TString argument; |
384 | TString parameter; |
385 | TObjArray* pTokens=optString.Tokenize(" "); |
386 | if (pTokens) { |
387 | int iEntries=pTokens->GetEntries(); |
388 | for (int i =0; i<iEntries; i++) { |
389 | argument=((TObjString*)pTokens->At(i))->GetString(); |
390 | // first scan all the other options |
391 | // no other options for the moment |
392 | |
393 | // it must be a detector name |
394 | int detId=AliDAQ::DetectorID(argument.Data()); |
395 | if (detId>=0) { |
396 | fDetectors.push_back(detId); |
397 | } |
398 | } |
399 | delete pTokens; |
400 | } |
401 | |
402 | return iResult; |
403 | } |
404 | |
405 | Bool_t AliRawReaderHLT::ReadNextHLTData() |
406 | { |
407 | // see header file for class documentation |
408 | bool result=kTRUE; |
409 | if (!fpHLTOUT) { |
410 | fpHLTOUT=new AliHLTOUTRawReader(fpParentReader); |
411 | if (result=(fpHLTOUT!=NULL)) { |
412 | if (result=(fpHLTOUT->Init()>=0)) { |
413 | result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec, |
414 | AliHLTModuleAgent::kRawReader)>=0; |
415 | } |
416 | } |
417 | } else { |
418 | fpHLTOUT->ReleaseDataBuffer(fpData); |
419 | if (!(result=fpHLTOUT->SelectNextDataBlock()>=0)) { |
420 | delete fpHLTOUT; |
421 | fpHLTOUT=NULL; |
422 | } |
423 | } |
424 | if (result) { |
425 | AliHLTUInt32_t size=0; |
426 | result=fpHLTOUT->GetDataBuffer(fpData, size)>=0; |
427 | fDataSize=(int)size; |
428 | fEquipmentId=-1; |
429 | } else { |
430 | fpData=NULL; |
431 | fDataSize=0; |
432 | fOffset=0; |
433 | fEquipmentId=-1; |
434 | } |
435 | return false; |
436 | } |
437 | |
438 | Bool_t AliRawReaderHLT::IsHLTInput(int ddlid) |
439 | { |
440 | // see header file for class documentation |
441 | vector<int>::iterator detector=fDetectors.begin(); |
442 | for (; detector!=fDetectors.end(); detector++) { |
443 | int ddlOffset=AliDAQ::DdlIDOffset(*detector); |
444 | int nofDDLs=AliDAQ::NumberOfDdls(*detector); |
445 | if (ddlid>=ddlOffset && ddlid<ddlOffset+nofDDLs) |
446 | return kTRUE; |
447 | } |
448 | return kFALSE; |
449 | } |
450 | |
9c7b5023 |
451 | AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options) |
452 | { |
453 | // see header file for class documentation |
e3917543 |
454 | if (!pParentReader) return NULL; |
9c7b5023 |
455 | return new AliRawReaderHLT(pParentReader, options); |
456 | } |