From ed13fb4410cef8d88a29dce27b8ef23ece6b6b62 Mon Sep 17 00:00:00 2001 From: Gerardo Ganis <Gerardo.Ganis@cern.ch> Date: Thu, 9 Nov 2017 19:25:00 +0100 Subject: [PATCH] tutorials/multicore: two new tutorials to illustrate autobin in power-of-2 mode --- tutorials/multicore/mt304_fillHistos.C | 92 ++++++++++++ tutorials/multicore/mt305_fillHistosAutobin.C | 133 ++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 tutorials/multicore/mt304_fillHistos.C create mode 100644 tutorials/multicore/mt305_fillHistosAutobin.C diff --git a/tutorials/multicore/mt304_fillHistos.C b/tutorials/multicore/mt304_fillHistos.C new file mode 100644 index 00000000000..5a604bb8704 --- /dev/null +++ b/tutorials/multicore/mt304_fillHistos.C @@ -0,0 +1,92 @@ +/// \file +/// \ingroup tutorial_multicore +/// Fill histograms in parallel with automatic binning. +/// Illustrates use of power-of-two autobin algorithm +/// +/// \macro_code +/// +/// \author Gerardo Ganis +/// \date November 2017 +#include "TH1D.h" +#include "TH2D.h" +#include "TH3D.h" +#include "TList.h" +#include "TRandom3.h" +#include "TDirectory.h" +#include "TROOT.h" +#include "TCanvas.h" +#include "TString.h" +#include "TStyle.h" +#include "ROOT/TSeq.hxx" +#include "ROOT/TThreadedObject.hxx" + +#include <thread> +#include <iostream> + + +// The number of workers +const UInt_t nWorkers = 8U; + +// Reference boundaries +const Double_t xmiref = -1.; +const Double_t xmaref = 7.; + +Int_t mt304_fillHistos(UInt_t nNumbers = 1001) +{ + + // The first, fundamental operation to be performed in order to make ROOT + // thread-aware. + ROOT::EnableThreadSafety(); + + // Histograms to be filled in parallel + ROOT::TThreadedObject<TH1D> h1d("h1d", "1D test histogram", 64, 0., -1.); + ROOT::TThreadedObject<TH1D> h1dr("h1dr", "1D test histogram w/ ref boundaries", 64, xmiref, xmaref); + + // We define our work item + auto workItem = [&](UInt_t workerID) { + // One generator, file and ntuple per worker + TRandom3 workerRndm(workerID); // Change the seed + + auto wh1d = h1d.Get(); + wh1d->SetBit(TH1::kAutoBinPTwo); + auto wh1dr = h1dr.Get(); + + Double_t x; + for (UInt_t i = 0; i < nNumbers; ++i) { + x = workerRndm.Gaus(3.); + wh1d->Fill(x); + wh1dr->Fill(x); + } + }; + + // Create the collection which will hold the threads, our "pool" + std::vector<std::thread> workers; + + // Fill the "pool" with workers + for (auto workerID : ROOT::TSeqI(nWorkers)) { + workers.emplace_back(workItem, workerID); + } + + // Now join them + for (auto && worker : workers) worker.join(); + + // Merge + auto fh1d = h1d.Merge(); + auto fh1dr = h1dr.Merge(); + + // Make the canvas + TCanvas *c = new TCanvas("c", "c", 800, 800); + c->Divide(1,2); + + gStyle->SetOptStat(111110); + c->cd(1); + fh1d->DrawCopy(); + c->cd(2); + fh1dr->DrawCopy(); + + c->Update(); + + gROOTMutex = 0; + + return 0; +} diff --git a/tutorials/multicore/mt305_fillHistosAutobin.C b/tutorials/multicore/mt305_fillHistosAutobin.C new file mode 100644 index 00000000000..6540ff41028 --- /dev/null +++ b/tutorials/multicore/mt305_fillHistosAutobin.C @@ -0,0 +1,133 @@ +/// \file +/// \ingroup tutorial_multicore +/// Fill multiple histograms with different functions and automatic binning. +/// Illustrates merging with the power-of-two autobin algorithm +/// +/// \macro_code +/// +/// \author Gerardo Ganis +/// \date November 2017 +#include "TF1.h" +#include "TH1D.h" +#include "TMath.h" +#include "TF1.h" +#include "TCanvas.h" +#include "TRandom3.h" +#include "TStatistic.h" +#include "TFile.h" +#include "TStyle.h" + +TF1 *gam = new TF1("gam", "1/(1+0.1*x*0.1*x)", -100., 100.); +TF1 *gam1 = new TF1("gam", "1/(1+0.1*x*0.1*x)", -1., .25); +TF1 *iga = new TF1("inv gam", "1.-1/(1+0.1*x*0.1*x)", -100., 100.); +TF1 *iga1 = new TF1("inv gam", "1.-1/(1+0.1*x*0.1*x)", -.5, 1.); + +void mt305_fillHistosAutobin(unsigned opt = 1, unsigned n = 1001) +{ + + UInt_t nh = 10; + UInt_t bsize = 1000; + + TRandom3 rndm((Long64_t)time(0)); + + // Standard autobinning reference + auto href = new TH1D("myhref", "current", 50, 0., -1.); + href->SetBuffer(bsize); + + // New autobinning 1-histo reference + auto href2 = new TH1D("myhref", "Auto P2, sequential", 50, 0., -1.); + href2->SetBit(TH1::kAutoBinPTwo); + href2->SetBuffer(bsize); + + TList *hlist = new TList; + + Int_t nbins = 50; + + TStatistic x("min"), y("max"), d("dif"), a("mean"), r("rms"); + for (UInt_t j = 0; j < nh; ++j) { + Double_t xmi = 1e15, xma = -1e15; + TStatistic xw("work"); + TString hname = TString::Format("myh%d", j); + auto hw = new TH1D(hname.Data(), "Auto P2, merged", nbins, 0., -1.); + hw->SetBit(TH1::kAutoBinPTwo); + hw->SetBuffer(bsize); + + Double_t xhma, xhmi, ovf, unf; + Bool_t emptied = kFALSE, tofill = kTRUE; + Bool_t buffering = kTRUE; + for (UInt_t i = 0; i < n; ++i) { + + Double_t xx; + switch (opt) { + case 1: xx = rndm.Gaus(3, 1); break; + case 2: xx = rndm.Rndm() * 100. - 50.; break; + case 3: xx = gam->GetRandom(); break; + case 4: xx = gam1->GetRandom(); break; + case 5: xx = iga->GetRandom(); break; + case 6: xx = iga1->GetRandom(); break; + default: xx = rndm.Gaus(0, 1); + } + + if (buffering) { + if (xx > xma) + xma = xx; + if (xx < xmi) + xmi = xx; + xw.Fill(xx); + } + hw->Fill(xx); + href->Fill(xx); + href2->Fill(xx); + if (!hw->GetBuffer()) { + // Not buffering anymore + buffering = kFALSE; + } + } + x.Fill(xmi); + y.Fill(xma); + d.Fill(xma - xmi); + a.Fill(xw.GetMean()); + r.Fill(xw.GetRMS()); + + hlist->Add(hw); + } + + x.Print(); + y.Print(); + d.Print(); + a.Print(); + r.Print(); + + TH1D *h0 = (TH1D *)hlist->First(); + hlist->Remove(h0); + if (!h0->Merge(hlist)) + return; + + gStyle->SetOptStat(111110); + + if (gROOT->GetListOfCanvases()->FindObject("c3")) + delete gROOT->GetListOfCanvases()->FindObject("c3"); + TCanvas *c3 = new TCanvas("c3", "c3", 800, 800); + c3->Divide(1, 3); + c3->cd(1); + h0->StatOverflows(); + h0->DrawClone("HIST"); + + c3->cd(2); + href2->StatOverflows(); + href2->DrawClone(); + + c3->cd(3); + href->StatOverflows(); + href->DrawClone(); + c3->Update(); + std::cout << " ent: " << h0->GetEntries() << "\n"; + h0->Print(); + href->Print(); + + hlist->SetOwner(kTRUE); + delete hlist; + delete href; + delete href2; + delete h0; +} -- GitLab