15 THLimitsFinder *THLimitsFinder::fgLimitsFinder = 0;
17 ClassImp(THLimitsFinder);
32 THLimitsFinder::THLimitsFinder()
38 THLimitsFinder::~THLimitsFinder()
53 Int_t THLimitsFinder::FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax)
56 TAxis *xaxis = h->GetXaxis();
59 if (xaxis->GetLabels()) {xmin = 0; xmax = xmin +xaxis->GetNbins();}
60 else {xmin -= 1; xmax += 1;}
63 THLimitsFinder::OptimizeLimits(xaxis->GetNbins(),
65 xaxis->TestBit(TAxis::kIsInteger));
67 h->SetBins(newbins,xmin,xmax);
78 Int_t THLimitsFinder::FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax)
80 Int_t newbinsx,newbinsy;
81 TAxis *xaxis = h->GetXaxis();
82 TAxis *yaxis = h->GetYaxis();
85 if (xaxis->GetLabels()) {xmin = 0; xmax = xmin +xaxis->GetNbins();}
86 else {xmin -= 1; xmax += 1;}
89 if (yaxis->GetLabels()) {ymin = 0; ymax = ymin +yaxis->GetNbins();}
90 else {ymin -= 1; ymax += 1;}
93 THLimitsFinder::OptimizeLimits(xaxis->GetNbins(),
95 xaxis->TestBit(TAxis::kIsInteger));
97 THLimitsFinder::OptimizeLimits(yaxis->GetNbins(),
99 yaxis->TestBit(TAxis::kIsInteger));
101 h->SetBins(newbinsx,xmin,xmax,newbinsy,ymin,ymax);
111 Int_t THLimitsFinder::FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax)
113 Int_t newbinsx,newbinsy,newbinsz;
114 TAxis *xaxis = h->GetXaxis();
115 TAxis *yaxis = h->GetYaxis();
116 TAxis *zaxis = h->GetZaxis();
119 if (xaxis->GetLabels()) {xmin = 0; xmax = xmin +xaxis->GetNbins();}
120 else {xmin -= 1; xmax += 1;}
123 if (yaxis->GetLabels()) {ymin = 0; ymax = ymin +yaxis->GetNbins();}
124 else {ymin -= 1; ymax += 1;}
127 if (zaxis->GetLabels()) {zmin = 0; zmax = zmin +zaxis->GetNbins();}
128 else {zmin -= 1; zmax += 1;}
131 THLimitsFinder::OptimizeLimits(xaxis->GetNbins(),
133 xaxis->TestBit(TAxis::kIsInteger));
135 THLimitsFinder::OptimizeLimits(yaxis->GetNbins(),
137 yaxis->TestBit(TAxis::kIsInteger));
139 THLimitsFinder::OptimizeLimits(zaxis->GetNbins(),
141 zaxis->TestBit(TAxis::kIsInteger));
143 h->SetBins(newbinsx,xmin,xmax,newbinsy,ymin,ymax,newbinsz,zmin,zmax);
153 THLimitsFinder *THLimitsFinder::GetLimitsFinder()
155 if (!fgLimitsFinder) fgLimitsFinder =
new THLimitsFinder();
156 return fgLimitsFinder;
165 void THLimitsFinder::SetLimitsFinder(THLimitsFinder *finder)
167 fgLimitsFinder = finder;
184 void THLimitsFinder::Optimize(Double_t A1, Double_t A2, Int_t nold ,
185 Double_t &BinLow, Double_t &BinHigh,
186 Int_t &nbins, Double_t &BinWidth,
192 Double_t siground = 0;
193 Double_t alb, awidth, sigfig;
194 Double_t timemulti = 1;
198 if(strchr(option,
't')) optionTime = 1;
else optionTime = 0;
202 Double_t al = TMath::Min(A1,A2);
203 Double_t ah = TMath::Max(A1,A2);
204 if (al == ah) ah = al+1;
206 if (nold == -1 && BinWidth > 0 )
goto L90;
207 ntemp = TMath::Max(nold,2);
208 if (ntemp < 1) ntemp = 1;
211 awidth = (ah-al)/Double_t(ntemp);
213 if (awidth >= FLT_MAX)
goto LOK;
214 if (awidth <= 0)
goto LOK;
219 if (optionTime && awidth>=60) {
221 awidth /= 60; timemulti *=60;
225 awidth /= 60; timemulti *= 60;
229 awidth /= 24; timemulti *= 24;
232 if (awidth>=30.43685) {
233 awidth /= 30.43685; timemulti *= 30.43685;
237 awidth /= 12; timemulti *= 12;
246 jlog = Int_t(TMath::Log10(awidth));
247 if (jlog <-200 || jlog > 200) {
254 if (awidth <= 1 && (!optionTime || timemulti==1) ) jlog--;
255 sigfig = awidth*TMath::Power(10,-jlog) -1e-10;
265 if (sigfig <= 1) siground = 1;
266 else if (sigfig <= 1.5 && jlog==1) siground = 1.5;
267 else if (sigfig <= 2) siground = 2;
268 else if (sigfig <= 3 && jlog ==1) siground = 3;
269 else if (sigfig <= 5 && sigfig>3 && jlog ==0) siground = 5;
270 else if (jlog==0) {siground = 1; jlog++;}
276 if (sigfig <= 1 && jlog==0) siground = 1;
277 else if (sigfig <= 1.2 && jlog==1) siground = 1.2;
278 else if (sigfig <= 2 && jlog==0) siground = 2;
279 else if (sigfig <= 2.4 && jlog==1) siground = 2.4;
280 else if (sigfig <= 3) siground = 3;
281 else if (sigfig <= 6) siground = 6;
282 else if (jlog==0) siground = 12;
288 if (sigfig <= 1 && jlog==0) siground = 1;
289 else if (sigfig <= 1.4 && jlog==1) siground = 1.4;
290 else if (sigfig <= 3 && jlog ==1) siground = 3;
296 if (sigfig <= 1) siground = 1;
297 else if (sigfig <= 2) siground = 2;
298 else if (sigfig <= 5 && (!optionTime || jlog<1)) siground = 5;
299 else if (sigfig <= 6 && optionTime && jlog==1) siground = 6;
300 else {siground = 1; jlog++; }
304 BinWidth = siground*TMath::Power(10,jlog);
305 if (optionTime) BinWidth *= timemulti;
311 if (TMath::Abs(alb) > 1e9) {
314 if (nbins > 10*nold && nbins > 10000) nbins = nold;
319 BinLow = BinWidth*Double_t(lwid);
320 alb = ah/BinWidth + 1.00001;
323 BinHigh = BinWidth*Double_t(kwid);
325 if (nold == -1)
goto LOK;
327 if (nold > 1 || nbins == 1)
goto LOK;
328 BinWidth = BinWidth*2;
332 if (2*nbins == nold && !optionTime) {ntemp++;
goto L20; }
335 Double_t oldBinLow = BinLow;
336 Double_t oldBinHigh = BinHigh;
337 Int_t oldnbins = nbins;
339 Double_t atest = BinWidth*0.0001;
342 if (al-BinLow >= atest) { BinLow += BinWidth; nbins--; }
343 if (BinHigh-ah >= atest) { BinHigh -= BinWidth; nbins--; }
344 if (!optionTime && BinLow >= BinHigh) {
347 BinHigh = oldBinHigh;
350 else if (optionTime && BinLow>=BinHigh) {
352 BinHigh = oldBinHigh;
354 BinWidth = (oldBinHigh - oldBinLow)/nbins;
355 atest = BinWidth*0.0001;
356 if (al-BinLow >= atest) { BinLow += BinWidth; nbins--; }
357 if (BinHigh-ah >= atest) { BinHigh -= BinWidth; nbins--; }
367 void THLimitsFinder::OptimizeLimits(Int_t nbins, Int_t &newbins, Double_t &xmin, Double_t &xmax, Bool_t isInteger)
369 Double_t binlow = 0,binhigh = 0,binwidth=0;
371 Double_t dx = 0.1*(xmax-xmin);
372 if (isInteger) dx = 5*(xmax-xmin)/nbins;
373 Double_t umin = xmin - dx;
374 Double_t umax = xmax + dx;
375 if (umin < 0 && xmin >= 0) umin = 0;
376 if (umax > 0 && xmax <= 0) umax = 0;
378 THLimitsFinder::Optimize(umin,umax,nbins,binlow,binhigh,n,binwidth,
"");
380 if (binwidth <= 0 || binwidth > 1.e+39) {
388 Int_t ixmin = Int_t(xmin);
389 Int_t ixmax = Int_t(xmax);
390 Double_t dxmin = Double_t(ixmin);
391 Double_t dxmax = Double_t(ixmax);
392 if (xmin < 0 && xmin != dxmin) xmin = dxmin - 1;
394 if (xmax > 0 && xmax != dxmax) xmax = dxmax + 1;
395 else if (xmax ==0 && xmax == dxmax) xmax = 1;
397 if (xmin >= xmax) xmax = xmin+1;
398 Int_t bw = Int_t((xmax-xmin)/nbins);
400 nbins = Int_t((xmax-xmin)/bw);
401 if (xmin +nbins*bw < umax) {nbins++; xmax = xmin +nbins*bw;}
402 if (xmin > umin) {nbins++; xmin = xmax -nbins*bw;}