handling of HLTOUT data added; access to parent raw reader restructured
[u/mrichter/AliRoot.git] / HLT / rec / AliRawReaderHLT.cxx
1 // $Id$
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"
32 #include "AliHLTOUTRawReader.h"
33 #include "AliHLTModuleAgent.h"
34 #include "AliLog.h"
35 #include "AliDAQ.h"            // RAW, for detector names and equipment ids
36 #include "TObjString.h"
37 #include <cassert>
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),
46   fOptions(),
47   fpData(NULL),
48   fDataSize(0),
49   fOffset(0),
50   fEquipmentId(-1),
51   fbHaveHLTData(false),
52   fDetectors(),
53   fpHLTOUT(NULL)
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;
61   ScanOptions(options);
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
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;
143   return fpParentReader->GetEquipmentElementSize();
144 }
145
146 Int_t    AliRawReaderHLT::GetEquipmentHeaderSize() const
147 {
148   // see header file for class documentation
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;
154   return fpParentReader->GetEquipmentHeaderSize();
155 }
156
157 Int_t    AliRawReaderHLT::GetEquipmentSize() const
158 {
159   // see header file for class documentation
160   if (fEquipmentId>=0) return fDataSize+sizeof(AliRawDataHeader);
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
173   Int_t id=-1;
174   if (fEquipmentId>=0) id=fEquipmentId;
175   else id=fpParentReader->GetEquipmentId();
176   return id;
177 }
178
179 Bool_t   AliRawReaderHLT::ReadHeader()
180 {
181   // see header file for class documentation
182   Bool_t result=fpParentReader->ReadHeader();
183   fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
184   return result;
185 }
186
187 Bool_t   AliRawReaderHLT::ReadNextData(UChar_t*& data)
188 {
189   // see header file for class documentation
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   }
229   return result;
230 }
231
232 Bool_t   AliRawReaderHLT::ReadNextInt(UInt_t& data)
233 {
234   // see header file for class documentation
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;
245 }
246
247 Bool_t   AliRawReaderHLT::ReadNextShort(UShort_t& data)
248 {
249   // see header file for class documentation
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;
260 }
261
262 Bool_t   AliRawReaderHLT::ReadNextChar(UChar_t& data)
263 {
264   // see header file for class documentation
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;
275 }
276
277 Bool_t   AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size)
278 {
279   // see header file for class documentation
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;
292 }
293
294 Bool_t   AliRawReaderHLT::Reset()
295 {
296   // see header file for class documentation
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;
315 }
316
317 Bool_t   AliRawReaderHLT::NextEvent()
318 {
319   // see header file for class documentation
320   Bool_t result=fpParentReader->NextEvent();
321   if (result) {
322     fEventNumber++;
323     Reset();
324   }
325   return result;
326 }
327
328 Bool_t   AliRawReaderHLT::RewindEvents()
329 {
330   // see header file for class documentation
331   fEventNumber=-1;
332   Reset();
333   return fpParentReader->RewindEvents();
334 }
335
336 void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
337 {
338   // see header file for class documentation
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 {
354   // see header file for class documentation
355
356   //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
357   AliRawReader::Select(equipmentType, minEquipmentId, maxEquipmentId);
358   fpParentReader->Select(equipmentType, minEquipmentId, maxEquipmentId);
359 }
360
361 void AliRawReaderHLT::SkipInvalid(Bool_t skip)
362 {
363   // see header file for class documentation
364
365   AliRawReader::SkipInvalid(skip);
366   fpParentReader->SkipInvalid(skip);
367 }
368
369 void AliRawReaderHLT::SelectEvents(Int_t type)
370 {
371   // see header file for class documentation
372
373   //AliInfo(Form("type=%d", type));
374   AliRawReader::SelectEvents(type);
375   fpParentReader->SelectEvents(type);
376 }
377
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
451 AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
452 {
453   // see header file for class documentation
454   if (!pParentReader) return NULL;
455   return new AliRawReaderHLT(pParentReader, options);
456 }