void dump_required_lvl2(TTree *tree, TLeaf &leaf, CodedOutputStream &o, CodedOutputStream &o2) { const int DL = 1; // definition level multiplier const int RL = 4; // repetition level multiplier std::cout << "Dump vector vector: " << leaf.GetName() << " " << leaf.GetTypeName() << std::endl; auto * branch = leaf.GetBranch(); std::vector<std::vector<T> > * data = NULL; tree->SetBranchAddress(leaf.GetBranch()->GetName(), &data); int entries = tree->GetEntries(); for (int i = 0; i < entries; i++) { branch->GetEntry(i); if (data->size() == 0) { write_out_32(o2, DL*0 + RL*0); } for (int j = 0; j < data->size(); j++) { if (data->at(j).size() == 0) { int dl = 1; int rl = (j > 0 ? 1 : 0); write_out_32(o2, dl*DL + rl*RL); } for (int k = 0; k < data->at(j).size(); k++) { int dl = 2; int rl = (k > 0 ? 2 : (j > 0 ? 1 : 0)); write_out_32(o2, dl*DL + rl*RL); write_out_type(o, data->at(j).at(k)); } } } }
// This piece of code is borrowed from Argo written by Nathaniel Tagg std::vector<std::string> DataFetcher::FindLeavesOfType(std::string pattern) { /// Look in the tree and try to find a leaf element that matches 'pattern'. /// Return the full name of that leaf. std::vector<std::string> leaf_names; // Strip whitespace from pattern. pattern.erase(std::remove_if(pattern.begin(), pattern.end(), ::isspace), pattern.end()); TObjArray * list = tree_->GetListOfLeaves(); for (int i = 0; i < list->GetEntriesFast(); ++i) { TObject * o = list->At(i); TLeaf * leaf = (TLeaf *) o; std::string name = leaf->GetTypeName(); // Strip whitespace from pattern. name.erase(std::remove_if(name.begin(), name.end(), ::isspace), name.end()); size_t found = name.find(pattern); if (found != std::string::npos) { // Return this match. leaf_names.push_back(leaf->GetName()); } } return leaf_names; }
void GAInputTreeData::SetBranchAddressToHolder(string branch_name){ if(!fTTree->GetBranch(branch_name.c_str())){ cout << "[GAInputTreeData-E]: branch " << branch_name << " is not found"; throw 1; } fBranchName.push_back(branch_name); TLeaf *leaf = fTTree->GetBranch(branch_name.c_str()) ->GetLeaf(branch_name.c_str()); Int_t n_data = leaf->GetNdata(); string type_name = leaf->GetTypeName(); fEventDataHolderManager->AddDetector(type_name,branch_name, n_data); }
void GAInputTreeData::SetAllBranches(){ TObjArray* ArrayOfBranches = fTTree->GetListOfBranches(); Int_t n_branch = ArrayOfBranches->GetEntries(); cout << "[GAInputTreeData-M]:Loading " << n_branch << " branches from " << fTTree->GetName() << endl; for(int i_branch=0; i_branch<n_branch; i_branch++){ TBranch* Branch = (TBranch*)ArrayOfBranches->At(i_branch); string branch_name = Branch->GetName(); TLeaf *leaf = (TLeaf*)Branch->GetListOfLeaves()->At(0);//(branch_name.c_str()); Int_t n_data = leaf->GetNdata(); string type_name = leaf->GetTypeName(); fBranchName.push_back(branch_name); fEventDataHolderManager->AddDetector(type_name, branch_name, n_data); cout << "[GAInputTreeData-M]:Loading branch " << branch_name << " (" << type_name << "[" << n_data << "])" << endl; } }
//std::mutex mtx; void ProcessFilePar(TString fileIn, TString fileOut, TString treename, vector<TString> friends, vector<TString> branches, vector<TString> newbranches, unsigned jobid = 0, unsigned NPAR = 1) { //mtx.lock(); //for threads TFile *fin = new TFile(fileIn); TTree *tjet = (TTree*)fin->Get(treename); //mtx.unlock(); vector<TTree *> friendTrees; vector<bool> sameFileFriend; for (auto f:friends) { auto fr = tokenize(f,":"); if (fr.size()==1) {tjet->AddFriend(fr[0]); sameFileFriend.push_back(true);} else if (fr.size()==2) {tjet->AddFriend(fr[1],fr[0]); sameFileFriend.push_back(false);} TTree *tfriend = (TTree*)fin->Get(f); friendTrees.push_back(tfriend); } AddBranchesByCounter(tjet, branches); for (unsigned i=0;i<friendTrees.size();i++) AddBranchesByCounter(friendTrees[i],branches); //sort branches into categories for (auto bName:branches) { TBranch *b=tjet->GetBranch(bName); if (b==0) cout <<"Branch "<<bName<<" doesn't exist!"<<endl; //parse in case there is a tree name in the branch auto branchtoken = tokenize(bName,"."); auto leafname = branchtoken[branchtoken.size()-1]; TObjArray *bl = b->GetListOfLeaves(); if (bl->GetEntries()>1) cout <<" Branch "<<b->GetTitle()<<" has more than 1 leave. Taking first..."<<endl; if (bl->GetEntries()==0) { cout <<" Branch "<<b->GetTitle()<<" has no leaves! Skipping..."<<endl; continue; } TLeaf * l = (TLeaf *)(*bl)[0]; //what's the type? TString type = l->GetTypeName(); if (VERBOSE) cout<<l->GetTitle()<<endl; //array? bool array = l->GetLeafCount()!=0; TString counter; if (array) counter = l->GetLeafCount()->GetBranch()->GetName(); if (type=="Float_t") { if (array) {brVFloat.push_back(bName); brVFloatCounter.push_back(counter); }else brFloat.push_back(bName);} else if (type=="Int_t") { if (array) {brVInt.push_back(bName); brVIntCounter.push_back(counter); }else brInt.push_back(bName);} else cout << "Unsupported branch type "<<type<<" for branch "<<bName<<". Skipping..."<<endl; } //treat counters as ints only AppendToListUniquely(brVIntCounter, brInt); AppendToListUniquely(brVFloatCounter, brInt); //too keep track of old branches, which cannot be read (todo: just check it...) int noldbrInt = brInt.size(), noldbrFloat = brFloat.size(), noldbrVInt = brVInt.size(), noldbrVIntCounter = brVIntCounter.size(), noldbrVFloat = brVFloat.size(), noldbrVFloatCounter = brVFloatCounter.size(); //add new branches ParseNewBranches(newbranches, brInt, brFloat, brVInt, brVIntCounter, brVFloat, brVFloatCounter); //print for debugging if (VERBOSE) { cout<<"int : "; for (auto s:brInt) cout <<s<<", "; cout<<endl; cout<<"float : "; for (auto s:brFloat) cout <<s<<", "; cout<<endl; cout<<"Vint : "; for (auto s:brVInt) cout <<s<<", "; cout<<endl; cout<<"Vfloat : "; for (auto s:brVFloat) cout <<s<<", "; cout<<endl; cout<<"Vintcnt : "; for (auto s:brVIntCounter) cout <<s<<", "; cout<<endl; cout<<"Vfloatcnt : "; for (auto s:brVFloatCounter) cout <<s<<", "; cout<<endl; } tjet->SetBranchStatus("*",1); for (auto b:brVFloat) if (tjet->GetBranch(b)!=0) tjet->SetBranchStatus(b,0); for (auto b:brFloat) if (tjet->GetBranch(b)!=0) tjet->SetBranchStatus(b,0); for (auto b:brVInt) if (tjet->GetBranch(b)!=0) tjet->SetBranchStatus(b,0); for (auto b:brInt) if (tjet->GetBranch(b)!=0) {unsigned f=0; tjet->SetBranchStatus(b,0,&f); if (VERBOSE) cout<<"turning off "<<b<<", found = "<<f<<endl;} TFile *fout = new TFile(fileOut,"recreate"); TTree *tjetout; //in case of one-to-many event - do not copy branches automatically! if (useOneToOne) tjetout = tjet->CloneTree(0); else tjetout = new TTree(tjet->GetName(),tjet->GetTitle()); //think about memory tree // tjetout->SetDirectory(0); tjetout->SetName(tjet->GetName()); //TTree *tjetout = new TTree("t","t"); //to see what is copied... //tjetout->Print(); for (auto b:brVFloat) if (tjet->GetBranch(b)!=0) tjet->SetBranchStatus(b,1); for (auto b:brFloat) if (tjet->GetBranch(b)!=0) tjet->SetBranchStatus(b,1); for (auto b:brVInt) if (tjet->GetBranch(b)!=0) tjet->SetBranchStatus(b,1); for (auto b:brInt) if (tjet->GetBranch(b)!=0) tjet->SetBranchStatus(b,1); vector<int> valIntIn(brInt.size()), valIntOut(brInt.size()); vector<float> valFloatIn(brFloat.size()), valFloatOut(brFloat.size()); vector<vector<int> >valVIntIn (brVInt.size()); vector<vector<int> >valVIntOut (brVInt.size()); vector<vector<float> >valVFloatIn (brVFloat.size()); vector<vector<float> >valVFloatOut (brVFloat.size()); for (unsigned i=0;i<brInt.size();i++) { if (tjet->GetBranch(brInt[i])!=0) tjet->SetBranchAddress(brInt[i],&valIntIn[i]); if (tjetout->GetBranch(brInt[i])!=0) {//why would it? tjetout->SetBranchAddress(brInt[i],&valIntOut[i]); cout<<"branch "<<brInt[i]<<" already exist for some reason..."<<endl; } else //logical... if (NonFriendBranch(tjet, brInt[i])) tjetout->Branch(brInt[i],&valIntOut[i],Form("%s/I",brInt[i].Data())); } for (unsigned i=0;i<brFloat.size();i++) { if (tjet->GetBranch(brFloat[i])!=0) tjet->SetBranchAddress(brFloat[i],&valFloatIn[i]); if (NonFriendBranch(tjet, brFloat[i])) tjetout->Branch(brFloat[i],&valFloatOut[i],Form("%s/F",brFloat[i].Data())); } for (unsigned i=0;i<brVFloat.size();i++) { if (tjet->GetBranch(brVFloat[i])!=0) { valVFloatIn[i] = vector<float>(NMAX); tjet->SetBranchAddress(brVFloat[i],&valVFloatIn[i][0]); } valVFloatOut[i] = vector<float>(NMAX); if (NonFriendBranch(tjet, brVFloat[i])) tjetout->Branch(brVFloat[i],&valVFloatOut[i][0],Form("%s[%s]/F",brVFloat[i].Data(),brVFloatCounter[i].Data())); } for (unsigned i=0;i<brVInt.size();i++) { if (tjet->GetBranch(brVInt[i])) { valVIntIn[i] = vector<int>(NMAX); tjet->SetBranchAddress(brVInt[i],&valVIntIn[i][0]); } valVIntOut[i] = vector<int>(NMAX); if (NonFriendBranch(tjet, brVInt[i])) tjetout->Branch(brVInt[i],&valVIntOut[i][0],Form("%s[%s]/I",brVInt[i].Data(),brVIntCounter[i].Data())); } Long64_t nentries = tjet->GetEntries(); int nentries1 = nentries/NPAR*jobid; int nentries2 = nentries/NPAR*(jobid+1); nentries = nentries2-nentries1; int oneperc = nentries/100; if (oneperc==0) oneperc = 1; cout<<"Start processing..."<<endl; TStopwatch s; s.Start(); TTimeStamp t0; double readTime = 0, processingTime = 0, copyToTime = 0, cloneTime=0, copyFromTime=0, fillTime = 0; for (Long64_t i=0; i<nentries;i++) { if (jobid==0 && i % oneperc == 0 && i>0) { std::cout << std::fixed; TTimeStamp t1; cout<<" \r"<<i/oneperc<<"% "<<" est. time "<<setprecision(2) <<(t1-t0)*nentries/(i+.1)<<" s "; cout<<";Processing:"<<setprecision(2)<<processingTime/(t1-t0)*100<<" %"; cout<<";Copy1:"<<setprecision(2) <<copyToTime/(t1-t0)*100<<" %"; cout<<";Clone:"<<setprecision(2) <<cloneTime/(t1-t0)*100<<" %"; cout<<";Copy2:"<<setprecision(2) <<copyFromTime/(t1-t0)*100<<" %"; cout<<";Fill:"<<setprecision(2) <<fillTime/(t1-t0)*100<<" %"; cout<<";Read:"<<setprecision(2) <<readTime/(t1-t0)*100<<" %"; cout<<flush; } TTimeStamp tsRead0; tjet->GetEntry(i+nentries1); TTimeStamp tsRead1; readTime+=tsRead1-tsRead0; Everything ev; TTimeStamp tsCpTo0; for (unsigned j=0;j<brInt.size();j++) ev.PutInt(brInt[j],valIntIn[j]); for (unsigned j=0;j<brFloat.size();j++) ev.PutFloat(brFloat[j],valFloatIn[j]); for (unsigned j=0;j<brVFloat.size();j++) ev.PutVFloat(brVFloat[j],brVFloatCounter[j],valVFloatIn[j]); for (unsigned j=0;j<brVInt.size();j++) ev.PutVInt(brVInt[j],brVIntCounter[j],valVIntIn[j]); TTimeStamp tsCpTo1; copyToTime+=tsCpTo1-tsCpTo0; TTimeStamp tsCl0; //think about: copy object (timing 10% ->3%) //but it copies vectors, so push_back will add in the end... // Everything evout = ev; //or even reference(in place?) (->0.2%) //Everything &evout = ev; Everything evout = ev.CloneStructure(); TTimeStamp tsCl1; cloneTime+=tsCl1-tsCl0; bool exitEvent = false; int counter = 0; while (!exitEvent) { TTimeStamp tsPr0; if (useOneToOne) { fProcessOneToOne(ev, evout); evout.UpdateCounters(); exitEvent = true; } else { exitEvent = fProcessOneToMany(ev, evout, counter); // if (!exitEvent) cout<<"event to write "<<counter<<endl; counter++; } TTimeStamp tsPr1; processingTime+=tsPr1-tsPr0; //Everything evout = ev; TTimeStamp tsCpFrom0; for (unsigned j=0;j<brInt.size();j++) valIntOut[j] = evout.GetInt(brInt[j]); for (unsigned j=0;j<brFloat.size();j++) {valFloatOut[j] = evout.GetFloat(brFloat[j]); // cout<<brFloat[j]<<" "<<evout.GetFloat(brFloat[j])<<endl; } for (unsigned j=0;j<brVFloat.size();j++) valVFloatOut[j] = evout[brVFloat[j]]; for (unsigned j=0;j<brVInt.size();j++) valVIntOut[j] = evout.GetVInt(brVInt[j]); TTimeStamp tsCpFrom1; copyFromTime+=tsCpFrom1-tsCpFrom0; TTimeStamp tsFill0; tjetout->Fill(); TTimeStamp tsFill1; fillTime+=tsFill1-tsFill0; } } cout<<endl; s.Stop(); cout<<"Done in ";s.Print(); tjetout->FlushBaskets(); tjetout->Write(); cout<<"Copying other trees..."<<endl; for (unsigned i=0;i<friendTrees.size();i++) { TTree *t = friendTrees[i]; if (sameFileFriend[i]) { //TTree *triendout = t->CloneTree(-1,"fast"); TTree *triendout = t->CopyTree("","",nentries,nentries1); triendout->Write(); } } fout->Close(); friendTrees.clear(); }
void dump_tree(TTree *tree, const char *outdir) { GzipOutputStream::Options options; options.compression_level = 1; for(int li = 0; li < tree->GetListOfLeaves()->GetEntries(); li++) { TLeaf *l = (TLeaf*) tree->GetListOfLeaves()->At(li); if (lstat(outdir, NULL) == -1) { mkdir(outdir, 0777); } // Open data file std::string fn = std::string(outdir) + "/" + l->GetName() + ".dit"; auto fd = open(fn.c_str(), O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); assert(fd != -1); FileOutputStream fstream(fd); GzipOutputStream zstream(&fstream, options); // Open meta file std::string mfn = fn + "m"; auto mfd = open(mfn.c_str(), O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR); assert(mfd != -1); FileOutputStream meta_fstream(mfd); GzipOutputStream meta_zstream(&meta_fstream, options); { // Coded stream block CodedOutputStream o(&zstream); CodedOutputStream o2(&meta_zstream); // determine level and type name int level = 0; std::string tn = l->GetTypeName(); while (tn.substr(0,6) == "vector") { level = level + 1; tn = remove_vector(tn); } if (tn == "double") { dump_required<double>(level, tree, *l, o, o2); } else if (tn == "float") { dump_required<float>(level, tree, *l, o, o2); } else if (tn == "int") { dump_required<int>(level, tree, *l, o, o2); } else if (tn == "short" || tn == "Short_t") { dump_required<short>(level, tree, *l, o, o2); } else if (tn == "unsigned int") { dump_required<unsigned int>(level, tree, *l, o, o2); } else if (tn == "unsigned short") { dump_required<unsigned short>(level, tree, *l, o, o2); } else if (tn == "Float_t") { dump_required<Float_t>(level, tree, *l, o, o2); } else if (tn == "Bool_t") { dump_required<Bool_t>(level, tree, *l, o, o2); } else if (tn == "Char_t") { dump_required<Char_t>(level, tree, *l, o, o2); } else if (tn == "Double_t") { dump_required<Double_t>(level, tree, *l, o, o2); } else if (tn == "Int_t") { dump_required<Int_t>(level, tree, *l, o, o2); } else if (tn == "UInt_t") { dump_required<UInt_t>(level, tree, *l, o, o2); } else if (tn == "string") { dump_required<std::string>(level, tree, *l, o, o2); } else { std::cerr << "Unknown branch type: " << tn << std::endl; assert(false); } } meta_zstream.Close(); zstream.Close(); meta_fstream.Close(); fstream.Close(); } }
bool TreeReader::Initialize(vector <string> br, string opt) { if(!init) { if( !fChain ) { cout << endl; cout << "No tree to initialize" << endl; cout << endl; return false; } TObjArray *fileElements = fChain->GetListOfFiles(); if( !fileElements || ( fileElements->GetEntries() == 0 )) { cout << endl; cout << "No file(s) to initialize" << endl; cout << endl; return false; } } varList.clear(); TObjArray* branches = fChain->GetListOfBranches(); int nBranches = branches->GetEntries(); for (int i = 0; i < nBranches; ++i) { TBranch* branch = (TBranch*)branches->At(i); string brname = branch->GetName(); TLeaf* leaf = branch->GetLeaf(branch->GetName()); if ( leaf == 0 ) // leaf name is different from branch name { TObjArray* leafs = branch->GetListOfLeaves(); leaf = (TLeaf*)leafs->At(0); } string curtype = leaf->GetTypeName(); int id = TypeDB::getType(curtype.c_str()); int arreysize = 1; string title = leaf->GetTitle(); //cout << curtype << " " << title << endl; // Find out whether we have array by inspecting leaf title if ( title.find("[")!=std::string::npos ) { TLeaf * nelem = leaf->GetLeafCounter(arreysize); if(arreysize == 1 && nelem != NULL) arreysize = nelem->GetMaximum() + 1; //search for maximum value of the lenght } if(id >= 0) { bool addVar = true; if(br.size()>0) { addVar = false; for(unsigned b = 0; b < br.size(); b++) { if(opt == "names" || opt == "except") { if(br[b] == brname) { addVar = true; break;} } else if(opt.find("contains")!=string::npos) { if((string(brname)).find(br[b])!=string::npos) { addVar = true; break;} } else if(opt.find("except")==string::npos) cout << "Option " << opt << " not found" << endl; } if(opt.find("except")!=string::npos) addVar = !addVar; } if(addVar) { variable * tmpVar = new variable(id,arreysize); tmpVar->name = leaf->GetName(); tmpVar->bname = branch->GetName(); tmpVar->title = title; varList.push_back(tmpVar); fChain->SetBranchAddress(tmpVar->bname,tmpVar->value.address); } } else { cout << curtype << ": type not found" << endl; exit(1); return false; } } init = true; continueSorting = true; if(pmode=="v") cout << endl << "Set up " << varList.size() << " / " << nBranches << " branches" << endl; return true; }
bool execute(const std::string& skeleton, const std::string& config_file, std::string output_dir/* = ""*/) { std::vector<Plot> plots; // If an output directory is specified, use it, otherwise use the current directory if (output_dir == "") output_dir = "."; std::map<std::string, std::string> unique_names; get_plots(config_file, plots); std::cout << "List of requested plots: "; for (size_t i = 0; i < plots.size(); i++) { std::cout << "'" << plots[i].name << "'"; if (i != plots.size() - 1) std::cout << ", "; } std::cout << std::endl; // Convert plots name to unique name to avoid collision between different runs for (Plot& plot: plots) { std::string uuid = get_uuid(); unique_names[uuid] = plot.name; plot.name = uuid; } std::unique_ptr<TChain> t(new TChain("t")); t->Add(skeleton.c_str()); std::vector<Branch> branches; std::function<void(TTreeFormula*)> getBranches = [&branches, &getBranches](TTreeFormula* f) { if (!f) return; for (size_t i = 0; i < f->GetNcodes(); i++) { TLeaf* leaf = f->GetLeaf(i); if (! leaf) continue; TBranch* p_branch = getTopBranch(leaf->GetBranch()); Branch branch; branch.name = p_branch->GetName(); if (std::find_if(branches.begin(), branches.end(), [&branch](const Branch& b) { return b.name == branch.name; }) == branches.end()) { branch.type = p_branch->GetClassName(); if (branch.type.empty()) branch.type = leaf->GetTypeName(); branches.push_back(branch); } for (size_t j = 0; j < f->fNdimensions[i]; j++) { if (f->fVarIndexes[i][j]) getBranches(f->fVarIndexes[i][j]); } } for (size_t i = 0; i < f->fAliases.GetEntriesFast(); i++) { getBranches((TTreeFormula*) f->fAliases.UncheckedAt(i)); } }; std::string hists_declaration; std::string text_plots; for (auto& p: plots) { // Create formulas std::shared_ptr<TTreeFormula> selector(new TTreeFormula("selector", p.plot_cut.c_str(), t.get())); getBranches(selector.get()); std::vector<std::string> splitted_variables = split(p.variable, ":"); for (const std::string& variable: splitted_variables) { std::shared_ptr<TTreeFormula> var(new TTreeFormula("var", variable.c_str(), t.get())); getBranches(var.get()); } std::string binning = p.binning; binning.erase(std::remove_if(binning.begin(), binning.end(), [](char chr) { return chr == '(' || chr == ')'; }), binning.end()); // If a variable bin size is specified, declare array that will be passed as array to histogram constructor if(binning.find("{") != std::string::npos){ std::string arrayString = buildArrayForVariableBinning(binning, splitted_variables.size(), p.name); hists_declaration += arrayString; } std::string title = p.title + ";" + p.x_axis + ";" + p.y_axis + ";" + p.z_axis; std::string histogram_type = getHistogramTypeForDimension(splitted_variables.size()); hists_declaration += " std::unique_ptr<" + histogram_type + "> " + p.name + "(new " + histogram_type + "(\"" + p.name + "\", \"" + title + "\", " + binning + ")); " + p.name + "->SetDirectory(nullptr);\n"; std::string variable_string; for (size_t i = 0; i < splitted_variables.size(); i++) { variable_string += splitted_variables[i]; if (i != splitted_variables.size() - 1) variable_string += ", "; } ctemplate::TemplateDictionary plot("plot"); plot.SetValue("CUT", p.plot_cut); plot.SetValue("VAR", variable_string); plot.SetValue("HIST", p.name); ctemplate::ExpandTemplate(getTemplate("Plot"), ctemplate::DO_NOT_STRIP, &plot, &text_plots); } // Sort alphabetically std::sort(branches.begin(), branches.end(), [](const Branch& a, const Branch& b) { return a.name < b.name; }); std::string text_branches; for (const auto& branch: branches) { text_branches += "const " + branch.type + "& " + branch.name + " = tree[\"" + branch.name + "\"].read<" + branch.type + ">();\n "; } ctemplate::TemplateDictionary header("header"); header.SetValue("BRANCHES", text_branches); std::string output; ctemplate::ExpandTemplate(getTemplate("Plotter.h"), ctemplate::DO_NOT_STRIP, &header, &output); std::ofstream out(output_dir + "/Plotter.h"); out << output; out.close(); output.clear(); std::string text_save_plots; for (auto& p: plots) { ctemplate::TemplateDictionary save_plot("save_plot"); save_plot.SetValue("UNIQUE_NAME", p.name); save_plot.SetValue("PLOT_NAME", unique_names[p.name]); ctemplate::ExpandTemplate(getTemplate("SavePlot"), ctemplate::DO_NOT_STRIP, &save_plot, &text_save_plots); } ctemplate::TemplateDictionary source("source"); source.SetValue("HISTS_DECLARATION", hists_declaration); source.SetValue("PLOTS", text_plots); source.SetValue("SAVE_PLOTS", text_save_plots); ctemplate::ExpandTemplate(getTemplate("Plotter.cc"), ctemplate::DO_NOT_STRIP, &source, &output); out.open(output_dir + "/Plotter.cc"); out << output; out.close(); return true; }
// Generate dictionaries required to read `tree`. void ensure_dictionaries(TTree *tree) { for (int li = 0; li < tree->GetListOfLeaves()->GetEntries(); li++) { TLeaf *l = (TLeaf*) tree->GetListOfLeaves()->At(li); ensure_dictionary(l->GetTypeName()); } }