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