bugfix: instead of unloading from the cache, retrieve the latest version and subversi...
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTReconstructor.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   AliHLTReconstructor.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Binding class for HLT reconstruction in AliRoot. */
23
24 #include <TSystem.h>
25 #include <TObjString.h>
26 #include "TFile.h"
27 #include "TTree.h"
28 #include "AliHLTReconstructor.h"
29 #include "AliLog.h"
30 #include "AliRawReader.h"
31 #include "AliESDEvent.h"
32 #include "AliHLTSystem.h"
33 #include "AliHLTOUTRawReader.h"
34 #include "AliHLTOUTDigitReader.h"
35 #include "AliHLTEsdManager.h"
36 #include "AliHLTPluginBase.h"
37
38 ClassImp(AliHLTReconstructor)
39
40 AliHLTReconstructor::AliHLTReconstructor()
41   : 
42   AliReconstructor(),
43   fFctProcessHLTOUT(NULL),
44   fpEsdManager(NULL),
45   fpPluginBase(new AliHLTPluginBase)
46
47   //constructor
48 }
49
50 AliHLTReconstructor::AliHLTReconstructor(const char* options)
51   : 
52   AliReconstructor(),
53   fFctProcessHLTOUT(NULL),
54   fpEsdManager(NULL),
55   fpPluginBase(new AliHLTPluginBase)
56
57   //constructor
58   if (options) Init(options);
59 }
60
61 AliHLTReconstructor::~AliHLTReconstructor()
62
63   //destructor
64
65   if (fpPluginBase) {
66   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
67   if (pSystem) {
68     AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
69     if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
70       // send specific 'event' to execute the stop sequence
71       pSystem->Reconstruct(0, NULL, NULL);
72     }
73   }
74   delete fpPluginBase;
75   }
76   fpPluginBase=NULL;
77
78   if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
79   fpEsdManager=NULL;
80 }
81
82 void AliHLTReconstructor::Init(const char* options)
83 {
84   // init the reconstructor
85   SetOption(options);
86   Init();
87 }
88
89 void AliHLTReconstructor::Init()
90 {
91   // init the reconstructor
92   if (!fpPluginBase) {
93     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
94     return;
95   }
96
97   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
98   if (!pSystem) {
99     AliError("can not create AliHLTSystem object");
100     return;
101   }
102   if (pSystem->CheckStatus(AliHLTSystem::kError)) {
103     AliError("HLT system in error state");
104     return;
105   }
106
107   TString esdManagerOptions;
108
109   // the options scan has been moved to AliHLTSystem, the old code
110   // here is kept to be able to run an older version of the HLT code
111   // with newer AliRoot versions.
112   TString libs("");
113   TString option = GetOption();
114   TObjArray* pTokens=option.Tokenize(" ");
115   option="";
116   if (pTokens) {
117     int iEntries=pTokens->GetEntries();
118     for (int i=0; i<iEntries; i++) {
119       TString token=(((TObjString*)pTokens->At(i))->GetString());
120       if (token.Contains("loglevel=")) {
121         TString param=token.ReplaceAll("loglevel=", "");
122         if (param.IsDigit()) {
123           pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
124         } else if (param.BeginsWith("0x") &&
125                    param.Replace(0,2,"",0).IsHex()) {
126           int severity=0;
127           sscanf(param.Data(),"%x", &severity);
128           pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
129         } else {
130           AliWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
131         }
132       } else if (token.Contains("alilog=off")) {
133         pSystem->SwitchAliLog(0);
134       } else if (token.Contains("esdmanager=")) {
135         token.ReplaceAll("esdmanager=", "");
136         token.ReplaceAll(","," ");
137         token.ReplaceAll("'","");
138         esdManagerOptions=token;
139       } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
140         libs+=token;
141         libs+=" ";
142       } else {
143         if (option.Length()>0) option+=" ";
144         option+=token;
145       }
146     }
147     delete pTokens;
148   }
149
150   if (!libs.IsNull() &&
151       (!pSystem->CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
152       (pSystem->LoadComponentLibraries(libs.Data())<0)) {
153     AliError("error while loading HLT libraries");
154     return;
155   }
156
157   if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
158     typedef int (*AliHLTSystemSetOptions)(AliHLTSystem* pInstance, const char* options);
159     gSystem->Load("libHLTinterface.so");
160     AliHLTSystemSetOptions pFunc=(AliHLTSystemSetOptions)(gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemSetOptions"));
161     if (pFunc) {
162       if ((pFunc)(pSystem, option.Data())<0) {
163       AliError("error setting options for HLT system");
164       return;   
165       }
166     } else if (option.Length()>0) {
167       AliError(Form("version of HLT system does not support the options \'%s\'", option.Data()));
168       return;
169     }
170     if ((pSystem->Configure())<0) {
171       AliError("error during HLT system configuration");
172       return;
173     }
174   }
175
176   gSystem->Load("libHLTinterface.so");
177   fFctProcessHLTOUT=(void (*)())gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemProcessHLTOUT");
178
179   fpEsdManager=AliHLTEsdManager::New();
180   fpEsdManager->SetOption(esdManagerOptions.Data());
181 }
182
183 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const 
184 {
185   // reconstruction of real data without writing of ESD
186   // For each event, HLT reconstruction chains can be executed and
187   // added to the existing HLTOUT data
188   // The HLTOUT data is finally processed in FillESD
189   if (!fpPluginBase) {
190     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
191     return;
192   }
193
194   int iResult=0;
195   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
196
197   if (pSystem) {
198     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
199       AliError("HLT system in error state");
200       return;
201     }
202     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
203       AliError("HLT system in wrong state");
204       return;
205     }
206     if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
207     }
208   }
209 }
210
211 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/, 
212                                   AliESDEvent* esd) const
213 {
214   // reconstruct real data and fill ESD
215   if (!rawReader || !esd) {
216     AliError("missing raw reader or esd object");
217     return;
218   }
219
220   if (!fpPluginBase) {
221     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
222     return;
223   }
224
225   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
226
227   if (pSystem) {
228     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
229       AliError("HLT system in error state");
230       return;
231     }
232     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
233       AliError("HLT system in wrong state");
234       return;
235     }
236     pSystem->FillESD(-1, NULL, esd);
237
238     AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(rawReader, esd->GetEventNumberInFile(), fpEsdManager);
239     if (pHLTOUT) {
240       ProcessHLTOUT(pHLTOUT, esd);
241       delete pHLTOUT;
242     } else {
243       AliError("error creating HLTOUT handler");
244     }
245   }
246 }
247
248 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
249 {
250   // reconstruct simulated data
251
252   // all reconstruction has been moved to FillESD
253   //AliReconstructor::Reconstruct(digitsTree,clustersTree);
254   AliInfo("running digit data reconstruction");
255 }
256
257 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
258 {
259   // reconstruct simulated data and fill ESD
260
261   // later this is the place to extract the simulated HLT data
262   // for now it's only an user failure condition as he tries to run HLT reconstruction
263   // on simulated data 
264   TString option = GetOption();
265   if (!option.IsNull() && 
266       (option.Contains("config=") || option.Contains("chains="))) {
267     AliWarning(Form("HLT reconstruction can be run embedded into Alireconstruction from\n"
268                     "raw data (real or simulated)). Reconstruction of of digit data takes\n"
269                     "place in AliSimulation, appropriate input conversion is needed.\n"
270                     "Consider running embedded into AliSimulation."
271                     "        /***  run macro *****************************************/\n"
272                     "        AliSimulation sim;\n"
273                     "        sim.SetRunHLT(\"%s\");\n"
274                     "        sim.SetRunGeneration(kFALSE);\n"
275                     "        sim.SetMakeDigits(\"\");\n"
276                     "        sim.SetMakeSDigits(\"\");\n"
277                     "        sim.SetMakeDigitsFromHits(\"\");\n"
278                     "        sim.Run();\n"
279                     "        /*********************************************************/", option.Data()));
280   }
281   if (!fpPluginBase) {
282     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
283     return;
284   }
285
286   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
287   if (pSystem) {
288     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
289       AliError("HLT system in error state");
290       return;
291     }
292     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
293       AliError("HLT system in wrong state");
294       return;
295     }
296
297     AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
298     if (pHLTOUT) {
299       ProcessHLTOUT(pHLTOUT, esd);
300       delete pHLTOUT;
301     } else {
302       AliError("error creating HLTOUT handler");
303     }
304   }
305 }
306
307 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
308 {
309   // treatment of simulated or real HLTOUT data
310   if (!pHLTOUT) return;
311   if (!fpPluginBase) {
312     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
313     return;
314   }
315
316   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
317   if (!pSystem) {
318     AliError("error getting HLT system instance");
319     return;
320   }
321
322   if (pHLTOUT->Init()<0) {
323     AliError("error : initialization of HLTOUT handler failed");
324     return;
325   }
326
327   if (bVerbose)
328     PrintHLTOUTContent(pHLTOUT);
329
330   if (fFctProcessHLTOUT) {
331     typedef int (*AliHLTSystemProcessHLTOUT)(AliHLTSystem* pInstance, AliHLTOUT* pHLTOUT, AliESDEvent* esd);
332     AliHLTSystemProcessHLTOUT pFunc=(AliHLTSystemProcessHLTOUT)fFctProcessHLTOUT;
333     if ((pFunc)(pSystem, pHLTOUT, esd)<0) {
334       AliError("error processing HLTOUT");
335     }
336   }
337   pHLTOUT->Reset();
338 }
339
340 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
341 {
342   // debugging/helper function to examine simulated data
343   if (!digitFile) return;
344
345   // read the number of events
346   TFile f(digitFile);
347   if (f.IsZombie()) return;
348   TTree* pTree=NULL;
349   f.GetObject("rawhltout", pTree);
350   if (!pTree) {
351     AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
352     return ;
353   }
354   int nofEvents=pTree->GetEntries();
355   f.Close();
356   //delete pTree; OF COURSE NOT! its an object in the file
357   pTree=NULL;
358
359   for (int event=0; event<nofEvents; event++) {
360     AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
361     if (pHLTOUT) {
362       AliInfo(Form("event %d", event));
363       ProcessHLTOUT(pHLTOUT, pEsd, true);
364       delete pHLTOUT;
365     } else {
366       AliError("error creating HLTOUT handler");
367     }
368   }
369 }
370
371 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
372 {
373   // debugging/helper function to examine simulated or real HLTOUT data
374   if (!pRawReader) return;
375
376   pRawReader->RewindEvents();
377   for (int event=0; pRawReader->NextEvent(); event++) {
378     AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
379     if (pHLTOUT) {
380       AliInfo(Form("event %d", event));
381       ProcessHLTOUT(pHLTOUT, pEsd, true);
382       delete pHLTOUT;
383     } else {
384       AliError("error creating HLTOUT handler");
385     }
386   }
387 }
388
389 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
390 {
391   // print the block specifications of the HLTOUT data blocks
392   if (!pHLTOUT) return;
393   int iResult=0;
394
395   for (iResult=pHLTOUT->SelectFirstDataBlock();
396        iResult>=0;
397        iResult=pHLTOUT->SelectNextDataBlock()) {
398     AliHLTComponentDataType dt=kAliHLTVoidDataType;
399     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
400     pHLTOUT->GetDataBlockDescription(dt, spec);
401     const AliHLTUInt8_t* pBuffer=NULL;
402     AliHLTUInt32_t size=0;
403     if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
404       pHLTOUT->ReleaseDataBuffer(pBuffer);
405       pBuffer=NULL; // just a dummy
406     }
407     AliInfo(Form("   %s  0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
408   }
409 }