{
"cells": [
{
"cell_type": "markdown",
"id": "66208283",
"metadata": {},
"source": [
"# mathcoreVectorCollection\n",
"Example showing how to write and read a std vector of ROOT::Math LorentzVector in a ROOT tree.\n",
"\n",
"In the write() function a variable number of track Vectors is generated\n",
"according to a Poisson distribution with random momentum uniformly distributed\n",
"in phi and eta.\n",
"In the read() the vectors are read back and the content analysed and\n",
"some information such as number of tracks per event or the track pt\n",
"distributions are displayed in a canvas.\n",
"\n",
"To execute the macro type in:\n",
"\n",
"```cpp\n",
" root[0]: .x mathcoreVectorCollection.C\n",
"```\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Andras Zsenei \n",
"This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:25 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "786a3e5c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:25:52.793555Z",
"iopub.status.busy": "2026-05-19T20:25:52.793444Z",
"iopub.status.idle": "2026-05-19T20:25:52.804768Z",
"shell.execute_reply": "2026-05-19T20:25:52.804369Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \"TRandom.h\"\n",
"#include \"TStopwatch.h\"\n",
"#include \"TSystem.h\"\n",
"#include \"TFile.h\"\n",
"#include \"TTree.h\"\n",
"#include \"TH1D.h\"\n",
"#include \"TCanvas.h\"\n",
"#include \"TMath.h\"\n",
"\n",
"#include \n",
"\n",
"#include \"Math/Vector3D.h\"\n",
"#include \"Math/Vector4D.h\"\n",
"\n",
"using namespace ROOT::Math;"
]
},