ATLAS Offline Software
Loading...
Searching...
No Matches
ScatterH2.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// $Id: ScatterH2.cxx,v 1.5 2008-01-17 20:56:38 ssnyder Exp $
12
13
14#include "RootUtils/ScatterH2.h"
15#include "TVirtualPad.h"
16#include "TPolyMarker.h"
17#include "TColor.h"
18#include "TArrayD.h"
19#include "TList.h"
20#include "TROOT.h"
21#include "TClass.h"
22#include "TMemberInspector.h"
23
24#include <vector>
25#include <cassert>
26
27
28namespace RootUtils {
29
30
35 : m_scatter (true),
36 m_shadestep (0)
37{
38}
39
40
52ScatterH2::ScatterH2 (const char *name, const char *title,
53 Int_t nbinsx, Axis_t xlow, Axis_t xup,
54 Int_t nbinsy, Axis_t ylow, Axis_t yup)
55 : TH2F (name, title, nbinsx, xlow, xup, nbinsy, ylow, yup),
56 m_scatter (true),
57 m_shadestep (0)
58{
59}
60
61
72ScatterH2::ScatterH2 (const char *name, const char *title,
73 Int_t nbinsx, const Double_t* xbins,
74 Int_t nbinsy, Axis_t ylow, Axis_t yup)
75 : TH2F (name, title, nbinsx, xbins, nbinsy, ylow, yup),
76 m_scatter (true),
77 m_shadestep (0)
78{
79}
80
81
82
92ScatterH2::ScatterH2 (const char *name, const char *title,
93 const TArrayD& xbins,
94 Int_t nbinsy, Axis_t ylow, Axis_t yup)
95 : TH2F (name, title, xbins.GetSize()-1, xbins.GetArray(),
96 nbinsy, ylow, yup),
97 m_scatter (true),
98 m_shadestep (0)
99{
100}
101
102
110void ScatterH2::Paint (Option_t* option /*= ""*/)
111{
112 if (!m_scatter) {
113 TH2F::Paint (option);
114 return;
115 }
116
117 // Muck with things to prevent the normal histogram output.
118 double oldmax = GetMaximumStored ();
119 double oldmin = GetMinimumStored ();
120 SetMaximum (0);
121 SetMinimum (0);
122
123 // Get the frame, etc., drawn.
124 TH2F::Paint (option);
125
126 SetMaximum (oldmax);
127 SetMinimum (oldmin);
128
129 // Gotta to this to get the coordinates set up properly.
130 gPad->Update();
131
132 // Work around a root bug.
133 // THistPainter::PaintTable2 will add a TPaveStats object
134 // to the function list. However, if we then try to paint
135 // the same histo again, then there is code in THistPainter
136 // that expects the things in the function list to derive
137 // from TF1. There's no checking on the downcast, so root
138 // crashes...
139 GetListOfFunctions()->Clear();
140
141 // Get coordinate bounds.
142 Double_t u, v;
143 Double_t umin = gPad->GetUxmin();
144 Double_t umax = gPad->GetUxmax();
145 Double_t vmin = gPad->GetUymin();
146 Double_t vmax = gPad->GetUymax();
147
148 int pxmin = gPad->XtoAbsPixel (umin);
149 int pxmax = gPad->XtoAbsPixel (umax);
150 int pymin = gPad->YtoAbsPixel (vmin);
151 int pymax = gPad->YtoAbsPixel (vmax);
152 if (pxmin > pxmax) std::swap (pxmin, pxmax);
153 if (pymin > pymax) std::swap (pymin, pymax);
154 int pxsize = pxmax - pxmin + 1;
155 int pysize = pymax - pymin + 1;
156 std::vector<unsigned int> counts (pxsize * pysize);
157
158 TVirtualPad* pad = gPad;
159
160 // Count the number of points on each pixel.
161 unsigned int maxcount = 0;
162 unsigned int n = m_vals.size();
163 for (unsigned int i=0; i<n; i++) {
164 u = pad->XtoPad (m_vals[i].first);
165 v = pad->YtoPad (m_vals[i].second);
166 if (u < umin) u = umin;
167 if (u > umax) u = umax;
168 if (v < vmin) v = vmin;
169 if (v > vmax) v = vmax;
170
171 int px = pad->XtoAbsPixel (u);
172 int py = pad->YtoAbsPixel (v);
173 if (px < pxmin || px > pxmax || py < pymin || py > pymax) continue;
174 unsigned ndx = (px-pxmin) + (py-pymin) * pxsize;
175 assert (ndx < counts.size());
176 ++counts[ndx];
177 if (counts[ndx] > maxcount)
178 maxcount = counts[ndx];
179 }
180
181 const unsigned int NCOLOR = 255;
182
183 // Figure out shading.
184 float step = 0;
185 if (m_shadestep) {
186 if (m_shadestep > 0)
187 step = m_shadestep;
188 else if (maxcount > 2)
189 step = static_cast<float>(NCOLOR-1)/(maxcount-1);
190 else
191 step = NCOLOR-1;
192 }
193
194 // Count the number of points for each color.
195 unsigned int ccounts[NCOLOR];
196 std::uninitialized_fill (ccounts, ccounts+NCOLOR, 0);
197 size_t ndxmax = counts.size();
198 for (unsigned int i=0; i < ndxmax; i++) {
199 unsigned int count = counts[i];
200 if (count > 0) {
201 unsigned int color = static_cast<unsigned int> ((count-1)*step);
202 if (color >= NCOLOR) color = NCOLOR-1;
203 ++ccounts[color];
204 }
205 }
206
207 TPolyMarker* pms[NCOLOR];
208 std::uninitialized_fill (pms, pms+NCOLOR, (TPolyMarker*)0);
209
210 // Fill in the polymarkers.
211 for (int py = pymin; py <= pymax; ++py) {
212 for (int px = pxmin; px <= pxmax; ++px) {
213 unsigned int ndx = (px-pxmin) + (py-pymin) * pxsize;
214 assert (ndx < ndxmax);
215 unsigned int count = counts[ndx];
216 if (count > 0) {
217 Double_t u = pad->AbsPixeltoX (px);
218 Double_t v = pad->AbsPixeltoY (py);
219 unsigned int color = static_cast<unsigned int> ((count-1)*step);
220 if (color >= NCOLOR) color = NCOLOR-1;
221
222 TPolyMarker* pm = pms[color];
223 if (!pm) {
224 pm = new TPolyMarker (ccounts[color]);
225 ccounts[color] = 0;
226 pm->SetMarkerStyle (GetMarkerStyle());
227 pm->SetMarkerSize (GetMarkerSize());
228 if (color != 0)
229 pm->SetMarkerColor (TColor::GetColor (color, 0, 0));
230 pms[color] = pm;
231 }
232 pm->SetPoint (ccounts[color]++, u, v);
233 }
234 }
235 }
236
237 // Draw the points.
238 for (unsigned int i = 0; i < NCOLOR; i++) {
239 if (pms[i]) {
240 pms[i]->Paint();
241 delete pms[i];
242 }
243 }
244}
245
246
254void ScatterH2::Reset (Option_t *option /*= ""*/)
255{
256 TString opt = option;
257 if (!opt.Contains("ICE")) {
258 // Clear out m_vals too, releasing memory.
259 std::vector<Pair> tmp;
260 m_vals.swap (tmp);
261 }
262 TH2F::Reset (option);
263}
264
265
275Int_t ScatterH2::Fill (Axis_t x, Axis_t y, Stat_t w)
276{
277 // Remember the point in m_vals.
278 m_vals.push_back (Pair (x, y));
279 return TH2F::Fill (x, y, w);
280}
281
282
288Int_t ScatterH2::Fill(Axis_t x, Axis_t y)
289{
290 return Fill (x, y, 1.0);
291}
292
293
301{
302 return m_scatter;
303}
304
305
314bool ScatterH2::scatter (bool flag)
315{
316 bool x = m_scatter;
317 m_scatter = flag;
318 return x;
319}
320
321
332{
333 return m_shadestep;
334}
335
336
349{
350 int x = m_shadestep;
352 return x;
353}
354
355
357ScatterH2::rescale (const char* name, double xscale, double yscale) const
358{
359 int nx = GetXaxis()->GetNbins();
360 double xlo = GetXaxis()->GetXmin();
361 double xhi = GetXaxis()->GetXmax();
362
363 int ny = GetYaxis()->GetNbins();
364 double ylo = GetYaxis()->GetXmin();
365 double yhi = GetYaxis()->GetXmax();
366
367#if 0
368 ScatterH2* hnew = new ScatterH2 (name, GetTitle(),
369 nx, xscale*xlo, xscale*xhi,
370 ny, yscale*ylo, yscale*yhi);
371#endif
372 ScatterH2* hnew = dynamic_cast<ScatterH2*> (this->Clone (name));
373 if (hnew == 0)
374 return 0;
375 hnew->GetXaxis()->Set (nx, xscale*xlo, xscale*xhi);
376 hnew->GetYaxis()->Set (ny, yscale*ylo, yscale*yhi);
377 size_t n = hnew->m_vals.size();
378 for (size_t i = 0; i < n; i++) {
379 hnew->m_vals[i].first *= xscale;
380 hnew->m_vals[i].second *= yscale;
381 }
382
383 return hnew;
384}
385
386
387} // namespace RootUtils
A 2-D histogram that can draw a proper scatter plot.
#define y
#define x
A 2-D histogram that can draw a proper scatter plot.
Definition ScatterH2.h:68
int m_shadestep
shadestep option.
Definition ScatterH2.h:228
virtual void Reset(Option_t *option="")
Standard ROOT reset method.
std::vector< Pair > m_vals
The collection of points that have been plotted.
Definition ScatterH2.h:240
int shadestep() const
Get the current value of shadestep.
ScatterH2()
Default constructor.
Definition ScatterH2.cxx:34
virtual Int_t Fill(Axis_t x, Axis_t y, Stat_t w)
Standard ROOT fill method.
virtual void Paint(Option_t *option="")
Standard ROOT paint method.
ScatterH2 * rescale(const char *name, double xscale, double yscale) const
Return a new plot with all data points multiplied by a constant.
bool m_scatter
The scatter flag.
Definition ScatterH2.h:219
bool scatter() const
Get the current value of the scatter flag.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
One point. Avoid std::pair so that we don't have duplicate dicts.
Definition ScatterH2.h:233