//C++ #include #include #include #include #include #include #include #include #include //root #include #include #include #include #include #include #include #include #include #include #include #include #include //local #include "../IOjuggler/ProgressBar.h" #include "../IOjuggler/IOjuggler.h" #include "../include/misID_betaRDF.h" #ifndef NTUPLE_GIZMO_GIT_HASH #define NTUPLE_GIZMO_GIT_HASH " " #endif int main(int argc, char** argv){ TStopwatch clock; clock.Start(); //parse command line options const auto options = IOjuggler::parse_options(argc, argv, "c:d:i:o:t:v:h","nonoptions: any number of combinations"); const auto wd = options.get("workdir"); const auto ofn = options.get("outfilename"); const auto ifn = options.get("infilename"); const auto itn = options.get("treename"); //init MessageService for easy and nice printout MessageService msgsvc("selector_rootMT",static_cast(options.get("verbosity"))); msgsvc.debugmsg("Current ntuple-gizmo git hash: " + static_cast(NTUPLE_GIZMO_GIT_HASH)); //get input as TChain auto chain = IOjuggler::get_chain(itn,ifn,wd,msgsvc); //attach friend-files, if any //[[maybe_unused]] auto fes = IOjuggler::get_friends(options,chain,msgsvc); //get config-file auto configtree = IOjuggler::get_ptree(options.get("config")); //manipulations of the config file IOjuggler::auto_replace_in_ptree(configtree); IOjuggler::auto_append_in_ptree(configtree); auto trim_vars = configtree.get_child_optional("variables"); auto tmp_msg = "Trimming input tree(s) with cut " + configtree.get("basiccuts",""); if(trim_vars) msgsvc.infomsg(tmp_msg + " and writing out " + configtree.get_child("variables").size() + " variables"); else msgsvc.infomsg(tmp_msg + " and writing out full tree"); const bool noImplicitCuts= (const bool) (configtree.get_child_optional("noImplicitCuts")); if(noImplicitCuts) msgsvc.infomsg("Implicit cuts switched off"); std::vector branches_in = {}; std::vector default_branches_out = {}; std::vector> transformations; if(trim_vars) for(const auto& var : *trim_vars){ branches_in.push_back(var.first); if(auto nn = var.second.get_optional("new_name")){ default_branches_out.push_back(*nn); if(auto tfm = var.second.get_optional("transformation")) transformations.emplace_back(default_branches_out.back(),*tfm); else transformations.emplace_back(default_branches_out.back(),var.first); } else if(var.first.find("[0]") != std::string::npos){ default_branches_out.push_back(boost::algorithm::replace_all_copy(var.first, "[0]", "Z")); transformations.emplace_back(default_branches_out.back(),var.first); } else if(!var.second.get("to_output",1)) msgsvc.infomsg("Using " + var.first + " only as input branch"); else default_branches_out.push_back(var.first); } //first, we need to know how many events there are and how many threads we use: auto nSlots = configtree.get("threads",ROOT::GetImplicitMTPoolSize()); ROOT::EnableImplicitMT(nSlots); ROOT::RDataFrame d(*chain.get(),branches_in); //use ROOT::RDF::RNode to chain commands on the dataframe ROOT::RDF::RNode df = d; if(!transformations.empty()) for(const auto& tf : transformations){ msgsvc.debugmsg("transforming " + tf.second + " to a new branch: " + tf.first); df = df.Define(tf.first,tf.second); } if(const auto misID = configtree.get_child_optional("misIDMbeta")){ std::vector daughters; for(const auto& daughter : *misID) daughters.push_back(daughter.first); MbetaRDF(daughters,df,default_branches_out,msgsvc); msgsvc.debugmsg("Added masses and betas for misID studies"); } //apply cuts if(const auto cut = configtree.get_optional("basiccuts")) df = df.Filter(*cut); //options for the output file ROOT::RDF::RSnapshotOptions rso(configtree.get("outfopt","RECREATE"), static_cast(configtree.get("outcompalg",1)), configtree.get("outcomplvl",1),0,99,true); rso.fLazy = true; /*auto dff = */df.Snapshot(configtree.get("outtreename",itn),wd + "/" + ofn,default_branches_out,rso); /*auto hff = df.Histo1D("M_12"); std::string progressBar; std::mutex barMutex; const auto barWidth = 100.; const auto everyN = static_cast(chain->GetEntries()/100.); hff.OnPartialResultSlot(everyN, [&barWidth, &progressBar,&barMutex](unsigned int, auto& ) { std::lock_guard l(barMutex); // lock_guard locks the mutex at construction, releases it at destruction progressBar.push_back('#'); // re-print the line with the progress bar std::cout << "\r[" << std::left << std::setw(100) << progressBar << ']' << std::flush; }); hff->Draw(); dff->Report();*/ clock.Stop(); clock.Print(); return 0; }