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