Adding base class of HLTOUT handler for TObjects to be merged into hltEsd.
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTEsdManagerImplementation.cxx
CommitLineData
c5123824 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
f1207f29 19/** @file AliHLTEsdManagerImplementation.cxx
c5123824 20 @author Matthias Richter
21 @date
22 @brief Manager for merging and writing of HLT ESDs
23*/
24
f1207f29 25#include "AliHLTEsdManagerImplementation.h"
c5123824 26#include "AliHLTComponent.h"
27#include "AliESDEvent.h"
28#include "AliHLTMessage.h"
29#include "AliESDEvent.h"
f527516f 30#include "AliESDtrack.h"
2bc81aef 31#include "AliESDFMD.h"
32#include "AliESDVZERO.h"
33#include "AliESDTZERO.h"
34#include "AliESDCaloCells.h"
35#include "AliMultiplicity.h"
36#include "AliESDACORDE.h"
c5123824 37#include "TFile.h"
38#include "TTree.h"
39#include "TClass.h"
40#include "TObject.h"
62ff1e23 41#include "TObjectTable.h"
90c37647 42#include "TSystem.h"
43#include "TChain.h"
44#include "TList.h"
c5123824 45
46/** ROOT macro for the implementation of ROOT specific class methods */
f1207f29 47ClassImp(AliHLTEsdManagerImplementation)
c5123824 48
f1207f29 49AliHLTEsdManagerImplementation::AliHLTEsdManagerImplementation()
c5123824 50 :
794de106 51 fESDs()
52 , fDirectory()
53 , fWriteLocal(false)
c5123824 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}
61
f1207f29 62AliHLTEsdManagerImplementation::~AliHLTEsdManagerImplementation()
c5123824 63{
64 // see header file for class documentation
62ff1e23 65 for (unsigned int i=0; i<fESDs.size(); i++) {
66 if (fESDs[i]) {
67 delete fESDs[i];
68 }
69 fESDs[i]=NULL;
70 }
c5123824 71}
72
794de106 73int AliHLTEsdManagerImplementation::SetOption(const char* option)
74{
75 // see header file for class documentation
76 int iResult=0;
77 TString strOptions=option;
78 TObjArray* pTokens=strOptions.Tokenize(" ");
79 if (pTokens) {
80 if (pTokens->GetEntriesFast()>0) {
81 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
82 TString data=((TObjString*)pTokens->At(n))->GetString();
83 if (data.IsNull()) continue;
84
85 if (data.CompareTo("-writelocal")==0) {
86 fWriteLocal=true;
87 } else if (data.Contains("-directory=")) {
88 data.ReplaceAll("-directory=", "");
89 SetDirectory(data.Data());
90 } else {
91 HLTError("unknown argument %s", data.Data());
92 iResult=-EINVAL;
93 break;
94 }
95 }
96 }
97 delete pTokens;
98 }
99 return iResult;
100}
101
f1207f29 102AliHLTEsdManagerImplementation::AliHLTEsdListEntry* AliHLTEsdManagerImplementation::Find(AliHLTComponentDataType dt) const
c5123824 103{
104 // see header file for class documentation
105 AliHLTEsdListEntry* pEntry=NULL;
106 for (unsigned int i=0; i<fESDs.size(); i++) {
62ff1e23 107 if (fESDs[i] && *(fESDs[i])==dt) {
108 pEntry=const_cast<AliHLTEsdListEntry*>(fESDs[i]);
c5123824 109 }
110 }
111 return pEntry;
112}
113
f1207f29 114int AliHLTEsdManagerImplementation::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
c5123824 115 AliHLTComponentDataType dt, AliESDEvent* tgtesd, int eventno)
116{
117 // see header file for class documentation
118 if (!pBuffer && size<=0) return -EINVAL;
119 int iResult=0;
120 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
121 if (firstWord==size-sizeof(AliHLTUInt32_t)) {
122 HLTDebug("create object from block %s size %d", AliHLTComponent::DataType2Text(dt).c_str(), size);
123 AliHLTMessage msg(const_cast<AliHLTUInt8_t*>(pBuffer), size);
124 TClass* objclass=msg.GetClass();
125 TObject* pObj=msg.ReadObject(objclass);
126 if (pObj && objclass) {
127 HLTDebug("object %p type %s created", pObj, objclass->GetName());
128 AliESDEvent* pESD=dynamic_cast<AliESDEvent*>(pObj);
129 TTree* pTree=NULL;
130 if (!pESD) {
131 pTree=dynamic_cast<TTree*>(pObj);
132 if (pTree) {
133 pESD=new AliESDEvent;
134 pESD->CreateStdContent();
135 if (pTree->GetEntries()>0) {
136 if (pTree->GetEntries()>1) {
137 HLTWarning("only one entry allowed for ESD embedded into tree, data block %s contains tree with %d entires, taking first entry",
138 AliHLTComponent::DataType2Text(dt).c_str(), pTree->GetEntries());
139 }
140 pESD->ReadFromTree(pTree);
141 pTree->GetEvent(0);
142 }
143 } else {
144 HLTWarning("tree of data block %s has no events, skipping data block", AliHLTComponent::DataType2Text(dt).c_str());
145 }
146 }
147 if (pESD) {
148 AliHLTEsdListEntry* entry=Find(dt);
149 if (!entry) {
57584811 150 if ((entry=new AliHLTEsdListEntry(dt))!=NULL) {
151 if (!fDirectory.IsNull()) {
152 entry->SetDirectory(fDirectory);
153 }
154 fESDs.push_back(entry);
90c37647 155 }
c5123824 156 }
57584811 157 if (entry) {
158 if (tgtesd) {
159#if !defined(HAVE_NOT_ESD_COPY)
160 Merge(tgtesd, pESD);
9877121c 161#else //HAVE_NOT_ESD_COPY
57584811 162 static bool warningPrinted=false;
163 if (!warningPrinted) {
164 HLTWarning("old version of AliESDEvent does not provide assignment operator, skip merging to global hltEsd");
165 }
166 warningPrinted=true;
9877121c 167#endif //HAVE_NOT_ESD_COPY
57584811 168 }
794de106 169
170 // Matthias 2009-06-06: writing of individual ESD files for the different origins was a
171 // first attempt when functionality was missing in the AliRoot framework and remained as
172 // debugging feature. ESD merging is now implemented and data written to the hltEsd, so
173 // the feature is now disabled by default because it causes increasing memory consumption.
174 // Presumably not because of a memory leak but the way the internal TTree is used and kept
175 // in memory.
176 // Writing of local files can be optionally switched on as e.g. by the EsdCollector component.
177 if (fWriteLocal) entry->WriteESD(pESD, eventno);
c5123824 178 } else {
179 HLTError("internal mismatch, can not create list entry");
180 iResult=-ENOMEM;
181 }
182 } else {
183 HLTWarning("data block %s is not of class type AliESDEvent, ignoring ...", AliHLTComponent::DataType2Text(dt).c_str());
184 }
185 if (pTree) {
186 // ESD has been created and must be cleaned up
242e6536 187 pESD->Reset();
c5123824 188 delete pESD;
189 pESD=NULL;
190 }
191 delete pObj;
192 pObj=NULL;
193 } else {
194 }
195 }
196 return iResult;
197}
198
f1207f29 199int AliHLTEsdManagerImplementation::PadESDs(int eventno)
c5123824 200{
201 // see header file for class documentation
90c37647 202 int iResult=0;
203 for (unsigned int i=0; i<fESDs.size(); i++) {
204 if (fESDs[i]) {
205 int res=fESDs[i]->WriteESD(NULL, eventno);
206 if (res<0 && iResult>=0) iResult=res;
207 }
208 }
209 return iResult;
c5123824 210}
211
f1207f29 212void AliHLTEsdManagerImplementation::SetDirectory(const char* directory)
c5123824 213{
214 // see header file for class documentation
90c37647 215 if (!directory) return;
216 fDirectory=directory;
217 for (unsigned int i=0; i<fESDs.size(); i++) {
218 if (fESDs[i]) {
219 fESDs[i]->SetDirectory(directory);
220 }
221 }
222}
223
f1207f29 224TString AliHLTEsdManagerImplementation::GetFileNames(AliHLTComponentDataType dt) const
90c37647 225{
226 TString result;
227 for (unsigned int i=0; i<fESDs.size(); i++) {
228 if (fESDs[i] && *(fESDs[i])==dt) {
229 if (!result.IsNull()) result+=" ";
230 result+=fESDs[i]->GetFileName();
231 }
c5123824 232 }
90c37647 233 return result;
234}
c5123824 235
f1207f29 236TTree* AliHLTEsdManagerImplementation::EmbedIntoTree(AliESDEvent* pESD, const char* name, const char* title)
90c37647 237{
238 // see header file for class documentation
239 int iResult=0;
240 TTree* pTree=new TTree(name, title);
241 if (pTree) {
242 pESD->WriteToTree(pTree);
243 pTree->Fill();
244 pTree->GetUserInfo()->Add(pESD);
245 } else {
246 iResult=-ENOMEM;
c5123824 247 }
248
90c37647 249 if (iResult<0) {
250 pTree->GetUserInfo()->Clear();
251 delete pTree;
c5123824 252 }
90c37647 253
254 return pTree;
255}
256
f1207f29 257AliHLTEsdManagerImplementation::AliHLTEsdListEntry::AliHLTEsdListEntry(AliHLTComponentDataType dt)
90c37647 258 :
259 fName(),
260 fDirectory(),
83cb7e1d 261 fDt(dt),
262 fpFile(NULL),
263 fpTree(NULL),
f527516f 264 fpEsd(NULL),
265 fPrefix()
90c37647 266{
267 // see header file for class documentation
268}
269
f1207f29 270AliHLTEsdManagerImplementation::AliHLTEsdListEntry::~AliHLTEsdListEntry()
90c37647 271{
272 // see header file for class documentation
242e6536 273 if (fpEsd) delete fpEsd;
274 fpEsd=NULL;
275
276 if (fpTree) delete fpTree;
277 fpTree=NULL;
278
ba93bdb0 279 if (fpFile) {
280 fpFile->Close();
281 delete fpFile;
282 }
242e6536 283 fpFile=NULL;
c5123824 284}
285
f1207f29 286bool AliHLTEsdManagerImplementation::AliHLTEsdListEntry::operator==(AliHLTComponentDataType dt) const
c5123824 287{
288 // see header file for class documentation
289 return fDt==dt;
290}
291
f1207f29 292int AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteESD(AliESDEvent* pSrcESD, int eventno)
c5123824 293{
83cb7e1d 294 // see header file for class documentation
295 int iResult=0;
d0d53f68 296
9877121c 297#ifndef HAVE_NOT_ESD_COPY
83cb7e1d 298 if (fName.IsNull()) {
299 // this is the first event, create the file name
83cb7e1d 300 fName="";
301 if (!fDirectory.IsNull()) {
302 fName+=fDirectory; fName+="/";
303 }
f527516f 304 fName+="Ali"; fName+=GetPrefix();
83cb7e1d 305 if (fDt!=kAliHLTDataTypeESDObject &&
306 fDt!=kAliHLTDataTypeESDTree) {
307
308 HLTWarning("non-standard ESD type %s", AliHLTComponent::DataType2Text(fDt).c_str());
309 TString id;
310 id.Insert(0, fDt.fID, kAliHLTComponentDataTypefIDsize);
311 id.Remove(TString::kTrailing, ' ');
312 id.ToUpper();
313 fName+="_"; fName+=id; fName+=".root";
314 } else {
315 fName+="ESDs.root";
316 }
317
318 fpFile=new TFile(fName, "RECREATE");
319 fpTree=new TTree("esdTree", "Tree with HLT ESD objects");
b952ebda 320 fpTree->SetDirectory(0);
83cb7e1d 321 fpEsd=new AliESDEvent;
322 if (fpEsd) {
323 fpEsd->CreateStdContent();
b952ebda 324 *fpEsd=*pSrcESD;
83cb7e1d 325 if (fpTree) {
326 fpEsd->WriteToTree(fpTree);
327 }
328 }
329 }
330
331 if (fpFile && fpTree && fpEsd) {
332 // synchronize and add empty events
333 fpEsd->Reset();
334 int nofCurrentEvents=fpTree->GetEntries();
335 if (nofCurrentEvents<eventno) {
336 iResult=1; // indicate tree to be written
337 HLTDebug("adding %d empty events to file %s", eventno-nofCurrentEvents, fName.Data());
338 for (int i=nofCurrentEvents; i<eventno; i++) {
339 fpTree->Fill();
340 }
341 }
342
343 if (iResult>=0 && pSrcESD) {
b952ebda 344 int nofObjects=fpEsd->GetList()->GetEntries();
83cb7e1d 345 *fpEsd=*pSrcESD;
b952ebda 346 if (nofObjects!=fpEsd->GetList()->GetEntries()) {
347 // The source ESD contains object not present in the target ESD
348 // before. Those objects will not be written to the tree since
349 // the branch layout has been created earlier.
350 // Create new tree with the additional branches, copy the entries
351 // of the current tree into the new tree, and continue.
352 TTree* pNewTree=new TTree("esdTree", "Tree with HLT ESD objects");
353 pNewTree->SetDirectory(0);
354 AliESDEvent* readESD=new AliESDEvent;
355 readESD->CreateStdContent();
356 readESD->ReadFromTree(fpTree);
357 fpEsd->Reset();
358 fpEsd->WriteToTree(pNewTree);
359 HLTDebug("cloning tree with %d entries", fpTree->GetEntries());
360 for (int event=0; event<fpTree->GetEntries(); event++) {
361 fpTree->GetEntry(event);
362 *fpEsd=*readESD;
363 pNewTree->Fill();
364 fpEsd->Reset();
365 }
366 fpFile->Close();
367 delete fpFile;
368 delete readESD;
369 delete fpTree;
370 fpFile=new TFile(fName, "RECREATE");
371 fpTree=pNewTree;
372 *fpEsd=*pSrcESD;
373 HLTDebug("new ESD with %d objects", fpEsd->GetList()->GetEntries());
374 }
83cb7e1d 375 fpTree->Fill();
376 iResult=1; // indicate tree to be written
377 }
378
379 if (iResult>0) {
380 fpFile->cd();
381 fpTree->GetUserInfo()->Add(fpEsd);
382 fpTree->Write(fpTree->GetName(),TObject::kOverwrite);
383 fpTree->GetUserInfo()->Clear();
384 }
385 }
9877121c 386#else //HAVE_NOT_ESD_COPY
83cb7e1d 387 // this is the old workaround, necessary for older AliRoot versions
388 // version<=v4-12-Release
389
90c37647 390 // we need to copy the ESD, I did not find an approptiate
391 // method, the workaround is to save the ESD in a temporary
392 // tree, read the content back into the ESD structure
393 // used for filling.
394 // Unfortunately the following code crashes at the second event.
395 // The expert on the ESD (Christian Klein Boesig) does not have
396 // a solution either. It seems to be a problem in ROOT.
397 // TTree* dummy=new TTree("dummy","dummy");
398 // dummy->SetDirectory(0);
399 // pESD->WriteToTree(dummy);
400 // dummy->Fill();
401 // dummy->GetUserInfo()->Add(pESD);
402 // fpEsd->ReadFromTree(dummy);
403 // dummy->GetEvent(0);
404 // fpEsd->WriteToTree(fpTree);
405 // fpTree->Fill();
406 // dummy->GetUserInfo()->Clear();
407 // delete dummy;
408 //
409 // The only way is via TChain, which is working on files only at the
410 // time of writing.
411 // We use temporary files for the new event to be copied into the
412 // existing tree.
413 //
90c37647 414 if (fName.IsNull()) {
415 // this is the first event, create the file on disk and write ESD
c5123824 416 TString origin;
417 origin.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize);
418 origin.Remove(TString::kTrailing, ' ');
419 origin.ToUpper();
90c37647 420 fName="";
421 if (!fDirectory.IsNull()) {
422 fName+=fDirectory; fName+="/";
423 }
424 fName+="AliHLT"; fName+=origin;
c5123824 425 if (fDt!=kAliHLTDataTypeESDObject &&
426 fDt!=kAliHLTDataTypeESDTree) {
427
428 HLTWarning("non-standard ESD type %s", AliHLTComponent::DataType2Text(fDt).c_str());
429 TString id;
430 id.Insert(0, fDt.fID, kAliHLTComponentDataTypefIDsize);
431 id.Remove(TString::kTrailing, ' ');
432 id.ToUpper();
433 fName+="_"; fName+=id; fName+=".root";
434 } else {
435 fName+="ESDs.root";
90c37647 436 }
437
438 if (!gSystem->AccessPathName(fName)) {
439 // file exists, delete
440 TString shellcmd="rm -f ";
441 shellcmd+=fName;
442 gSystem->Exec(shellcmd);
c5123824 443 }
444 }
90c37647 445
446 TChain chain("esdTree");
447 TList cleanup;
448 cleanup.SetOwner();
449
450 int nofCurrentEvents=0;
451 if (iResult>=0) {
452 if (!gSystem->AccessPathName(fName)) {
453 // these are the other events, use the target file and temporary files to merge
454 // with TChain
455 chain.Add(fName);
456
457 if (eventno>=0) {
458 TFile file(fName);
459 if (!file.IsZombie()) {
460 TTree* pSrcTree;
461 file.GetObject("esdTree", pSrcTree);
462 if (pSrcTree) {
463 nofCurrentEvents=pSrcTree->GetEntries();
464 }
465 file.Close();
466 }
c5123824 467 }
468 }
90c37647 469 }
470
471 // synchronize and add empty events
472 if (nofCurrentEvents<eventno) {
473 iResult=1; // indicate files to merge
474 TTree* pTgtTree=new TTree("esdTree", "Tree with HLT ESD objects");
475 if (pTgtTree) {
476 pTgtTree->SetDirectory(0);
477 AliESDEvent* pTmpESD=new AliESDEvent;
478 if (pTmpESD) {
479 TString tmpfilename;
480 FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
481 if (pTmpFile) {
482 fclose(pTmpFile);
483 pTmpFile=NULL;
484 cleanup.Add(new TObjString(tmpfilename));
485 TFile emptyevents(tmpfilename, "RECREATE");
486 if (!emptyevents.IsZombie()) {
487 pTmpESD->CreateStdContent();
488 pTmpESD->WriteToTree(pTgtTree);
489 HLTDebug("adding %d empty events to file %s", eventno-nofCurrentEvents, fName.Data());
490 for (int i=nofCurrentEvents; i<eventno; i++) {
491 pTgtTree->Fill();
492 }
493 pTgtTree->GetUserInfo()->Add(pTmpESD);
494 emptyevents.cd();
495 pTgtTree->Write();
496 emptyevents.Close();
497 chain.Add(tmpfilename);
498 pTgtTree->GetUserInfo()->Clear();
499 }
c5123824 500 }
90c37647 501 delete pTmpESD;
c5123824 502 } else {
90c37647 503 iResult=-ENOMEM;
c5123824 504 }
90c37647 505 delete pTgtTree;
506 } else {
507 iResult=-ENOMEM;
508 }
509 }
510
511 if (iResult>=0 && pSrcESD) {
512 // add the new event to the chain
513 iResult=1; // indicate files to merge
514 TString tmpfilename=WriteTempFile(pSrcESD);
515 if (!tmpfilename.IsNull()) {
516 chain.Add(tmpfilename);
517 cleanup.Add(new TObjString(tmpfilename));
518 }
519 }
520
521 if (iResult>0) {
522 // build temporary file name for chain output
523 TString tgtName;
524 FILE* pTmpFile=gSystem->TempFileName(tgtName);
525 if (pTmpFile) {
526 fclose(pTmpFile);
527 pTmpFile=NULL;
528
41b5c1b6 529 // there have been problems with the memory consumption when using
530 // TChain::Merge
83cb7e1d 531 // but using a separate loop soemtimes crashes in AliESDEvent::ReadFromTree
532 // since this is for backward compatiblity only, we take the TChain::Merge
533 chain.Merge(tgtName);
534// TFile tgtFile(tgtName, "RECREATE");
535// TTree* pTgtTree=new TTree("esdTree", "Tree with HLT ESD objects");
536// AliESDEvent* pTgtESD=new AliESDEvent;
537// if (pTgtTree && pTgtESD) {
538// pTgtESD->ReadFromTree(&chain);
539// pTgtESD->WriteToTree(pTgtTree);
540
541// int nofEvents=chain.GetEntries();
542// for (int event=0; event<nofEvents; event++) {
543// chain.GetEntry(event);
544// pTgtTree->Fill();
545// }
546
547// pTgtTree->GetUserInfo()->Add(pTgtESD);
548// tgtFile.cd();
549// pTgtTree->Write();
550// pTgtTree->GetUserInfo()->Clear();
551// } else {
552// iResult=-ENOMEM;
553// }
554
555// if (pTgtTree) delete pTgtTree;
556// if (pTgtESD) delete pTgtESD;
557// tgtFile.Close();
41b5c1b6 558
90c37647 559 // rename the merged file to the original file
560 TString shellcmd="mv ";
561 shellcmd+=tgtName + " " + fName;
562 if (gSystem->Exec(shellcmd)==0) {
563 HLTDebug("renaming %s to %s", tgtName.Data(), fName.Data());
564 } else {
565 HLTError("can not rename temporary file %s to %s", tgtName.Data(), fName.Data());
c5123824 566 }
90c37647 567 } else {
568 HLTError("can not get temporary file name from system");
569 iResult=-EBADF;
570 }
571 }
572
573 // delete temporary files
41b5c1b6 574 // the list objects are cleaned up by the TList destructor as the
90c37647 575 // list is owner
576 TIter entry(&cleanup);
577 while (TObject* pObj=entry.Next()) {
578 if (dynamic_cast<TObjString*>(pObj)) {
579 TString shellcmd="rm -f ";
580 shellcmd+=(dynamic_cast<TObjString*>(pObj))->GetString();
581 gSystem->Exec(shellcmd);
582 }
583 }
9877121c 584#endif //HAVE_NOT_ESD_COPY
90c37647 585
586 return iResult;
587}
588
f1207f29 589TString AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteTempFile(AliESDEvent* pESD) const
90c37647 590{
591 // see header file for class documentation
f7561f8d 592 int iResult=0;
90c37647 593 TString tmpfilename;
594 FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
595 if (pTmpFile) {
596 fclose(pTmpFile);
597 pTmpFile=NULL;
598
599 TFile file(tmpfilename, "RECREATE");
600 if (!file.IsZombie()) {
f1207f29 601 TTree* pTree=AliHLTEsdManagerImplementation::EmbedIntoTree(pESD);
90c37647 602 if (pTree) {
603 file.cd();
604 if (pTree->Write()>0) {
c5123824 605 } else {
90c37647 606 HLTError("can not write esd tree to temporary file %s", tmpfilename.Data());
c5123824 607 }
90c37647 608
609 pTree->GetUserInfo()->Clear();
610 delete pTree;
c5123824 611 } else {
612 iResult=-ENOMEM;
613 }
90c37647 614 file.Close();
615 } else {
616 HLTError("can not open file %s", tmpfilename.Data());
3dd8541e 617 iResult=-EBADF;
c5123824 618 }
90c37647 619 } else {
620 HLTError("can not get temporary file name from system");
621 iResult=-EBADF;
c5123824 622 }
90c37647 623
624 if (iResult<0) {
625 if (gSystem->AccessPathName(tmpfilename)==0) {
626 TString shellcmd="rm -f ";
627 shellcmd+=tmpfilename;
628 gSystem->Exec(shellcmd);
629 }
630 tmpfilename="";
631 }
632 return tmpfilename;
633}
634
f1207f29 635void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::SetDirectory(const char* directory)
90c37647 636{
637 // see header file for class documentation
638 if (!directory) return;
639 if (!fName.IsNull()) {
640 HLTWarning("ESD entry already in writing mode (%s), ignoring directory", fName.Data());
641 return;
642 }
643 fDirectory=directory;
644}
645
f1207f29 646void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::Delete()
90c37647 647{
648 // see header file for class documentation
649 if (fName.IsNull()) return;
650 if (gSystem->AccessPathName(fName)!=0) return;
651
652 TString shellcmd="rm -f ";
653 shellcmd+=fName;
654 gSystem->Exec(shellcmd);
655 fName="";
656}
657
f1207f29 658const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetFileName() const
90c37647 659{
660 // see header file for class documentation
661 return fName.Data();
c5123824 662}
f527516f 663
664const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetPrefix()
665{
666 // see header file for class documentation
667 if (fPrefix.IsNull()) {
668 fPrefix.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize);
669 fPrefix.Remove(TString::kTrailing, ' ');
670 fPrefix.ToUpper();
671 if (!fPrefix.Contains("HLT")) {
672 fPrefix.Insert(0, "HLT");
673 }
674 }
675 return fPrefix.Data();
676}
677
57584811 678int AliHLTEsdManagerImplementation::Merge(AliESDEvent* pTgt, AliESDEvent* pSrc) const
f527516f 679{
680 // see header file for class documentation
681 int iResult=0;
682 if (!pTgt || !pSrc) return -EINVAL;
683
f527516f 684 TIter next(pSrc->GetList());
685 TObject* pSrcObject=NULL;
57584811 686 static int warningCount=0;
f527516f 687 while ((pSrcObject=next())) {
688 if(!pSrcObject->InheritsFrom("TCollection")){
689 // simple objects
2bc81aef 690 // for every type of object we have to find out whether it is empty or not
691 // objects are only copied if non-empty, otherwise valid content would be
692 // overridden by empty objects during the merging
693 bool copy=false;
30d84601 694 TString name=pSrcObject->GetName();
18a9a5ad 695 if(pSrcObject->InheritsFrom("AliHLTTriggerDecision")){
2bc81aef 696 copy=true;
697 } else if (pSrcObject->IsA()==AliESDRun::Class()) {
698 AliESDRun* pESDRun=dynamic_cast<AliESDRun*>(pSrcObject);
699 // zero might be a valid run no in simulation, so we check also whether the CTP trigger classes are set
700 copy=(pESDRun && (pESDRun->GetRunNumber()>0 || !pESDRun->GetActiveTriggerClasses().IsNull()));
701 } else if (pSrcObject->IsA()==AliESDHeader::Class()) {
702 AliESDHeader* pESDHeader=dynamic_cast<AliESDHeader*>(pSrcObject);
703 copy=(pESDHeader && pESDHeader->GetTriggerMask()!=0);
704 } else if (pSrcObject->IsA()==AliESDVertex::Class()) {
705 AliESDVertex* pESDVertex=dynamic_cast<AliESDVertex*>(pSrcObject);
706 copy=(pESDVertex && pESDVertex->GetNContributors()>0);
707 } else if (pSrcObject->IsA()==AliESDTZERO::Class()) {
708 AliESDTZERO* pESDTZero=dynamic_cast<AliESDTZERO*>(pSrcObject);
709 copy=(pESDTZero && (pESDTZero->GetT0zVertex()!=0.0 || pESDTZero->GetT0()!=0.0));
710 } else if (pSrcObject->IsA()==AliESDVZERO::Class()) {
711 AliESDVZERO* pESDVZero=dynamic_cast<AliESDVZERO*>(pSrcObject);
712 copy=(pESDVZero && false); // could not find an easy valid condition
713 } else if (pSrcObject->IsA()==AliESDFMD::Class()) {
714 AliESDFMD* pESDFMD=dynamic_cast<AliESDFMD*>(pSrcObject);
715 copy=(pESDFMD && false); // have to find an easy valid condition
716 } else if (pSrcObject->IsA()==AliESDZDC::Class()) {
717 AliESDZDC* pESDZDC=dynamic_cast<AliESDZDC*>(pSrcObject);
718 copy=(pESDZDC && false); // have to find an easy valid condition
719 } else if (pSrcObject->IsA()==AliMultiplicity::Class()) {
720 AliMultiplicity* pMultiplicity=dynamic_cast<AliMultiplicity*>(pSrcObject);
721 copy=(pMultiplicity && pMultiplicity->GetNumberOfTracklets()>0);
722 } else if (pSrcObject->IsA()==AliESDCaloTrigger::Class()) {
723 AliESDCaloTrigger* pESDCaloTrigger=dynamic_cast<AliESDCaloTrigger*>(pSrcObject);
724 copy=(pESDCaloTrigger && false); // have to find an easy valid condition
725 } else if (pSrcObject->IsA()==AliESDCaloCells::Class()) {
726 AliESDCaloCells* pESDCaloCells=dynamic_cast<AliESDCaloCells*>(pSrcObject);
727 copy=(pESDCaloCells && false); // have to find an easy valid condition
728 } else if (pSrcObject->IsA()==AliESDACORDE::Class()) {
729 AliESDACORDE* pESDACORDE=dynamic_cast<AliESDACORDE*>(pSrcObject);
730 copy=(pESDACORDE && false); // have to find an easy valid condition
731 } else {
732 HLTError("no merging implemented for object %s, omitting", name.Data());
733 }
734 if (copy) {
e13512e4 735 //pSrcObject->Print();
30d84601 736 TObject* pTgtObject=pTgt->FindListObject(name);
18a9a5ad 737 if (pTgtObject) {
30d84601 738 pSrcObject->Copy(*pTgtObject);
18a9a5ad 739 } else {
30d84601 740 pTgt->AddObject(pSrcObject->Clone());
18a9a5ad 741 }
18a9a5ad 742 }
f527516f 743 } else if(pSrcObject->InheritsFrom("TClonesArray")){
744 TClonesArray* pTClA=dynamic_cast<TClonesArray*>(pSrcObject);
745 if (pTClA!=NULL && pTClA->GetEntriesFast()>0) {
30d84601 746 TString name=pTClA->GetName();
f527516f 747 TObject* pTgtObject=pTgt->GetList()->FindObject(name);
748 TClonesArray* pTgtArray=NULL;
57584811 749 if (pTgtObject!=NULL && pTgtObject->InheritsFrom("TClonesArray")){
f527516f 750 pTgtArray=dynamic_cast<TClonesArray*>(pTgtObject);
751 if (pTgtArray) {
752 TString classType=pTClA->Class()->GetName();
753 if (classType.CompareTo(pTgtArray->Class()->GetName())==0) {
754 if (pTgtArray->GetEntries()==0) {
57584811 755 pTgtArray->ExpandCreate(pTClA->GetEntries());
756 for(int i=0; i<pTClA->GetEntriesFast(); ++i){
757 (*pTClA)[i]->Copy(*((*pTgtArray)[i]));
758 }
f527516f 759 } else {
57584811 760 if (warningCount++<10) {
761 HLTWarning("TClonesArray \"%s\" in target ESD %p is already filled with %d entries",
762 name.Data(), pTgt, pTgtArray->GetEntries());
763 }
764 iResult=-EBUSY;
f527516f 765 }
766 } else {
57584811 767 if (warningCount++<10) {
768 HLTWarning("TClonesArray \"%s\" exists in target ESD %p, but describes incompatible class type %s instead of %s",
769 name.Data(), pTgt, pTgtArray->GetClass()->GetName(), pTClA->GetClass()->GetName());
770 }
771 iResult=-EBUSY;
f527516f 772 }
773 } else {
57584811 774 if (warningCount++<10) {
775 HLTError("internal error: dynamic cast failed for object %s %p", pTgtObject->GetName(), pTgtObject);
776 }
777 iResult=-EBUSY;
f527516f 778 }
779 } else if (pTgtObject) {
57584811 780 if (warningCount++<10) {
781 HLTWarning("object \"%s\" does already exist in target ESD %p, but is %s rather than TClonesArray"
782 " skipping data",
783 name.Data(), pTgt, pTgtObject->Class()->GetName());
f527516f 784 }
57584811 785 iResult=-EBUSY;
f527516f 786 } else {
57584811 787 if (warningCount++<10) {
788 HLTWarning("object \"%s\" does not exist in target ESD %p, data can not be copied because it will be lost when filling the tree",
789 name.Data(), pTgt);
f527516f 790 }
57584811 791 iResult=-ENOENT;
f527516f 792 }
793 }
794 }
795 }
796 return iResult;
797}