//------------------------------------------------------------------------------ THStack* PlotAlignmentValidation::addHists(const char *selection, const TString &residType, bool printModuleIds) { enum ResidType { xPrimeRes, yPrimeRes, xPrimeNormRes, yPrimeNormRes, xRes, yRes, xNormRes, /*yResNorm*/ ResXvsXProfile, ResXvsYProfile, ResYvsXProfile, ResYvsYProfile }; ResidType rType = xPrimeRes; if (residType == "xPrime") rType = xPrimeRes; else if (residType == "yPrime") rType = yPrimeRes; else if (residType == "xPrimeNorm") rType = xPrimeNormRes; else if (residType == "yPrimeNorm") rType = yPrimeNormRes; else if (residType == "x") rType = xRes; else if (residType == "y") rType = yRes; else if (residType == "xNorm") rType = xNormRes; // else if (residType == "yNorm") rType = yResNorm; else if (residType == "ResXvsXProfile") rType = ResXvsXProfile; else if (residType == "ResYvsXProfile") rType = ResYvsXProfile; else if (residType == "ResXvsYProfile") rType = ResXvsYProfile; else if (residType == "ResYvsYProfile") rType = ResYvsYProfile; else { std::cout << "PlotAlignmentValidation::addHists: Unknown residual type " << residType << std::endl; return 0; } cout << "PlotAlignmentValidation::addHists: using selection " << selection << endl; THStack * retHistoStack = new THStack(); double legendY = 0.80; TLegend * myLegend = new TLegend(0.17, legendY, 0.85, 0.88); setLegendStyle( *myLegend ); for(std::vector<TkOfflineVariables*>::iterator itSourceFile = sourceList.begin(); itSourceFile != sourceList.end(); ++itSourceFile) { // TFile *f = (*sourceList.begin())->getFile(); TFile *f = (*itSourceFile)->getFile(); // TTree *tree= (*sourceList.begin())->getTree(); TTree *tree= (*itSourceFile)->getTree(); int myLineColor = (*itSourceFile)->getLineColor(); int myLineStyle = (*itSourceFile)->getLineStyle(); TString myLegendName = (*itSourceFile)->getName(); if (!f || !tree) { std::cout << "PlotAlignmentValidation::addHists: no tree or no file" << std::endl; return 0; } // Todo: TLegend? // first loop on tree to find out which entries (i.e. modules) fulfill the selection // 'Entry$' gives the entry number in the tree Long64_t nSel = tree->Draw("Entry$", selection, "goff"); if (nSel == -1) return 0; // error in selection if (nSel == 0) { std::cout << "PlotAlignmentValidation::addHists: no selected module." << std::endl; return 0; } // copy entry numbers that fulfil the selection const std::vector<double> selected(tree->GetV1(), tree->GetV1() + nSel); TH1 *h = 0; // becomes result UInt_t nEmpty = 0;// selected, but empty hists Long64_t nentries = tree->GetEntriesFast(); std::vector<double>::const_iterator iterEnt = selected.begin(); // second loop on tree: // for each selected entry get the hist from the file and merge TkOffTreeVariables *treeMem = 0; // ROOT will initialise tree->SetBranchAddress("TkOffTreeVariables", &treeMem); for (Long64_t i = 0; i < nentries; i++){ if (i < *iterEnt - 0.1 // smaller index (with tolerance): skip || iterEnt == selected.end()) { // at the end: skip continue; } else if (TMath::Abs(i - *iterEnt) < 0.11) { ++iterEnt; // take this entry! } else std::cout << "Must not happen: " << i << " " << *iterEnt << std::endl; tree->GetEntry(i); if (printModuleIds) { std::cout << treeMem->moduleId << ": " << treeMem->entries << " entries" << std::endl; } if (treeMem->entries <= 0) { // little speed up: skip empty hists ++nEmpty; continue; } TString hName; switch(rType) { case xPrimeRes: hName = treeMem->histNameX.c_str(); break; case yPrimeRes: hName = treeMem->histNameY.c_str(); break; case xPrimeNormRes: hName = treeMem->histNameNormX.c_str(); break; case yPrimeNormRes: hName = treeMem->histNameNormY.c_str(); break; case xRes: hName = treeMem->histNameLocalX.c_str(); break; case yRes: hName = treeMem->histNameLocalY.c_str(); break; case xNormRes: hName = treeMem->histNameNormLocalX.c_str(); break; /*case yResNorm: hName = treeMem->histNameNormLocalY.c_str(); break;*/ case ResXvsXProfile: hName = treeMem->profileNameResXvsX.c_str(); break; case ResXvsYProfile: hName = treeMem->profileNameResXvsY.c_str(); break; case ResYvsXProfile: hName = treeMem->profileNameResYvsX.c_str(); break; case ResYvsYProfile: hName = treeMem->profileNameResYvsY.c_str(); break; } TKey *histKey = f->FindKeyAny(hName); TH1 *newHist = (histKey ? static_cast<TH1*>(histKey->ReadObj()) : 0); if (!newHist) { std::cout << "Hist " << hName << " not found in file, break loop." << std::endl; break; } newHist->SetLineColor(myLineColor); newHist->SetLineStyle(myLineStyle); if (!h) { // first hist: clone, but rename keeping only first part of name TString name(newHist->GetName()); Ssiz_t pos_ = 0; for (UInt_t i2 = 0; i2 < 3; ++i2) pos_ = name.Index("_", pos_+1); name = name(0, pos_); // only up to three '_' h = static_cast<TH1*>(newHist->Clone("summed_"+name)); // TString myTitle = Form("%s: %lld modules", selection, nSel); // h->SetTitle( myTitle ); } else { // otherwise just add h->Add(newHist); } delete newHist; } std::cout << "PlotAlignmentValidation::addHists" << "Result is merged from " << nSel-nEmpty << " modules, " << nEmpty << " hists were empty." << std::endl; if (nSel-nEmpty == 0) continue; myLegend->AddEntry(myLegendName, myLegendName, "L"); retHistoStack->Add(h); } myLegend->Draw(); return retHistoStack; }