(histogram-analyze-c)= # Walkthrough: Making a histogram with Analyze **(15 minutes)** Edit the file Analyze.C. In the Definitions section, insert the following code: TH1* chi2Hist = NULL; :::{note} This means "define a new histogram pointer and call it `chi2Hist`." Why define this as a pointer when plain ol' variables are easier to use? The short answer is that ROOT uses pointers all the time; for example, if you want to read something from a file, you must always use pointers. The sooner you get used to pointers, the better.[^f79] Don't forget the semi-colons ";" at the ends of the lines! You can omit them in interactive commands, but not in macros. ::: In the Initialization section, insert the following code: chi2Hist = new TH1D("chi2","Histogram of Chi2",100,0,20); :::{note} This means "set this pointer to a new histogram object." We're doing this here, instead of the Definitions section, because sometimes you want quantities like histogram limits to be variable rather than fixed; e.g., they depend on user input. ::: In the Loop section, put this in: GetEntry(entry); chi2Hist->Fill(*chi2); :::{note} The first of these two lines means "get the '(entry+1)-th' row from the `TTree`"; e.g., if **`entry`** is 100, get the 101st row from the n-tuple.[^f80] Note that the variable **`entry`** comes from an argument to the `Process` method, so you don't have to set it. This line will assign values to variables defined in the n-tuple: **`*ebeam`**, **`*chi2`**, and so on.[^f81] In code prepared by `MakeSelector`, the variables extracted from an n-tuple are pointers; they have to be prefixed with "*" to access their values. The second line means "in the histogram **`chi2Hist`** add 1 to a bin that corresponds to the value of **`*chi2`**." ::: This goes in the Wrap-up section: chi2Hist->Draw(); :::{note} You already know what this does; you've used it before! ::: Save the file, quit and restart ROOT, then enter the same commands as before: [] TFile myFile("experiment.root") [] tree1->Process("Analyze.C") :::{note} Finally, we've made our first histogram with a C++ analysis macro. In the Initialization section, we defined a histogram; in the Loop section, we filled the histogram with values; in the Wrap-up section, we drew the histogram. "What histogram? I don't see anything!" Don't forget: if you have the TBrowser open, you may need to click on the **Canvas 1** tab. How did I know which bin limits to use on **`chi2Hist`**? Before I wrote the code, I drew a test histogram with the command: [] tree1->Draw("chi2") Hmm, the histogram's axes aren't labeled. How do I put the labels in the macro? Here's how I figured it out: I labeled the axes on the test histogram by right-clicking on them and selecting {menuselection}`SetTitle`. I saved the canvas by selecting {menuselection}`File --> Save --> c1.C`. I looked at c1.C and saw these commands in the file: chi2->GetXaxis()->SetTitle("chi2"); chi2->GetYaxis()->SetTitle("number of events"); I scrolled up and saw that ROOT had used the variable `chi2` for the name of the histogram pointer. I copied the lines into Analyze.C, but used the name of my histogram instead: chi2Hist->GetXaxis()->SetTitle("chi2"); chi2Hist->GetYaxis()->SetTitle("number of events"); ::: Try this yourself: add the two lines above to the Initialization section, right after the line that defines the histogram. Test the revised Analyze class. [^f79]: Why are we defining a pointer then setting it equal to `NULL`? I'm teaching you to avoid a common problem in programming: uninitialized variables. If we didn't set `chi2Hist` to `NULL`, what would its value be? I don't know. It would likely be set to zero, which is also the typical value of `NULL`. But this behavior varies between different C++ compilers. It's better to be sure. This is not an issue in the code we're writing now, but in the future you'll discover that uninitialized variables cause lots of crashes. Let's get into good programming habits and avoid them from the start. Some compilers offer another name for `NULL`: `nullptr`. They both have the same value, but for you one may be clearer than the other. [^f80]: Actually, in the context of `MakeSelector` it means "get the data from the `TTree` pointed to by `fReader.SetEntry(entry)`". Note that when **`entry`** is 0, `GetEntry` will fetch the first row in the n-tuple; that's why when **`entry`** is 100, `GetEntry` will fetch the 101st row in the n-tuple. [^f81]: It's mildly annoying that whenever you use `MakeSelector` to create an analysis skeleton, you must remember to put a `GetEntry` line. Since `MakeSelector` is doing everything else for us, why can't it put in that one line too so we don't have to remember? The answer is that there's more that can be done with the `TSelector` skeleton than we're doing in this course; do a web search on "[TSelector example](https://www.google.com/search?q=tselector+example)" for some ideas. Since there are times when a simple line like `GetEntry(entry)` is not what you want, or you might create an analysis skeleton for one tree and use it on another, `MakeSelector` makes you put in the `GetEntry` line manually.