]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/trigger/AliHLTTriggerAgent.cxx
Merge branch 'master' into TPCdev
[u/mrichter/AliRoot.git] / HLT / trigger / AliHLTTriggerAgent.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   AliHLTTriggerAgent.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Agent of the libAliHLTTrigger library
23 */
24
25 #include <cassert>
26 #include "AliHLTTriggerAgent.h"
27 #include "AliHLTTriggerDecision.h"
28 #include "AliHLTGlobalTriggerDecision.h"
29 #include "AliHLTOUT.h"
30 #include "AliHLTMessage.h"
31 #include "AliESDEvent.h"
32 #include "TObjString.h"
33 #include "TObjArray.h"
34 #include "TArrayC.h"
35 #include "TFile.h"
36 #include "TTree.h"
37
38 // header files of library components
39 #include "AliHLTTriggerBarrelMultiplicity.h"
40 #include "AliHLTD0Trigger.h"
41 #include "AliHLTTriggerITSMultiplicity.h"
42 #include "AliHLTTriggerBarrelGeomMultiplicity.h"
43 #include "AliHLTGlobalTriggerComponent.h"
44 #include "AliHLTTriggerPhosClusterEnergy.h"
45 #include "AliHLTTriggerEmcalClusterEnergy.h"
46 #include "AliHLTTriggerPhosMip.h"
47 #include "AliHLTTriggerTrdClusterMultiplicity.h"
48 #include "AliHLTTriggerGammaConversion.h"
49 #include "AliHLTMuonSpectroTriggerComponent.h"
50 #include "AliHLTUpcTriggerComponent.h"
51 #include "AliHLTTriggerCosmics.h"
52 #include "AliHLTTriggerCounterComponent.h"
53 #include "AliHLTTriggerEmcalElectron.h"
54 //#include "AliHLTTriggerFastJet.h"
55 #include "AliHLTFastJetMonitorComponent.h"
56 #include "AliHLTEmcalElectronMonitorComponent.h"
57 #include "AliHLTTRDTriggerComponent.h"
58
59 /** global instance for agent registration */
60 AliHLTTriggerAgent gAliHLTTriggerAgent;
61
62 /** ROOT macro for the implementation of ROOT specific class methods */
63 ClassImp(AliHLTTriggerAgent)
64
65 AliHLTTriggerAgent::AliHLTTriggerAgent()
66   : AliHLTModuleAgent("Trigger")
67   , fTriggerDecisionHandler(NULL)
68 {
69   // see header file for class documentation
70   // or
71   // refer to README to build package
72   // or
73   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
74 }
75
76 AliHLTTriggerAgent::~AliHLTTriggerAgent()
77 {
78   // see header file for class documentation
79 }
80
81 int AliHLTTriggerAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
82 {
83   // see header file for class documentation
84   assert(pHandler);
85   if (!pHandler) return -EINVAL;
86   pHandler->AddComponent(new AliHLTGlobalTriggerComponent);
87   pHandler->AddComponent(new AliHLTTriggerBarrelMultiplicity);
88   pHandler->AddComponent(new AliHLTTriggerITSMultiplicity);
89   pHandler->AddComponent(new AliHLTD0Trigger);
90   pHandler->AddComponent(new AliHLTTriggerBarrelGeomMultiplicity);
91   pHandler->AddComponent(new AliHLTTriggerPhosClusterEnergy); 
92   pHandler->AddComponent(new AliHLTTriggerEmcalClusterEnergy); 
93   pHandler->AddComponent(new AliHLTTriggerPhosMip); 
94   pHandler->AddComponent(new AliHLTTriggerTrdClusterMultiplicity);
95   pHandler->AddComponent(new AliHLTTriggerGammaConversion);
96   pHandler->AddComponent(new AliHLTMuonSpectroTriggerComponent);
97   pHandler->AddComponent(new AliHLTUpcTriggerComponent);
98   pHandler->AddComponent(new AliHLTTriggerCosmics);
99   pHandler->AddComponent(new AliHLTTriggerCounterComponent);
100   pHandler->AddComponent(new AliHLTTriggerEmcalElectron);
101   //pHandler->AddComponent(new AliHLTTriggerFastJet);
102   pHandler->AddComponent(new AliHLTFastJetMonitorComponent);
103   pHandler->AddComponent(new AliHLTEmcalElectronMonitorComponent);
104   pHandler->AddComponent(new AliHLTTRDTriggerComponent);
105  return 0;
106 }
107
108 int AliHLTTriggerAgent::CreateConfigurations(AliHLTConfigurationHandler* pHandler,
109                                             AliRawReader* rawReader,
110                                             AliRunLoader* runloader) const
111 {
112   // see header file for class documentation
113   if (!pHandler) return -EINVAL;
114
115   TString triggerInputs;
116   TString triggerOutputs;
117   TString configurationId;
118   /////////////////////////////////////////////////////////////////////////////////////
119   //
120   // a central barrel charged particle multiplicity trigger
121   configurationId="TRIGGER-Barrel-Multiplicity";
122
123   // define the inputs for the BarrelMultiplicityTrigger
124   triggerInputs="GLOBAL-esd-converter";
125
126   // check for the availibility
127   TObjArray* pTokens=triggerInputs.Tokenize(" ");
128   triggerInputs="";
129   if (pTokens) {
130     for (int n=0; n<pTokens->GetEntriesFast(); n++) {
131       if (!pTokens->At(n)) continue;
132       TString module=pTokens->At(n)->GetName();
133       if (pHandler->FindConfiguration(module.Data())) {
134         triggerInputs+=module;
135         triggerInputs+=" ";
136       }
137     }
138     delete pTokens;
139   }
140
141   TString arg;
142   if (triggerInputs.Length()>0) {
143     // define multiple instances of the BarrelMultiplicityTrigger with different settings
144     HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
145     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), "");
146     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
147     triggerOutputs+=configurationId;
148
149     configurationId="TRIGGER-Barrel-HighMultiplicity";
150     arg="-triggername BarrelHighMultiplicity";
151     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
152     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
153     triggerOutputs+=configurationId;
154
155     configurationId="TRIGGER-Barrel-Pt_v01";
156     arg="-triggername BarrelPt_v01";
157     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
158     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
159     triggerOutputs+=configurationId;
160
161     configurationId="TRIGGER-Barrel-Pt_v02";
162     arg="-triggername BarrelPt_v02";
163     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
164     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
165     triggerOutputs+=configurationId;
166
167     configurationId="TRIGGER-Barrel-Pt_v03";
168     arg="-triggername BarrelPt_v03";
169     pHandler->CreateConfiguration(configurationId.Data(), "BarrelMultiplicityTrigger", triggerInputs.Data(), arg.Data());
170     if (triggerOutputs.Length()>0) triggerOutputs+=" ";
171     triggerOutputs+=configurationId;
172   } else {
173     HLTWarning("No inputs for %s found, skipping component", configurationId.Data());
174   }
175   
176   /////////////////////////////////////////////////////////////////////////////////////
177   // The muon spectrometer trigger
178   configurationId = "TRIGGER-Muon-Spectrometer";
179
180   // define the inputsfor the muon spectrometer trigger.
181   if (pHandler->FindConfiguration("dHLT-sim-fromRaw")) {
182     triggerInputs = "dHLT-sim-fromRaw";
183   }
184   else if (pHandler->FindConfiguration("dHLT-sim")) {
185     triggerInputs = "dHLT-sim";
186   }
187   else if (pHandler->FindConfiguration("dHLT-sim-fromMC")) {
188     triggerInputs = "dHLT-sim-fromMC";
189   }
190
191   if (triggerInputs.Length() > 0) {
192     HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
193     pHandler->CreateConfiguration(configurationId.Data(), "MuonSpectroTrigger", triggerInputs.Data(), "-makestats");
194     if (triggerOutputs.Length() > 0) triggerOutputs += " ";
195     triggerOutputs += configurationId;
196   } else {
197     HLTWarning("No inputs for %s found, skipping component.", configurationId.Data());
198   }
199
200   /////////////////////////////////////////////////////////////////////////////////////
201   // D0 trigger
202   configurationId = "TRIGGER-D0";
203   if(runloader && !rawReader){
204     // simulation without simulated raw data
205     // use ESD as input
206     triggerInputs="GLOBAL-esd-converter ";
207   }
208   else{
209     // simulation with simulated raw data, or raw data reconstruction
210     // use input from ITS tracker and vertexer directly
211     triggerInputs="ITS-tracker GLOBAL-vertexer";
212   }
213
214   // check for the availibility of inputs
215   pTokens=triggerInputs.Tokenize(" ");
216   triggerInputs="";
217   if (pTokens) {
218     for (int n=0; n<pTokens->GetEntriesFast(); n++) {
219       if (!pTokens->At(n)) continue;
220       TString module=pTokens->At(n)->GetName();
221       if (pHandler->FindConfiguration(module.Data())) {
222         triggerInputs+=module;
223         triggerInputs+=" ";
224       }
225     }
226     delete pTokens;
227   }
228
229   TString argD0 = "";
230   if (triggerInputs.Length()>0) {
231     HLTInfo("Configuring inputs for %s: %s", configurationId.Data(), triggerInputs.Data());
232     pHandler->CreateConfiguration(configurationId.Data(), "D0Trigger", triggerInputs.Data(), argD0.Data());
233     // FIXME: due to a rare segfault for reconstruction of PbPb data the
234     // component is temporarily excluded
235     // https://savannah.cern.ch/bugs/?72590
236     //if (triggerOutputs.Length()>0) triggerOutputs+=" ";
237     //triggerOutputs+=configurationId;
238   } else {
239     HLTWarning("No inputs for %s found, skipping component", configurationId.Data());
240   }
241
242   /////////////////////////////////////////////////////////////////////////////////////
243   //
244   // the global trigger component
245   configurationId="GLOBAL-Trigger";
246   HLTInfo("setting inputs for %s: %s", configurationId.Data(), triggerOutputs.IsNull()?"none":triggerOutputs.Data());
247   pHandler->CreateConfiguration(configurationId.Data(), "HLTGlobalTrigger", triggerOutputs.Data(), "-skipctp");
248   
249   return 0;
250 }
251
252 const char* AliHLTTriggerAgent::GetReconstructionChains(AliRawReader* /*rawReader*/,
253                                                     AliRunLoader* runloader) const
254 {
255   // see header file for class documentation
256   if (runloader) {
257     // reconstruction chains for AliRoot simulation
258     // Note: run loader is only available while running embedded into
259     // AliRoot simulation
260
261     // currently disabled due to a problem compiling the runtime trigger library
262     return "GLOBAL-Trigger";
263   }
264   return NULL;
265 }
266
267 const char* AliHLTTriggerAgent::GetRequiredComponentLibraries() const
268 {
269   // see header file for class documentation
270
271   return "";
272 }
273
274 int AliHLTTriggerAgent::GetHandlerDescription(AliHLTComponentDataType dt,
275                                            AliHLTUInt32_t /*spec*/,
276                                           AliHLTOUTHandlerDesc& desc) const
277 {
278   // get description of HLTOUT data blocks handled by this agent
279
280   // handler of the trigger decisions {'ROOTTOBJ':'HLT '}
281   // currently stored as a TObject with the common data type and origin
282   // HLTOUT. However we might need a separate data type in order to
283   // avoid interference with other handlers
284   // the handler produces an ESD object in order to be merged to the
285   // hltEsd afterwards
286   // 2009-11-17 adding the data types for (global) trigger decisions
287   // {GLOBTRIG:HLT } and {TRIG_DEC:HLT }
288   // the TObject data types stays for a while in order to preserve
289   // backward compatibility
290   if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut) ||
291       dt==kAliHLTDataTypeTriggerDecision ||
292       dt==kAliHLTDataTypeGlobalTrigger) {
293     desc=AliHLTOUTHandlerDesc(AliHLTModuleAgent::kEsd, dt, GetModuleId());
294     return 1;
295   }
296
297   // handler for the HLT readout list and trigger data data blocks {'HLTRDLST':'HLT '}
298   if (dt==AliHLTComponentDataTypeInitializer("HLTRDLST", kAliHLTDataOriginOut) ||
299       dt==AliHLTComponentDataTypeInitializer("HLTTRGDT", kAliHLTDataOriginOut)) {
300       desc=AliHLTOUTHandlerDesc(kProprietary, dt, GetModuleId());
301       return 1;
302   }
303
304   return 0;
305 }
306
307 AliHLTOUTHandler* AliHLTTriggerAgent::GetOutputHandler(AliHLTComponentDataType dt,
308                                                        AliHLTUInt32_t /*spec*/)
309 {
310   // see header file for class documentation
311
312   // raw data blocks to be fed into offline reconstruction
313   if ((dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut) ||
314        (dt==kAliHLTDataTypeTriggerDecision) ||
315        (dt==kAliHLTDataTypeGlobalTrigger))) {
316     if (!fTriggerDecisionHandler) {
317       fTriggerDecisionHandler=new AliHLTTriggerAgent::AliHLTTriggerDecisionHandler;
318     }
319     return fTriggerDecisionHandler;
320   }
321
322   // handler for the HLT readou list and trigger data data blocks {'HLTRDLST':'HLT '}
323   if (dt==AliHLTComponentDataTypeInitializer("HLTRDLST", kAliHLTDataOriginOut) ||
324       dt==AliHLTComponentDataTypeInitializer("HLTTRGDT", kAliHLTDataOriginOut)) {
325     return NULL;
326   }
327
328   return NULL;
329 }
330
331 int AliHLTTriggerAgent::DeleteOutputHandler(AliHLTOUTHandler* pInstance)
332 {
333   // see header file for class documentation
334   if (pInstance==NULL) return -EINVAL;
335
336   if (pInstance==fTriggerDecisionHandler) {
337     delete fTriggerDecisionHandler;
338     fTriggerDecisionHandler=NULL;
339   }
340
341   return 0;
342 }
343
344 AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::AliHLTTriggerDecisionHandler()
345   : AliHLTOUTHandler() 
346   , fESD(NULL)
347   , fpData(NULL)
348   , fSize(0)
349   , fpESDfile(NULL)
350   , fpESDtree(NULL)
351 {
352   // see header file for class documentation
353 }
354
355 AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::~AliHLTTriggerDecisionHandler()
356 {
357   // see header file for class documentation
358   if (fpESDtree) {
359     fpESDtree->GetUserInfo()->Clear();
360     delete fpESDtree;
361   }
362   fpESDtree=NULL;
363
364   if (fpESDfile) {
365     fpESDfile->Close();
366     delete fpESDfile;
367   }
368   fpESDfile=NULL;
369
370   if (fESD) delete fESD;
371   fESD=NULL;
372
373   if (fpData) delete fpData;
374   fpData=NULL;
375   fSize=0;
376 }
377
378 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::ProcessData(AliHLTOUT* pData)
379 {
380   // see header file for class documentation
381   if (!pData) return -EINVAL;
382   int iResult=0;
383   AliHLTGlobalTriggerDecision* pGlobalDecision=NULL;
384   TObjArray triggerDecisions;
385   triggerDecisions.SetOwner(kTRUE);
386   for (iResult=pData->SelectFirstDataBlock(); iResult>=0; iResult=pData->SelectNextDataBlock()) {
387     AliHLTComponentDataType dt=kAliHLTVoidDataType;
388     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
389     if ((iResult=pData->GetDataBlockDescription(dt, spec))<0) break;
390     TObject* pObject=pData->GetDataObject();
391     if (pObject) {
392       if(dt==kAliHLTDataTypeGlobalTrigger) {
393         if (!pGlobalDecision) {
394           if ((pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pObject))==NULL ||
395               (pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pGlobalDecision->Clone()))==NULL) {
396             HLTFatal("can not convert object of name %s (%s) to HLTGlobalTriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
397           }
398         } else {
399           HLTWarning("multiple HLT GlobalTrigger decision objects, ignoring all but the first one");
400         }
401       } else if (dt==kAliHLTDataTypeTriggerDecision) {
402         if (pObject->IsA() == AliHLTTriggerDecision::Class() &&
403             !(pObject->IsA() == AliHLTGlobalTriggerDecision::Class())) {
404           AliHLTTriggerDecision* pDecision=dynamic_cast<AliHLTTriggerDecision*>(pObject);
405           if (pDecision) {
406             if (pGlobalDecision) {
407               // add directly
408               pGlobalDecision->AddTriggerInput(*pDecision);
409             } else {
410               // schedule
411               triggerDecisions.Add(pDecision->Clone());
412             }
413           } else {
414             HLTFatal("can not convert object of name %s (%s) to HLT TriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
415           }
416         }
417       } else if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginOut)){
418         // this is the branch for keeping compatibility
419         // the first version of the trigger framework was using the kAliHLTDataTypeTObject
420         // data type instead of the specific data types for HLT triggers
421           // this effects the cosmic data taken Sep to Oct 2009
422         if (pObject->IsA() == AliHLTGlobalTriggerDecision::Class()) {
423           if (!pGlobalDecision) {
424             if ((pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pObject))==NULL ||
425                 (pGlobalDecision=dynamic_cast<AliHLTGlobalTriggerDecision*>(pGlobalDecision->Clone()))==NULL) {
426               HLTFatal("can not convert object of name %s (%s) to HLTGlobalTriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
427             }
428           } else {
429             HLTWarning("multiple HLT GlobalTrigger decision objects, ignoring all but the first one");
430           }
431         } else if (pObject->IsA() == AliHLTTriggerDecision::Class()) {
432           AliHLTTriggerDecision* pDecision=dynamic_cast<AliHLTTriggerDecision*>(pObject);
433           if (pDecision) {
434             if (pGlobalDecision) {
435               // add directly
436               pGlobalDecision->AddTriggerInput(*pDecision);
437             } else {
438               // schedule
439               triggerDecisions.Add(pDecision->Clone());
440             }
441           } else {
442             HLTFatal("can not convert object of name %s (%s) to HLT TriggerDecsion according to data type", pObject->GetName(), pObject->Class()->GetName());
443           }
444         }
445       }
446       pData->ReleaseDataObject(pObject);
447       pObject=NULL;
448     } else {
449       HLTError("can not get TObject from HLTOUT buffer");
450       iResult=-ENODATA;
451     }
452   }
453   // -ENOENT just signals that there  are no more entries
454   if (iResult==-ENOENT) iResult=0;
455
456   if (pGlobalDecision) {
457     for (int i=0; i<triggerDecisions.GetEntriesFast(); i++) {
458       if (triggerDecisions[i]) {
459         pGlobalDecision->AddTriggerInput(*((AliHLTTriggerDecision*)triggerDecisions[i]));
460       }
461     }
462     triggerDecisions.Delete();
463     AliHLTTriggerDecision* pDecision=pGlobalDecision;
464     {
465       if (pDecision) {
466         //pDecision->Print();
467         HLTDebug("extracted %s", pDecision->GetName());
468         if (!fESD) {
469           // create the ESD container, but without std content
470           fESD = new AliESDEvent;
471         }
472         if (!fpData) fpData=new TArrayC;
473         if (fESD && fpData) {
474           fESD->Reset();
475           TObject* pESDObject=fESD->FindListObject("HLTGlobalTrigger");
476           if (pESDObject) {
477             // copy the content to the already existing object
478             pDecision->Copy(*pESDObject);
479           } else {
480             // add a new object
481             fESD->AddObject(pDecision->Clone());
482           }
483           WriteESD();
484           AliHLTMessage* pMsg=AliHLTMessage::Stream(fESD);
485           if (pMsg) {
486             if (!pMsg->CompBuffer()) {
487               fSize=pMsg->Length();
488               fpData->Set(fSize, pMsg->Buffer());
489             } else {
490               fSize=pMsg->CompLength();
491               fpData->Set(fSize, pMsg->CompBuffer());
492             }
493             delete pMsg;
494             pMsg=NULL;
495           } else {
496             HLTError("streaming of objects failed");
497           }
498         } else {
499           HLTError("memory allocation failed");
500           iResult=-ENOMEM;
501         }
502       }
503     }
504     delete pGlobalDecision;
505     pGlobalDecision=NULL;
506   } else {
507     HLTError("no global trigger found in data collection");
508   }
509
510   if (iResult>=0) {
511     return fSize;
512   }
513   fSize=0;
514   return iResult;
515 }
516
517 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::GetProcessedData(const AliHLTUInt8_t* &pData)
518 {
519   // see header file for class documentation
520   if (!fpData) {
521     pData=NULL;
522     return 0;
523   }
524
525   pData=reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray());
526   return fSize;
527 }
528
529 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::ReleaseProcessedData(const AliHLTUInt8_t* pData, int size)
530 {
531   // see header file for class documentation
532   int iResult=0;
533   if (!fpData || size != fSize ||
534       const_cast<AliHLTUInt8_t*>(pData) != reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray())) {
535     HLTError("attempt to release to wrong data buffer %p size %d, expected %p size %d", pData, size, fpData?fpData->GetArray():NULL, fSize);
536   }
537   fSize=0;
538   return iResult;
539 }
540
541 int AliHLTTriggerAgent::AliHLTTriggerDecisionHandler::WriteESD()
542 {
543   // see header file for class documentation
544   int iResult=0;
545   if (!fESD) return 0;
546   if (!fpESDfile) {
547     fpESDfile=new TFile("HLTdecision.root", "RECREATE");
548   }
549   if (!fpESDtree) {
550     fpESDtree=new TTree("HLTesdTree", "Tree with HLT ESD containing HLT decision");
551     if (fpESDtree) {
552       fESD->WriteToTree(fpESDtree);
553       fpESDtree->GetUserInfo()->Add(fESD);
554     }
555   }
556   if (!fpESDfile || !fpESDtree) return -ENOMEM;
557
558   fpESDtree->Fill();
559   fpESDfile->cd();
560   fpESDtree->Write(fpESDtree->GetName(),TObject::kOverwrite);
561
562   return iResult;
563 }