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