{ "cells": [ { "cell_type": "markdown", "id": "b6d51927", "metadata": {}, "source": [ "# tree106_tree\n", "This example is the same as tree105_tree.C, but uses a class instead of a C-struct.\n", "In this example, we are mapping a class to one of the Geant3\n", "common blocks /gctrak/. In the real life, this common will be filled\n", "by Geant3 at each step and only the Tree Fill function should be called.\n", "The example emulates the Geant3 step routines.\n", "\n", "to run the example, do to execute with native compiler:\n", "```\n", ".x tree106_tree.C+ \n", "```\n", "\n", "Note that since IO is involved, ACLiC has to be invoked to create the dictionary of class Gctrak.\n", "\n", "\n", "\n", "**Author:** Rene Brun \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:17 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "05262140", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:18:00.256231Z", "iopub.status.busy": "2026-05-19T20:18:00.256117Z", "iopub.status.idle": "2026-05-19T20:18:00.265183Z", "shell.execute_reply": "2026-05-19T20:18:00.264722Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "\n", "#include \"TROOT.h\"\n", "#include \"TFile.h\"\n", "#include \"TTree.h\"\n", "#include \"TBrowser.h\"\n", "#include \"TH2.h\"\n", "#include \"TMath.h\"\n", "#include \"TRandom.h\"\n", "#include \"TCanvas.h\"\n", "\n", "const Int_t MAXMEC = 30;\n", "\n", "class Gctrak : public TObject {\n", "public:\n", " Float_t vect[7];\n", " Float_t getot;\n", " Float_t gekin;\n", " Float_t vout[7]; ///lmec = new Int_t[MAXMEC];\n", " gstep->namec = new Int_t[MAXMEC];\n", " gstep->step = 0.1;\n", " gstep->destep = 0;\n", " gstep->nmec = 0;\n", " gstep->pid = 0;\n", "\n", " // transport particles\n", " for (Int_t i=0;i <10000; i++) {\n", " // generate a new particle if necessary\n", " if (newParticle) {\n", " px = gRandom->Gaus(0, .02);\n", " py = gRandom->Gaus(0, .02);\n", " pz = gRandom->Gaus(0, .02);\n", " p = TMath::Sqrt(px * px + py * py + pz * pz);\n", " charge = 1;\n", " if (gRandom->Rndm() < 0.5)\n", " charge = -1;\n", " gstep->pid += 1;\n", " gstep->vect[0] = 0;\n", " gstep->vect[1] = 0;\n", " gstep->vect[2] = 0;\n", " gstep->vect[3] = px / p;\n", " gstep->vect[4] = py / p;\n", " gstep->vect[5] = pz / p;\n", " gstep->vect[6] = p*charge;\n", " gstep->getot = TMath::Sqrt(p * p + mass * mass);\n", " gstep->gekin = gstep->getot - mass;\n", " newParticle = kFALSE;\n", " }\n", "\n", " // fill the Tree with current step parameters\n", " t2.Fill();\n", "\n", " // transport particle in magnetic field\n", " helixStep(gstep->step, gstep->vect, vout); // make one step\n", "\n", " //apply energy loss\n", " gstep->destep = gstep->step*gRandom->Gaus(0.0002, 0.00001);\n", " gstep->gekin -= gstep->destep;\n", " gstep->getot = gstep->gekin + mass;\n", " gstep->vect[6] = charge * TMath::Sqrt(gstep->getot * gstep->getot - mass * mass);\n", " gstep->vect[0] = vout[0];\n", " gstep->vect[1] = vout[1];\n", " gstep->vect[2] = vout[2];\n", " gstep->vect[3] = vout[3];\n", " gstep->vect[4] = vout[4];\n", " gstep->vect[5] = vout[5];\n", " gstep->nmec = (Int_t)(5 * gRandom->Rndm());\n", " for (Int_t l=0; lnmec; l++) {\n", " gstep->lmec[l] = l;\n", " gstep->namec[l] = l + 100;\n", " }\n", " if (gstep->gekin < 0.001)\n", " newParticle = kTRUE;\n", " if (TMath::Abs(gstep->vect[2]) > 30)\n", " newParticle = kTRUE;\n", " }\n", "\n", " // save the Tree header. The file will be automatically closed\n", " // when going out of the function scope\n", " t2.Write();\n", "}" ] }, { "cell_type": "markdown", "id": "fc69aeb7", "metadata": {}, "source": [ " Definition of a helper function: " ] }, { "cell_type": "code", "execution_count": 4, "id": "1e2ebc7b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:18:00.290538Z", "iopub.status.busy": "2026-05-19T20:18:00.290421Z", "iopub.status.idle": "2026-05-19T20:18:00.305122Z", "shell.execute_reply": "2026-05-19T20:18:00.304585Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "void tree106_read()\n", "{\n", " // read the Tree generated by tree2w and fill one histogram\n", " // we are only interested by the destep branch.\n", "\n", " // note that we create the TFile and TTree objects on the heap\n", " // because we want to keep these objects alive when we leave\n", " // this function.\n", " auto f = TFile::Open(\"tree106.root\");\n", " auto t2 = f->Get(\"t2\");\n", " Gctrak *gstep = nullptr;\n", " t2->SetBranchAddress(\"track\", &gstep);\n", " auto b_destep = t2->GetBranch(\"destep\");\n", "\n", " // create one histogram\n", " auto hdestep = new TH1F(\"hdestep\", \"destep in Mev\", 100, 1e-5, 3e-5);\n", "\n", " // read only the destep branch for all entries\n", " Long64_t nentries = t2->GetEntries();\n", " for (Long64_t i=0; iGetEntry(i);\n", " hdestep->Fill(gstep->destep);\n", " }\n", "\n", " // we do not close the file\n", " // we want to keep the generated histograms\n", " // we fill a 3-d scatter plot with the particle step coordinates\n", " auto c1 = new TCanvas(\"c1\", \"c1\", 600, 800);\n", " c1->SetFillColor(42);\n", " c1->Divide(1, 2);\n", " c1->cd(1);\n", " hdestep->SetFillColor(45);\n", " hdestep->Fit(\"gaus\");\n", " c1->cd(2);\n", " gPad->SetFillColor(37);\n", " t2->SetMarkerColor(kRed);\n", " t2->Draw(\"vect[0]:vect[1]:vect[2]\");\n", " if (gROOT->IsBatch())\n", " return;\n", "\n", " // invoke the x3d viewer\n", " gPad->GetViewer3D(\"ogl\");\n", "}" ] }, { "cell_type": "code", "execution_count": 5, "id": "d5e9aec9", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:18:00.306579Z", "iopub.status.busy": "2026-05-19T20:18:00.306458Z", "iopub.status.idle": "2026-05-19T20:18:01.094627Z", "shell.execute_reply": "2026-05-19T20:18:01.093776Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "****************************************\n", "Minimizer is Minuit2 / Migrad\n", "Chi2 = 54.4259\n", "NDf = 36\n", "Edm = 8.03293e-06\n", "NCalls = 57\n", "Constant = 801.839 +/- 9.64936 \n", "Mean = 1.99798e-05 +/- 9.94778e-09 \n", "Sigma = 9.89855e-07 +/- 6.61264e-09 \t (limited)\n" ] } ], "source": [ "tree106_write();\n", "tree106_read();" ] }, { "cell_type": "markdown", "id": "e77f90cc", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 6, "id": "5e53586b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:18:01.096047Z", "iopub.status.busy": "2026-05-19T20:18:01.095920Z", "iopub.status.idle": "2026-05-19T20:18:01.301358Z", "shell.execute_reply": "2026-05-19T20:18:01.300613Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "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 }