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 |
e3917543 |
195 | Bool_t result=fpParentReader->ReadHeader(); |
093f4dba |
196 | fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader()); |
e3917543 |
197 | return result; |
9c7b5023 |
198 | } |
199 | |
200 | Bool_t AliRawReaderHLT::ReadNextData(UChar_t*& data) |
201 | { |
202 | // see header file for class documentation |
13b78f4c |
203 | |
204 | // this function is the backbone of the ReadNext functions, it gets the |
205 | // whole data block either from the HLT stream or the parent raw reader. |
206 | // Each call of ReadNextData directly jumps to the next data set. |
207 | Bool_t result=kFALSE; |
208 | if (fbHaveHLTData&=ReadNextHLTData()) { |
209 | // all internal data variables set |
210 | assert(fpData!=NULL); |
211 | data=const_cast<AliHLTUInt8_t*>(fpData); |
212 | result=kTRUE; |
213 | } |
214 | if (!result) { |
215 | // no data in the HLT stream, read real data |
216 | //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId)); |
217 | |
218 | // first set the selection back to the original one |
219 | fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId); |
220 | |
221 | // read data |
222 | while (result=fpParentReader->ReadNextData(data)) { |
223 | // continue if the Equipment Id is supposed to be replaced by the HLT stream |
224 | // in that case we do not want to read it from the parent raw reader |
225 | if (!IsHLTInput(fpParentReader->GetEquipmentId())) break; |
226 | } |
227 | |
228 | // set the header of this reader from the parent reader. |
229 | // This is necessary because of a few base class methods working directly |
230 | // on the header |
231 | fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader()); |
232 | if (result) { |
233 | fpData=data; |
234 | fDataSize=fpParentReader->GetDataSize(); |
235 | } else { |
236 | fpData=NULL; |
237 | fDataSize=0; |
238 | } |
239 | fOffset=0; |
240 | fEquipmentId=-1; |
241 | } |
e3917543 |
242 | return result; |
9c7b5023 |
243 | } |
244 | |
245 | Bool_t AliRawReaderHLT::ReadNextInt(UInt_t& data) |
246 | { |
247 | // see header file for class documentation |
13b78f4c |
248 | int iCopy=sizeof(UInt_t); |
249 | UChar_t* dummy=NULL; |
250 | do { |
251 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
252 | data=*reinterpret_cast<const UInt_t*>(fpData+fOffset); |
253 | fOffset+=iCopy; |
254 | return kTRUE; |
255 | } |
256 | } while (ReadNextData(dummy)); |
257 | return kFALSE; |
9c7b5023 |
258 | } |
259 | |
260 | Bool_t AliRawReaderHLT::ReadNextShort(UShort_t& data) |
261 | { |
262 | // see header file for class documentation |
13b78f4c |
263 | int iCopy=sizeof(UShort_t); |
264 | UChar_t* dummy=NULL; |
265 | do { |
266 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
267 | data=*reinterpret_cast<const UShort_t*>(fpData+fOffset); |
268 | fOffset+=iCopy; |
269 | return kTRUE; |
270 | } |
271 | } while (ReadNextData(dummy)); |
272 | return kFALSE; |
9c7b5023 |
273 | } |
274 | |
275 | Bool_t AliRawReaderHLT::ReadNextChar(UChar_t& data) |
276 | { |
277 | // see header file for class documentation |
13b78f4c |
278 | int iCopy=sizeof(UChar_t); |
279 | UChar_t* dummy=NULL; |
280 | do { |
281 | if (fpData && (fDataSize-fOffset)>=iCopy) { |
282 | data=*reinterpret_cast<const UChar_t*>(fpData+fOffset); |
283 | fOffset+=iCopy; |
284 | return kTRUE; |
285 | } |
286 | } while (ReadNextData(dummy)); |
287 | return kFALSE; |
9c7b5023 |
288 | } |
289 | |
290 | Bool_t AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size) |
291 | { |
292 | // see header file for class documentation |
13b78f4c |
293 | UChar_t* dummy=NULL; |
294 | do { |
295 | if (fpData && (fDataSize-fOffset)>=size) { |
296 | // copy remaining data |
297 | int iCopy=fDataSize-fOffset; |
298 | if (iCopy>size) iCopy=size; |
299 | memcpy(data, fpData+fOffset, iCopy); |
300 | fOffset+=iCopy; |
301 | return kTRUE; |
302 | } |
303 | } while (ReadNextData(dummy)); |
304 | return kFALSE; |
9c7b5023 |
305 | } |
306 | |
307 | Bool_t AliRawReaderHLT::Reset() |
308 | { |
309 | // see header file for class documentation |
13b78f4c |
310 | Bool_t result=fpParentReader->Reset(); |
311 | fpData=NULL; |
312 | fDataSize=0; |
313 | fOffset=0; |
314 | fEquipmentId=-1; |
315 | if (fbHaveHLTData=(fDetectors.size()>0)) { |
316 | vector<int>::iterator detector=fDetectors.begin(); |
317 | for (; detector!=fDetectors.end(); detector++) { |
318 | int ddlOffset=AliDAQ::DdlIDOffset(*detector); |
319 | int nofDDLs=AliDAQ::NumberOfDdls(*detector); |
320 | if ((fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>ddlOffset+nofDDLs) || |
321 | (fSelectMinEquipmentId>=0 && fSelectMaxEquipmentId<ddlOffset)) |
322 | continue; |
323 | break; |
324 | } |
325 | fbHaveHLTData=detector!=fDetectors.end(); |
326 | } |
626bfcc1 |
327 | |
328 | if (fpHLTOUT) { |
329 | if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize); |
330 | else fpHLTOUT->ReleaseDataBuffer(fpData); |
331 | fpDataHandler=NULL; |
332 | delete fpHLTOUT; |
333 | fpHLTOUT=NULL; |
334 | } |
335 | |
13b78f4c |
336 | return result; |
9c7b5023 |
337 | } |
338 | |
339 | Bool_t AliRawReaderHLT::NextEvent() |
340 | { |
341 | // see header file for class documentation |
e3917543 |
342 | Bool_t result=fpParentReader->NextEvent(); |
13b78f4c |
343 | if (result) { |
344 | fEventNumber++; |
345 | Reset(); |
346 | } |
e3917543 |
347 | return result; |
9c7b5023 |
348 | } |
349 | |
350 | Bool_t AliRawReaderHLT::RewindEvents() |
351 | { |
352 | // see header file for class documentation |
e3917543 |
353 | fEventNumber=-1; |
13b78f4c |
354 | Reset(); |
9c7b5023 |
355 | return fpParentReader->RewindEvents(); |
356 | } |
357 | |
e3917543 |
358 | void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID) |
359 | { |
13b78f4c |
360 | // see header file for class documentation |
e3917543 |
361 | AliRawReader::Select(detectorID, minDDLID, maxDDLID); |
362 | fpParentReader->Select(detectorID, minDDLID, maxDDLID); |
363 | } |
364 | |
365 | // most likely we do not need this method since the base class directly forwards |
366 | // to this method |
367 | // void AliRawReaderHLT::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID) |
368 | // { |
369 | // AliInfo(Form("detectorName=%s, minDDLID=%d, maxDDLID=%d", detectorName, minDDLID, maxDDLID)); |
370 | // AliRawReader::Select(detectorName, minDDLID, maxDDLID); |
371 | // fpParentReader->Select(detectorName, minDDLID, maxDDLID); |
372 | // } |
373 | |
374 | void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId, Int_t maxEquipmentId) |
375 | { |
13b78f4c |
376 | // see header file for class documentation |
377 | |
093f4dba |
378 | //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId)); |
e3917543 |
379 | AliRawReader::Select(equipmentType, minEquipmentId, maxEquipmentId); |
380 | fpParentReader->Select(equipmentType, minEquipmentId, maxEquipmentId); |
381 | } |
382 | |
383 | void AliRawReaderHLT::SkipInvalid(Bool_t skip) |
384 | { |
13b78f4c |
385 | // see header file for class documentation |
386 | |
e3917543 |
387 | AliRawReader::SkipInvalid(skip); |
388 | fpParentReader->SkipInvalid(skip); |
389 | } |
390 | |
391 | void AliRawReaderHLT::SelectEvents(Int_t type) |
392 | { |
13b78f4c |
393 | // see header file for class documentation |
394 | |
093f4dba |
395 | //AliInfo(Form("type=%d", type)); |
e3917543 |
396 | AliRawReader::SelectEvents(type); |
397 | fpParentReader->SelectEvents(type); |
398 | } |
399 | |
13b78f4c |
400 | int AliRawReaderHLT::ScanOptions(const char* options) |
401 | { |
402 | // see header file for class documentation |
403 | int iResult=0; |
404 | TString optString(options); |
405 | TString argument; |
406 | TString parameter; |
407 | TObjArray* pTokens=optString.Tokenize(" "); |
408 | if (pTokens) { |
409 | int iEntries=pTokens->GetEntries(); |
410 | for (int i =0; i<iEntries; i++) { |
411 | argument=((TObjString*)pTokens->At(i))->GetString(); |
412 | // first scan all the other options |
413 | // no other options for the moment |
414 | |
415 | // it must be a detector name |
416 | int detId=AliDAQ::DetectorID(argument.Data()); |
417 | if (detId>=0) { |
418 | fDetectors.push_back(detId); |
a3ef3c1d |
419 | } else { |
420 | if (!fSystemOptions.IsNull()) fSystemOptions+=" "; |
421 | fSystemOptions+=argument; |
13b78f4c |
422 | } |
423 | } |
424 | delete pTokens; |
425 | } |
426 | |
427 | return iResult; |
428 | } |
429 | |
430 | Bool_t AliRawReaderHLT::ReadNextHLTData() |
431 | { |
432 | // see header file for class documentation |
433 | bool result=kTRUE; |
434 | if (!fpHLTOUT) { |
435 | fpHLTOUT=new AliHLTOUTRawReader(fpParentReader); |
436 | if (result=(fpHLTOUT!=NULL)) { |
a3ef3c1d |
437 | AliHLTSystem* pSystem=GetInstance(); |
438 | if (pSystem) { |
439 | pSystem->ScanOptions(fSystemOptions.Data()); |
440 | } |
13b78f4c |
441 | if (result=(fpHLTOUT->Init()>=0)) { |
442 | result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec, |
443 | AliHLTModuleAgent::kRawReader)>=0; |
444 | } |
445 | } |
446 | } else { |
626bfcc1 |
447 | // first release the data buffer |
448 | if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize); |
449 | else fpHLTOUT->ReleaseDataBuffer(fpData); |
450 | fpDataHandler=NULL; |
13b78f4c |
451 | if (!(result=fpHLTOUT->SelectNextDataBlock()>=0)) { |
452 | delete fpHLTOUT; |
453 | fpHLTOUT=NULL; |
454 | } |
455 | } |
456 | if (result) { |
626bfcc1 |
457 | AliHLTComponentDataType dt=kAliHLTVoidDataType; |
458 | AliHLTUInt32_t spec=kAliHLTVoidDataSpec; |
459 | fpHLTOUT->GetDataBlockDescription(dt, spec); |
13b78f4c |
460 | AliHLTUInt32_t size=0; |
626bfcc1 |
461 | AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler(); |
462 | if (pHandler) { |
463 | if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) { |
464 | AliHLTOUT::AliHLTOUTLockGuard g(fpHLTOUT); |
465 | fEquipmentId=pHandler->ProcessData(fpHLTOUT); |
466 | fpData=NULL; |
467 | fDataSize=pHandler->GetProcessedData(fpData); |
468 | if (!fpData) { |
469 | result=fpHLTOUT->GetDataBuffer(fpData, size)>=0; |
470 | AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId)); |
471 | fDataSize=(int)size; |
472 | } else { |
473 | // remember the current handler in order to properly release the data buffer |
474 | fpDataHandler=pHandler; |
475 | AliDebug(AliLog::kDebug, Form("forward decoded data block provided by handler to equipment %d", fEquipmentId)); |
476 | } |
477 | } else { |
478 | AliError(Form("handler is not of type AliHLTOUTHandlerEquId for block %x data type %s spec %#x; data block skipped", |
479 | fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec)); |
480 | } |
481 | } else { |
482 | AliWarning(Form("no data handler found for block %x data type %s spec %#x; data block skipped", |
483 | fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec)); |
484 | } |
13b78f4c |
485 | } else { |
486 | fpData=NULL; |
487 | fDataSize=0; |
488 | fOffset=0; |
489 | fEquipmentId=-1; |
490 | } |
491 | return false; |
492 | } |
493 | |
494 | Bool_t AliRawReaderHLT::IsHLTInput(int ddlid) |
495 | { |
496 | // see header file for class documentation |
497 | vector<int>::iterator detector=fDetectors.begin(); |
498 | for (; detector!=fDetectors.end(); detector++) { |
499 | int ddlOffset=AliDAQ::DdlIDOffset(*detector); |
500 | int nofDDLs=AliDAQ::NumberOfDdls(*detector); |
501 | if (ddlid>=ddlOffset && ddlid<ddlOffset+nofDDLs) |
502 | return kTRUE; |
503 | } |
504 | return kFALSE; |
505 | } |
506 | |
9c7b5023 |
507 | AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options) |
508 | { |
509 | // see header file for class documentation |
e3917543 |
510 | if (!pParentReader) return NULL; |
9c7b5023 |
511 | return new AliRawReaderHLT(pParentReader, options); |
512 | } |