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