
{
"cell_type": "markdown",
"id": "ce0b0565",
"metadata": {},
"source": [
" CLING does not understand some files included by LorentzVector\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "eb89c43d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:25:52.806349Z",
"iopub.status.busy": "2026-05-19T20:25:52.806232Z",
"iopub.status.idle": "2026-05-19T20:25:52.856719Z",
"shell.execute_reply": "2026-05-19T20:25:52.856262Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"double write(int n) {\n",
" TRandom R;\n",
" TStopwatch timer;\n",
"\n",
" TFile f1(\"mathcoreLV.root\",\"RECREATE\");\n",
"\n",
" // create tree\n",
" TTree t1(\"t1\",\"Tree with new LorentzVector\");\n",
"\n",
" std::vector tracks;\n",
" std::vector * pTracks = &tracks;\n",
" t1.Branch(\"tracks\",\"std::vector > >\",&pTracks);\n",
"\n",
" double M = 0.13957; // set pi+ mass\n",
"\n",
" timer.Start();\n",
" double sum = 0;\n",
" for (int i = 0; i < n; ++i) {\n",
" int nPart = R.Poisson(5);\n",
" pTracks->clear();\n",
" pTracks->reserve(nPart);\n",
" for (int j = 0; j < nPart; ++j) {\n",
" double px = R.Gaus(0,10);\n",
" double py = R.Gaus(0,10);\n",
" double pt = sqrt(px*px +py*py);\n",
" double eta = R.Uniform(-3,3);\n",
" double phi = R.Uniform(0.0 , 2*TMath::Pi() );\n",
" RhoEtaPhiVector vcyl( pt, eta, phi);\n",
" // set energy\n",
" double E = sqrt( vcyl.R()*vcyl.R() + M*M);\n",
" XYZTVector q( vcyl.X(), vcyl.Y(), vcyl.Z(), E);\n",
" // fill track vector\n",
" pTracks->push_back(q);\n",
" // evaluate sum of components to check\n",
" sum += q.x()+q.y()+q.z()+q.t();\n",
" }\n",
" t1.Fill();\n",
" }\n",
"\n",
" f1.Write();\n",
" timer.Stop();\n",
" std::cout << \" Time for new Vector \" << timer.RealTime() << \" \" << timer.CpuTime() << std::endl;\n",
"\n",
" t1.Print();\n",
" return sum;\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "62dc49d9",
"metadata": {},
"source": [
" Definition of a helper function: "
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "f269d4ce",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:25:52.858320Z",
"iopub.status.busy": "2026-05-19T20:25:52.858202Z",
"iopub.status.idle": "2026-05-19T20:25:52.878519Z",
"shell.execute_reply": "2026-05-19T20:25:52.878071Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"double read() {\n",
" TRandom R;\n",
" TStopwatch timer;\n",
"\n",
" TH1D * h1 = new TH1D(\"h1\",\"total event energy \",100,0,1000.);\n",
" TH1D * h2 = new TH1D(\"h2\",\"Number of track per event\",21,-0.5,20.5);\n",
" TH1D * h3 = new TH1D(\"h3\",\"Track Energy\",100,0,200);\n",
" TH1D * h4 = new TH1D(\"h4\",\"Track Pt\",100,0,100);\n",
" TH1D * h5 = new TH1D(\"h5\",\"Track Eta\",100,-5,5);\n",
" TH1D * h6 = new TH1D(\"h6\",\"Track Cos(theta)\",100,-1,1);\n",
"\n",
" TFile f1(\"mathcoreLV.root\");\n",
"\n",
" // create tree\n",
" TTree *t1 = (TTree*)f1.Get(\"t1\");\n",
"\n",
" std::vector > > * pTracks = nullptr;\n",
" t1->SetBranchAddress(\"tracks\",&pTracks);\n",
"\n",
" timer.Start();\n",
" int n = (int) t1->GetEntries();\n",
" std::cout << \" Tree Entries \" << n << std::endl;\n",
" double sum=0;\n",
" for (int i = 0; i < n; ++i) {\n",
" t1->GetEntry(i);\n",
" int ntrk = pTracks->size();\n",
" h3->Fill(ntrk);\n",
" XYZTVector q;\n",
" for (int j = 0; j < ntrk; ++j) {\n",
" XYZTVector v = (*pTracks)[j];\n",
" q += v;\n",
" h3->Fill(v.E());\n",
" h4->Fill(v.Pt());\n",
" h5->Fill(v.Eta());\n",
" h6->Fill(cos(v.Theta()));\n",
" sum += v.x() + v.y() + v.z() + v.t();\n",
" }\n",
" h1->Fill(q.E() );\n",
" h2->Fill(ntrk);\n",
" }\n",
"\n",
" timer.Stop();\n",
" std::cout << \" Time for new Vector \" << timer.RealTime() << \" \" << timer.CpuTime() << std::endl;\n",
"\n",
" TCanvas *c1 = new TCanvas(\"c1\",\"demo of Trees\",10,10,600,800);\n",
" c1->Divide(2,3);\n",
"\n",
" c1->cd(1);\n",
" h1->Draw();\n",
" c1->cd(2);\n",
" h2->Draw();\n",
" c1->cd(3);\n",
" h3->Draw();\n",
" c1->cd(3);\n",
" h3->Draw();\n",
" c1->cd(4);\n",
" h4->Draw();\n",
" c1->cd(5);\n",
" h5->Draw();\n",
" c1->cd(6);\n",
" h6->Draw();\n",
"\n",
" return sum;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "aaff9366",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:25:52.879797Z",
"iopub.status.busy": "2026-05-19T20:25:52.879679Z",
"iopub.status.idle": "2026-05-19T20:25:53.434501Z",
"shell.execute_reply": "2026-05-19T20:25:53.433894Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Time for new Vector 0.076153 0.07\n",
"******************************************************************************\n",
"*Tree :t1 : Tree with new LorentzVector *\n",
"*Entries : 10000 : Total = 1854288 bytes File Size = 1701478 *\n",
"* : : Tree compression factor = 1.09 *\n",
"******************************************************************************\n",
"*Br 0 :tracks : Int_t tracks_ *\n",
"*Entries : 10000 : Total Size= 84910 bytes File Size = 33319 *\n",
"*Baskets : 4 : Basket Size= 32000 bytes Compression= 2.41 *\n",
"*............................................................................*\n",
"*Br 1 :tracks.fCoordinates.fX : Double_t fX[tracks_] *\n",
"*Entries : 10000 : Total Size= 443177 bytes File Size = 419376 *\n",
"*Baskets : 16 : Basket Size= 32000 bytes Compression= 1.05 *\n",
"*............................................................................*\n",
"*Br 2 :tracks.fCoordinates.fY : Double_t fY[tracks_] *\n",
"*Entries : 10000 : Total Size= 443177 bytes File Size = 419376 *\n",
"*Baskets : 16 : Basket Size= 32000 bytes Compression= 1.05 *\n",
"*............................................................................*\n",
"*Br 3 :tracks.fCoordinates.fZ : Double_t fZ[tracks_] *\n",
"*Entries : 10000 : Total Size= 443177 bytes File Size = 417769 *\n",
"*Baskets : 16 : Basket Size= 32000 bytes Compression= 1.06 *\n",
"*............................................................................*\n",
"*Br 4 :tracks.fCoordinates.fT : Double_t fT[tracks_] *\n",
"*Entries : 10000 : Total Size= 443177 bytes File Size = 410297 *\n",
"*Baskets : 16 : Basket Size= 32000 bytes Compression= 1.08 *\n",
"*............................................................................*\n",
" Tree Entries 10000\n",
" Time for new Vector 0.014905 0.01\n"
]
}
],
"source": [
"int nEvents = 10000;\n",
"double s1 = write(nEvents);\n",
"double s2 = read();\n",
"\n",
"if (fabs(s1-s2) > s1*1.E-15 ) {\n",
" std::cout << \"ERROR: Found difference in Vector when reading ( \" << s1 << \" != \" << s2 << \" diff = \" << fabs(s1-s2) << \" ) \" << std::endl;\n",
" return -1;\n",
"}\n",
"return 0;"
]
},
{
"cell_type": "markdown",
"id": "de383b78",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "68206951",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:25:53.436229Z",
"iopub.status.busy": "2026-05-19T20:25:53.436110Z",
"iopub.status.idle": "2026-05-19T20:25:53.661851Z",
"shell.execute_reply": "2026-05-19T20:25:53.660915Z"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"
\n",
"\n",
"\n",
"\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%jsroot on\n",
"gROOT->GetListOfCanvases()->Draw()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ROOT C++",
"language": "c++",
"name": "root"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".C",
"mimetype": " text/x-c++src",
"name": "c++"
}
},
"nbformat": 4,
"nbformat_minor": 5
}