#include "IAnalyzeTreesMain.hxx" #include "ITreeAnalyzerFactory.hxx" #include "IBeamlineParameterExtractor.hxx" #include "IParticleTagRegister.hxx" #include #include #include #include #include #include #include #include #include #include #include #include COMET::IAnalyzeTreesMain::IAnalyzeTreesMain(): fInputTreeName("COMETEventsSummary"), fOutputFileName("tree_analysis.root"), fParamFile(""), fEntriesToRead(0), fPrintEntry(1000), fInputChain(NULL) { } COMET::IAnalyzeTreesMain::~IAnalyzeTreesMain(){ delete fInputChain; } void COMET::IAnalyzeTreesMain::PrintUsage(){ COMETLog("Usage: \n" <>fPrintEntry; break; case 'p': fParamFile=optarg; break; case 'o': fOutputFileName=std::string(optarg); break; case 't': fInputTreeName=std::string(optarg); break; case 'n': sstream>>fEntriesToRead; break; case 'E': fBranchWhiteList.insert(value); break; case 'D': fBranchBlackList.insert(value); break; case 'u': if(!COMET::ITreeAnalyzerFactory::Instance().Enable(value)) return kErrorStop; break; case 'd': if(!COMET::ITreeAnalyzerFactory::Instance().Disable(value)) return kErrorStop; break; case 'I': return ParseInputFileList(value); break; case 'h': PrintUsage(); return kNoErrorStop; default: std::cout<<"Error: Unknown option "<GetNtrees()<<" files will be studied"); if(!fParamFile.empty()){ COMET::IOARuntimeParameters::Get().ReadParamOverrideFile(fParamFile); } std::map data; status=PrepareData(data); if(Terminate(status)) return false; status=SetupAnalyzers(data); if(Terminate(status)) return false; DisableUnusedBranches(); return true; } COMET::IAnalyzeTreesMain::Terminate_t COMET::IAnalyzeTreesMain::ProcessAllOptions(int argc,char* argv[]){ for (;;) { int opt = getopt(argc, argv, GetOptionString().c_str()); if (opt<0) break; Terminate_t status=ProcessOption(opt,optarg); if(Terminate(status)) return status; } for(; optind& file_list, const std::string& tree_name){ // Open the input file(s) TChain* inChain=new TChain(tree_name.c_str()); int n_added=0; for(size_t i=0; iAdd(file_list.at(i).c_str()); if(added<=0){ COMETError("Filename (or glob): "<GetNtrees()<=0 || inChain->LoadTree(0)){ COMETError("No valid input filename(s) provided."); return NULL; } return inChain; } COMET::IAnalyzeTreesMain::Terminate_t COMET::IAnalyzeTreesMain::PrepareData( std::map& data){ // It seems we need to do both of these for the chain to work with more than one // input file. Doesn't seem to be documented anywhere though... const long int entries=fInputChain->GetEntries(); fInputChain->LoadTree(0); COMETLog("Input file(s) contain :"<GetListOfBranches()); TObject* object; while((object=next())){ TBranch* branch=(TBranch*)object; if(!branch) continue; std::string name=branch->GetName(); if(branch->GetClassName()!=std::string("TClonesArray")) continue; if(!fBranchWhiteList.empty()){ if(fBranchWhiteList.find(branch->GetName())==fBranchWhiteList.end()) continue; }else if (fBranchBlackList.find(branch->GetName())!=fBranchBlackList.end()) continue; COMET::analysis::ListOfClonesArrays::iterator i_data= fClonesArrays.insert(std::make_pair(name,COMET::analysis::TreeData())).first; const TClonesArray*& array=i_data->second.array; fInputChain->SetBranchAddress(name.c_str(),&array,&i_data->second.branch); branch->SetAddress(&array); for(int i=0; !array && i<100;++i)branch->GetEntry(i); if(!array){ COMETError("Problem identifying data type for branch: "<GetName()); return kErrorStop; } data[branch->GetName()]=array->GetClass()->GetName(); COMETLog("Analyzing: "<GetName()<<" of type: "<GetClass()->GetName()); } fInputChain->LoadTree(0); bool ok=COMET::IParticleTagRegister::InitFromFile(fInputChain->GetFile()); if(!ok) return kErrorStop; COMETLog("Valid tags are:"); COMET::IParticleTagRegister::Instance().PrintAllTags(); return kNoErrorContinue; } COMET::IAnalyzeTreesMain::Terminate_t COMET::IAnalyzeTreesMain::SetupAnalyzers( std::map& data){ // Create TreeAnalyzers for the input data COMET::ITreeAnalyzerFactory::Instance().GetAnalyzers(data,fAnalyzers); if(fAnalyzers.empty()){ COMETError("No valid analyzers were created"); COMET::ITreeAnalyzerFactory::Instance().PrintKnownTypes(); return kErrorStop; } fOutputFile=TFile::Open(fOutputFileName.c_str(),"CREATE"); if(!fOutputFile || fOutputFile->IsZombie()){ COMETError("Problem opening output file"); return kErrorStop; } bool ok=true; for(AnalyzerList::const_iterator i_analyzer=fAnalyzers.begin(); i_analyzer!=fAnalyzers.end(); ++i_analyzer){ ok&=(*i_analyzer)->Initialise(fClonesArrays,*this); } if(!ok) return kErrorStop; return kNoErrorContinue; } void COMET::IAnalyzeTreesMain::DisableUnusedBranches(){ std::set used_data; for(AnalyzerList::const_iterator i_analyzer=fAnalyzers.begin(); i_analyzer!=fAnalyzers.end(); ++i_analyzer){ const std::set* targets=COMET::ITreeAnalyzerFactory::Instance().GetTargetDataNames((*i_analyzer)->GetName()); if(targets && !targets->empty()) used_data.insert(targets->begin(), targets->end()); else used_data.insert((*i_analyzer)->GetDatumName()); } fInputChain->SetBranchStatus("*",0); for(COMET::analysis::ListOfClonesArrays::const_iterator i_data=fClonesArrays.begin(); i_data!=fClonesArrays.end(); ++i_data){ if(used_data.find(i_data->first)==used_data.end()) continue; fInputChain->SetBranchStatus((i_data->first).c_str(),1); fInputChain->SetBranchStatus((i_data->first+".*").c_str(),1); COMETLog("Enabled branch: "<first); } } bool COMET::IAnalyzeTreesMain::Process(){ TDirectory::TContext context(0); bool ok=true; for(fCurrentEntry=0; (fEntriesToRead<1 || fCurrentEntryLoadTree(fCurrentEntry); if(read<0) break; if(read==0){ // New file opened COMET::IParticleTagRegister::InitFromFile(fInputChain->GetFile()); } read=fInputChain->GetEntry(fCurrentEntry); if(read<0){ COMETError("Problem reading in event "<Analyze(); } if(!ok) break; } return ok; } bool COMET::IAnalyzeTreesMain::Finalize(){ bool ok=true; for(AnalyzerList::const_iterator i_analyzer=fAnalyzers.begin(); i_analyzer!=fAnalyzers.end(); ++i_analyzer){ ok&=(*i_analyzer)->Finalize(); } //fOutputFile->ls(); COMETLog("Read "<Write(); fOutputFile->Write(); fOutputFile->Close(); return ok; }