(histogram-analyze-reader-c)= # Walkthrough: Making a histogram with the Reader macro **(15 minutes)** Edit the file {file}`AnalyzeReader.C`. In the Definitions section, insert the following code: TH1* chi2Hist = nullptr; :::{admonition} Why use a pointer? :class: 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); :::{admonition} Why here? :class: 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: chi2Hist->Fill(*chi2); :::{admonition} Entry getting and filling :class: note This line means "in the histogram **`chi2Hist`** add 1 to a bin that corresponds to the value of **`*chi2`**." **Important:** Any variable that you define using `TTreeReaderValue` behaves like a pointer. ::: This goes in the Wrap-up section: chi2Hist->Draw(); :::{admonition} Reminder :class: note You already know what this does; you've used it before! ::: Save the file, then enter the same command as before: [] .x AnalyzeReader.C :::{admonition} Finally! :class: 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") :::{admonition} Adding axis labels :class: note 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 AnalyzeReader.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 AnalyzeReader class. [^f79]: Why are we defining a pointer then setting it equal to `nullptr`? I'm teaching you to avoid a common problem in programming: uninitialized variables. If we didn't set `chi2Hist` to `nullptr`, what would its value be? I don't know. It would likely be set to zero, which is also the typical value of `nullptr`. 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.