Logo ROOT   6.10/09
Reference Guide
tdf002_dataModel.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_tdataframe
3 /// \notebook -draw
4 /// This tutorial shows the possibility to use data models which are more
5 /// complex than flat ntuples with TDataFrame
6 ///
7 /// \macro_code
8 ///
9 /// \date December 2016
10 /// \author Danilo Piparo
11 
12 // ## Preparation
13 // This notebook can be compiled with this invocation
14 // `g++ -o tdf002_dataModel tdf002_dataModel.C `root-config --cflags --libs` -lTreePlayer`
15 
16 #include "Math/Vector3D.h"
17 #include "Math/Vector4D.h"
18 #include "TCanvas.h"
19 #include "TMath.h"
20 #include "TRandom3.h"
21 #include "TFile.h"
22 #include "TH1F.h"
23 #include "TTree.h"
24 
25 #include "ROOT/TDataFrame.hxx"
26 
27 using FourVector = ROOT::Math::XYZTVector;
28 using FourVectors = std::vector<FourVector>;
29 using CylFourVector = ROOT::Math::RhoEtaPhiVector;
30 
31 // A simple helper function to fill a test tree: this makes the example
32 // stand-alone.
33 void fill_tree(const char *filename, const char *treeName)
34 {
35  TFile f(filename, "RECREATE");
36  TTree t(treeName, treeName);
37  FourVectors tracks;
38  t.Branch("tracks", &tracks);
39 
40  const double M = 0.13957; // set pi+ mass
41  TRandom3 R(1);
42 
43  for (int i = 0; i < 50; ++i) {
44  auto nPart = R.Poisson(15);
45  tracks.clear();
46  tracks.reserve(nPart);
47  for (int j = 0; j < nPart; ++j) {
48  double px = R.Gaus(0, 10);
49  double py = R.Gaus(0, 10);
50  double pt = sqrt(px * px + py * py);
51  double eta = R.Uniform(-3, 3);
52  double phi = R.Uniform(0.0, 2 * TMath::Pi());
53  CylFourVector vcyl(pt, eta, phi);
54  // set energy
55  double E = sqrt(vcyl.R() * vcyl.R() + M * M);
56  FourVector q(vcyl.X(), vcyl.Y(), vcyl.Z(), E);
57  // fill track vector
58  tracks.emplace_back(q);
59  }
60  t.Fill();
61  }
62 
63  t.Write();
64  f.Close();
65  return;
66 }
67 
68 int tdf002_dataModel()
69 {
70 
71  // We prepare an input tree to run on
72  auto fileName = "tdf002_dataModel.root";
73  auto treeName = "myTree";
74  fill_tree(fileName, treeName);
75 
76  // We read the tree from the file and create a TDataFrame, a class that
77  // allows us to interact with the data contained in the tree.
78  ROOT::Experimental::TDataFrame d(treeName, fileName, {"tracks"});
79 
80  // ## Operating on branches which are collection of objects
81  // Here we deal with the simplest of the cuts: we decide to accept the event
82  // only if the number of tracks is greater than 5.
83  auto n_cut = [](const FourVectors &tracks) { return tracks.size() > 8; };
84  auto nentries = d.Filter(n_cut, {"tracks"}).Count();
85 
86  std::cout << *nentries << " passed all filters" << std::endl;
87 
88  // Another possibility consists in creating a new column containing the
89  // quantity we are interested in.
90  // In this example, we will cut on the number of tracks and plot their
91  // transverse momentum.
92  auto getPt = [](const FourVectors &tracks) {
93  std::vector<double> pts;
94  pts.reserve(tracks.size());
95  for (auto &t : tracks) pts.emplace_back(t.Pt());
96  return pts;
97  };
98 
99  // We do the same for the weights.
100  auto getPtWeights = [](const FourVectors &tracks) {
101  std::vector<double> ptsw;
102  ptsw.reserve(tracks.size());
103  for (auto &t : tracks) ptsw.emplace_back(1. / t.Pt());
104  return ptsw;
105  };
106 
107  auto augmented_d = d.Define("tracks_n", [](const FourVectors &tracks) { return (int)tracks.size(); })
108  .Filter([](int tracks_n) { return tracks_n > 2; }, {"tracks_n"})
109  .Define("tracks_pts", getPt)
110  .Define("tracks_pts_weights", getPtWeights);
111 
112  auto trN = augmented_d.Histo1D(TH1F{"", "", 40, -.5, 39.5}, "tracks_n");
113  auto trPts = augmented_d.Histo1D("tracks_pts");
114  auto trWPts = augmented_d.Histo1D("tracks_pts", "tracks_pts_weights");
115 
116  TCanvas c1;
117  trN->Draw();
118  c1.Print("tracks_n.png");
119 
120  TCanvas c2;
121  trPts->Draw();
122  c2.Print("tracks_pt.png");
123 
124  TCanvas c3;
125  trWPts->Draw();
126  c3.Print("tracks_Wpt.png");
127 
128  return 0;
129 }
130 
131 int main()
132 {
133  return tdf002_dataModel();
134 }
Random number generator class based on M.
Definition: TRandom3.h:27
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
Definition: TRandom.cxx:235
return c1
Definition: legend1.C:41
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:46
tomato 1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:551
DisplacementVector3D< CylindricalEta3D< double >, DefaultCoordinateSystemTag > RhoEtaPhiVector
3D Vector based on the eta based cylindrical coordinates rho, eta, phi in double precision.
Definition: Vector3Dfwd.h:50
double sqrt(double)
LorentzVector< PxPyPzE4D< double > > XYZTVector
LorentzVector based on x,y,x,t (or px,py,pz,E) coordinates in double precision with metric (-...
Definition: Vector4Dfwd.h:33
constexpr Double_t Pi()
Definition: TMath.h:40
TPaveText * pt
virtual void Print(const char *filename="") const
Save Pad contents in a file in one of various formats.
Definition: TPad.cxx:4581
constexpr Double_t E()
Definition: TMath.h:74
The Canvas class.
Definition: TCanvas.h:31
return c2
Definition: legend2.C:14
double f(double x)
int nentries
Definition: THbookFile.cxx:89
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition: TRandom.cxx:606
ROOT&#39;s TDataFrame offers a high level interface for analyses of data stored in TTrees.
Definition: TDataFrame.hxx:36
A TTree object has a header with a name and a title.
Definition: TTree.h:78
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:362
float * q
Definition: THbookFile.cxx:87
return c3
Definition: legend3.C:15
TRandom3 R
a TMatrixD.
Definition: testIO.cxx:28
int main(int argc, char **argv)