Corrected streaming problem.
[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");
284 fpEsd=new AliESDEvent;
285 if (fpEsd) {
286 fpEsd->CreateStdContent();
287 if (fpTree) {
288 fpEsd->WriteToTree(fpTree);
289 }
290 }
291 }
292
293 if (fpFile && fpTree && fpEsd) {
294 // synchronize and add empty events
295 fpEsd->Reset();
296 int nofCurrentEvents=fpTree->GetEntries();
297 if (nofCurrentEvents<eventno) {
298 iResult=1; // indicate tree to be written
299 HLTDebug("adding %d empty events to file %s", eventno-nofCurrentEvents, fName.Data());
300 for (int i=nofCurrentEvents; i<eventno; i++) {
301 fpTree->Fill();
302 }
303 }
304
305 if (iResult>=0 && pSrcESD) {
306 *fpEsd=*pSrcESD;
307 fpTree->Fill();
308 iResult=1; // indicate tree to be written
309 }
310
311 if (iResult>0) {
312 fpFile->cd();
313 fpTree->GetUserInfo()->Add(fpEsd);
314 fpTree->Write(fpTree->GetName(),TObject::kOverwrite);
315 fpTree->GetUserInfo()->Clear();
316 }
317 }
9877121c 318#else //HAVE_NOT_ESD_COPY
83cb7e1d 319 // this is the old workaround, necessary for older AliRoot versions
320 // version<=v4-12-Release
321
90c37647 322 // we need to copy the ESD, I did not find an approptiate
323 // method, the workaround is to save the ESD in a temporary
324 // tree, read the content back into the ESD structure
325 // used for filling.
326 // Unfortunately the following code crashes at the second event.
327 // The expert on the ESD (Christian Klein Boesig) does not have
328 // a solution either. It seems to be a problem in ROOT.
329 // TTree* dummy=new TTree("dummy","dummy");
330 // dummy->SetDirectory(0);
331 // pESD->WriteToTree(dummy);
332 // dummy->Fill();
333 // dummy->GetUserInfo()->Add(pESD);
334 // fpEsd->ReadFromTree(dummy);
335 // dummy->GetEvent(0);
336 // fpEsd->WriteToTree(fpTree);
337 // fpTree->Fill();
338 // dummy->GetUserInfo()->Clear();
339 // delete dummy;
340 //
341 // The only way is via TChain, which is working on files only at the
342 // time of writing.
343 // We use temporary files for the new event to be copied into the
344 // existing tree.
345 //
90c37647 346 if (fName.IsNull()) {
347 // this is the first event, create the file on disk and write ESD
c5123824 348 TString origin;
349 origin.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize);
350 origin.Remove(TString::kTrailing, ' ');
351 origin.ToUpper();
90c37647 352 fName="";
353 if (!fDirectory.IsNull()) {
354 fName+=fDirectory; fName+="/";
355 }
356 fName+="AliHLT"; fName+=origin;
c5123824 357 if (fDt!=kAliHLTDataTypeESDObject &&
358 fDt!=kAliHLTDataTypeESDTree) {
359
360 HLTWarning("non-standard ESD type %s", AliHLTComponent::DataType2Text(fDt).c_str());
361 TString id;
362 id.Insert(0, fDt.fID, kAliHLTComponentDataTypefIDsize);
363 id.Remove(TString::kTrailing, ' ');
364 id.ToUpper();
365 fName+="_"; fName+=id; fName+=".root";
366 } else {
367 fName+="ESDs.root";
90c37647 368 }
369
370 if (!gSystem->AccessPathName(fName)) {
371 // file exists, delete
372 TString shellcmd="rm -f ";
373 shellcmd+=fName;
374 gSystem->Exec(shellcmd);
c5123824 375 }
376 }
90c37647 377
378 TChain chain("esdTree");
379 TList cleanup;
380 cleanup.SetOwner();
381
382 int nofCurrentEvents=0;
383 if (iResult>=0) {
384 if (!gSystem->AccessPathName(fName)) {
385 // these are the other events, use the target file and temporary files to merge
386 // with TChain
387 chain.Add(fName);
388
389 if (eventno>=0) {
390 TFile file(fName);
391 if (!file.IsZombie()) {
392 TTree* pSrcTree;
393 file.GetObject("esdTree", pSrcTree);
394 if (pSrcTree) {
395 nofCurrentEvents=pSrcTree->GetEntries();
396 }
397 file.Close();
398 }
c5123824 399 }
400 }
90c37647 401 }
402
403 // synchronize and add empty events
404 if (nofCurrentEvents<eventno) {
405 iResult=1; // indicate files to merge
406 TTree* pTgtTree=new TTree("esdTree", "Tree with HLT ESD objects");
407 if (pTgtTree) {
408 pTgtTree->SetDirectory(0);
409 AliESDEvent* pTmpESD=new AliESDEvent;
410 if (pTmpESD) {
411 TString tmpfilename;
412 FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
413 if (pTmpFile) {
414 fclose(pTmpFile);
415 pTmpFile=NULL;
416 cleanup.Add(new TObjString(tmpfilename));
417 TFile emptyevents(tmpfilename, "RECREATE");
418 if (!emptyevents.IsZombie()) {
419 pTmpESD->CreateStdContent();
420 pTmpESD->WriteToTree(pTgtTree);
421 HLTDebug("adding %d empty events to file %s", eventno-nofCurrentEvents, fName.Data());
422 for (int i=nofCurrentEvents; i<eventno; i++) {
423 pTgtTree->Fill();
424 }
425 pTgtTree->GetUserInfo()->Add(pTmpESD);
426 emptyevents.cd();
427 pTgtTree->Write();
428 emptyevents.Close();
429 chain.Add(tmpfilename);
430 pTgtTree->GetUserInfo()->Clear();
431 }
c5123824 432 }
90c37647 433 delete pTmpESD;
c5123824 434 } else {
90c37647 435 iResult=-ENOMEM;
c5123824 436 }
90c37647 437 delete pTgtTree;
438 } else {
439 iResult=-ENOMEM;
440 }
441 }
442
443 if (iResult>=0 && pSrcESD) {
444 // add the new event to the chain
445 iResult=1; // indicate files to merge
446 TString tmpfilename=WriteTempFile(pSrcESD);
447 if (!tmpfilename.IsNull()) {
448 chain.Add(tmpfilename);
449 cleanup.Add(new TObjString(tmpfilename));
450 }
451 }
452
453 if (iResult>0) {
454 // build temporary file name for chain output
455 TString tgtName;
456 FILE* pTmpFile=gSystem->TempFileName(tgtName);
457 if (pTmpFile) {
458 fclose(pTmpFile);
459 pTmpFile=NULL;
460
41b5c1b6 461 // there have been problems with the memory consumption when using
462 // TChain::Merge
83cb7e1d 463 // but using a separate loop soemtimes crashes in AliESDEvent::ReadFromTree
464 // since this is for backward compatiblity only, we take the TChain::Merge
465 chain.Merge(tgtName);
466// TFile tgtFile(tgtName, "RECREATE");
467// TTree* pTgtTree=new TTree("esdTree", "Tree with HLT ESD objects");
468// AliESDEvent* pTgtESD=new AliESDEvent;
469// if (pTgtTree && pTgtESD) {
470// pTgtESD->ReadFromTree(&chain);
471// pTgtESD->WriteToTree(pTgtTree);
472
473// int nofEvents=chain.GetEntries();
474// for (int event=0; event<nofEvents; event++) {
475// chain.GetEntry(event);
476// pTgtTree->Fill();
477// }
478
479// pTgtTree->GetUserInfo()->Add(pTgtESD);
480// tgtFile.cd();
481// pTgtTree->Write();
482// pTgtTree->GetUserInfo()->Clear();
483// } else {
484// iResult=-ENOMEM;
485// }
486
487// if (pTgtTree) delete pTgtTree;
488// if (pTgtESD) delete pTgtESD;
489// tgtFile.Close();
41b5c1b6 490
90c37647 491 // rename the merged file to the original file
492 TString shellcmd="mv ";
493 shellcmd+=tgtName + " " + fName;
494 if (gSystem->Exec(shellcmd)==0) {
495 HLTDebug("renaming %s to %s", tgtName.Data(), fName.Data());
496 } else {
497 HLTError("can not rename temporary file %s to %s", tgtName.Data(), fName.Data());
c5123824 498 }
90c37647 499 } else {
500 HLTError("can not get temporary file name from system");
501 iResult=-EBADF;
502 }
503 }
504
505 // delete temporary files
41b5c1b6 506 // the list objects are cleaned up by the TList destructor as the
90c37647 507 // list is owner
508 TIter entry(&cleanup);
509 while (TObject* pObj=entry.Next()) {
510 if (dynamic_cast<TObjString*>(pObj)) {
511 TString shellcmd="rm -f ";
512 shellcmd+=(dynamic_cast<TObjString*>(pObj))->GetString();
513 gSystem->Exec(shellcmd);
514 }
515 }
9877121c 516#endif //HAVE_NOT_ESD_COPY
90c37647 517
518 return iResult;
519}
520
f1207f29 521TString AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteTempFile(AliESDEvent* pESD) const
90c37647 522{
523 // see header file for class documentation
f7561f8d 524 int iResult=0;
90c37647 525 TString tmpfilename;
526 FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
527 if (pTmpFile) {
528 fclose(pTmpFile);
529 pTmpFile=NULL;
530
531 TFile file(tmpfilename, "RECREATE");
532 if (!file.IsZombie()) {
f1207f29 533 TTree* pTree=AliHLTEsdManagerImplementation::EmbedIntoTree(pESD);
90c37647 534 if (pTree) {
535 file.cd();
536 if (pTree->Write()>0) {
c5123824 537 } else {
90c37647 538 HLTError("can not write esd tree to temporary file %s", tmpfilename.Data());
c5123824 539 }
90c37647 540
541 pTree->GetUserInfo()->Clear();
542 delete pTree;
c5123824 543 } else {
544 iResult=-ENOMEM;
545 }
90c37647 546 file.Close();
547 } else {
548 HLTError("can not open file %s", tmpfilename.Data());
3dd8541e 549 iResult=-EBADF;
c5123824 550 }
90c37647 551 } else {
552 HLTError("can not get temporary file name from system");
553 iResult=-EBADF;
c5123824 554 }
90c37647 555
556 if (iResult<0) {
557 if (gSystem->AccessPathName(tmpfilename)==0) {
558 TString shellcmd="rm -f ";
559 shellcmd+=tmpfilename;
560 gSystem->Exec(shellcmd);
561 }
562 tmpfilename="";
563 }
564 return tmpfilename;
565}
566
f1207f29 567void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::SetDirectory(const char* directory)
90c37647 568{
569 // see header file for class documentation
570 if (!directory) return;
571 if (!fName.IsNull()) {
572 HLTWarning("ESD entry already in writing mode (%s), ignoring directory", fName.Data());
573 return;
574 }
575 fDirectory=directory;
576}
577
f1207f29 578void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::Delete()
90c37647 579{
580 // see header file for class documentation
581 if (fName.IsNull()) return;
582 if (gSystem->AccessPathName(fName)!=0) return;
583
584 TString shellcmd="rm -f ";
585 shellcmd+=fName;
586 gSystem->Exec(shellcmd);
587 fName="";
588}
589
f1207f29 590const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetFileName() const
90c37647 591{
592 // see header file for class documentation
593 return fName.Data();
c5123824 594}
f527516f 595
596const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetPrefix()
597{
598 // see header file for class documentation
599 if (fPrefix.IsNull()) {
600 fPrefix.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize);
601 fPrefix.Remove(TString::kTrailing, ' ');
602 fPrefix.ToUpper();
603 if (!fPrefix.Contains("HLT")) {
604 fPrefix.Insert(0, "HLT");
605 }
606 }
607 return fPrefix.Data();
608}
609
610int AliHLTEsdManagerImplementation::AliHLTEsdListEntry::CopyNonEmptyObjects(AliESDEvent* pTgt, AliESDEvent* pSrc)
611{
612 // see header file for class documentation
613 int iResult=0;
614 if (!pTgt || !pSrc) return -EINVAL;
615
616 const char* defaultPrefix="HLT";
617 TIter next(pSrc->GetList());
618 TObject* pSrcObject=NULL;
619 TString name;
620 while ((pSrcObject=next())) {
621 if(!pSrcObject->InheritsFrom("TCollection")){
622 // simple objects
623 } else if(pSrcObject->InheritsFrom("TClonesArray")){
624 TClonesArray* pTClA=dynamic_cast<TClonesArray*>(pSrcObject);
625 if (pTClA!=NULL && pTClA->GetEntriesFast()>0) {
626 bool bMakeNewName=true;
627 name=defaultPrefix;
628 name+=pTClA->GetName();
629 TObject* pTgtObject=pTgt->GetList()->FindObject(name);
630 TClonesArray* pTgtArray=NULL;
631 if (bMakeNewName=(pTgtObject!=NULL) && pTgtObject->InheritsFrom("TClonesArray")){
632 pTgtArray=dynamic_cast<TClonesArray*>(pTgtObject);
633 if (pTgtArray) {
634 TString classType=pTClA->Class()->GetName();
635 if (classType.CompareTo(pTgtArray->Class()->GetName())==0) {
636 if (pTgtArray->GetEntries()==0) {
637 bMakeNewName=false;
638 } else {
639 HLTWarning("TClonesArray \"%s\" in target ESD %p is already filled with %d entries",
640 name.Data(), pTgt, pTgtArray->GetEntries());
641 }
642 } else {
643 HLTWarning("TClonesArray \"%s\" exists in target ESD %p, but describes incompatible class type %s instead of %s",
644 name.Data(), pTgt, pTgtArray->GetClass()->GetName(), pTClA->GetClass()->GetName());
645 }
646 } else {
647 HLTError("internal error: dynamic cast failed for object %s %p", pTgtObject->GetName(), pTgtObject);
648 }
649 } else if (pTgtObject) {
650 HLTWarning("object \"%s\" does already exist in target ESD %p, but is %s rather than TClonesArray",
651 name.Data(), pTgt, pTgtObject->Class()->GetName());
652 // TODO: temporary solution, think about a general naming scheme and add
653 // the name as property of AliHLTEsdListEntry
654 }
655
656 if (bMakeNewName) {
657 pTgtArray=NULL;
658 int count=1;
659 while (pTgt->GetList()->FindObject(name)) {
660 name.Form("%sESD_%s", GetPrefix(), pTClA->GetName());
661 if (count++>1) {
662 name+=Form("%d", count);
663 }
664 }
665 HLTWarning("adding new TClonesArray \"%s\" because of conflicts", name.Data());
666 }
667
668 if (pTgtArray) {
669 pTgtArray->ExpandCreate(pTClA->GetEntries());
670 HLTInfo("Expanding TClonesArray \"%s\" to %d elements", pTgtArray->GetClass()->GetName(), pTClA->GetEntries());
671 } else {
672 pTgtArray=new TClonesArray(pTClA->GetClass(), pTClA->GetEntries());
673 pTgtArray->ExpandCreate(pTClA->GetEntries());
674 pTgtArray->SetName(name);
675 pTgt->AddObject(pTgtArray);
676 HLTInfo("Adding TClonesArray \"%s\" with %d elements to ESD %p", name.Data(), pTClA->GetEntries(), pTgt);
677 }
678
679 if (pTgtArray) {
680 for(int i=0; i<pTClA->GetEntriesFast(); ++i){
681 (*pTClA)[i]->Copy(*((*pTgtArray)[i]));
682 }
683 } else {
684 iResult=-ENOMEM;
685 }
686 }
687 }
688 }
689 return iResult;
690}