00001 #include <iostream>
00002
00003 #include "TF1.h"
00004 #include "TH2.h"
00005 #include "TMath.h"
00006 #include "TCanvas.h"
00007 #include "TROOT.h"
00008 #include "TAxis.h"
00009 #include "TGaxis.h"
00010 #include "TLine.h"
00011 #include "TLatex.h"
00012 #include "TGraph.h"
00013 #include "TStyle.h"
00014 #include "MessageService/MsgService.h"
00015
00016
00017 #include "NtupleUtils/NuContour.h"
00018
00019 using namespace std;
00020 int NuContour::nFillCols = 10;
00021 int NuContour::usedFills = 0;
00022 Int_t* NuContour::colFill = 0;
00023 CVSID("$Id: ");
00024
00025
00026
00027 NuContour::NuContour()
00028 : lin(true), loglin(false), log(false),
00029 fillLevel(-1), contLevel(0), neg(1),
00030 hdivide(9999), ymid(0), bmid(250), bmax(500)
00031 {
00032 if (!colFill) {
00033 colFill = new Int_t[10];
00034 for (int i = 0; i < 10; i++) {
00035 colFill[i] = 0;
00036 }
00037 }
00038
00039 hist = 0;
00040 disp_hist = 0;
00041 hist_high = 0;
00042
00043 graph = 0;
00044 disp_graph = 0;
00045 }
00046
00047
00048
00049 NuContour::NuContour(const TH2D *hin)
00050 : lin(true), loglin(false), log(false),
00051 fillLevel(-1), contLevel(0), neg(1),
00052 hdivide(9999), ymid(0), bmid(250), bmax(500)
00053 {
00054 if (!colFill) {
00055 colFill = new Int_t[10];
00056 for (int i = 0; i < 10; i++) {
00057 colFill[i] = 0;
00058 }
00059 }
00060
00061 hist = new TH2D(*hin);
00062 disp_hist = 0;
00063 hist_high = 0;
00064
00065 graph = 0;
00066 disp_graph = 0;
00067 }
00068
00069
00070
00071 NuContour::NuContour(const TGraph *g)
00072 : lin(true), loglin(false), log(false),
00073 fillLevel(-1), contLevel(0), neg(1),
00074 hdivide(9999), ymid(0), bmid(250), bmax(500)
00075 {
00076
00077 if (!colFill) {
00078 colFill = new Int_t[10];
00079 for (int i = 0; i < 10; i++) {
00080 colFill[i] = 0;
00081 }
00082 }
00083
00084 hist = 0;
00085 disp_hist = 0;
00086 hist_high = 0;
00087
00088 graph = new TGraph(*g);
00089 disp_graph = 0;
00090 }
00091
00092
00093
00094 NuContour::NuContour(const NuContour &rhs)
00095 {
00096 Reset();
00097 if (rhs.hist) hist = new TH2D(*rhs.hist);
00098 if (rhs.disp_hist) disp_hist = new TH2D(*rhs.disp_hist);
00099 if (rhs.hist_high) hist_high = new TH2D(*rhs.hist_high);
00100 if (rhs.graph) graph = new TGraph(*rhs.graph);
00101 if (rhs.disp_graph) disp_graph = new TGraph(*rhs.disp_graph);
00102
00103 lin = rhs.lin;
00104 loglin = rhs.loglin;
00105 log = rhs.log;
00106 fillLevel = rhs.fillLevel;
00107 contLevel = rhs.contLevel;
00108 neg = rhs.neg;
00109 hdivide = rhs.hdivide;
00110 ymid = rhs.ymid;
00111 ymax = rhs.ymax;
00112 bmid = rhs.bmid;
00113 bmax = rhs.bmax;
00114 }
00115
00116
00117
00118 NuContour & NuContour::operator=(const NuContour &rhs)
00119 {
00120
00121 if (this == &rhs) return *this;
00122
00123 Reset();
00124 if (rhs.hist) hist = new TH2D(*rhs.hist);
00125 if (rhs.disp_hist) disp_hist = new TH2D(*rhs.disp_hist);
00126 if (rhs.hist_high) hist_high = new TH2D(*rhs.hist_high);
00127 if (rhs.graph) graph = new TGraph(*rhs.graph);
00128 if (rhs.disp_graph) disp_graph = new TGraph(*rhs.disp_graph);
00129
00130 lin = rhs.lin;
00131 loglin = rhs.loglin;
00132 log = rhs.log;
00133 fillLevel = rhs.fillLevel;
00134 contLevel = rhs.contLevel;
00135 neg = rhs.neg;
00136 hdivide = rhs.hdivide;
00137 ymid = rhs.ymid;
00138 ymax = rhs.ymax;
00139 bmid = rhs.bmid;
00140 bmax = rhs.bmax;
00141
00142 return *this;
00143 }
00144
00145
00146
00147 NuContour::~NuContour()
00148 {
00149 Reset();
00150 }
00151
00152
00153
00154 void NuContour::Reset()
00155 {
00156
00157
00158
00159
00160
00161
00162
00163
00164 hist = 0;
00165 disp_hist = 0;
00166 hist_high = 0;
00167 graph = 0;
00168 disp_graph = 0;
00169
00170 }
00171
00172
00173 void NuContour::Reset(TH2D *hin)
00174 {
00175 Reset();
00176 hist = new TH2D(*hin);
00177 if (IsLogLin()) DoLogLin();
00178 if (IsLog()) DoLog();
00179 }
00180
00181
00182 void NuContour::Reset(TGraph *g)
00183 {
00184 Reset();
00185 graph = new TGraph(*g);
00186 if (IsLogLin()) DoLogLin();
00187 if (IsLog()) DoLog();
00188 }
00189
00190
00191 void NuContour::AddExtraHist(TH2D *hin, double crossover)
00192 {
00193 hist_high = new TH2D(*hin);
00194 hdivide = crossover;
00195
00196 Double_t diff = MinBin(*hist) - MinBin(*hist_high);
00197 if (diff < 0) ShiftHist(hist_high, diff);
00198 else ShiftHist(hist, -diff);
00199
00200 if (IsLogLin()) DoLogLin();
00201 if (IsLog()) DoLog();
00202 }
00203
00204
00205
00206 void NuContour::Combine(TH2D* correction)
00207 {
00208 double min = 0;
00209
00210 if (hist) {
00211 min = MinBin(*hist);
00212 ShiftHist(hist, -min);
00213 Add(hist, correction);
00214 }
00215 if (hist_high) {
00216 ShiftHist(hist_high, -min);
00217 Add(hist_high, correction);
00218 }
00219 if (disp_hist) {
00220 ShiftHist(disp_hist, -min);
00221 Add(disp_hist, correction, 1, true);
00222 }
00223
00224 }
00225
00226
00227
00228 void NuContour::Combine(TH2D* correction_low, TH2D* correction_high)
00229 {
00230 double min = 0;
00231
00232 if (hist) {
00233 min = MinBin(*hist);
00234 ShiftHist(hist, -min);
00235 Add(hist, correction_low);
00236 }
00237 if (hist_high) {
00238 ShiftHist(hist_high, -min);
00239 Add(hist_high, correction_high);
00240 AddExtraHist(hist_high, hdivide);
00241 }
00242 }
00243
00244
00245
00246 void NuContour::SetGauss(double level)
00247 {
00248 double min = 0;
00249 contLevel = 0;
00250
00251 if (hist) {
00252 min = MinBin(*hist);
00253 ShiftHist(hist, -min-level);
00254 ChooseContour(hist);
00255 }
00256 if (hist_high) {
00257 ShiftHist(hist_high, -min-level);
00258 ChooseContour(hist_high);
00259 }
00260 if (disp_hist) {
00261 ShiftHist(disp_hist, -min-level);
00262 ChooseContour(disp_hist);
00263 }
00264 }
00265
00266
00267
00268
00269
00270 void NuContour::SetFC(TH2D* correction)
00271 {
00272 double min = 0;
00273 contLevel = 0;
00274
00275 if (hist) {
00276 min = MinBin(*hist);
00277 ShiftHist(hist, -min);
00278 Add(hist, correction, -1);
00279 ChooseContour(hist);
00280 }
00281 if (hist_high) {
00282 ShiftHist(hist_high, -min);
00283 Add(hist_high, correction, -1);
00284 ChooseContour(hist_high);
00285 }
00286 if (disp_hist) {
00287 ShiftHist(disp_hist, -min);
00288 Add(disp_hist, correction, -1, true);
00289 ChooseContour(disp_hist);
00290 }
00291
00292 }
00293
00294
00295
00296
00297 void NuContour::Add(TH2D *surface, TH2D* correction, double scale, bool convert)
00298 {
00299 double xval, yval, val, corr;
00300
00301 for (int xbin = 1; xbin <= surface->GetNbinsX(); xbin++) {
00302 for (int ybin = 1; ybin <= surface->GetNbinsY(); ybin++) {
00303 val = surface->GetBinContent(xbin, ybin);
00304
00305 xval = surface->GetXaxis()->GetBinCenter(xbin);
00306 yval = surface->GetYaxis()->GetBinCenter(ybin);
00307 if (convert) yval = Can2Cont(yval);
00308
00309 corr = interpolate(correction, xval, yval, 0);
00310
00311 surface->SetBinContent(xbin, ybin, val + scale*corr);
00312 }
00313 }
00314 }
00315
00316
00317
00318 void NuContour::ContourStyle(int color, int width, int style)
00319 {
00320 if (graph) {
00321 graph->SetLineWidth(width);
00322 graph->SetLineColor(color);
00323 graph->SetLineStyle(style);
00324 }
00325 if (disp_graph) {
00326 disp_graph->SetLineWidth(width);
00327 disp_graph->SetLineColor(color);
00328 disp_graph->SetLineStyle(style);
00329 }
00330
00331 if (hist) {
00332 if (style != 1 && !graph && !disp_graph) {
00333 MSG("NuContour",Msg::kWarning)
00334 << "Line styles other than solid do not come out well on histogram." << endl
00335 << "For better results call ConvertToGraph() on this contour." << endl;
00336 }
00337
00338 hist->SetLineWidth(width);
00339 hist->SetLineColor(color);
00340 hist->SetLineStyle(style);
00341 ChooseContour(hist);
00342 }
00343 if (hist_high) {
00344 hist_high->SetLineWidth(width);
00345 hist_high->SetLineColor(color);
00346 hist_high->SetLineStyle(style);
00347 ChooseContour(hist_high);
00348 }
00349 if (disp_hist) {
00350 disp_hist->SetLineWidth(width);
00351 disp_hist->SetLineColor(color);
00352 disp_hist->SetLineStyle(style);
00353 ChooseContour(disp_hist);
00354 }
00355 }
00356
00357
00358 void NuContour::ContourFillStyle(int color, int style)
00359 {
00360
00361 if (graph || disp_graph) {
00362 fillLevel = 999;
00363 if (graph) {
00364 graph->SetFillColor(color);
00365 graph->SetFillStyle(style);
00366 }
00367 if (disp_graph) {
00368 disp_graph->SetFillColor(color);
00369 disp_graph->SetFillStyle(style);
00370 }
00371 }
00372 else {
00373 neg = -1;
00374 fillLevel = usedFills;
00375 usedFills++;
00376
00377 MSG("NuContour",Msg::kInfo) << "Setting countour level " << fillLevel << " to color " << color << endl;
00378 MSG("NuContour",Msg::kInfo) << "Current palette: " << endl;
00379 colFill[nFillCols-fillLevel-1] = color;
00380 gStyle->SetPalette(nFillCols,colFill);
00381 for (int i = nFillCols - fillLevel - 1; i < nFillCols; i++) {
00382 MSG("NuContour",Msg::kInfo) << " colFill[" << i << "] = " << colFill[i] << endl;
00383 }
00384
00385
00386 if (hist) {
00387 ChooseContour(hist);
00388 hist->SetFillColor(color);
00389 hist->SetFillStyle(style);
00390 }
00391 if (hist_high) {
00392 ChooseContour(hist_high);
00393 hist_high->SetFillColor(color);
00394 hist_high->SetFillStyle(style);
00395 }
00396 if (disp_hist) {
00397 ChooseContour(disp_hist);
00398 disp_hist->SetFillColor(color);
00399 disp_hist->SetFillStyle(style);
00400 }
00401 }
00402
00403
00404 }
00405
00406
00407 void NuContour::DoLin()
00408 {
00409 lin = true;
00410 loglin = false;
00411 log = false;
00412 bmid = bmax;
00413
00414 hist->GetXaxis()->CenterTitle();
00415 TAxis *a1 = hist->GetYaxis();
00416 a1->SetLabelSize(0);
00417 a1->SetTickLength(0);
00418 a1->SetTitleOffset(1.2);
00419 a1->CenterTitle();
00420 a1->SetTitleOffset(1.2);
00421 hist->SetTitle(";sin^{2}(2#bar{#theta});|#Delta#bar{m}^{2}| (10^{-3} eV^{2})");
00422 }
00423
00424
00425
00426 void NuContour::DoLogLin()
00427 {
00428 lin = false;
00429 loglin = true;
00430 log = false;
00431 bmid = bmax / 2;
00432 GenerateLogLin();
00433 }
00434
00435
00436
00437 void NuContour::DoLog()
00438 {
00439 lin = false;
00440 loglin = false;
00441 log = true;
00442 bmid = 0;
00443 GenerateLog();
00444 }
00445
00446
00447
00448 TH2D * NuContour::GetHist()
00449 {
00450 if (!hist) {
00451 MSG("NuContour",Msg::kWarning)
00452 << "Histogram not defined for this contour." << endl;
00453 return 0;
00454 }
00455 if (IsLin()) {
00456
00457 return hist;
00458 }
00459 else if (IsLogLin()) {
00460
00461 return disp_hist;
00462 }
00463 else if (IsLog()) {
00464
00465 return disp_hist;
00466 }
00467 else {
00468 MSG("NuContour",Msg::kError)
00469 << "Contour is in undefined mode. This shouldn't happen." << endl;
00470 return 0;
00471 }
00472 }
00473
00474
00475
00476 TGraph * NuContour::GetGraph()
00477 {
00478 if (!graph && !disp_graph) {
00479 MSG("NuContour",Msg::kWarning)
00480 << "Graph not defined for this contour." << endl;
00481 return 0;
00482 }
00483 if (IsLin()) {
00484
00485 return graph;
00486 }
00487 else if (IsLogLin() || IsLog()) {
00488
00489 return disp_graph;
00490 }
00491 else {
00492 MSG("NuContour",Msg::kError)
00493 << "Contour is in undefined mode. This shouldn't happen." << endl;
00494 return 0;
00495 }
00496 }
00497
00498
00499
00500
00501 void NuContour::ConvertToGraph()
00502 {
00503 if (graph && !hist) {
00504 MSG("NuContour",Msg::kWarning)
00505 << "Already a graph contour -- cannot be converted" << endl;
00506 return;
00507 }
00508 else if (!hist && !disp_hist) {
00509 MSG("NuContour",Msg::kWarning)
00510 << "No histogram -- cannot be converted" << endl;
00511 return;
00512 }
00513 else if (IsLogLin()) {
00514 MSG("NuContour",Msg::kWarning)
00515 << "Convert to graph not supported for LogLin histograms" << endl;
00516 return;
00517 }
00518 else {
00519 MSG("NuContour",Msg::kInfo)
00520 << "Converting histogram to graph" << endl;
00521 }
00522
00523 TVirtualPad *curr = gPad;
00524 TCanvas *ctemp = new TCanvas("ctemp","ctemp");
00525
00526
00527
00528
00529
00530
00531 if (!hist_high) {
00532 hist->Draw("cont list");
00533
00534 ctemp->Update();
00535 ctemp->Paint();
00536
00537 TObjArray *contours = (TObjArray*)gROOT->GetListOfSpecials()->At(0);
00538 TList *lcontour1 = (TList*)contours->At(0);
00539 graph = new TGraph();
00540 graph->Merge(lcontour1);
00541
00542
00543 delete ctemp; ctemp = 0;
00544
00545 if (curr) curr->cd();
00546
00547 if (IsLog()) DoLog();
00548 if (IsLogLin()) DoLogLin();
00549 }
00550 else {
00551 if (IsLog()) DoLog();
00552 if (IsLogLin()) DoLogLin();
00553 ChooseContour(disp_hist);
00554 disp_hist->Draw("cont list");
00555
00556 ctemp->Update();
00557 ctemp->Paint();
00558
00559 TObjArray *contours = (TObjArray*)gROOT->GetListOfSpecials()->At(0);
00560 TList *lcontour1 = (TList*)contours->At(0);
00561 disp_graph = new TGraph();
00562 graph = new TGraph();
00563 disp_graph->Merge(lcontour1);
00564 double px, py, y;
00565 for (int i = 0; i < disp_graph->GetN(); i++) {
00566 disp_graph->GetPoint(i, px, py);
00567 y = Can2Cont(py);
00568 graph->SetPoint(i, px, y);
00569 }
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 delete ctemp; ctemp = 0;
00604
00605 if (curr) curr->cd();
00606
00607 }
00608 }
00609
00610
00611 void NuContour::AddCorner(bool upper, bool right)
00612 {
00613 double x, y, yd;
00614 if (upper) {
00615 y = ymax;
00616 yd = bmax;
00617 }
00618 else {
00619 if (IsLog()) y = ymid;
00620 else y = 0;
00621 yd = 0;
00622 }
00623 if (right) x = 1;
00624 else x = 0;
00625
00626 disp_graph->SetPoint(disp_graph->GetN(), x, yd);
00627 graph->SetPoint(graph->GetN(), x, y);
00628 }
00629
00630
00631
00632 void NuContour::CompleteGraph()
00633 {
00634 double x, y;
00635
00636 disp_graph->GetPoint(0, x, y);
00637 disp_graph->SetPoint(disp_graph->GetN(), x, y);
00638
00639 graph->GetPoint(0, x, y);
00640 graph->SetPoint(graph->GetN(), x, y);
00641
00642
00643 }
00644
00645
00646
00647 void NuContour::Draw(TString opt)
00648 {
00649 if (graph || disp_graph) {
00650 opt += "l";
00651 if (fillLevel >= 0) opt+="cf";
00652 MSG("NuContour",Msg::kInfo) << "Drawing graph with opt=" << opt << endl;
00653 GetGraph()->Draw(opt);
00654 }
00655 else {
00656 opt += "cont3";
00657 if (fillLevel >= 0) {
00658 opt+="col";
00659 }
00660 MSG("NuContour",Msg::kInfo) << "Drawing histogram with opt=" << opt << endl;
00661 TH2D *htemp = new TH2D(*GetHist());
00662 htemp->Scale(neg);
00663 htemp->Draw(opt);
00664 }
00665 }
00666
00667
00668
00669 void NuContour::GenerateLogLin()
00670 {
00671 if (hist) {
00672 GenerateLogLinHist();
00673 }
00674 if (graph) {
00675 GenerateLogLinGraph();
00676 }
00677 }
00678
00679
00680
00681 void NuContour::GenerateLog()
00682 {
00683 GenerateLogLin();
00684
00685
00686
00687
00688 }
00689
00690
00691
00692 void NuContour::GenerateLogLinHist()
00693 {
00694 static int n = -1;
00695 n++;
00696 TString num(n);
00697 disp_hist = new TH2D("hCombo"+num,";sin^{2}(2#bar{#theta});|#Delta#bar{m}^{2}| (10^{-3} eV^{2})",
00698 500, 0, 1,
00699 bmax, 0, bmax);
00700 disp_hist->GetXaxis()->CenterTitle();
00701 disp_hist->GetYaxis()->CenterTitle();
00702
00703
00704 TAxis *a1 = disp_hist->GetYaxis();
00705 a1->SetLabelSize(0);
00706 a1->SetTickLength(0);
00707 a1->SetTitleOffset(1.2);
00708
00709
00710 double val;
00711 double x, y;
00712 TH2D * hOld = 0;
00713
00714 for (int by = 1; by <= disp_hist->GetNbinsY(); by++) {
00715 y = Can2Cont(by);
00716
00717 if (hist_high) {
00718 if (y > hdivide) hOld = hist_high;
00719 else hOld = hist;
00720 }
00721 else {
00722 hOld = hist;
00723 }
00724
00725 for (int bx = 1; bx <= disp_hist->GetNbinsX(); bx++) {
00726 x = disp_hist->GetBinCenter(bx);
00727
00728
00729
00730
00731 val = interpolate(hOld, x, y);
00732
00733 disp_hist->SetBinContent(bx, by, val);
00734 }
00735 }
00736 }
00737
00738
00739
00740 void NuContour::GenerateLogHist()
00741 {
00742 static int n = -1;
00743 n++;
00744 TString num(n);
00745 disp_hist = new TH2D("hLog"+num,";sin^{2}(2#bar{#theta});|#Delta#bar{m}^{2}| (10^{-3} eV^{2})",
00746 100, 0, 1,
00747 500, ymid, ymax);
00748 disp_hist->GetXaxis()->CenterTitle();
00749 disp_hist->GetYaxis()->CenterTitle();
00750
00751
00752 TAxis *a1 = disp_hist->GetYaxis();
00753
00754
00755 a1->SetTitleOffset(1.2);
00756
00757
00758 double val;
00759 double x, y;
00760 TH2D * hOld = 0;
00761
00762 for (int by = 1; by <= disp_hist->GetNbinsY(); by++) {
00763 y = Can2Cont(by);
00764
00765 if (hist_high) {
00766 if (y > hdivide) hOld = hist_high;
00767 else hOld = hist;
00768 }
00769 else {
00770 hOld = hist;
00771 }
00772
00773 for (int bx = 1; bx <= disp_hist->GetNbinsX(); bx++) {
00774 x = disp_hist->GetBinCenter(bx);
00775
00776
00777
00778
00779 val = interpolate(hOld, x, y);
00780
00781 disp_hist->SetBinContent(bx, by, val);
00782 }
00783 }
00784 }
00785
00786
00787
00788 void NuContour::GenerateLogLinGraph()
00789 {
00790 if (graph == disp_graph) {
00791 MSG("NuContour",Msg::kInfo) << "Converting disp_graph has precednece -- no conversion" << endl;
00792 }
00793
00794 disp_graph = new TGraph(*graph);
00795 TString name = graph->GetName();
00796 disp_graph->SetName(name+"LL");
00797 double px, py, y;
00798
00799 for (int i = 0; i < disp_graph->GetN(); i++) {
00800 disp_graph->GetPoint(i, px, py);
00801 y = Cont2Can(py);
00802
00803 disp_graph->SetPoint(i, px, y);
00804 }
00805 }
00806
00807
00808
00809 void NuContour::FixCanvas(TCanvas *c1)
00810 {
00811 c1->SetCanvasSize(700,1000);
00812 c1->SetWindowSize(700,1000);
00813 c1->SetLeftMargin(0.2);
00814 c1->SetRightMargin(0.05);
00815 }
00816
00817
00818
00819 void NuContour::DrawAxes(int size)
00820 {
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 double gxmin = gPad->GetUxmin();
00831 double gymin = gPad->GetUymin();
00832 double gxmax = gPad->GetUxmax();
00833 double gymax = gPad->GetUymax();
00834 MSG("NuContour",Msg::kInfo) << "Drawing axes. Found canvas range x: " << gxmin << " - " << gxmax << ", y: " << gymin << " - " << gymax << endl;
00835 int div_lin = 505;
00836 int div_log = 505;
00837
00838
00839 double x1 = gxmin;
00840 double x2 = gxmax;
00841 double y0 = gymin;
00842 double y1 = gymax*bmid/bmax;
00843 double y2 = gymax;
00844
00845
00846
00847 if (IsLin()) {
00848 ymid = y2;
00849 }
00850
00851 TF1 *fLin = new TF1("fLin","x",0,ymid);
00852 TF1 *fLog = new TF1("fLog","TMath::Log10(x)",ymid,ymax);
00853
00854 fLin->GetName();
00855 fLog->GetName();
00856
00857
00858 if (IsLog() || IsLogLin()) {
00859
00860
00861 TGaxis *aLeft_log = new TGaxis(x1, y1, x1, y2, "fLog", div_log,"G");
00862 TGaxis *aRight_log = new TGaxis(x2, y1, x2, y2, "fLog", div_log, "+G");
00863
00864 aLeft_log->SetLabelSize(0);
00865 aRight_log->SetLabelSize(0);
00866 aRight_log->SetTickSize(0.05);
00867 aLeft_log->SetTickSize(0.05);
00868
00869 aLeft_log->SetGridLength(.75);
00870
00871 aLeft_log->Draw();
00872 aRight_log->Draw();
00873 }
00874
00875 if (IsLin() || IsLogLin()) {
00876
00877
00878 TGaxis *aLeft_lin = new TGaxis(x1, y0, x1, y1, "fLin", div_lin,"");
00879 TGaxis *aRight_lin = new TGaxis(x2, y0, x2, y1, "fLin", div_lin, "+");
00880
00881 aLeft_lin->SetLabelSize(0);
00882 aRight_lin->SetLabelSize(0);
00883 aLeft_lin->SetTickSize(0.05);
00884 aRight_lin->SetTickSize(0.05);
00885
00886 aLeft_lin->SetGridLength(.75);
00887
00888 aLeft_lin->Draw();
00889 aRight_lin->Draw();
00890 }
00891
00892
00893 double yl, ln, yl_p;
00894 int nlab = 0;
00895 double log_num[99];
00896
00897
00898 if (IsLin() || IsLogLin()) {
00899
00900 for (ln = 0; ln/1e3 <= ymid; ln += 2) {
00901
00902 log_num[nlab++] = ln;
00903 }
00904 }
00905
00906 if (IsLog() || IsLogLin()) {
00907 for (ln = 1e-5 ; ln/1e3 <= ymax; ln *= 10) {
00908 if (ln/1e3 > ymid)
00909 log_num[nlab++] = ln;
00910 if (ln*2/1e3 <= ymax && ln/1e3*2 > ymid)
00911 log_num[nlab++] = ln*2;
00912 if (ln*4/1e3 <= ymax && ln/1e3*4 > ymid)
00913 log_num[nlab++] = ln*4;
00914 }
00915 }
00916
00917 TLatex *lab_tex[99];
00918 yl_p = -999;
00919 for (int i = 0; i < nlab; i++) {
00920 yl = Cont2Can(log_num[i]/1e3);
00921 if (!IsLin()) {
00922 if ( yl - yl_p < 0.04*bmax ) {
00923 if (log_num[i] < ymid) log_num[i] += 2;
00924 else log_num[i] *= 2;
00925 yl = Cont2Can(log_num[i]/1e3);
00926 }
00927 yl_p = yl;
00928 }
00929
00930 lab_tex[i] = new TLatex(x1-0.01, yl, TString::Format("%3g",log_num[i]));
00931 if (size == -1) {
00932 lab_tex[i]->SetTextFont(42);
00933 lab_tex[i]->SetTextSize(0.05);
00934 }
00935 else {
00936 lab_tex[i]->SetTextFont(43);
00937 lab_tex[i]->SetTextSize(size);
00938 }
00939 lab_tex[i]->SetTextAlign(32);
00940 lab_tex[i]->Draw();
00941 }
00942
00943
00944
00945 if (IsLogLin()) {
00946 TLine *l1 = new TLine(x1, y1, x2, y1);
00947 l1->SetLineStyle(2);
00948 l1->Draw();
00949
00950 TLatex *t[99];
00951 int nT = -1;
00952
00953 t[++nT] = new TLatex(x1+0.08, y1+0.01*y2, "Log");
00954 t[nT]->SetTextAlign(11);
00955 double defsize = t[nT]->GetTextSize();
00956
00957 t[++nT] = new TLatex(x1+0.08, y1-0.01*y2, "Linear");
00958 t[nT]->SetTextAlign(13);
00959
00960
00961 for (int i = 0; i <= nT; i++) {
00962 if (size == -1) {
00963 if (t[i]->GetTextSize() == defsize) {
00964 t[i]->SetTextSize(0.045);
00965 }
00966 t[i]->SetTextFont(42);
00967 }
00968 else {
00969 t[i]->SetTextFont(43);
00970 t[i]->SetTextSize(size);
00971 }
00972 t[i]->Draw();
00973 }
00974 }
00975 }
00976
00977
00978
00979 void NuContour::DispBins(int n)
00980 {
00981 bmax = n;
00982
00983 if (IsLogLin()) DoLogLin();
00984 if (IsLog()) DoLog();
00985 }
00986
00987
00988 void NuContour::LogMax(double y)
00989 {
00990 ymax = y;
00991 if (IsLogLin()) DoLogLin();
00992 if (IsLog()) DoLog();
00993 }
00994
00995
00996
00997 void NuContour::LogMin(double y)
00998 {
00999 ymid = y;
01000 if (IsLogLin()) DoLogLin();
01001 if (IsLog()) DoLog();
01002 }
01003
01004
01005
01006 double NuContour::interpolate(TH2D *h, double x, double y, double def)
01007 {
01008
01009
01010
01011
01012
01013
01014 Double_t f=0;
01015 Double_t x1=0,x2=0,y1=0,y2=0;
01016 Double_t dx,dy;
01017
01018 TAxis *fXaxis = h->GetXaxis();
01019 TAxis *fYaxis = h->GetYaxis();
01020
01021 Int_t bin_x = fXaxis->FindBin(x);
01022 Int_t bin_y = fYaxis->FindBin(y);
01023 if(bin_x<1 || bin_x>h->GetNbinsX() || bin_y<1 || bin_y>h->GetNbinsY()) {
01024 MAXMSG("NuContour",Msg::kWarning,5)
01025 << "Cannot interpolate outside histogram domain, using default value "
01026 << def << endl;
01027 return 999.;
01028 }
01029
01030 Int_t quadrant = 0;
01031
01032 dx = fXaxis->GetBinUpEdge(bin_x)-x;
01033 dy = fYaxis->GetBinUpEdge(bin_y)-y;
01034 if (dx<=fXaxis->GetBinWidth(bin_x)/2 && dy<=fYaxis->GetBinWidth(bin_y)/2)
01035 quadrant = 1;
01036 if (dx>fXaxis->GetBinWidth(bin_x)/2 && dy<=fYaxis->GetBinWidth(bin_y)/2)
01037 quadrant = 2;
01038 if (dx>fXaxis->GetBinWidth(bin_x)/2 && dy>fYaxis->GetBinWidth(bin_y)/2)
01039 quadrant = 3;
01040 if (dx<=fXaxis->GetBinWidth(bin_x)/2 && dy>fYaxis->GetBinWidth(bin_y)/2)
01041 quadrant = 4;
01042
01043 switch(quadrant) {
01044 case 1:
01045 x1 = fXaxis->GetBinCenter(bin_x);
01046 y1 = fYaxis->GetBinCenter(bin_y);
01047 x2 = fXaxis->GetBinCenter(bin_x+1);
01048 y2 = fYaxis->GetBinCenter(bin_y+1);
01049 break;
01050 case 2:
01051 x1 = fXaxis->GetBinCenter(bin_x-1);
01052 y1 = fYaxis->GetBinCenter(bin_y);
01053 x2 = fXaxis->GetBinCenter(bin_x);
01054 y2 = fYaxis->GetBinCenter(bin_y+1);
01055 break;
01056 case 3:
01057 x1 = fXaxis->GetBinCenter(bin_x-1);
01058 y1 = fYaxis->GetBinCenter(bin_y-1);
01059 x2 = fXaxis->GetBinCenter(bin_x);
01060 y2 = fYaxis->GetBinCenter(bin_y);
01061 break;
01062 case 4:
01063 x1 = fXaxis->GetBinCenter(bin_x);
01064 y1 = fYaxis->GetBinCenter(bin_y-1);
01065 x2 = fXaxis->GetBinCenter(bin_x+1);
01066 y2 = fYaxis->GetBinCenter(bin_y);
01067 break;
01068 }
01069
01070 Int_t bin_x1 = fXaxis->FindBin(x1);
01071 if(bin_x1<1) bin_x1=1;
01072 Int_t bin_x2 = fXaxis->FindBin(x2);
01073 if(bin_x2>h->GetNbinsX()) bin_x2=h->GetNbinsX();
01074 Int_t bin_y1 = fYaxis->FindBin(y1);
01075 if(bin_y1<1) bin_y1=1;
01076 Int_t bin_y2 = fYaxis->FindBin(y2);
01077 if(bin_y2>h->GetNbinsY()) bin_y2=h->GetNbinsY();
01078
01079 Int_t bin_q22 = h->GetBin(bin_x2,bin_y2);
01080 Int_t bin_q12 = h->GetBin(bin_x1,bin_y2);
01081 Int_t bin_q11 = h->GetBin(bin_x1,bin_y1);
01082 Int_t bin_q21 = h->GetBin(bin_x2,bin_y1);
01083 Double_t q11 = h->GetBinContent(bin_q11);
01084 Double_t q12 = h->GetBinContent(bin_q12);
01085 Double_t q21 = h->GetBinContent(bin_q21);
01086 Double_t q22 = h->GetBinContent(bin_q22);
01087 Double_t d = 1.0*(x2-x1)*(y2-y1);
01088
01089 f = 1.0*q11/d*(x2-x)*(y2-y)+1.0*q21/d*(x-x1)*(y2-y)+1.0*q12/d*(x2-x)*(y-y1)+1.0*q22/d*(x-x1)*(y-y1);
01090 return f;
01091
01092 }
01093
01094
01095
01096
01097 double NuContour::Can2Cont(double bin)
01098 {
01099
01100
01101
01102 if (IsLin()) return bin;
01103
01104 double c = TMath::Log10(ymax/ymid)/(bmax-bmid);
01105 double y;
01106 if (bin < bmid) {
01107 y = ymid / bmid * bin;
01108 }
01109 else {
01110 y = ymid*pow(10, c * (bin - bmid));
01111 }
01112 return y;
01113 }
01114
01115
01116
01117 double NuContour::Cont2Can(double y)
01118 {
01119 if (IsLin()) return y;
01120
01121 double c = TMath::Log10(ymax/ymid)/(bmax-bmid);
01122 double bin;
01123 if (y <= ymid) {
01124 bin = y * bmid/ymid;
01125 }
01126 else {
01127 bin = 1/c * TMath::Log10(y/ymid)+bmid;
01128 }
01129 return bin;
01130 }
01131
01132
01133
01134
01135
01136 Double_t NuContour::MinBin(const TH2D& hist)
01137 {
01138 Double_t minimum = -1.;
01139 for(Int_t x = 1; x <= hist.GetNbinsX(); x++) {
01140 for(Int_t y = 1; y <= hist.GetNbinsY(); y++) {
01141
01142 Double_t val = hist.GetBinContent(x, y);
01143 if (x == 1 && y == 1) {
01144 minimum = val;
01145 } else {
01146 minimum = TMath::Min(minimum, val);
01147 }
01148 }
01149 }
01150
01151 return minimum;
01152 }
01153
01154
01155
01156 void NuContour::ShiftHist(TH2D *hist, Double_t shift)
01157 {
01158 for(Int_t x = 1; x <= hist->GetNbinsX(); x++) {
01159 for(Int_t y = 1; y <= hist->GetNbinsY(); y++) {
01160 Double_t val = hist->GetBinContent(x, y);
01161 hist->SetBinContent(x, y, val + shift);
01162 }
01163 }
01164 }
01165
01166
01167
01168 void NuContour::ChooseContour(TH2 *h)
01169 {
01170 h->SetContour(fillLevel+1);
01171
01172 if (fillLevel < 0) {
01173 h->SetContour(1);
01174 h->SetContourLevel(0, neg*contLevel);
01175 }
01176 else {
01177 h->SetContour(nFillCols);
01178
01179 for (int i = 0; i < nFillCols; i++) {
01180 if (i >= nFillCols-fillLevel-1) h->SetContourLevel(i, 0);
01181 else h->SetContourLevel(i, 999);
01182 }
01183 }
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 h->SetDirectory(0);
01210 }