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" |
626bfcc1 |
34 | #include "AliHLTOUTHandler.h" |
35 | #include "AliHLTOUTHandlerEquId.h" |
e3917543 |
36 | #include "AliLog.h" |
13b78f4c |
37 | #include "AliDAQ.h" // RAW, for detector names and equipment ids |
38 | #include "TObjString.h" |
39 | #include <cassert> |
9c7b5023 |
40 | |
41 | /** ROOT macro for the implementation of ROOT specific class methods */ |
42 | ClassImp(AliRawReaderHLT) |
43 | |
44 | AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options) |
45 | : |
46 | AliRawReader(), |
47 | fpParentReader(pRawreader), |
13b78f4c |
48 | fOptions(), |
49 | fpData(NULL), |
50 | fDataSize(0), |
51 | fOffset(0), |
52 | fEquipmentId(-1), |
53 | fbHaveHLTData(false), |
54 | fDetectors(), |
626bfcc1 |
55 | fpHLTOUT(NULL), |
56 | fpDataHandler(NULL) |
9c7b5023 |
57 | { |
58 | // see header file for class documentation |
59 | // or |
60 | // refer to README to build package |
61 | // or |
62 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt |
63 | fOptions=options; |
13b78f4c |
64 | ScanOptions(options); |
9c7b5023 |
65 | } |
66 | |
67 | AliRawReaderHLT::~AliRawReaderHLT() |
68 | { |
69 | // see header file for class documentation |
626bfcc1 |
70 | if (fpHLTOUT) { |
71 | if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize); |
72 | else fpHLTOUT->ReleaseDataBuffer(fpData); |
73 | fpDataHandler=NULL; |
74 | delete fpHLTOUT; |
75 | fpHLTOUT=NULL; |
76 | } |
9c7b5023 |
77 | } |
78 | |
79 | UInt_t AliRawReaderHLT::GetType() const |
80 | { |
81 | // see header file for class documentation |
82 | return fpParentReader->GetType(); |
83 | } |
84 | |
85 | UInt_t AliRawReaderHLT::GetRunNumber() const |
86 | { |
87 | // see header file for class documentation |
88 | return fpParentReader->GetRunNumber(); |
89 | } |
90 | |
91 | const UInt_t* AliRawReaderHLT::GetEventId() const |
92 | { |
93 | // see header file for class documentation |
94 | return fpParentReader->GetEventId(); |
95 | } |
96 | |
97 | const UInt_t* AliRawReaderHLT::GetTriggerPattern() const |
98 | { |
99 | // see header file for class documentation |
100 | return fpParentReader->GetTriggerPattern(); |
101 | } |
102 | |
103 | const UInt_t* AliRawReaderHLT::GetDetectorPattern() const |
104 | { |
105 | // see header file for class documentation |
106 | return fpParentReader->GetDetectorPattern(); |
107 | } |
108 | |
109 | const UInt_t* AliRawReaderHLT::GetAttributes() const |
110 | { |
111 | // see header file for class documentation |
112 | return fpParentReader->GetAttributes(); |
113 | } |
114 | |
115 | const UInt_t* AliRawReaderHLT::GetSubEventAttributes() const |
116 | { |
117 | // see header file for class documentation |
118 | return fpParentReader->GetSubEventAttributes(); |
119 | } |
120 | |
121 | UInt_t AliRawReaderHLT::GetLDCId() const |
122 | { |
123 | // see header file for class documentation |
124 | return fpParentReader->GetLDCId(); |
125 | } |
126 | |
127 | UInt_t AliRawReaderHLT::GetGDCId() const |
128 | { |
129 | // see header file for class documentation |
130 | return fpParentReader->GetGDCId(); |
131 | } |
132 | |
133 | UInt_t AliRawReaderHLT::GetTimestamp() const |
134 | { |
135 | // see header file for class documentation |
136 | return fpParentReader->GetTimestamp(); |
137 | } |
138 | |
139 | const UInt_t* AliRawReaderHLT::GetEquipmentAttributes() const |
140 | { |
141 | // see header file for class documentation |
142 | return fpParentReader->GetEquipmentAttributes(); |
143 | } |
144 | |
145 | Int_t AliRawReaderHLT::GetEquipmentElementSize() const |
146 | { |
147 | // see header file for class documentation |
13b78f4c |
148 | // don't know what it really means, bu the AliRawReaderFile |
149 | // just sets it to 0 |
150 | // do the same if we have a valid equipment data set from |
151 | // the HLT stream |
152 | if (fEquipmentId>=0) return 0; |
9c7b5023 |
153 | return fpParentReader->GetEquipmentElementSize(); |
154 | } |
155 | |
156 | Int_t AliRawReaderHLT::GetEquipmentHeaderSize() const |
157 | { |
158 | // see header file for class documentation |
13b78f4c |
159 | |
160 | // equipment header means the additional data header? |
161 | // if we have a valid equipment data set from the HLT stream |
162 | // there is no additional header |
163 | if (fEquipmentId>=0) return 0; |
9c7b5023 |
164 | return fpParentReader->GetEquipmentHeaderSize(); |
165 | } |
166 | |
167 | Int_t AliRawReaderHLT::GetEquipmentSize() const |
168 | { |
169 | // see header file for class documentation |
13b78f4c |
170 | if (fEquipmentId>=0) return fDataSize+sizeof(AliRawDataHeader); |
9c7b5023 |
171 | return fpParentReader->GetEquipmentSize(); |
172 | } |
173 | |
174 | Int_t AliRawReaderHLT::GetEquipmentType() const |
175 | { |
176 | // see header file for class documentation |
177 | return fpParentReader->GetEquipmentType(); |
178 | } |
179 | |
180 | Int_t AliRawReaderHLT::GetEquipmentId() const |
181 | { |
182 | // see header file for class documentation |
13b78f4c |
183 | Int_t id=-1; |
184 | if (fEquipmentId>=0) id=fEquipmentId; |
185 | else id=fpParentReader->GetEquipmentId(); |
e3917543 |
186 | return id; |
9c7b5023 |
187 | } |
188 | |
189 | Bool_t AliRawReaderHLT::ReadHeader() |
190 | { |
191 | // see header file for class documentation |
e3917543 |
192 | Bool_t result=fpParentReader->ReadHeader(); |
093f4dba |
193 | fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader()); |
e3917543 |
194 | return result; |
9c7b5023 |
195 | } |
196 | |
197 | Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data) |
198 | { |
199 | // see header file for class documentation |
13b78f4c |
200 | |
201 | // this function is the backbone of the ReadNext functions, it gets the |
202 | // whole data block either from the HLT stream or the parent raw reader. |
203 | // Each call of ReadNextData directly jumps to the next data set. |
204 | Bool_t result=kFALSE; |
205 | if (fbHaveHLTData&=ReadNextHLTData()) { |
206 | // all internal data variables set |
207 | assert(fpData!=NULL); |
208 | data=const_cast<AliHLTUInt8_t*>(fpData); |
209 | result=kTRUE; |
210 | } |
211 | if (!result) { |
212 | // no data in the HLT stream, read real data |
213 | //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId)); |
214 | |
215 | // first set the selection back to the original one |
216 | fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId); |
217 | |
218 | // read data |
219 | while (result=fpParentReader->ReadNextData(data)) { |
220 | // continue if the Equipment Id is supposed to be replaced by the HLT stream |
221 | // in that case we do not want to read it from the parent raw reader |
222 | if (!IsHLTInput(fpParentReader->GetEquipmentId())) break; |
223 | } |
224 | |
225 | // set the header of this reader from the parent reader. |
226 | // This is necessary because of a few base class methods working directly |
227 | // on the header |
228 | fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader()); |
229 | if (result) { |
230 | fpData=data; |
231 | fDataSize=fpParentReader->GetDataSize(); |
232 | } else { |
233 | fpData=NULL; |
234 | fDataSize=0; |
235 | } |
236 | fOffset=0; |
237 | fEquipmentId=-1; |
238 | } |
e3917543 |
239 | return result; |
9c7b5023 |
240 | } |
241 | |
242 | Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data) |
243 | { |
244 | // see header file for class documentation |
13b78f4c |
245 | int iCopy=sizeof(UInt_t); |
246 | UChar_t* dummy=NULL; |
247 | do { |
248 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
249 | data=*reinterpret_cast<const UInt_t*>(fpData+fOffset); |
250 | fOffset+=iCopy; |
251 | return kTRUE; |
252 | } |
253 | } while (ReadNextData(dummy)); |
254 | return kFALSE; |
9c7b5023 |
255 | } |
256 | |
257 | Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data) |
258 | { |
259 | // see header file for class documentation |
13b78f4c |
260 | int iCopy=sizeof(UShort_t); |
261 | UChar_t* dummy=NULL; |
262 | do { |
263 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
264 | data=*reinterpret_cast<const UShort_t*>(fpData+fOffset); |
265 | fOffset+=iCopy; |
266 | return kTRUE; |
267 | } |
268 | } while (ReadNextData(dummy)); |
269 | return kFALSE; |
9c7b5023 |
270 | } |
271 | |
272 | Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data) |
273 | { |
274 | // see header file for class documentation |
13b78f4c |
275 | int iCopy=sizeof(UChar_t); |
276 | UChar_t* dummy=NULL; |
277 | do { |
278 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
279 | data=*reinterpret_cast<const UChar_t*>(fpData+fOffset); |
280 | fOffset+=iCopy; |
281 | return kTRUE; |
282 | } |
283 | } while (ReadNextData(dummy)); |
284 | return kFALSE; |
9c7b5023 |
285 | } |
286 | |
287 | Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size) |
288 | { |
289 | // see header file for class documentation |
13b78f4c |
290 | UChar_t* dummy=NULL; |
291 | do { |
292 | if (fpData && (fDataSize-fOffset)>=size) { |
293 | // copy remaining data |
294 | int iCopy=fDataSize-fOffset; |
295 | if (iCopy>size) iCopy=size; |
296 | memcpy(data, fpData+fOffset, iCopy); |
297 | fOffset+=iCopy; |
298 | return kTRUE; |
299 | } |
300 | } while (ReadNextData(dummy)); |
301 | return kFALSE; |
9c7b5023 |
302 | } |
303 | |
304 | Bool_t AliRawReaderHLT::Reset() |
305 | { |
306 | // see header file for class documentation |
13b78f4c |
307 | Bool_t result=fpParentReader->Reset(); |
308 | fpData=NULL; |
309 | fDataSize=0; |
310 | fOffset=0; |
311 | fEquipmentId=-1; |
312 | if (fbHaveHLTData=(fDetectors.size()>0)) { |
313 | vector<int>::iterator detector=fDetectors.begin(); |
314 | for (; detector!=fDetectors.end(); detector++) { |
315 | int ddlOffset=AliDAQ::DdlIDOffset(*detector); |
316 | int nofDDLs=AliDAQ::NumberOfDdls(*detector); |
317 | if ((fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>ddlOffset+nofDDLs) || |
318 | (fSelectMinEquipmentId>=0 && fSelectMaxEquipmentId<ddlOffset)) |
319 | continue; |
320 | break; |
321 | } |
322 | fbHaveHLTData=detector!=fDetectors.end(); |
323 | } |
626bfcc1 |
324 | |
325 | if (fpHLTOUT) { |
326 | if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize); |
327 | else fpHLTOUT->ReleaseDataBuffer(fpData); |
328 | fpDataHandler=NULL; |
329 | delete fpHLTOUT; |
330 | fpHLTOUT=NULL; |
331 | } |
332 | |
13b78f4c |
333 | return result; |
9c7b5023 |
334 | } |
335 | |
336 | Bool_t AliRawReaderHLT::NextEvent() |
337 | { |
338 | // see header file for class documentation |
e3917543 |
339 | Bool_t result=fpParentReader->NextEvent(); |
13b78f4c |
340 | if (result) { |
341 | fEventNumber++; |
342 | Reset(); |
343 | } |
e3917543 |
344 | return result; |
9c7b5023 |
345 | } |
346 | |
347 | Bool_t AliRawReaderHLT::RewindEvents() |
348 | { |
349 | // see header file for class documentation |
e3917543 |
350 | fEventNumber=-1; |
13b78f4c |
351 | Reset(); |
9c7b5023 |
352 | return fpParentReader->RewindEvents(); |
353 | } |
354 | |
e3917543 |
355 | void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID) |
356 | { |
13b78f4c |
357 | // see header file for class documentation |
e3917543 |
358 | AliRawReader::Select(detectorID, minDDLID, maxDDLID); |
359 | fpParentReader->Select(detectorID, minDDLID, maxDDLID); |
360 | } |
361 | |
362 | // most likely we do not need this method since the base class directly forwards |
363 | // to this method |
364 | // void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID) |
365 | // { |
366 | // AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID)); |
367 | // AliRawReader::Select(detectorName, minDDLID, maxDDLID); |
368 | // fpParentReader->Select(detectorName, minDDLID, maxDDLID); |
369 | // } |
370 | |
371 | void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId) |
372 | { |
13b78f4c |
373 | // see header file for class documentation |
374 | |
093f4dba |
375 | //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId)); |
e3917543 |
376 | AliRawReader::Select(equipmentType, minEquipmentId, maxEquipmentId); |
377 | fpParentReader->Select(equipmentType, minEquipmentId, maxEquipmentId); |
378 | } |
379 | |
380 | void AliRawReaderHLT::SkipInvalid(Bool_t skip) |
381 | { |
13b78f4c |
382 | // see header file for class documentation |
383 | |
e3917543 |
384 | AliRawReader::SkipInvalid(skip); |
385 | fpParentReader->SkipInvalid(skip); |
386 | } |
387 | |
388 | void AliRawReaderHLT::SelectEvents(Int_t type) |
389 | { |
13b78f4c |
390 | // see header file for class documentation |
391 | |
093f4dba |
392 | //AliInfo(Form("type=%d", type)); |
e3917543 |
393 | AliRawReader::SelectEvents(type); |
394 | fpParentReader->SelectEvents(type); |
395 | } |
396 | |
13b78f4c |
397 | int AliRawReaderHLT::ScanOptions(const char* options) |
398 | { |
399 | // see header file for class documentation |
400 | int iResult=0; |
401 | TString optString(options); |
402 | TString argument; |
403 | TString parameter; |
404 | TObjArray* pTokens=optString.Tokenize(" "); |
405 | if (pTokens) { |
406 | int iEntries=pTokens->GetEntries(); |
407 | for (int i =0; i<iEntries; i++) { |
408 | argument=((TObjString*)pTokens->At(i))->GetString(); |
409 | // first scan all the other options |
410 | // no other options for the moment |
411 | |
412 | // it must be a detector name |
413 | int detId=AliDAQ::DetectorID(argument.Data()); |
414 | if (detId>=0) { |
415 | fDetectors.push_back(detId); |
416 | } |
417 | } |
418 | delete pTokens; |
419 | } |
420 | |
421 | return iResult; |
422 | } |
423 | |
424 | Bool_t AliRawReaderHLT::ReadNextHLTData() |
425 | { |
426 | // see header file for class documentation |
427 | bool result=kTRUE; |
428 | if (!fpHLTOUT) { |
429 | fpHLTOUT=new AliHLTOUTRawReader(fpParentReader); |
430 | if (result=(fpHLTOUT!=NULL)) { |
431 | if (result=(fpHLTOUT->Init()>=0)) { |
432 | result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec, |
433 | AliHLTModuleAgent::kRawReader)>=0; |
434 | } |
435 | } |
436 | } else { |
626bfcc1 |
437 | // first release the data buffer |
438 | if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize); |
439 | else fpHLTOUT->ReleaseDataBuffer(fpData); |
440 | fpDataHandler=NULL; |
13b78f4c |
441 | if (!(result=fpHLTOUT->SelectNextDataBlock()>=0)) { |
442 | delete fpHLTOUT; |
443 | fpHLTOUT=NULL; |
444 | } |
445 | } |
446 | if (result) { |
626bfcc1 |
447 | AliHLTComponentDataType dt=kAliHLTVoidDataType; |
448 | AliHLTUInt32_t spec=kAliHLTVoidDataSpec; |
449 | fpHLTOUT->GetDataBlockDescription(dt, spec); |
13b78f4c |
450 | AliHLTUInt32_t size=0; |
626bfcc1 |
451 | AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler(); |
452 | if (pHandler) { |
453 | if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) { |
454 | AliHLTOUT::AliHLTOUTLockGuard g(fpHLTOUT); |
455 | fEquipmentId=pHandler->ProcessData(fpHLTOUT); |
456 | fpData=NULL; |
457 | fDataSize=pHandler->GetProcessedData(fpData); |
458 | if (!fpData) { |
459 | result=fpHLTOUT->GetDataBuffer(fpData, size)>=0; |
460 | AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId)); |
461 | fDataSize=(int)size; |
462 | } else { |
463 | // remember the current handler in order to properly release the data buffer |
464 | fpDataHandler=pHandler; |
465 | AliDebug(AliLog::kDebug, Form("forward decoded data block provided by handler to equipment %d", fEquipmentId)); |
466 | } |
467 | } else { |
468 | AliError(Form("handler is not of type AliHLTOUTHandlerEquId for block %x data type %s spec %#x; data block skipped", |
469 | fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec)); |
470 | } |
471 | } else { |
472 | AliWarning(Form("no data handler found for block %x data type %s spec %#x; data block skipped", |
473 | fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec)); |
474 | } |
13b78f4c |
475 | } else { |
476 | fpData=NULL; |
477 | fDataSize=0; |
478 | fOffset=0; |
479 | fEquipmentId=-1; |
480 | } |
481 | return false; |
482 | } |
483 | |
484 | Bool_t AliRawReaderHLT::IsHLTInput(int ddlid) |
485 | { |
486 | // see header file for class documentation |
487 | vector<int>::iterator detector=fDetectors.begin(); |
488 | for (; detector!=fDetectors.end(); detector++) { |
489 | int ddlOffset=AliDAQ::DdlIDOffset(*detector); |
490 | int nofDDLs=AliDAQ::NumberOfDdls(*detector); |
491 | if (ddlid>=ddlOffset && ddlid<ddlOffset+nofDDLs) |
492 | return kTRUE; |
493 | } |
494 | return kFALSE; |
495 | } |
496 | |
9c7b5023 |
497 | AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options) |
498 | { |
499 | // see header file for class documentation |
e3917543 |
500 | if (!pParentReader) return NULL; |
9c7b5023 |
501 | return new AliRawReaderHLT(pParentReader, options); |
502 | } |