3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /** @file AliHLTEsdManagerImplementation.cxx
20 @author Matthias Richter
22 @brief Manager for merging and writing of HLT ESDs
25 #include "AliHLTEsdManagerImplementation.h"
26 #include "AliHLTComponent.h"
27 #include "AliESDEvent.h"
28 #include "AliHLTMessage.h"
29 #include "AliESDEvent.h"
30 #include "AliESDtrack.h"
31 #include "AliESDFMD.h"
32 #include "AliESDVZERO.h"
33 #include "AliESDTZERO.h"
34 #include "AliESDCaloCells.h"
35 #include "AliMultiplicity.h"
36 #include "AliESDACORDE.h"
41 #include "TObjectTable.h"
46 /** ROOT macro for the implementation of ROOT specific class methods */
47 ClassImp(AliHLTEsdManagerImplementation)
49 AliHLTEsdManagerImplementation::AliHLTEsdManagerImplementation()
55 // see header file for class documentation
57 // refer to README to build package
59 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
62 AliHLTEsdManagerImplementation::~AliHLTEsdManagerImplementation()
64 // see header file for class documentation
65 for (unsigned int i=0; i<fESDs.size(); i++) {
73 int AliHLTEsdManagerImplementation::SetOption(const char* option)
75 // see header file for class documentation
77 TString strOptions=option;
78 TObjArray* pTokens=strOptions.Tokenize(" ");
80 if (pTokens->GetEntriesFast()>0) {
81 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
82 TString data=((TObjString*)pTokens->At(n))->GetString();
83 if (data.IsNull()) continue;
85 if (data.CompareTo("-writelocal")==0) {
87 } else if (data.Contains("-directory=")) {
88 data.ReplaceAll("-directory=", "");
89 SetDirectory(data.Data());
91 HLTError("unknown argument %s", data.Data());
102 AliHLTEsdManagerImplementation::AliHLTEsdListEntry* AliHLTEsdManagerImplementation::Find(AliHLTComponentDataType dt) const
104 // see header file for class documentation
105 AliHLTEsdListEntry* pEntry=NULL;
106 for (unsigned int i=0; i<fESDs.size(); i++) {
107 if (fESDs[i] && *(fESDs[i])==dt) {
108 pEntry=const_cast<AliHLTEsdListEntry*>(fESDs[i]);
114 int AliHLTEsdManagerImplementation::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
115 AliHLTComponentDataType dt, AliESDEvent* tgtesd, int eventno)
117 // see header file for class documentation
118 if (!pBuffer && size<=0) return -EINVAL;
120 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
121 if (firstWord==size-sizeof(AliHLTUInt32_t)) {
122 HLTDebug("create object from block %s size %d", AliHLTComponent::DataType2Text(dt).c_str(), size);
123 AliHLTMessage msg(const_cast<AliHLTUInt8_t*>(pBuffer), size);
124 TClass* objclass=msg.GetClass();
125 TObject* pObj=msg.ReadObject(objclass);
126 if (pObj && objclass) {
127 HLTDebug("object %p type %s created", pObj, objclass->GetName());
128 AliESDEvent* pESD=dynamic_cast<AliESDEvent*>(pObj);
131 pTree=dynamic_cast<TTree*>(pObj);
133 pESD=new AliESDEvent;
134 pESD->CreateStdContent();
135 if (pTree->GetEntries()>0) {
136 if (pTree->GetEntries()>1) {
137 HLTWarning("only one entry allowed for ESD embedded into tree, data block %s contains tree with %d entires, taking first entry",
138 AliHLTComponent::DataType2Text(dt).c_str(), pTree->GetEntries());
140 pESD->ReadFromTree(pTree);
144 HLTWarning("tree of data block %s has no events, skipping data block", AliHLTComponent::DataType2Text(dt).c_str());
148 AliHLTEsdListEntry* entry=Find(dt);
150 if ((entry=new AliHLTEsdListEntry(dt))!=NULL) {
151 if (!fDirectory.IsNull()) {
152 entry->SetDirectory(fDirectory);
154 fESDs.push_back(entry);
159 #if !defined(HAVE_NOT_ESD_COPY)
161 #else //HAVE_NOT_ESD_COPY
162 static bool warningPrinted=false;
163 if (!warningPrinted) {
164 HLTWarning("old version of AliESDEvent does not provide assignment operator, skip merging to global hltEsd");
167 #endif //HAVE_NOT_ESD_COPY
170 // Matthias 2009-06-06: writing of individual ESD files for the different origins was a
171 // first attempt when functionality was missing in the AliRoot framework and remained as
172 // debugging feature. ESD merging is now implemented and data written to the hltEsd, so
173 // the feature is now disabled by default because it causes increasing memory consumption.
174 // Presumably not because of a memory leak but the way the internal TTree is used and kept
176 // Writing of local files can be optionally switched on as e.g. by the EsdCollector component.
177 if (fWriteLocal) entry->WriteESD(pESD, eventno);
179 HLTError("internal mismatch, can not create list entry");
183 HLTWarning("data block %s is not of class type AliESDEvent, ignoring ...", AliHLTComponent::DataType2Text(dt).c_str());
186 // ESD has been created and must be cleaned up
199 int AliHLTEsdManagerImplementation::PadESDs(int eventno)
201 // see header file for class documentation
203 for (unsigned int i=0; i<fESDs.size(); i++) {
205 int res=fESDs[i]->WriteESD(NULL, eventno);
206 if (res<0 && iResult>=0) iResult=res;
212 void AliHLTEsdManagerImplementation::SetDirectory(const char* directory)
214 // see header file for class documentation
215 if (!directory) return;
216 fDirectory=directory;
217 for (unsigned int i=0; i<fESDs.size(); i++) {
219 fESDs[i]->SetDirectory(directory);
224 TString AliHLTEsdManagerImplementation::GetFileNames(AliHLTComponentDataType dt) const
227 for (unsigned int i=0; i<fESDs.size(); i++) {
228 if (fESDs[i] && *(fESDs[i])==dt) {
229 if (!result.IsNull()) result+=" ";
230 result+=fESDs[i]->GetFileName();
236 TTree* AliHLTEsdManagerImplementation::EmbedIntoTree(AliESDEvent* pESD, const char* name, const char* title)
238 // see header file for class documentation
240 TTree* pTree=new TTree(name, title);
242 pESD->WriteToTree(pTree);
244 pTree->GetUserInfo()->Add(pESD);
250 pTree->GetUserInfo()->Clear();
257 AliHLTEsdManagerImplementation::AliHLTEsdListEntry::AliHLTEsdListEntry(AliHLTComponentDataType dt)
267 // see header file for class documentation
270 AliHLTEsdManagerImplementation::AliHLTEsdListEntry::~AliHLTEsdListEntry()
272 // see header file for class documentation
273 if (fpEsd) delete fpEsd;
276 if (fpTree) delete fpTree;
286 bool AliHLTEsdManagerImplementation::AliHLTEsdListEntry::operator==(AliHLTComponentDataType dt) const
288 // see header file for class documentation
292 int AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteESD(AliESDEvent* pSrcESD, int eventno)
294 // see header file for class documentation
297 #ifndef HAVE_NOT_ESD_COPY
298 if (fName.IsNull()) {
299 // this is the first event, create the file name
301 if (!fDirectory.IsNull()) {
302 fName+=fDirectory; fName+="/";
304 fName+="Ali"; fName+=GetPrefix();
305 if (fDt!=kAliHLTDataTypeESDObject &&
306 fDt!=kAliHLTDataTypeESDTree) {
308 HLTWarning("non-standard ESD type %s", AliHLTComponent::DataType2Text(fDt).c_str());
310 id.Insert(0, fDt.fID, kAliHLTComponentDataTypefIDsize);
311 id.Remove(TString::kTrailing, ' ');
313 fName+="_"; fName+=id; fName+=".root";
318 fpFile=new TFile(fName, "RECREATE");
319 fpTree=new TTree("esdTree", "Tree with HLT ESD objects");
320 fpTree->SetDirectory(0);
321 fpEsd=new AliESDEvent;
323 fpEsd->CreateStdContent();
326 fpEsd->WriteToTree(fpTree);
331 if (fpFile && fpTree && fpEsd) {
332 // synchronize and add empty events
334 int nofCurrentEvents=fpTree->GetEntries();
335 if (nofCurrentEvents<eventno) {
336 iResult=1; // indicate tree to be written
337 HLTDebug("adding %d empty events to file %s", eventno-nofCurrentEvents, fName.Data());
338 for (int i=nofCurrentEvents; i<eventno; i++) {
343 if (iResult>=0 && pSrcESD) {
344 int nofObjects=fpEsd->GetList()->GetEntries();
346 if (nofObjects!=fpEsd->GetList()->GetEntries()) {
347 // The source ESD contains object not present in the target ESD
348 // before. Those objects will not be written to the tree since
349 // the branch layout has been created earlier.
350 // Create new tree with the additional branches, copy the entries
351 // of the current tree into the new tree, and continue.
352 TTree* pNewTree=new TTree("esdTree", "Tree with HLT ESD objects");
353 pNewTree->SetDirectory(0);
354 AliESDEvent* readESD=new AliESDEvent;
355 readESD->CreateStdContent();
356 readESD->ReadFromTree(fpTree);
358 fpEsd->WriteToTree(pNewTree);
359 HLTDebug("cloning tree with %d entries", fpTree->GetEntries());
360 for (int event=0; event<fpTree->GetEntries(); event++) {
361 fpTree->GetEntry(event);
370 fpFile=new TFile(fName, "RECREATE");
373 HLTDebug("new ESD with %d objects", fpEsd->GetList()->GetEntries());
376 iResult=1; // indicate tree to be written
381 fpTree->GetUserInfo()->Add(fpEsd);
382 fpTree->Write(fpTree->GetName(),TObject::kOverwrite);
383 fpTree->GetUserInfo()->Clear();
386 #else //HAVE_NOT_ESD_COPY
387 // this is the old workaround, necessary for older AliRoot versions
388 // version<=v4-12-Release
390 // we need to copy the ESD, I did not find an approptiate
391 // method, the workaround is to save the ESD in a temporary
392 // tree, read the content back into the ESD structure
394 // Unfortunately the following code crashes at the second event.
395 // The expert on the ESD (Christian Klein Boesig) does not have
396 // a solution either. It seems to be a problem in ROOT.
397 // TTree* dummy=new TTree("dummy","dummy");
398 // dummy->SetDirectory(0);
399 // pESD->WriteToTree(dummy);
401 // dummy->GetUserInfo()->Add(pESD);
402 // fpEsd->ReadFromTree(dummy);
403 // dummy->GetEvent(0);
404 // fpEsd->WriteToTree(fpTree);
406 // dummy->GetUserInfo()->Clear();
409 // The only way is via TChain, which is working on files only at the
411 // We use temporary files for the new event to be copied into the
414 if (fName.IsNull()) {
415 // this is the first event, create the file on disk and write ESD
417 origin.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize);
418 origin.Remove(TString::kTrailing, ' ');
421 if (!fDirectory.IsNull()) {
422 fName+=fDirectory; fName+="/";
424 fName+="AliHLT"; fName+=origin;
425 if (fDt!=kAliHLTDataTypeESDObject &&
426 fDt!=kAliHLTDataTypeESDTree) {
428 HLTWarning("non-standard ESD type %s", AliHLTComponent::DataType2Text(fDt).c_str());
430 id.Insert(0, fDt.fID, kAliHLTComponentDataTypefIDsize);
431 id.Remove(TString::kTrailing, ' ');
433 fName+="_"; fName+=id; fName+=".root";
438 if (!gSystem->AccessPathName(fName)) {
439 // file exists, delete
440 TString shellcmd="rm -f ";
442 gSystem->Exec(shellcmd);
446 TChain chain("esdTree");
450 int nofCurrentEvents=0;
452 if (!gSystem->AccessPathName(fName)) {
453 // these are the other events, use the target file and temporary files to merge
459 if (!file.IsZombie()) {
461 file.GetObject("esdTree", pSrcTree);
463 nofCurrentEvents=pSrcTree->GetEntries();
471 // synchronize and add empty events
472 if (nofCurrentEvents<eventno) {
473 iResult=1; // indicate files to merge
474 TTree* pTgtTree=new TTree("esdTree", "Tree with HLT ESD objects");
476 pTgtTree->SetDirectory(0);
477 AliESDEvent* pTmpESD=new AliESDEvent;
480 FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
484 cleanup.Add(new TObjString(tmpfilename));
485 TFile emptyevents(tmpfilename, "RECREATE");
486 if (!emptyevents.IsZombie()) {
487 pTmpESD->CreateStdContent();
488 pTmpESD->WriteToTree(pTgtTree);
489 HLTDebug("adding %d empty events to file %s", eventno-nofCurrentEvents, fName.Data());
490 for (int i=nofCurrentEvents; i<eventno; i++) {
493 pTgtTree->GetUserInfo()->Add(pTmpESD);
497 chain.Add(tmpfilename);
498 pTgtTree->GetUserInfo()->Clear();
511 if (iResult>=0 && pSrcESD) {
512 // add the new event to the chain
513 iResult=1; // indicate files to merge
514 TString tmpfilename=WriteTempFile(pSrcESD);
515 if (!tmpfilename.IsNull()) {
516 chain.Add(tmpfilename);
517 cleanup.Add(new TObjString(tmpfilename));
522 // build temporary file name for chain output
524 FILE* pTmpFile=gSystem->TempFileName(tgtName);
529 // there have been problems with the memory consumption when using
531 // but using a separate loop soemtimes crashes in AliESDEvent::ReadFromTree
532 // since this is for backward compatiblity only, we take the TChain::Merge
533 chain.Merge(tgtName);
534 // TFile tgtFile(tgtName, "RECREATE");
535 // TTree* pTgtTree=new TTree("esdTree", "Tree with HLT ESD objects");
536 // AliESDEvent* pTgtESD=new AliESDEvent;
537 // if (pTgtTree && pTgtESD) {
538 // pTgtESD->ReadFromTree(&chain);
539 // pTgtESD->WriteToTree(pTgtTree);
541 // int nofEvents=chain.GetEntries();
542 // for (int event=0; event<nofEvents; event++) {
543 // chain.GetEntry(event);
547 // pTgtTree->GetUserInfo()->Add(pTgtESD);
549 // pTgtTree->Write();
550 // pTgtTree->GetUserInfo()->Clear();
555 // if (pTgtTree) delete pTgtTree;
556 // if (pTgtESD) delete pTgtESD;
559 // rename the merged file to the original file
560 TString shellcmd="mv ";
561 shellcmd+=tgtName + " " + fName;
562 if (gSystem->Exec(shellcmd)==0) {
563 HLTDebug("renaming %s to %s", tgtName.Data(), fName.Data());
565 HLTError("can not rename temporary file %s to %s", tgtName.Data(), fName.Data());
568 HLTError("can not get temporary file name from system");
573 // delete temporary files
574 // the list objects are cleaned up by the TList destructor as the
576 TIter entry(&cleanup);
577 while (TObject* pObj=entry.Next()) {
578 if (dynamic_cast<TObjString*>(pObj)) {
579 TString shellcmd="rm -f ";
580 shellcmd+=(dynamic_cast<TObjString*>(pObj))->GetString();
581 gSystem->Exec(shellcmd);
584 #endif //HAVE_NOT_ESD_COPY
589 TString AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteTempFile(AliESDEvent* pESD) const
591 // see header file for class documentation
594 FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
599 TFile file(tmpfilename, "RECREATE");
600 if (!file.IsZombie()) {
601 TTree* pTree=AliHLTEsdManagerImplementation::EmbedIntoTree(pESD);
604 if (pTree->Write()>0) {
606 HLTError("can not write esd tree to temporary file %s", tmpfilename.Data());
609 pTree->GetUserInfo()->Clear();
616 HLTError("can not open file %s", tmpfilename.Data());
620 HLTError("can not get temporary file name from system");
625 if (gSystem->AccessPathName(tmpfilename)==0) {
626 TString shellcmd="rm -f ";
627 shellcmd+=tmpfilename;
628 gSystem->Exec(shellcmd);
635 void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::SetDirectory(const char* directory)
637 // see header file for class documentation
638 if (!directory) return;
639 if (!fName.IsNull()) {
640 HLTWarning("ESD entry already in writing mode (%s), ignoring directory", fName.Data());
643 fDirectory=directory;
646 void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::Delete()
648 // see header file for class documentation
649 if (fName.IsNull()) return;
650 if (gSystem->AccessPathName(fName)!=0) return;
652 TString shellcmd="rm -f ";
654 gSystem->Exec(shellcmd);
658 const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetFileName() const
660 // see header file for class documentation
664 const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetPrefix()
666 // see header file for class documentation
667 if (fPrefix.IsNull()) {
668 fPrefix.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize);
669 fPrefix.Remove(TString::kTrailing, ' ');
671 if (!fPrefix.Contains("HLT")) {
672 fPrefix.Insert(0, "HLT");
675 return fPrefix.Data();
678 int AliHLTEsdManagerImplementation::Merge(AliESDEvent* pTgt, AliESDEvent* pSrc) const
680 // see header file for class documentation
682 if (!pTgt || !pSrc) return -EINVAL;
684 TIter next(pSrc->GetList());
685 TObject* pSrcObject=NULL;
686 static int warningCount=0;
687 while ((pSrcObject=next())) {
688 if(!pSrcObject->InheritsFrom("TCollection")){
690 // for every type of object we have to find out whether it is empty or not
691 // objects are only copied if non-empty, otherwise valid content would be
692 // overridden by empty objects during the merging
694 TString name=pSrcObject->GetName();
695 if(pSrcObject->InheritsFrom("AliHLTTriggerDecision")){
697 } else if (pSrcObject->IsA()==AliESDRun::Class()) {
698 AliESDRun* pESDRun=dynamic_cast<AliESDRun*>(pSrcObject);
699 // zero might be a valid run no in simulation, so we check also whether the CTP trigger classes are set
700 copy=(pESDRun && (pESDRun->GetRunNumber()>0 || !pESDRun->GetActiveTriggerClasses().IsNull()));
701 } else if (pSrcObject->IsA()==AliESDHeader::Class()) {
702 AliESDHeader* pESDHeader=dynamic_cast<AliESDHeader*>(pSrcObject);
703 copy=(pESDHeader && pESDHeader->GetTriggerMask()!=0);
704 } else if (pSrcObject->IsA()==AliESDVertex::Class()) {
705 AliESDVertex* pESDVertex=dynamic_cast<AliESDVertex*>(pSrcObject);
706 copy=(pESDVertex && pESDVertex->GetNContributors()>0);
707 } else if (pSrcObject->IsA()==AliESDTZERO::Class()) {
708 AliESDTZERO* pESDTZero=dynamic_cast<AliESDTZERO*>(pSrcObject);
709 copy=(pESDTZero && (pESDTZero->GetT0zVertex()!=0.0 || pESDTZero->GetT0()!=0.0));
710 } else if (pSrcObject->IsA()==AliESDVZERO::Class()) {
711 AliESDVZERO* pESDVZero=dynamic_cast<AliESDVZERO*>(pSrcObject);
712 copy=(pESDVZero && false); // could not find an easy valid condition
713 } else if (pSrcObject->IsA()==AliESDFMD::Class()) {
714 AliESDFMD* pESDFMD=dynamic_cast<AliESDFMD*>(pSrcObject);
715 copy=(pESDFMD && false); // have to find an easy valid condition
716 } else if (pSrcObject->IsA()==AliESDZDC::Class()) {
717 AliESDZDC* pESDZDC=dynamic_cast<AliESDZDC*>(pSrcObject);
718 copy=(pESDZDC && false); // have to find an easy valid condition
719 } else if (pSrcObject->IsA()==AliMultiplicity::Class()) {
720 AliMultiplicity* pMultiplicity=dynamic_cast<AliMultiplicity*>(pSrcObject);
721 copy=(pMultiplicity && pMultiplicity->GetNumberOfTracklets()>0);
722 } else if (pSrcObject->IsA()==AliESDCaloTrigger::Class()) {
723 AliESDCaloTrigger* pESDCaloTrigger=dynamic_cast<AliESDCaloTrigger*>(pSrcObject);
724 copy=(pESDCaloTrigger && false); // have to find an easy valid condition
725 } else if (pSrcObject->IsA()==AliESDCaloCells::Class()) {
726 AliESDCaloCells* pESDCaloCells=dynamic_cast<AliESDCaloCells*>(pSrcObject);
727 copy=(pESDCaloCells && false); // have to find an easy valid condition
728 } else if (pSrcObject->IsA()==AliESDACORDE::Class()) {
729 AliESDACORDE* pESDACORDE=dynamic_cast<AliESDACORDE*>(pSrcObject);
730 copy=(pESDACORDE && false); // have to find an easy valid condition
731 } else if (!AliHLTESDEventHelper::IsStdContent(name)) {
732 // this is likely to be ok as long as it is not any object of the std content.
735 HLTError("no merging implemented for object %s, omitting", name.Data());
738 //pSrcObject->Print();
739 TObject* pTgtObject=pTgt->FindListObject(name);
741 pSrcObject->Copy(*pTgtObject);
743 pTgt->AddObject(pSrcObject->Clone());
746 } else if(pSrcObject->InheritsFrom("TClonesArray")){
747 TClonesArray* pTClA=dynamic_cast<TClonesArray*>(pSrcObject);
748 if (pTClA!=NULL && pTClA->GetEntriesFast()>0) {
749 TString name=pTClA->GetName();
750 TObject* pTgtObject=pTgt->GetList()->FindObject(name);
751 TClonesArray* pTgtArray=NULL;
752 if (pTgtObject!=NULL && pTgtObject->InheritsFrom("TClonesArray")){
753 pTgtArray=dynamic_cast<TClonesArray*>(pTgtObject);
755 TString classType=pTClA->Class()->GetName();
756 if (classType.CompareTo(pTgtArray->Class()->GetName())==0) {
757 if (pTgtArray->GetEntries()==0) {
758 pTgtArray->ExpandCreate(pTClA->GetEntries());
759 for(int i=0; i<pTClA->GetEntriesFast(); ++i){
760 (*pTClA)[i]->Copy(*((*pTgtArray)[i]));
763 if (warningCount++<10) {
764 HLTWarning("TClonesArray \"%s\" in target ESD %p is already filled with %d entries",
765 name.Data(), pTgt, pTgtArray->GetEntries());
770 if (warningCount++<10) {
771 HLTWarning("TClonesArray \"%s\" exists in target ESD %p, but describes incompatible class type %s instead of %s",
772 name.Data(), pTgt, pTgtArray->GetClass()->GetName(), pTClA->GetClass()->GetName());
777 if (warningCount++<10) {
778 HLTError("internal error: dynamic cast failed for object %s %p", pTgtObject->GetName(), pTgtObject);
782 } else if (pTgtObject) {
783 if (warningCount++<10) {
784 HLTWarning("object \"%s\" does already exist in target ESD %p, but is %s rather than TClonesArray"
786 name.Data(), pTgt, pTgtObject->Class()->GetName());
790 if (warningCount++<10) {
791 HLTWarning("object \"%s\" does not exist in target ESD %p, data can not be copied because it will be lost when filling the tree",
802 bool AliHLTEsdManagerImplementation::AliHLTESDEventHelper::IsStdContent(const char* key)
804 // check if the key denotes a std object
806 for (int i=0; i<kESDListN; i++) {
807 if (needle.CompareTo(fgkESDListName[i])==0) return true;