Debug msg
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTReconstructor.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the                          * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                                                                        *
9 //* Permission to use, copy, modify and distribute this software and its   *
10 //* documentation strictly for non-commercial purposes is hereby granted   *
11 //* without fee, provided that the above copyright notice appears in all   *
12 //* copies and that both the copyright notice and this permission notice   *
13 //* appear in the supporting documentation. The authors make no claims     *
14 //* about the suitability of this software for any purpose. It is          *
15 //* provided "as is" without express or implied warranty.                  *
16 //**************************************************************************
17
18 //  @file   AliHLTReconstructor.cxx
19 //  @author Matthias Richter
20 //  @date   
21 //  @brief  Binding class for HLT reconstruction in AliRoot
22 //          Implements bot the interface to run HLT chains embedded into
23 //          AliReconstruction and the unpacking and treatment of HLTOUT
24
25 #include <TSystem.h>
26 #include <TObjString.h>
27 #include "TFile.h"
28 #include "TTree.h"
29 #include "TObject.h"
30 #include "TObjArray.h"
31 #include "TClass.h"
32 #include "TStreamerInfo.h"
33 #include "AliHLTReconstructor.h"
34 #include "AliLog.h"
35 #include "AliRawReader.h"
36 #include "AliESDEvent.h"
37 #include "AliHLTSystem.h"
38 #include "AliHLTOUTRawReader.h"
39 #include "AliHLTOUTDigitReader.h"
40 #include "AliHLTEsdManager.h"
41 #include "AliHLTPluginBase.h"
42 #include "AliHLTMisc.h"
43 #include "AliCDBManager.h"
44 #include "AliCDBEntry.h"
45 #include "AliHLTMessage.h"
46 #include "AliCentralTrigger.h"
47 #include "AliTriggerConfiguration.h"
48 #include "AliTriggerClass.h"
49 #include "AliTriggerCluster.h"
50 #include "AliDAQ.h"
51 #include "AliRunLoader.h"
52 #include "AliRunInfo.h"
53
54 class AliCDBEntry;
55
56 /** ROOT macro for the implementation of ROOT specific class methods */
57 ClassImp(AliHLTReconstructor)
58
59 AliHLTReconstructor::AliHLTReconstructor()
60   : AliReconstructor()
61   , fpEsdManager(NULL)
62   , fpPluginBase(new AliHLTPluginBase)
63   , fFlags(0)
64   , fProcessingStep(kProcessingStepUndefined)
65
66   //constructor
67 }
68
69 AliHLTReconstructor::AliHLTReconstructor(const char* options)
70   : AliReconstructor()
71   , fpEsdManager(NULL)
72   , fpPluginBase(new AliHLTPluginBase)
73   , fFlags(0)
74   , fProcessingStep(kProcessingStepUndefined)
75
76   //constructor
77   if (options) Init(options);
78 }
79
80 AliHLTReconstructor::~AliHLTReconstructor()
81
82   //destructor
83
84   if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
85   fpEsdManager=NULL;
86
87   if (fpPluginBase) {
88   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
89   if (pSystem) {
90     AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
91     if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
92       // send specific 'event' to execute the stop sequence
93       pSystem->Reconstruct(0, NULL, NULL);
94     }
95   }
96   delete fpPluginBase;
97   }
98   fpPluginBase=NULL;
99
100 }
101
102 void AliHLTReconstructor::Init(const char* options)
103 {
104   // init the reconstructor
105   SetOption(options);
106   Init();
107 }
108
109 void AliHLTReconstructor::Init()
110 {
111   // init the reconstructor
112   if (!fpPluginBase) {
113     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
114     return;
115   }
116
117   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
118   if (!pSystem) {
119     AliError("can not create AliHLTSystem object");
120     return;
121   }
122   if (pSystem->CheckStatus(AliHLTSystem::kError)) {
123     AliError("HLT system in error state");
124     return;
125   }
126
127   TString esdManagerOptions;
128
129   // the options scan has been moved to AliHLTSystem, the old code
130   // here is kept to be able to run an older version of the HLT code
131   // with newer AliRoot versions.
132   TString option = GetOption();
133   TObjArray* pTokens=option.Tokenize(" ");
134   option="";
135   if (pTokens) {
136     int iEntries=pTokens->GetEntries();
137     for (int i=0; i<iEntries; i++) {
138       TString token=(((TObjString*)pTokens->At(i))->GetString());
139       if (token.Contains("loglevel=")) {
140         TString param=token.ReplaceAll("loglevel=", "");
141         if (param.IsDigit()) {
142           pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
143         } else if (param.BeginsWith("0x") &&
144                    param.Replace(0,2,"",0).IsHex()) {
145           int severity=0;
146           sscanf(param.Data(),"%x", &severity);
147           pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
148         } else {
149           AliWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
150         }
151       } else if (token.Contains("alilog=off")) {
152         pSystem->SwitchAliLog(0);
153       } else if (token.CompareTo("ignore-hltout")==0) {
154         fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
155       } else if (token.CompareTo("run-online-config")==0) {
156         fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
157         if (option.Length()>0) option+=" ";
158         option+=token;
159       } else if (token.CompareTo("ignore-ctp")==0) {
160         fFlags|=kAliHLTReconstructorIgnoreCTP;
161       } else if (token.Contains("esdmanager=")) {
162         token.ReplaceAll("esdmanager=", "");
163         token.ReplaceAll(","," ");
164         token.ReplaceAll("'","");
165         esdManagerOptions=token;
166       } else {
167         if (option.Length()>0) option+=" ";
168         option+=token;
169       }
170     }
171     delete pTokens;
172   }
173
174   TString ecsParam;
175   TString ctpParam;
176   if ((fFlags&kAliHLTReconstructorIgnoreCTP)==0 &&
177       BuildCTPTriggerClassString(ctpParam)>=0) {
178     if (!ecsParam.IsNull()) ecsParam+=";";
179     ecsParam+="CTP_TRIGGER_CLASS=";
180     ecsParam+=ctpParam;
181   }
182
183   if (!ecsParam.IsNull()) {
184     option+=" ECS=";
185     option+=ecsParam;
186   }
187
188   if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
189     pSystem->SetDetectorMask(GetRunInfo()->GetDetectorMask());
190     if (pSystem->ScanOptions(option.Data())<0) {
191       AliError("error setting options for HLT system");
192       return;
193     }
194     if ((pSystem->Configure())<0) {
195       AliError("error during HLT system configuration");
196       return;
197     }
198   }
199
200   fpEsdManager=AliHLTEsdManager::New();
201   if (fpEsdManager) {
202     fpEsdManager->SetOption(esdManagerOptions.Data());
203   }
204
205   AliHLTMisc::Instance().InitStreamerInfos(fgkCalibStreamerInfoEntry);
206 }
207
208 void AliHLTReconstructor::Terminate()
209 {
210   /// overloaded from AliReconstructor: terminate event processing
211
212   // indicate step 'Terminate'
213   SetProcessingStep(kProcessingStepTerminate);
214
215   if (fpPluginBase) {
216     AliHLTSystem* pSystem=fpPluginBase->GetInstance();
217     if (pSystem) {
218       // 2012-04-02
219       // clean up the HLTOUT instance if still existing, currently FinishEvent
220       // is not called at the end of the event processing and the cleanup
221       // needs to be done here to avoid a warning message. Later it can be
222       // declared a malfunction if the HLTOUT instance is still existing at
223       // this point.
224       AliHLTOUT* pHLTOUT=NULL;
225       pSystem->InvalidateHLTOUT(&pHLTOUT);
226       if (pHLTOUT) {
227         pHLTOUT->Reset();
228         delete pHLTOUT;
229         pHLTOUT=NULL;
230       }
231
232       AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
233       if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
234         // send specific 'event' to execute the stop sequence
235         pSystem->Reconstruct(0, NULL, NULL);
236       }
237     }
238   }
239 }
240
241 void AliHLTReconstructor::FinishEvent()
242 {
243   /// overloaded from AliReconstructor: finish current event
244   if (!fpPluginBase) return;
245
246   // indicate step 'FinishEvent'
247   SetProcessingStep(kProcessingStepFinishEvent);
248
249   AliInfo("finishing event");
250   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
251   if (pSystem) {
252     // this is the end of the lifetime of the HLTOUT instance
253     // called after all other modules have been reconstructed
254     AliHLTOUT* pHLTOUT=NULL;
255     pSystem->InvalidateHLTOUT(&pHLTOUT);
256     if (pHLTOUT) {
257       pHLTOUT->Reset();
258       delete pHLTOUT;
259       pHLTOUT=NULL;
260     }
261   }
262 }
263
264 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
265
266 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const 
267 {
268   // reconstruction of real data without writing of ESD
269   // For each event, HLT reconstruction chains can be executed and
270   // added to the existing HLTOUT data
271   // The HLTOUT data is finally processed in FillESD
272
273   if (!fpPluginBase) {
274     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
275     return;
276   }
277
278   int iResult=0;
279   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
280
281   if (pSystem) {
282     AliHLTOUT* pHLTOUT=NULL;
283     pSystem->InvalidateHLTOUT(&pHLTOUT);
284     if (pHLTOUT) {
285       // at this stage we always have a new event, regardless state of
286       // fProcessingStep; build the HLTOUT instance from scratch
287       pHLTOUT->Reset();
288       delete pHLTOUT;
289       pHLTOUT=NULL;
290     }
291     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
292       // this is the highest level where an error can be detected, no error
293       // codes can be returned
294       AliFatal("HLT system in error state");
295       return;
296     }
297     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
298       AliError("HLT system in wrong state");
299       return;
300     }
301
302     // indicate the local reconstruction step
303     SetProcessingStep(kProcessingStepLocal);
304
305     // init the HLTOUT instance for the current event
306     // not nice. Have to query the global run loader to get the current event no.
307     Int_t eventNo=-1;
308     AliRunLoader* runloader = AliRunLoader::Instance();
309     if (runloader) {
310       eventNo=runloader->GetEventNumber();
311     }
312     if (eventNo>=0) {
313       AliRawReader* input=NULL;
314       if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
315         input=rawReader;
316       }
317       pHLTOUT=new AliHLTOUTRawReader(input, eventNo, fpEsdManager);
318       if (pHLTOUT) {
319         if (pHLTOUT->Init()>=0) {
320           pSystem->InitHLTOUT(pHLTOUT);
321         } else {
322           AliError("error : initialization of HLTOUT handler failed");
323         }
324       } else {
325         AliError("memory allocation failed: can not create AliHLTOUT object");
326       }
327     } else {
328       AliError("can not get event number");
329     }
330
331     if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
332     }
333   }
334 }
335
336 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/, 
337                                   AliESDEvent* esd) const
338 {
339   // reconstruct real data and fill ESD
340   if (!rawReader || !esd) {
341     AliError("missing raw reader or esd object");
342     return;
343   }
344
345   if (!fpPluginBase) {
346     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
347     return;
348   }
349
350   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
351
352   if (pSystem) {
353     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
354       // this is the highest level where an error can be detected, no error
355       // codes can be returned
356       AliFatal("HLT system in error state");
357       return;
358     }
359     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
360       AliError("HLT system in wrong state");
361       return;
362     }
363     pSystem->FillESD(-1, NULL, esd);
364
365     // the HLTOUT handler has either been created in the AliHLTReconstructor::Reconstruct
366     // step of this event or is created now. In either case the instance is deleted after
367     // the processing
368     AliHLTOUT* pHLTOUT=NULL;
369     pSystem->InvalidateHLTOUT(&pHLTOUT);
370     if (pHLTOUT && fProcessingStep!=kProcessingStepLocal) {
371       // this is a new event, if local reconstruction would have been executed
372       // the HLTOUT instance would have been created for the current event already,
373       // in all other cases one has to create the HLTOUT instance here
374       pHLTOUT->Reset();
375       delete pHLTOUT;
376       pHLTOUT=NULL;
377     }
378     if (!pHLTOUT) {
379       AliRawReader* input=NULL;
380       if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
381         input=rawReader;
382       }
383       pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
384     }
385
386     // indicate step 'ESD filling'
387     SetProcessingStep(kProcessingStepESD);
388
389     if (pHLTOUT) {
390       ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
391       // 2012-03-30: a change in the module sequence of AliReconstruction is soon
392       // going to be applied: HLT reconstruction is executed fully (i.e. both local
393       // reconstruction and FillESD) before all the other modules. In order to make the
394       // HLTOUT data available for other modules it is kept here and released in the method
395       // FinishEvent
396       pSystem->InitHLTOUT(pHLTOUT);
397     } else {
398       AliError("error creating HLTOUT handler");
399     }
400   }
401 }
402
403 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
404 {
405   // reconstruct simulated data
406
407   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
408
409   if (pSystem) {
410     // create the HLTOUT instance in order to be available for other detector reconstruction
411     // first cleanup any existing instance
412     AliHLTOUT* pHLTOUT=NULL;
413     pSystem->InvalidateHLTOUT(&pHLTOUT);
414     if (pHLTOUT) {
415       // at this stage we always have a new event, regardless state of
416       // fProcessingStep; build the HLTOUT instance from scratch
417       pHLTOUT->Reset();
418       delete pHLTOUT;
419       pHLTOUT=NULL;
420     }
421
422     // indicate the local reconstruction step
423     SetProcessingStep(kProcessingStepLocal);
424
425     // not nice. Have to query the global run loader to get the current event no.
426     // This is related to the missing AliLoader for HLT.
427     // Since AliReconstruction can not provide a digits tree, the file needs to be accessed
428     // explicitely, and the corresponding event needs to be selected.
429     Int_t eventNo=-1;
430     AliRunLoader* runloader = AliRunLoader::Instance();
431     if (runloader) {
432       eventNo=runloader->GetEventNumber();
433     }
434     if (eventNo>=0) {
435       const char* digitfile=NULL;
436       if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
437         digitfile="HLT.Digits.root";
438       }
439
440       pHLTOUT=new AliHLTOUTDigitReader(eventNo, fpEsdManager, digitfile);
441       if (pHLTOUT) {
442         if (pHLTOUT->Init()>=0) {
443           pSystem->InitHLTOUT(pHLTOUT);
444         } else {
445           AliError("error : initialization of HLTOUT handler failed");
446         }
447       } else {
448         AliError("memory allocation failed: can not create AliHLTOUT object");
449       }
450     } else {
451       AliError("can not get event number");
452     }
453
454     // all data processing happens in FillESD
455   }
456 }
457
458 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
459 {
460   // reconstruct simulated data and fill ESD
461
462   // later this is the place to extract the simulated HLT data
463   // for now it's only an user failure condition as he tries to run HLT reconstruction
464   // on simulated data 
465   TString option = GetOption();
466   if (!option.IsNull() && 
467       (option.Contains("config=") || option.Contains("chains="))) {
468     AliWarning(Form("You are trying to run a custom HLT chain on digits data.\n\n"
469                     "HLT reconstruction can be run embedded into AliReconstruction from\n"
470                     "raw data (real or simulated)). Reconstruction of digit data takes\n"
471                     "place in AliSimulation, appropriate input conversion is needed to\n"
472                     "feed data from the detector digits into the HLT chain.\n"
473                     "Consider running embedded into AliSimulation.\n"
474                     "        /***  run macro *****************************************/\n"
475                     "        AliSimulation sim;\n"
476                     "        sim.SetRunHLT(\"%s\");\n"
477                     "        sim.SetRunGeneration(kFALSE);\n"
478                     "        sim.SetMakeDigits(\"\");\n"
479                     "        sim.SetMakeSDigits(\"\");\n"
480                     "        sim.SetMakeDigitsFromHits(\"\");\n"
481                     "        sim.Run();\n"
482                     "        /*********************************************************/\n\n",
483                     option.Data()));
484   }
485   if (!fpPluginBase) {
486     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
487     return;
488   }
489
490   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
491   if (pSystem) {
492     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
493       // this is the highest level where an error can be detected, no error
494       // codes can be returned
495       AliFatal("HLT system in error state");
496       return;
497     }
498     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
499       AliError("HLT system in wrong state");
500       return;
501     }
502
503     // the HLTOUT handler has either been created in the AliHLTReconstructor::Reconstruct
504     // step of this event or is created now. In either case the instance is deleted after
505     // the processing
506     AliHLTOUT* pHLTOUT=NULL;
507     pSystem->InvalidateHLTOUT(&pHLTOUT);
508     if (pHLTOUT && fProcessingStep!=kProcessingStepLocal) {
509       // this is a new event, if local reconstruction would have been executed
510       // the HLTOUT instance would have been created for the current event already,
511       // in all other cases one has to create the HLTOUT instance here
512       pHLTOUT->Reset();
513       delete pHLTOUT;
514       pHLTOUT=NULL;
515     }
516     if (!pHLTOUT) {
517       const char* digitfile=NULL;
518       if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
519         digitfile="HLT.Digits.root";
520       }
521       pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager, digitfile);
522     }
523
524     // indicate step 'ESD filling'
525     SetProcessingStep(kProcessingStepESD);
526
527     if (pHLTOUT) {
528       ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
529       // 2012-03-30: a change in the module sequence of AliReconstruction is soon
530       // going to be applied: HLT reconstruction is executed fully (i.e. both local
531       // reconstruction and FillESD) before all the other modules. In order to make the
532       // HLTOUT data available for other modules it is kept here and released in the method
533       // FinishEvent
534       pSystem->InitHLTOUT(pHLTOUT);
535     } else {
536       AliError("error creating HLTOUT handler");
537     }
538   }
539 }
540
541 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
542 {
543   // treatment of simulated or real HLTOUT data
544   if (!pHLTOUT) return;
545   if (!fpPluginBase) {
546     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
547     return;
548   }
549
550   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
551   if (!pSystem) {
552     AliError("error getting HLT system instance");
553     return;
554   }
555
556   if (pHLTOUT->Init()<0) {
557     AliError("error : initialization of HLTOUT handler failed");
558     return;
559   }
560
561   if (bVerbose)
562     PrintHLTOUTContent(pHLTOUT);
563
564   int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
565   if (blockindex>=0) {
566     const AliHLTUInt8_t* pBuffer=NULL;
567     AliHLTUInt32_t size=0;
568     if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
569       TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
570       if (pObject) {
571         TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
572         if (pArray) {
573           AliHLTMisc::Instance().InitStreamerInfos(pArray);
574         } else {
575           AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
576         }
577       } else {
578         AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
579       }
580     } else {
581       AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
582     }
583   }
584
585   if (pSystem->ProcessHLTOUT(pHLTOUT, esd)<0) {
586     AliError("error processing HLTOUT");
587   }
588
589   if (bVerbose && esd) {
590     AliInfo("HLT ESD content:");
591     esd->Print();
592   }
593 }
594
595 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
596 {
597   // debugging/helper function to examine simulated data
598   if (!digitFile) return;
599
600   // read the number of events
601   TFile f(digitFile);
602   if (f.IsZombie()) return;
603   TTree* pTree=NULL;
604   f.GetObject("rawhltout", pTree);
605   if (!pTree) {
606     AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
607     return ;
608   }
609   int nofEvents=pTree->GetEntries();
610   f.Close();
611   //delete pTree; OF COURSE NOT! its an object in the file
612   pTree=NULL;
613
614   for (int event=0; event<nofEvents; event++) {
615     AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
616     if (pHLTOUT) {
617       AliInfo(Form("event %d", event));
618       ProcessHLTOUT(pHLTOUT, pEsd, true);
619       delete pHLTOUT;
620     } else {
621       AliError("error creating HLTOUT handler");
622     }
623   }
624 }
625
626 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
627 {
628   // debugging/helper function to examine simulated or real HLTOUT data
629   if (!pRawReader) return;
630
631   pRawReader->RewindEvents();
632   for (int event=0; pRawReader->NextEvent(); event++) {
633     AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
634     if (pHLTOUT) {
635       AliInfo(Form("event %d", event));
636       // the two event fields contain: period - orbit - bunch crossing counter
637       //        id[0]               id[1]
638       // |32                0|32                0|
639       //
640       // |      28 bit    |       24 bit     | 12|
641       //        period          orbit         bcc
642       AliHLTUInt64_t eventId=0;
643       const UInt_t* rawreaderEventId=pRawReader->GetEventId();
644       if (rawreaderEventId) {
645         eventId=rawreaderEventId[0];
646         eventId=eventId<<32;
647         eventId|=rawreaderEventId[1];
648       }
649       AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
650       ProcessHLTOUT(pHLTOUT, pEsd, true);
651       delete pHLTOUT;
652     } else {
653       AliError("error creating HLTOUT handler");
654     }
655   }
656 }
657
658 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
659 {
660   // print the block specifications of the HLTOUT data blocks
661   if (!pHLTOUT) return;
662   int iResult=0;
663
664   AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
665   for (iResult=pHLTOUT->SelectFirstDataBlock();
666        iResult>=0;
667        iResult=pHLTOUT->SelectNextDataBlock()) {
668     AliHLTComponentDataType dt=kAliHLTVoidDataType;
669     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
670     pHLTOUT->GetDataBlockDescription(dt, spec);
671     const AliHLTUInt8_t* pBuffer=NULL;
672     AliHLTUInt32_t size=0;
673     if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
674       pHLTOUT->ReleaseDataBuffer(pBuffer);
675       pBuffer=NULL; // just a dummy
676     }
677     AliInfo(Form("   %s  0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
678   }
679 }
680
681 int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
682 {
683   // build the CTP trigger class string from the OCDB entry of the CTP trigger
684   int iResult=0;
685   
686   triggerclasses.Clear();
687   AliCentralTrigger* pCTP = new AliCentralTrigger();
688   AliTriggerConfiguration *config=NULL;
689   TString configstr("");
690   if (pCTP->LoadConfiguration(configstr) && 
691       (config = pCTP->GetConfiguration())!=NULL) {
692     const TObjArray& classesArray = config->GetClasses();
693     int nclasses = classesArray.GetEntriesFast();
694     for( int iclass=0; iclass < nclasses; iclass++ ) {
695       AliTriggerClass* trclass = NULL;
696       if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
697         TString entry;
698         int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
699         entry.Form("%02d:%s:", trindex, trclass->GetName());
700         AliTriggerCluster* cluster=NULL;
701         TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
702         if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
703           TString detectors=cluster->GetDetectorsInCluster();
704           TObjArray* pTokens=detectors.Tokenize(" ");
705           if (pTokens) {
706             for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
707               int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
708               if (id>=0) {
709                 TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
710                 entry+=detstr;
711               } else {
712                 AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
713                 iResult=-EPROTO;
714                 break;
715               }
716             }
717             delete pTokens;
718           }
719         } else {
720           AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()?trclass->GetCluster()->GetName():"NULL"));
721           iResult=-EPROTO;
722           break;
723         }
724         if (!triggerclasses.IsNull()) triggerclasses+=",";
725         triggerclasses+=entry;
726       }
727     }
728   }
729
730   return iResult;
731 }