00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TParallelCoordVar.h"
00013 #include "TParallelCoord.h"
00014 #include "TParallelCoordRange.h"
00015
00016 #include "Riostream.h"
00017 #include "TROOT.h"
00018 #include "TLatex.h"
00019 #include "TLine.h"
00020 #include "TVirtualPad.h"
00021 #include "TMath.h"
00022 #include "TH1.h"
00023 #include "TStyle.h"
00024 #include "TBox.h"
00025 #include "TCollection.h"
00026 #include "TList.h"
00027 #include "TFrame.h"
00028 #include "TCanvas.h"
00029 #include "TMarker.h"
00030
00031 ClassImp(TParallelCoordVar)
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 TParallelCoordVar::TParallelCoordVar()
00051 :TNamed(), TAttLine(), TAttFill(kOrange+9,0)
00052 {
00053
00054
00055 Init();
00056 }
00057
00058
00059
00060 TParallelCoordVar::~TParallelCoordVar()
00061 {
00062
00063
00064 if (fHistogram) delete fHistogram;
00065 if (fRanges){
00066 TIter next(fRanges);
00067 TParallelCoordRange* range;
00068 while((range = (TParallelCoordRange*)next())) fParallel->CleanUpSelections(range);
00069 fRanges->Delete();
00070 delete fRanges;
00071 }
00072 if (fVal) delete [] fVal;
00073 }
00074
00075
00076
00077 TParallelCoordVar::TParallelCoordVar(Double_t *val, const char* title, Int_t id, TParallelCoord* parallel)
00078 :TNamed(title,title), TAttLine(1,1,1), TAttFill(kOrange+9,3001)
00079 {
00080
00081
00082
00083 Init();
00084 fId = id;
00085 fParallel = parallel;
00086 fRanges = new TList();
00087 fNentries = fParallel->GetNentries();
00088
00089 fVal = new Double_t[fParallel->GetNentries()];
00090
00091 for(Long64_t ui = 0;ui<fParallel->GetNentries();++ui) fVal[ui]=val[ui];
00092
00093 GetMinMaxMean();
00094 GetHistogram();
00095 GetQuantiles();
00096 }
00097
00098
00099
00100 void TParallelCoordVar::AddRange(TParallelCoordRange* range)
00101 {
00102
00103
00104 if (!range) {
00105 TParallelCoordSelect *select = fParallel->GetCurrentSelection();
00106 if (select) {
00107 range = new TParallelCoordRange(this,0,0,select);
00108 fRanges->Add(range);
00109 range->GetSelection()->Add(range);
00110 range->Draw();
00111 } else {
00112 Error("AddRange","You must create a selection before adding ranges.");
00113 }
00114 } else {
00115 fRanges->Add(range);
00116 range->GetSelection()->Add(range);
00117 range->Draw();
00118 }
00119 }
00120
00121
00122
00123 void TParallelCoordVar::DeleteVariable()
00124 {
00125
00126
00127 fParallel->RemoveVariable(this);
00128 delete this;
00129 }
00130
00131
00132
00133 Int_t TParallelCoordVar::DistancetoPrimitive(Int_t px, Int_t py)
00134 {
00135
00136
00137 if(!gPad) return 9999;
00138 Double_t xx = gPad->AbsPixeltoX(px);
00139 Double_t yy = gPad->AbsPixeltoY(py);
00140 Double_t dist = 9999;
00141
00142 if (fX1==fX2) {
00143 if (yy>fY1+0.01 && yy<fY2-0.01) dist = TMath::Abs(xx - fX1);
00144 } else {
00145 if (xx>fX1+0.01 && xx<fX2-0.01) dist = TMath::Abs(yy - fY1);
00146 }
00147 if (dist<=0.005) return 0;
00148 else return 9999;
00149 }
00150
00151
00152
00153 void TParallelCoordVar::Draw(Option_t *option)
00154 {
00155
00156
00157 TIter next(fRanges);
00158 TParallelCoordRange* range;
00159 while ((range = (TParallelCoordRange*)next())) range->Draw();
00160 AppendPad(option);
00161 }
00162
00163
00164
00165 Bool_t TParallelCoordVar::Eval(Long64_t evtidx, TParallelCoordSelect *select)
00166 {
00167
00168
00169
00170
00171 if (fRanges->GetSize() > 0){
00172 TIter next(fRanges);
00173 Bool_t inarange = kFALSE;
00174 Bool_t noOwnedRange = kTRUE;
00175 TParallelCoordRange *range;
00176 while ((range = (TParallelCoordRange*)next())){
00177 if(select->Contains(range)) {
00178 noOwnedRange = kFALSE;
00179 if(range->IsIn(fVal[evtidx])) inarange = kTRUE;
00180 }
00181 }
00182 if (noOwnedRange) return kTRUE;
00183 else return inarange;
00184 }
00185 else return kTRUE;
00186 }
00187
00188
00189
00190 void TParallelCoordVar::ExecuteEvent(Int_t entry, Int_t px, Int_t py)
00191 {
00192
00193
00194 if (!gPad) return;
00195 if (!gPad->IsEditable() && entry!=kMouseEnter) return;
00196
00197 static Int_t pxold, pyold;
00198 static Int_t zoom;
00199 static Int_t pzoomold;
00200 static Bool_t first = kTRUE;
00201
00202 Int_t px1,px2,py1,py2,n=-1;
00203 px1 = gPad->XtoAbsPixel(fX1);
00204 px2 = gPad->XtoAbsPixel(fX2);
00205 py1 = gPad->YtoAbsPixel(fY1);
00206 py2 = gPad->YtoAbsPixel(fY2);
00207
00208 if(fX1 == fX2) {
00209 if(gPad->AbsPixeltoX(px)-fX1 > 0) gPad->SetCursor(kArrowVer);
00210 else gPad->SetCursor(kArrowHor);
00211 } else {
00212 if(gPad->AbsPixeltoY(py)-fY1 > 0) gPad->SetCursor(kArrowHor);
00213 else gPad->SetCursor(kArrowVer);
00214 }
00215
00216 gVirtualX->SetLineColor(-1);
00217 switch (entry) {
00218 case kButton1Down:
00219 if (fX1==fX2){
00220 ((TCanvas*)gPad)->Selected(gPad,fParallel,1);
00221 if(gPad->AbsPixeltoX(px)-fX1 > 0){
00222 zoom = 1;
00223 gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),py,gPad->XtoAbsPixel(fX1+0.05),py);
00224 first = kTRUE;
00225 pzoomold = py;
00226 } else {
00227 zoom = 0;
00228 gVirtualX->DrawLine(px,py1,px,py2);
00229 }
00230 } else {
00231 if(gPad->AbsPixeltoY(py)-fY1 > 0){
00232 zoom = 1;
00233 gVirtualX->DrawLine(px,gPad->YtoAbsPixel(fY1-0.05),px,gPad->YtoAbsPixel(fY1+0.05));
00234 first=kTRUE;
00235 pzoomold = px;
00236 } else {
00237 zoom = 0;
00238 gVirtualX->DrawLine(px1,py,px2,py);
00239 }
00240 }
00241 pxold = px;
00242 pyold = py;
00243 break;
00244 case kButton1Up: {
00245 Double_t xx = gPad->AbsPixeltoX(px);
00246 Double_t yy = gPad->AbsPixeltoY(py);
00247 TFrame *frame = gPad->GetFrame();
00248 if (fX1==fX2) {
00249 if(zoom == 0){
00250 Double_t axisSpace = (frame->GetX2() - frame->GetX1())/(fParallel->GetNvar() - 1);
00251 Double_t pos = (xx - frame->GetX1())/axisSpace;
00252 if (pos < 0) n = -1;
00253 else n = (Int_t)pos;
00254 } else {
00255 Double_t min = GetValuefromXY(xx,yy);
00256 Double_t max = GetValuefromXY(xx,gPad->AbsPixeltoY(pzoomold));
00257 if(TMath::Abs(min-max) < 0.00001) return;
00258 if (fParallel->TestBit(TParallelCoord::kGlobalScale)) {
00259 if (min>max) {
00260 Double_t mem = min;
00261 min = max; max = mem;
00262 }
00263 fParallel->SetGlobalMin(min);
00264 fParallel->SetGlobalMax(max);
00265 } else {
00266 SetCurrentLimits(min,max);
00267 }
00268 }
00269 } else {
00270 if(zoom == 0) {
00271 Double_t axisSpace = (frame->GetY2() - frame->GetY1())/(fParallel->GetNvar() - 1);
00272 Double_t pos = (yy-frame->GetY1())/axisSpace;
00273 if (pos < 0) n= -1;
00274 else n = (Int_t)pos;
00275 } else {
00276 Double_t min = GetValuefromXY(xx,yy);
00277 Double_t max = GetValuefromXY(gPad->AbsPixeltoX(pzoomold),yy);
00278 SetCurrentLimits(min,max);
00279 }
00280 }
00281 if(zoom == 0){
00282 if (n>=0 && (UInt_t)n>=fParallel->GetNvar()) --n;
00283 else if (n<fParallel->GetVarList()->IndexOf(this)) ++n;
00284 fParallel->GetVarList()->Remove(this);
00285 fParallel->GetVarList()->AddAt(this,n);
00286 }
00287 gPad->Modified();
00288 break;
00289 }
00290 case kMouseMotion:
00291 pxold=px;
00292 pyold=py;
00293 break;
00294 case kButton1Motion:
00295 if(fX1==fX2){
00296 if(zoom==0){
00297 gPad->SetCursor(kArrowHor);
00298 gVirtualX->DrawLine(pxold,py1,pxold,py2);
00299 gVirtualX->DrawLine(px,py1,px,py2);
00300 } else if(zoom==1) {
00301 gPad->SetCursor(kArrowVer);
00302 if(!first) gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),pyold,gPad->XtoAbsPixel(fX1+0.05),pyold);
00303 gVirtualX->DrawLine(gPad->XtoAbsPixel(fX1-0.05),py,gPad->XtoAbsPixel(fX1+0.05),py);
00304 first = kFALSE;
00305 }
00306 } else {
00307 if(zoom==0){
00308 gPad->SetCursor(kArrowVer);
00309 gVirtualX->DrawLine(px1,pyold,px2,pyold);
00310 gVirtualX->DrawLine(px1,py,px2,py);
00311 } else if(zoom==1){
00312 gPad->SetCursor(kArrowHor);
00313 if(!first) gVirtualX->DrawLine(pxold,gPad->YtoAbsPixel(fY1-0.05),pxold,gPad->YtoAbsPixel(fY1+0.05));
00314 gVirtualX->DrawLine(px,gPad->YtoAbsPixel(fY1-0.05),px,gPad->YtoAbsPixel(fY1+0.05));
00315 first = kFALSE;
00316 }
00317 }
00318 pxold = px;
00319 pyold = py;
00320 break;
00321 }
00322 }
00323
00324
00325
00326 void TParallelCoordVar::GetEntryXY(Long64_t n, Double_t & x, Double_t & y)
00327 {
00328
00329
00330 if(fX1==fX2){
00331 x = fX1;
00332 if (fMinCurrent != fMaxCurrent) {
00333 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
00334 (TMath::Log10(fVal[n]/fMinCurrent)) / (TMath::Log10(fMaxCurrent/fMinCurrent));
00335 else y = fY1 + (fY2 - fY1) *
00336 (fVal[n] - fMinCurrent) / (fMaxCurrent - fMinCurrent);
00337 } else {
00338 y = fY1 + 0.5*(fY2-fY1);
00339 }
00340 } else {
00341 y = fY1;
00342 if (fMinCurrent != fMaxCurrent) {
00343 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
00344 (TMath::Log10(fVal[n]/fMinCurrent)) / (TMath::Log10(fMaxCurrent/fMinCurrent));
00345 else x = fX1 + (fX2 - fX1) *
00346 (fVal[n] - fMinCurrent) / (fMaxCurrent - fMinCurrent);
00347 } else {
00348 x = fX1 + 0.5*(fX2-fX1);
00349 }
00350 }
00351 }
00352
00353
00354
00355 Int_t TParallelCoordVar::GetEntryWeight(Long64_t evtidx)
00356 {
00357
00358
00359
00360 Int_t bin = 1 + (Int_t)((fVal[evtidx] - fMinCurrent)/((fMaxCurrent-fMinCurrent)/fNbins));
00361 return (Int_t)fHistogram->GetBinContent(bin);
00362 }
00363
00364
00365
00366 TH1F* TParallelCoordVar::GetHistogram()
00367 {
00368
00369
00370 if (fHistogram) delete fHistogram;
00371 fHistogram = NULL;
00372 fHistogram = new TH1F("hpa", "hpa", fNbins, fMinCurrent, fMaxCurrent+0.0001*(fMaxCurrent-fMinCurrent));
00373 fHistogram->SetDirectory(0);
00374 Long64_t first = fParallel->GetCurrentFirst();
00375 Long64_t nentries = fParallel->GetCurrentN();
00376 for(Long64_t li=first; li<first+nentries;++li) {
00377 if(fVal[li] >= fMinCurrent && fVal[li] <= fMaxCurrent) fHistogram->Fill(fVal[li]);
00378 }
00379 return fHistogram;
00380 }
00381
00382
00383
00384 void TParallelCoordVar::GetMinMaxMean()
00385 {
00386
00387 Double_t min,max,ave = 0;
00388 min = FLT_MAX;
00389 max = -FLT_MAX;
00390 Long64_t first,nentries;
00391 first = fParallel->GetCurrentFirst();
00392 nentries = fParallel->GetCurrentN();
00393 for(Long64_t li=first; li<first+nentries;++li){
00394 if(fVal[li]<min) min = fVal[li];
00395 if(fVal[li]>max) max = fVal[li];
00396 ave+=fVal[li];
00397 }
00398
00399 fMean = ave/((Double_t)nentries);
00400 fMinCurrent = fMinInit = min;
00401 fMaxCurrent = fMaxInit = max;
00402 }
00403
00404
00405
00406 char* TParallelCoordVar::GetObjectInfo(Int_t px, Int_t py) const
00407 {
00408
00409
00410 static char info[128];
00411 info[0] = 0;
00412
00413 if (!gPad) return info;
00414 Double_t xx = gPad->AbsPixeltoX(px);
00415 Double_t yy = gPad->AbsPixeltoY(py);
00416 if (fX1 == fX2) {
00417 if (yy<fY1) {
00418 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
00419 } else if (yy>fY2) {
00420 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
00421 } else {
00422 Double_t axislength = fY2-fY1;
00423 Double_t pos = (yy-fY1)/axislength;
00424 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent + pos*(fMaxCurrent-fMinCurrent));
00425 }
00426 } else {
00427 if (xx<fX1) {
00428 snprintf(info,128,"%s = %f", GetTitle(), fMinCurrent);
00429 } else if(xx>fX2) {
00430 snprintf(info,128,"%s = %f", GetTitle(), fMaxCurrent);
00431 } else {
00432 Double_t axislength = fX2-fX1;
00433 Double_t pos = (xx-fX1)/axislength;
00434 snprintf(info,128,"%s = %f", GetTitle(), pos*(fMaxCurrent-fMinCurrent));
00435 }
00436 }
00437 return info;
00438 }
00439
00440
00441
00442 void TParallelCoordVar::GetQuantiles()
00443 {
00444
00445
00446 Double_t *quantiles = new Double_t[3];
00447 Double_t *prob = new Double_t[3];
00448 prob[0]=0.25; prob[1]=0.5; prob[2] = 0.75;
00449 Long64_t first = fParallel->GetCurrentFirst();
00450 Long64_t nentries = fParallel->GetCurrentN();
00451 if (!TestBit(kLogScale) && first==0 && nentries==fNentries) TMath::Quantiles(fNentries,3,fVal,quantiles,prob,kFALSE);
00452 else {
00453 Double_t* val = new Double_t[nentries];
00454 Int_t selected = 0;
00455 if(fMinInit<=0) {
00456 for (Long64_t n=first;n<first+nentries;++n) {
00457 if (fVal[n] >= fMinCurrent) {
00458 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
00459 else val[selected] = fVal[n];
00460 ++selected;
00461 }
00462 }
00463 } else {
00464 for (Long64_t n=first;n<first+nentries;++n) {
00465 if (TestBit(kLogScale)) val[selected] = TMath::Log10(fVal[n]);
00466 else val[selected] = fVal[n];
00467 ++selected;
00468 }
00469 }
00470 TMath::Quantiles(selected,3,val,quantiles,prob,kFALSE);
00471 delete [] val;
00472 }
00473 fQua1 = quantiles[0];
00474 fMed = quantiles[1];
00475 fQua3 = quantiles[2];
00476 delete [] quantiles;
00477 delete [] prob;
00478 }
00479
00480
00481
00482 Double_t TParallelCoordVar::GetValuefromXY(Double_t x,Double_t y)
00483 {
00484
00485
00486 Double_t pos;
00487 if (fMinCurrent == fMaxCurrent) return fMinCurrent;
00488 if (fX1 == fX2) {
00489 if (y<=fY1) pos = fMinCurrent;
00490 else if (y>=fY2) pos = fMaxCurrent;
00491 else pos = fMinCurrent + ((y-fY1)/(fY2-fY1))*(fMaxCurrent-fMinCurrent);
00492 } else {
00493 if (x<=fX1) pos = fMinCurrent;
00494 else if (x>=fX2) pos = fMaxCurrent;
00495 else pos = fMinCurrent + ((x-fX1)/(fX2-fX1))*(fMaxCurrent-fMinCurrent);
00496 }
00497 return pos;
00498 }
00499
00500
00501
00502 void TParallelCoordVar::GetXYfromValue(Double_t value, Double_t & x, Double_t & y)
00503 {
00504
00505
00506 if(value < fMinCurrent || value > fMaxCurrent) return;
00507
00508 if (fX1==fX2) {
00509 x = fX1;
00510 if (fMinCurrent != fMaxCurrent) {
00511 if (TestBit(kLogScale)) y = fY1 + (fY2 - fY1) *
00512 (TMath::Log10(value/fMinCurrent)) / (TMath::Log10(fMaxCurrent/fMinCurrent));
00513 else y = fY1 + (fY2 - fY1) *
00514 (value - fMinCurrent) / (fMaxCurrent - fMinCurrent);
00515 } else {
00516 y = fY1 + 0.5*(fY2-fY1);
00517 }
00518 } else {
00519 y = fY1;
00520 if (fMinCurrent != fMaxCurrent) {
00521 if (TestBit(kLogScale)) x = fX1 + (fX2 - fX1) *
00522 (TMath::Log10(value/fMinCurrent)) / (TMath::Log10(fMaxCurrent/fMinCurrent));
00523 else x = fX1 + (fX2 - fX1) *
00524 (value - fMinCurrent) / (fMaxCurrent - fMinCurrent);
00525 } else {
00526 x = fX1 + 0.5*(fX2-fX1);
00527 }
00528 }
00529 }
00530
00531
00532
00533 void TParallelCoordVar::Init()
00534 {
00535
00536
00537 fX1 = 0;
00538 fX2 = 0;
00539 fY1 = 0;
00540 fY2 = 0;
00541 fId = 0;
00542 fVal = NULL;
00543 fMean = 0;
00544 fMinInit = 0;
00545 fMinCurrent = 0;
00546 fMaxInit = 0;
00547 fMaxCurrent = 0;
00548 fMed = 0;
00549 fQua1 = 0;
00550 fQua3 = 0;
00551 fNentries = 0;
00552 fParallel = NULL;
00553 fHistogram = NULL;
00554 fNbins = 100;
00555 fHistoLW = 2;
00556 fHistoHeight = 0.5;
00557 fRanges = NULL;
00558 SetBit(kLogScale,kFALSE);
00559 SetBit(kShowBox,kFALSE);
00560 SetBit(kShowBarHisto,kTRUE);
00561 }
00562
00563
00564
00565 void TParallelCoordVar::Paint(Option_t* )
00566 {
00567
00568
00569 PaintHistogram();
00570 if (TestBit(kShowBox)) PaintBoxPlot();
00571 PaintLabels();
00572 }
00573
00574
00575
00576 void TParallelCoordVar::PaintBoxPlot()
00577 {
00578
00579
00580 TLine *line = new TLine();
00581 line->SetLineColor(GetLineColor());
00582 line->SetLineWidth(1);
00583 TBox *box = new TBox();
00584 box->SetLineWidth(1);
00585 box->SetLineColor(GetLineColor());
00586 box->SetLineStyle(1);
00587 box->SetFillStyle(0);
00588
00589 TFrame* frame = gPad->GetFrame();
00590
00591 Double_t boxSize;
00592 if (fParallel->GetNvar() > 1) {
00593 if (fX1==fX2) boxSize = fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
00594 else boxSize = fHistoHeight*((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
00595 if (boxSize >= 0.03) boxSize = 0.03;
00596 }
00597 else boxSize = 0.03;
00598
00599 Double_t qua1,med,qua3,max,min;
00600 Double_t a,b,maxinit,mininit;
00601 if (TestBit(kLogScale)) {
00602 a = TMath::Log10(fMinCurrent);
00603 b = TMath::Log10(fMaxCurrent/fMinCurrent);
00604 if(fMinInit > 0) mininit = TMath::Log10(fMinInit);
00605 else mininit = TMath::Log10(fMinCurrent);
00606 maxinit = TMath::Log10(fMaxInit);
00607 } else {
00608 a = fMinCurrent;
00609 b = fMaxCurrent-fMinCurrent;
00610 mininit = fMinInit;
00611 maxinit = fMaxInit;
00612 }
00613 if(fX1==fX2) {
00614 qua1 = fY1 + ((fQua1-a)/b)*(fY2-fY1);
00615 qua3 = fY1 + ((fQua3-a)/b)*(fY2-fY1);
00616 med = fY1 + ((fMed-a)/b)*(fY2-fY1);
00617 max = fY1 + ((maxinit-a)/b)*(fY2-fY1);
00618 min = fY1 + ((mininit-a)/b)*(fY2-fY1);
00619 } else {
00620 qua1 = fX1 + ((fQua1-a)/b)*(fX2-fX1);
00621 qua3 = fX1 + ((fQua3-a)/b)*(fX2-fX1);
00622 med = fX1 + ((fMed-a)/b)*(fX2-fX1);
00623 max = fX1 + ((maxinit-a)/b)*(fX2-fX1);
00624 min = fX1 + ((mininit-a)/b)*(fX2-fX1);
00625 }
00626
00627
00628 if (fX1==fX2) {
00629 line->PaintLine(fX1-boxSize,min,fX1+boxSize,min);
00630 line->PaintLine(fX2-boxSize,max,fX2+boxSize,max);
00631 } else {
00632 line->PaintLine(min,fY1-boxSize,min,fY1+boxSize);
00633 line->PaintLine(max,fY2-boxSize,max,fY2+boxSize);
00634 }
00635
00636
00637 line->SetLineStyle(7);
00638 if (fX1==fX2) {
00639 if (min<frame->GetY1()) min = frame->GetY1();
00640 if (max>frame->GetY2()) max = frame->GetY2();
00641 line->PaintLine(fX1,min,fX1,qua1);
00642 line->PaintLine(fX1,qua3,fX1,max);
00643 } else {
00644 if (min<frame->GetX1()) min = frame->GetX1();
00645 if (max>frame->GetX2()) max = frame->GetX2();
00646 line->PaintLine(min,fY1,qua1,fY2);
00647 line->PaintLine(qua3,fY1,max,fY2);
00648 }
00649
00650
00651 if(fX1==fX2) box->PaintBox(fX1-boxSize,qua1,fX1+boxSize,qua3);
00652 else box->PaintBox(qua1,fY1-boxSize,qua3,fY1+boxSize);
00653
00654
00655 line->SetLineStyle(1);
00656 if(fX1==fX2) line->PaintLine(fX1-boxSize,med,fX1+boxSize,med);
00657 else line->PaintLine(med,fY1-boxSize,med,fY1+boxSize);
00658
00659
00660 if (!TestBit(kLogScale) || (TestBit(kLogScale) && fMean > 0)) {
00661 Double_t mean;
00662 if (TestBit(kLogScale)) mean = TMath::Log10(fMean);
00663 else mean = fMean;
00664 TMarker *mark = NULL;
00665 if(fX1==fX2) mark = new TMarker(fX1,fY1 + ((mean-a)/b)*(fY2-fY1),24);
00666 else mark = new TMarker(fX1 + ((mean-a)/b)*(fX2-fX1),fY1,24);
00667 mark->Paint();
00668 delete mark;
00669 }
00670
00671 delete line;
00672 delete box;
00673 }
00674
00675
00676
00677 void TParallelCoordVar::PaintHistogram()
00678 {
00679
00680
00681 Int_t i;
00682
00683 TFrame *frame = gPad->GetFrame();
00684
00685 if (!fHistogram) GetHistogram();
00686
00687
00688 if (fHistoHeight!=0 && TestBit(kShowBarHisto)) {
00689
00690 TBox *b = new TBox();
00691 b->SetFillStyle(GetFillStyle());
00692 b->SetFillColor(GetFillColor());
00693 b->SetLineStyle(1);
00694 b->SetLineColor(GetFillColor());
00695 b->SetLineWidth(1);
00696 Double_t hmin = fHistogram->GetMinimum();
00697 Double_t hmax = fHistogram->GetMaximum();
00698 if (fX1 == fX2) {
00699
00700 Double_t dy = (fY2-fY1)/fNbins;
00701 Double_t dv = (fMaxCurrent - fMinCurrent)/fNbins;
00702 Double_t v = fMinCurrent;
00703 Double_t y1 = fY1,x2,y2;
00704 for (i=1; i<=fNbins; i++) {
00705 x2 = fX1+((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*fHistoHeight*
00706 ((frame->GetX2()-frame->GetX1())/(fParallel->GetNvar()-1));
00707 if(TestBit(kLogScale)) y2 = fY1 + (fY2-fY1)*(TMath::Log10((v+dv)/fMinCurrent)) / (TMath::Log10(fMaxCurrent/fMinCurrent));
00708 else y2=y1+dy;
00709 b->PaintBox(fX1,y1,x2,y2,"l");
00710 y1=y2;
00711 v += dv;
00712 }
00713 } else {
00714
00715 Double_t dx = (fX2-fX1)/fNbins;
00716 Double_t dv = (fMaxCurrent - fMinCurrent)/fNbins;
00717 Double_t v = fMinCurrent;
00718 Double_t x1 = fX1,x2,y2;
00719 for (i=1; i<=fNbins; i++) {
00720 y2 = fY1+((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*fHistoHeight*((frame->GetY2()-frame->GetY1())/(fParallel->GetNvar()-1));
00721 if(TestBit(kLogScale)) x2 = fX1 + (fX2-fX1)*(TMath::Log10((v+dv)/fMinCurrent)) / (TMath::Log10(fMaxCurrent/fMinCurrent));
00722 else x2=x1+dx;
00723 b->PaintBox(x1,fY1,x2,y2,"l");
00724 x1=x2;
00725 v+=dv;
00726 }
00727 }
00728 delete b;
00729 }
00730 if (fHistoLW==0 && !TestBit(kShowBox)) {
00731
00732 TLine* l = new TLine(fX1,fY1,fX2,fY2);
00733 l->SetLineWidth(GetLineWidth());
00734 l->SetLineColor(GetLineColor());
00735 l->SetLineStyle(GetLineColor());
00736 l->Paint();
00737 delete l;
00738 } else if (fHistoLW!=0){
00739
00740 TLine *lb = new TLine();
00741 lb->SetLineWidth(fHistoLW);
00742 Double_t hmin = fHistogram->GetMinimum();
00743 Double_t hmax = fHistogram->GetMaximum();
00744 Int_t theColor;
00745 Int_t ncolors = gStyle->GetNumberOfColors();
00746 if (fX1 == fX2) {
00747
00748 Double_t dy = (fY2-fY1)/fNbins;
00749 Double_t y1 = fY1,y2;
00750 Double_t dv = (fMaxCurrent - fMinCurrent)/fNbins;
00751 Double_t v = fMinCurrent;
00752 for (i=1; i<=fNbins; i++) {
00753 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
00754 if(TestBit(kLogScale)) y2 = fY1 + (fY2-fY1)*(TMath::Log10((v+dv)/fMinCurrent)) / (TMath::Log10(fMaxCurrent/fMinCurrent));
00755 else y2=y1+dy;
00756 lb->SetLineColor(gStyle->GetColorPalette(theColor));
00757 lb->PaintLine(fX1,y1,fX1,y2);
00758 y1=y2;
00759 v+=dv;
00760 }
00761 } else {
00762
00763 Double_t dx = (fX2-fX1)/fNbins;
00764 Double_t dv = (fMaxCurrent - fMinCurrent)/fNbins;
00765 Double_t v = fMinCurrent;
00766 Double_t x1 = fX1,x2;
00767 for (i=1; i<=fNbins; i++) {
00768 theColor = (Int_t)( ((fHistogram->GetBinContent(i)-hmin)/(hmax-hmin))*(ncolors-1) );
00769 lb->SetLineColor(gStyle->GetColorPalette(theColor));
00770 if(TestBit(kLogScale)) x2 = fX1 + (fX2-fX1)*(TMath::Log10((v+dv)/fMinCurrent)) / (TMath::Log10(fMaxCurrent/fMinCurrent));
00771 else x2=x1+dx;
00772 lb->PaintLine(x1,fY1,x2,fY1);
00773 x1=x2;
00774 v+=dv;
00775 }
00776 }
00777 delete lb;
00778 }
00779 }
00780
00781
00782
00783 void TParallelCoordVar::PaintLabels()
00784 {
00785
00786
00787 TLatex* t = new TLatex();
00788 TFrame *frame = gPad->GetFrame();
00789 t->SetTextSize(0.03);
00790 if (fX1==fX2) {
00791 t->SetText(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
00792 Double_t tlength = t->GetXsize();
00793 if (fX1-0.5*tlength<0.01) {
00794 t->SetTextAlign(11);
00795 t->SetText(0.01, frame->GetY1() - 0.04 - t->GetTextSize(), GetName());
00796 t->Paint();
00797 } else if (fX1+0.5*tlength > 0.99) {
00798 t->SetTextAlign(31);
00799 t->SetText(0.99,frame->GetY1() - 0.04 - t->GetTextSize(),GetName());
00800 t->Paint();
00801 } else {
00802 t->SetTextAlign(21);
00803 t->PaintLatex(fX1,frame->GetY1() - 0.04 - t->GetTextSize(),0,0.03,GetName());
00804 }
00805 if (!fParallel->TestBit(TParallelCoord::kCandleChart)) {
00806 t->SetTextAlign(21);
00807 t->PaintLatex(fX1,frame->GetY2() + 0.005,0,0.025,Form("%6.4f",fMaxCurrent));
00808 t->SetTextAlign(23);
00809 t->PaintLatex(fX1,frame->GetY1() - 0.005,0,0.025,Form("%6.4f",fMinCurrent));
00810 }
00811 } else {
00812 t->SetText(fX1-0.04,fY1+0.02,GetName());
00813 t->SetTextSize(0.03);
00814 Double_t tlength = t->GetXsize();
00815 if (fX1-0.04-tlength<0.01) {
00816 t->SetTextAlign(12);
00817 t->SetText(0.01,fY1+0.02,GetName());
00818 t->Paint();
00819 } else {
00820 t->SetTextAlign(32);
00821 t->PaintLatex(fX1-0.04,fY1+0.02,0,0.03,GetName());
00822 }
00823 if (!fParallel->TestBit(TParallelCoord::kCandleChart)) {
00824 t->SetTextAlign(12);
00825 t->PaintLatex(0.01,fY1-0.02,0,0.025,Form("%6.4f",fMinCurrent));
00826 t->SetTextAlign(32);
00827 t->PaintLatex(0.99,fY1-0.02,0,0.025,Form("%6.4f",fMaxCurrent));
00828 }
00829 }
00830 delete t;
00831 }
00832
00833
00834
00835 void TParallelCoordVar::Print(Option_t* ) const
00836 {
00837
00838
00839 printf("**************variable #%d**************\n",fParallel->GetVarList()->IndexOf(this));
00840 printf("at x1=%f, y1=%f, x2=%f, y2=%f.\n",fX1,fY1,fX2,fY2);
00841 printf("min = %f, Q1 = %f, Med = %f, Q3 = %f, Max = %f\n", fMinInit, fQua1, fMed, fQua3, fMaxInit);
00842 }
00843
00844
00845
00846 void TParallelCoordVar::SavePrimitive(ostream & out, Option_t* options)
00847 {
00848
00849
00850
00851
00852 TString opt = options;
00853 if (opt.Contains("pcalled")) {
00854 out<<" var->SetBit(TParallelCoordVar::kLogScale,"<<TestBit(kLogScale)<<");"<<endl;
00855 out<<" var->SetBit(TParallelCoordVar::kShowBox,"<<TestBit(kShowBox)<<");"<<endl;
00856 out<<" var->SetBit(TParallelCoordVar::kShowBarHisto,"<<TestBit(kShowBarHisto)<<");"<<endl;
00857 out<<" var->SetHistogramBinning("<<fNbins<<");"<<endl;
00858 out<<" var->SetHistogramLineWidth("<<fHistoLW<<");"<<endl;
00859 out<<" var->SetInitMin("<<fMinInit<<");"<<endl;
00860 out<<" var->SetInitMax("<<fMaxInit<<");"<<endl;
00861 out<<" var->SetHistogramHeight("<<fHistoHeight<<");"<<endl;
00862 out<<" var->GetMinMaxMean();"<<endl;
00863 out<<" var->GetHistogram();"<<endl;
00864 out<<" var->SetFillStyle("<<GetFillStyle()<<");"<<endl;
00865 out<<" var->SetFillColor("<<GetFillColor()<<");"<<endl;
00866 out<<" var->SetLineColor("<<GetLineColor()<<");"<<endl;
00867 out<<" var->SetLineWidth("<<GetLineWidth()<<");"<<endl;
00868 out<<" var->SetLineStyle("<<GetLineStyle()<<");"<<endl;
00869 if (TestBit(kShowBox)) out<<" var->GetQuantiles();"<<endl;
00870 TIter next(fRanges);
00871 TParallelCoordRange* range;
00872 Int_t i = 1;
00873 while ((range = (TParallelCoordRange*)next())) {
00874 out<<" //***************************************"<<endl;
00875 out<<" // Create the "<<i<<"th range owned by the axis \""<<GetTitle()<<"\"."<<endl;
00876 out<<" TParallelCoordSelect* sel = para->GetSelection(\""<<range->GetSelection()->GetTitle()<<"\");"<<endl;
00877 out<<" TParallelCoordRange* newrange = new TParallelCoordRange(var,"<<range->GetMin()<<","<<range->GetMax()<<",sel);"<<endl;
00878 out<<" var->AddRange(newrange);"<<endl;
00879 out<<" sel->Add(newrange);"<<endl;
00880 ++i;
00881 }
00882 }
00883 }
00884
00885
00886
00887 void TParallelCoordVar::SetBoxPlot(Bool_t box)
00888 {
00889
00890
00891 SetBit(kShowBox,box);
00892 if (box) SetHistogramHeight(0.5);
00893 else {
00894 SetHistogramHeight(0);
00895 SetHistogramLineWidth(2);
00896 }
00897 }
00898
00899
00900
00901 void TParallelCoordVar::SetHistogramBinning(Int_t n)
00902 {
00903
00904
00905 if (n < 0 || n == fNbins) return;
00906 fNbins = n;
00907 GetHistogram();
00908 }
00909
00910
00911
00912 void TParallelCoordVar::SetHistogramHeight(Double_t h)
00913 {
00914
00915
00916 fHistoHeight = h;
00917 if (!fParallel->TestBit(TParallelCoord::kCandleChart)){
00918 if(h!=0) SetBit(kShowBarHisto,kTRUE);
00919 else SetBit(kShowBarHisto,kFALSE);
00920 }
00921 }
00922
00923
00924
00925 void TParallelCoordVar::SetCurrentMin(Double_t min)
00926 {
00927
00928
00929 fMinCurrent = min;
00930 }
00931
00932
00933
00934 void TParallelCoordVar::SetCurrentMax(Double_t max)
00935 {
00936
00937
00938 fMaxCurrent = max;
00939 }
00940
00941
00942
00943 void TParallelCoordVar::SetCurrentLimits(Double_t min, Double_t max)
00944 {
00945
00946
00947 if (min>max) {
00948 Double_t mem = min;
00949 min = max;
00950 max = mem;
00951 }
00952 if(TestBit(kLogScale) && max<=0) return;
00953 if(TestBit(kLogScale) && min<=0) min = 0.00001*max;
00954 fMinCurrent = min;
00955 fMaxCurrent = max;
00956
00957 delete fHistogram;
00958 fHistogram = NULL;
00959 GetHistogram();
00960
00961 if (fParallel->TestBit(TParallelCoord::kGlobalScale)) {
00962 fParallel->SetGlobalMin(min);
00963 fParallel->SetGlobalMax(max);
00964 }
00965 }
00966
00967
00968
00969 void TParallelCoordVar::SetLiveRangesUpdate(Bool_t on)
00970 {
00971
00972
00973 TIter next(fRanges);
00974 TParallelCoordRange* range;
00975 while ((range = (TParallelCoordRange*)next())) range->SetBit(TParallelCoordRange::kLiveUpdate,on);
00976 }
00977
00978
00979
00980 void TParallelCoordVar::SetLogScale(Bool_t log)
00981 {
00982
00983
00984 if (log == TestBit (kLogScale)) return;
00985 if (fMaxInit < 0) SetBit(kLogScale,kFALSE);
00986 else if (log) {
00987 if (fMaxCurrent < 0 ) fMaxCurrent = fMaxInit;
00988 if (fMinCurrent < 0 ) fMinCurrent = 0.00001*fMaxCurrent;
00989 SetBit(kLogScale,kTRUE);
00990 SetCurrentMin(fMinCurrent);
00991 SetCurrentMax(fMaxCurrent);
00992 } else {
00993 SetBit(kLogScale,kFALSE);
00994 SetCurrentMin(fMinInit);
00995 SetCurrentMax(fMaxInit);
00996 }
00997 GetQuantiles();
00998 GetHistogram();
00999 }
01000
01001
01002
01003 void TParallelCoordVar::SetValues(Long64_t length, Double_t* val)
01004 {
01005
01006
01007 if (fVal) delete [] fVal;
01008 fVal = new Double_t[length];
01009 fNentries = length;
01010 for (Long64_t li = 0; li < length; ++li) fVal[li] = val[li];
01011 GetMinMaxMean();
01012 GetHistogram();
01013 if (TestBit(kShowBox)) GetQuantiles();
01014 }
01015
01016
01017
01018 void TParallelCoordVar::SetX(Double_t x, Bool_t gl)
01019 {
01020
01021
01022
01023 TFrame *frame = gPad->GetFrame();
01024 if (!gl) {
01025 fY1 = frame->GetY1();
01026 fY2 = frame->GetY2();
01027 } else {
01028 Double_t gmin = fParallel->GetGlobalMin();
01029 Double_t gmax = fParallel->GetGlobalMax();
01030 fY1 = frame->GetY1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
01031 fY2 = frame->GetY1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetY2()-frame->GetY1());
01032 }
01033 fX1 = fX2 = x;
01034 }
01035
01036
01037
01038 void TParallelCoordVar::SetY(Double_t y, Bool_t gl)
01039 {
01040
01041
01042
01043 TFrame *frame = gPad->GetFrame();
01044 if (!gl) {
01045 fX1 = frame->GetX1();
01046 fX2 = frame->GetX2();
01047 } else {
01048 Double_t gmin = fParallel->GetGlobalMin();
01049 Double_t gmax = fParallel->GetGlobalMax();
01050 fX1 = frame->GetX1() + ((fMinCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
01051 fX2 = frame->GetX1() + ((fMaxCurrent-gmin)/(gmax-gmin))*(frame->GetX2()-frame->GetX1());
01052 }
01053 fY1 = fY2 = y;
01054 }