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