00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TParallelCoord.h"
00013 #include "TParallelCoordVar.h"
00014 #include "TParallelCoordRange.h"
00015
00016 #include "Riostream.h"
00017 #include "TROOT.h"
00018 #include "TVirtualX.h"
00019 #include "TPad.h"
00020 #include "TPolyLine.h"
00021 #include "TGraph.h"
00022 #include "TPaveText.h"
00023 #include "float.h"
00024 #include "TMath.h"
00025 #include "TBox.h"
00026 #include "TH1.h"
00027 #include "TStyle.h"
00028 #include "TEntryList.h"
00029 #include "TFrame.h"
00030 #include "TTree.h"
00031 #include "TTreePlayer.h"
00032 #include "TSelectorDraw.h"
00033 #include "TTreeFormula.h"
00034 #include "TView.h"
00035 #include "TRandom.h"
00036 #include "TEnv.h"
00037 #include "TCanvas.h"
00038 #include "TGaxis.h"
00039 #include "TFile.h"
00040
00041 ClassImp(TParallelCoord)
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 TParallelCoord::TParallelCoord()
00104 :TNamed()
00105 {
00106
00107
00108 Init();
00109 }
00110
00111
00112
00113 TParallelCoord::TParallelCoord(Long64_t nentries)
00114 {
00115
00116
00117
00118
00119 Init();
00120 fNentries = nentries;
00121 fCurrentN = fNentries;
00122 fVarList = new TList();
00123 fSelectList = new TList();
00124 fCurrentSelection = new TParallelCoordSelect();
00125 fSelectList->Add(fCurrentSelection);
00126 }
00127
00128
00129
00130 TParallelCoord::TParallelCoord(TTree* tree, Long64_t nentries)
00131 :TNamed("ParaCoord","ParaCoord")
00132 {
00133
00134
00135
00136 Init();
00137 Int_t estimate = tree->GetEstimate();
00138 if (nentries>estimate) {
00139 Warning("TParallelCoord","Call tree->SetEstimate(tree->GetEntries()) to display all the tree variables");
00140 fNentries = estimate;
00141 } else {
00142 fNentries = nentries;
00143 }
00144 fCurrentN = fNentries;
00145 fTree = tree;
00146 fTreeName = fTree->GetName();
00147 if (fTree->GetCurrentFile()) fTreeFileName = fTree->GetCurrentFile()->GetName();
00148 else fTreeFileName = "";
00149 fVarList = new TList();
00150 fSelectList = new TList();
00151 fCurrentSelection = new TParallelCoordSelect();
00152 fSelectList->Add(fCurrentSelection);
00153 }
00154
00155
00156
00157 TParallelCoord::~TParallelCoord()
00158 {
00159
00160
00161 if (fCurrentEntries) delete fCurrentEntries;
00162 if (fInitEntries != fCurrentEntries && fInitEntries != 0) delete fInitEntries;
00163 if (fVarList) {
00164 fVarList->Delete();
00165 delete fVarList;
00166 }
00167 if (fSelectList) {
00168 fSelectList->Delete();
00169 delete fSelectList;
00170 }
00171 if (fCandleAxis) delete fCandleAxis;
00172 SetDotsSpacing(0);
00173 }
00174
00175
00176
00177 void TParallelCoord::AddVariable(Double_t* val, const char* title)
00178 {
00179
00180
00181 ++fNvar;
00182 fVarList->Add(new TParallelCoordVar(val,title,fVarList->GetSize(),this));
00183 SetAxesPosition();
00184 }
00185
00186
00187
00188 void TParallelCoord::AddVariable(const char* varexp)
00189 {
00190
00191
00192 if(!fTree) return;
00193
00194
00195 TEntryList *list = GetEntryList(kFALSE);
00196 fTree->SetEntryList(list);
00197
00198
00199
00200 TString exp = varexp;
00201
00202 if (exp.Contains(':') || exp.Contains(">>") || exp.Contains("<<")) {
00203 Warning("AddVariable","Only a single variable can be added at a time.");
00204 return;
00205 }
00206 if (exp == ""){
00207 Warning("AddVariable","Nothing to add");
00208 return;
00209 }
00210
00211 Long64_t en = fTree->Draw(varexp,"","goff");
00212 if (en<0) {
00213 Warning("AddVariable","%s could not be evaluated",varexp);
00214 return;
00215 }
00216
00217 AddVariable(fTree->GetV1(),varexp);
00218 TParallelCoordVar* var = (TParallelCoordVar*)fVarList->Last();
00219 var->Draw();
00220 }
00221
00222
00223
00224 void TParallelCoord::AddSelection(const char* title)
00225 {
00226
00227
00228 TParallelCoordSelect *sel = new TParallelCoordSelect(title);
00229 fSelectList->Add(sel);
00230 fCurrentSelection = sel;
00231 }
00232
00233
00234
00235 void TParallelCoord::ApplySelectionToTree()
00236 {
00237
00238
00239 if(!fTree) return;
00240 if(fSelectList) {
00241 if(fSelectList->GetSize() == 0) return;
00242 if(fCurrentSelection == 0) fCurrentSelection = (TParallelCoordSelect*)fSelectList->First();
00243 }
00244 fCurrentEntries = GetEntryList();
00245 fNentries = fCurrentEntries->GetN();
00246 fCurrentFirst = 0;
00247 fCurrentN = fNentries;
00248 fTree->SetEntryList(fCurrentEntries);
00249 TString varexp = "";
00250 TIter next(fVarList);
00251 TParallelCoordVar* var;
00252 while ((var = (TParallelCoordVar*)next())) varexp.Append(Form(":%s",var->GetTitle()));
00253 varexp.Remove(TString::kLeading,':');
00254 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
00255 fTree->Draw(varexp.Data(),"","goff para");
00256 next.Reset();
00257 Int_t i = 0;
00258 while ((var = (TParallelCoordVar*)next())) {
00259 var->SetValues(fNentries, selector->GetVal(i));
00260 ++i;
00261 }
00262 if (fSelectList) {
00263 fSelectList->Delete();
00264 fCurrentSelection = 0;
00265 }
00266 gPad->Modified();
00267 gPad->Update();
00268 }
00269
00270
00271
00272 void TParallelCoord::BuildParallelCoord(TSelectorDraw* selector, Bool_t candle)
00273 {
00274
00275
00276 TParallelCoord* pc = new TParallelCoord(selector->GetTree(),selector->GetNfill());
00277 pc->SetBit(kCanDelete);
00278 selector->SetObject(pc);
00279 TString varexp = "";
00280 for(Int_t i=0;i<selector->GetDimension();++i) {
00281 pc->AddVariable(selector->GetVal(i),selector->GetVar(i)->GetTitle());
00282 varexp.Append(Form(":%s",selector->GetVar(i)->GetTitle()));
00283 }
00284 varexp.Remove(TString::kLeading,':');
00285 if (selector->GetSelect()) varexp.Append(Form("{%s}",selector->GetSelect()->GetTitle()));
00286 pc->SetTitle(varexp.Data());
00287 if (!candle) pc->Draw();
00288 else pc->Draw("candle");
00289 }
00290
00291
00292 void TParallelCoord::CleanUpSelections(TParallelCoordRange* range)
00293 {
00294
00295
00296
00297 TIter next(fSelectList);
00298 TParallelCoordSelect* select;
00299 while ((select = (TParallelCoordSelect*)next())){
00300 if(select->Contains(range)) select->Remove(range);
00301 }
00302 }
00303
00304
00305
00306 void TParallelCoord::DeleteSelection(TParallelCoordSelect * sel)
00307 {
00308
00309
00310 fSelectList->Remove(sel);
00311 delete sel;
00312 if(fSelectList->GetSize() == 0) fCurrentSelection = 0;
00313 else fCurrentSelection = (TParallelCoordSelect*)fSelectList->At(0);
00314 }
00315
00316
00317
00318 Int_t TParallelCoord::DistancetoPrimitive(Int_t px, Int_t py)
00319 {
00320
00321
00322 if(!gPad) return 9999;
00323
00324 TFrame *frame = gPad->GetFrame();
00325
00326 Double_t x1,x2,y1,y2,xx,yy;
00327
00328 x1 = frame->GetX1()+0.01;
00329 x2 = frame->GetX2()-0.01;
00330 y2 = frame->GetY2()-0.01;
00331 y1 = frame->GetY1()+0.01;
00332
00333 xx = gPad->AbsPixeltoX(px);
00334 yy = gPad->AbsPixeltoY(py);
00335
00336 if(xx>x1 && xx<x2 && yy>y1 && yy<y2) return 0;
00337 else return 9999;
00338 }
00339
00340
00341
00342 void TParallelCoord::Draw(Option_t* option)
00343 {
00344
00345
00346 if (!GetTree()) return;
00347 if (!fCurrentEntries) fCurrentEntries = fInitEntries;
00348 Bool_t optcandle = kFALSE;
00349 TString opt = option;
00350 opt.ToLower();
00351 if(opt.Contains("candle")) {
00352 optcandle = kTRUE;
00353 opt.ReplaceAll("candle","");
00354 }
00355 if(optcandle) {
00356 SetBit(kPaintEntries,kFALSE);
00357 SetBit(kCandleChart,kTRUE);
00358 SetGlobalScale(kTRUE);
00359 }
00360
00361 if (gPad) {
00362 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
00363 } else gROOT->MakeDefCanvas();
00364 TView *view = gPad->GetView();
00365 if(view){
00366 delete view;
00367 gPad->SetView(0);
00368 }
00369 gPad->Clear();
00370 if (!optcandle) {
00371 if (gPad && gPad->IsA() == TCanvas::Class()
00372 && !((TCanvas*)gPad)->GetShowEditor()) {
00373 ((TCanvas*)gPad)->ToggleEditor();
00374 ((TCanvas*)gPad)->ToggleEventStatus();
00375 }
00376 }
00377
00378 gPad->SetBit(TGraph::kClipFrame,kTRUE);
00379
00380 TFrame *frame = new TFrame(0.1,0.1,0.9,0.9);
00381 frame->SetBorderSize(0);
00382 frame->SetBorderMode(0);
00383 frame->SetFillStyle(0);
00384 frame->SetLineColor(gPad->GetFillColor());
00385 frame->Draw();
00386 AppendPad(option);
00387 TPaveText *title = new TPaveText(0.05,0.95,0.35,1);
00388 title->AddText(GetTitle());
00389 title->Draw();
00390 SetAxesPosition();
00391 TIter next(fVarList);
00392 TParallelCoordVar* var;
00393 while ((var = (TParallelCoordVar*)next())) {
00394 if(optcandle) {
00395 var->SetBoxPlot(kTRUE);
00396 var->SetHistogramHeight(0.5);
00397 var->SetHistogramLineWidth(0);
00398 }
00399 var->Draw();
00400 }
00401
00402 if (optcandle) {
00403 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
00404 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
00405 fCandleAxis->Draw();
00406 }
00407
00408 if (gPad && gPad->IsA() == TCanvas::Class())
00409 ((TCanvas*)gPad)->Selected(gPad,this,1);
00410 }
00411
00412
00413
00414 void TParallelCoord::ExecuteEvent(Int_t , Int_t , Int_t )
00415 {
00416
00417
00418 gPad->SetCursor(kHand);
00419 }
00420
00421
00422
00423 TParallelCoordSelect* TParallelCoord::GetCurrentSelection()
00424 {
00425
00426
00427 if (!fSelectList) return 0;
00428 if (!fCurrentSelection) {
00429 fCurrentSelection = (TParallelCoordSelect*)fSelectList->First();
00430 }
00431 return fCurrentSelection;
00432 }
00433
00434
00435
00436 TEntryList* TParallelCoord::GetEntryList(Bool_t sel)
00437 {
00438
00439
00440 if(!sel || fCurrentSelection->GetSize() == 0){
00441 return fInitEntries;
00442 } else {
00443 TEntryList *enlist = new TEntryList(fTree);
00444 TIter next(fVarList);
00445 for (Long64_t li=0;li<fNentries;++li) {
00446 next.Reset();
00447 Bool_t inrange=kTRUE;
00448 TParallelCoordVar* var;
00449 while((var = (TParallelCoordVar*)next())){
00450 if(!var->Eval(li,fCurrentSelection)) inrange = kFALSE;
00451 }
00452 if(!inrange) continue;
00453 enlist->Enter(fCurrentEntries->GetEntry(li));
00454 }
00455 return enlist;
00456 }
00457 }
00458
00459
00460
00461 Double_t TParallelCoord::GetGlobalMax()
00462 {
00463
00464
00465 Double_t gmax=-FLT_MAX;
00466 TIter next(fVarList);
00467 TParallelCoordVar* var;
00468 while ((var = (TParallelCoordVar*)next())) {
00469 if (gmax < var->GetCurrentMax()) gmax = var->GetCurrentMax();
00470 }
00471 return gmax;
00472 }
00473
00474
00475
00476 Double_t TParallelCoord::GetGlobalMin()
00477 {
00478
00479
00480 Double_t gmin=FLT_MAX;
00481 TIter next(fVarList);
00482 TParallelCoordVar* var;
00483 while ((var = (TParallelCoordVar*)next())) {
00484 if (gmin > var->GetCurrentMin()) gmin = var->GetCurrentMin();
00485 }
00486 return gmin;
00487 }
00488
00489
00490
00491 Int_t TParallelCoord::GetNbins()
00492 {
00493
00494
00495 return ((TParallelCoordVar*)fVarList->First())->GetNbins();
00496 }
00497
00498
00499
00500 TParallelCoordSelect* TParallelCoord::GetSelection(const char* title)
00501 {
00502
00503
00504 TIter next(fSelectList);
00505 TParallelCoordSelect* sel;
00506 while ((sel = (TParallelCoordSelect*)next()) && strcmp(title,sel->GetTitle())) { }
00507 return sel;
00508 }
00509
00510
00511
00512 TTree* TParallelCoord::GetTree()
00513 {
00514
00515
00516
00517 if (fTree) return fTree;
00518 if (fTreeFileName=="" || fTreeName=="") {
00519 Error("GetTree","Cannot load the tree: no tree defined!");
00520 return 0;
00521 }
00522 TFile *f = TFile::Open(fTreeFileName.Data());
00523 if (!f) {
00524 Error("GetTree","Tree file name : \"%s\" does not exsist (Are you in the correct directory?).",fTreeFileName.Data());
00525 return 0;
00526 } else if (f->IsZombie()) {
00527 Error("GetTree","while opening \"%s\".",fTreeFileName.Data());
00528 return 0;
00529 } else {
00530 fTree = (TTree*)f->Get(fTreeName.Data());
00531 if (!fTree) {
00532 Error("GetTree","\"%s\" not found in \"%s\".", fTreeName.Data(), fTreeFileName.Data());
00533 return 0;
00534 } else {
00535 fTree->SetEntryList(fCurrentEntries);
00536 TString varexp = "";
00537 TIter next(fVarList);
00538 TParallelCoordVar* var;
00539 while ((var = (TParallelCoordVar*)next())) varexp.Append(Form(":%s",var->GetTitle()));
00540 varexp.Remove(TString::kLeading,':');
00541 fTree->Draw(varexp.Data(),"","goff para");
00542 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
00543 next.Reset();
00544 Int_t i = 0;
00545 while ((var = (TParallelCoordVar*)next())) {
00546 var->SetValues(fNentries, selector->GetVal(i));
00547 ++i;
00548 }
00549 return fTree;
00550 }
00551 }
00552 }
00553
00554
00555
00556 Double_t* TParallelCoord::GetVariable(const char* vartitle)
00557 {
00558
00559
00560 TIter next(fVarList);
00561 TParallelCoordVar* var = 0;
00562 while(((var = (TParallelCoordVar*)next()) != 0) && (var->GetTitle() != vartitle)) { }
00563 if(!var) return 0;
00564 else return var->GetValues();
00565 }
00566
00567
00568
00569 Double_t* TParallelCoord::GetVariable(Int_t i)
00570 {
00571
00572
00573 if(i<0 || (UInt_t)i>fNvar) return 0;
00574 else return ((TParallelCoordVar*)fVarList->At(i))->GetValues();
00575 }
00576
00577
00578
00579 void TParallelCoord::Init()
00580 {
00581
00582
00583 fNentries = 0;
00584 fVarList = 0;
00585 fSelectList = 0;
00586 SetBit(kVertDisplay,kTRUE);
00587 SetBit(kCurveDisplay,kFALSE);
00588 SetBit(kPaintEntries,kTRUE);
00589 SetBit(kLiveUpdate,kFALSE);
00590 SetBit(kGlobalScale,kFALSE);
00591 SetBit(kCandleChart,kFALSE);
00592 SetBit(kGlobalLogScale,kFALSE);
00593 fTree = 0;
00594 fCurrentEntries = 0;
00595 fInitEntries = 0;
00596 fCurrentSelection = 0;
00597 fNvar = 0;
00598 fDotsSpacing = 0;
00599 fCurrentFirst = 0;
00600 fCurrentN = 0;
00601 fCandleAxis = 0;
00602 fWeightCut = 0;
00603 fLineWidth = 1;
00604 fLineColor = kGreen-8;
00605 fTreeName = "";
00606 fTreeFileName = "";
00607 }
00608
00609
00610 void TParallelCoord::Paint(Option_t* )
00611 {
00612
00613
00614 if (!GetTree()) return;
00615 gPad->Range(0,0,1,1);
00616 TFrame *frame = gPad->GetFrame();
00617 frame->SetLineColor(gPad->GetFillColor());
00618 SetAxesPosition();
00619 if(TestBit(kPaintEntries)){
00620 PaintEntries(0);
00621 TIter next(fSelectList);
00622 TParallelCoordSelect* sel;
00623 while((sel = (TParallelCoordSelect*)next())) {
00624 if(sel->GetSize()>0 && sel->TestBit(TParallelCoordSelect::kActivated)) {
00625 PaintEntries(sel);
00626 }
00627 }
00628 }
00629 gPad->RangeAxis(0,0,1,1);
00630 }
00631
00632
00633
00634 void TParallelCoord::PaintEntries(TParallelCoordSelect* sel)
00635 {
00636
00637
00638 if (fVarList->GetSize() < 2) return;
00639 Int_t i=0;
00640 Long64_t n=0;
00641
00642 Double_t *x = new Double_t[fNvar];
00643 Double_t *y = new Double_t[fNvar];
00644
00645 TGraph *gr = 0;
00646 TPolyLine *pl = 0;
00647 TAttLine *evline = 0;
00648
00649 if (TestBit (kCurveDisplay)) {gr = new TGraph(fNvar); evline = (TAttLine*)gr;}
00650 else {pl = new TPolyLine(fNvar); evline = (TAttLine*)pl;}
00651
00652 if (fDotsSpacing == 0) evline->SetLineStyle(1);
00653 else evline->SetLineStyle(11);
00654 if (!sel){
00655 evline->SetLineWidth(GetLineWidth());
00656 evline->SetLineColor(GetLineColor());
00657 } else {
00658 evline->SetLineWidth(sel->GetLineWidth());
00659 evline->SetLineColor(sel->GetLineColor());
00660 }
00661 TParallelCoordVar *var;
00662
00663 TFrame *frame = gPad->GetFrame();
00664 Double_t lx = ((frame->GetX2() - frame->GetX1())/(fNvar-1));
00665 Double_t ly = ((frame->GetY2() - frame->GetY1())/(fNvar-1));
00666 Double_t a,b;
00667 TRandom r;
00668
00669 for (n=fCurrentFirst; n<fCurrentFirst+fCurrentN; ++n) {
00670 TListIter next(fVarList);
00671 Bool_t inrange = kTRUE;
00672
00673 if (sel) {
00674 while ((var = (TParallelCoordVar*)next())){
00675 if (!var->Eval(n,sel)) inrange = kFALSE;
00676 }
00677 }
00678 if (fWeightCut > 0) {
00679 next.Reset();
00680 Int_t entryweight = 0;
00681 while ((var = (TParallelCoordVar*)next())) entryweight+=var->GetEntryWeight(n);
00682 if (entryweight/(Int_t)fNvar < fWeightCut) inrange = kFALSE;
00683 }
00684 if(!inrange) continue;
00685 i = 0;
00686 next.Reset();
00687
00688 while ((var = (TParallelCoordVar*)next())) {
00689 var->GetEntryXY(n,x[i],y[i]);
00690 ++i;
00691 }
00692
00693
00694 if (fDotsSpacing != 0) {
00695 if (TestBit(kVertDisplay)) {
00696 a = (y[1]-y[0])/(x[1]-x[0]);
00697 b = y[0]-a*x[0];
00698 x[0] = x[0]+lx*r.Rndm(n);
00699 y[0] = a*x[0]+b;
00700 } else {
00701 a = (x[1]-x[0])/(y[1]-y[0]);
00702 b = x[0]-a*y[0];
00703 y[0] = y[0]+ly*r.Rndm(n);
00704 x[0] = a*y[0]+b;
00705 }
00706 }
00707 if (pl) pl->PaintPolyLine(fNvar,x,y);
00708 else gr->PaintGraph(fNvar,x,y,"C");
00709 }
00710
00711 if (pl) delete pl;
00712 if (gr) delete gr;
00713 delete [] x;
00714 delete [] y;
00715 }
00716
00717
00718
00719 void TParallelCoord::RemoveVariable(TParallelCoordVar *var)
00720 {
00721
00722
00723 fVarList->Remove(var);
00724 fNvar = fVarList->GetSize();
00725 SetAxesPosition();
00726 }
00727
00728
00729
00730 TParallelCoordVar* TParallelCoord::RemoveVariable(const char* vartitle)
00731 {
00732
00733
00734 TIter next(fVarList);
00735 TParallelCoordVar* var=0;
00736 while((var = (TParallelCoordVar*)next())) {
00737 if (!strcmp(var->GetTitle(),vartitle)) break;
00738 }
00739 if(!var) Error("RemoveVariable","\"%s\" not a variable",vartitle);
00740 fVarList->Remove(var);
00741 fNvar = fVarList->GetSize();
00742 SetAxesPosition();
00743 var->DeleteVariable();
00744 return var;
00745 }
00746
00747
00748
00749 void TParallelCoord::ResetTree()
00750 {
00751
00752
00753 if(!fTree) return;
00754 fTree->SetEntryList(fInitEntries);
00755 fCurrentEntries = fInitEntries;
00756 fNentries = fCurrentEntries->GetN();
00757 fCurrentFirst = 0;
00758 fCurrentN = fNentries;
00759 TString varexp = "";
00760 TIter next(fVarList);
00761 TParallelCoordVar* var;
00762 while ((var = (TParallelCoordVar*)next())) varexp.Append(Form(":%s",var->GetTitle()));
00763 varexp.Remove(TString::kLeading,':');
00764 fTree->Draw(varexp.Data(),"","goff para");
00765 next.Reset();
00766 TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)fTree->GetPlayer())->GetSelector();
00767 Int_t i = 0;
00768 while ((var = (TParallelCoordVar*)next())) {
00769 var->SetValues(fNentries, selector->GetVal(i));
00770 ++i;
00771 }
00772 if (fSelectList) {
00773 fSelectList->Delete();
00774 fCurrentSelection = 0;
00775 }
00776 gPad->Modified();
00777 gPad->Update();
00778 }
00779
00780
00781
00782 void TParallelCoord::SaveEntryLists(const char* filename, Bool_t overwrite)
00783 {
00784
00785
00786 TString sfile = filename;
00787 if (sfile == "") sfile = Form("%s_parallelcoord_entries.root",fTree->GetName());
00788
00789 TFile* f = TFile::Open(sfile.Data());
00790 if (f) {
00791 Warning("SaveEntryLists","%s already exists.", sfile.Data());
00792 if (!overwrite) return;
00793 else Warning("SaveEntryLists","Overwriting.");
00794 f = new TFile(sfile.Data(),"RECREATE");
00795 } else {
00796 f = new TFile(sfile.Data(),"CREATE");
00797 }
00798 gDirectory = f;
00799 fInitEntries->Write("initentries");
00800 fCurrentEntries->Write("currententries");
00801 Info("SaveEntryLists","File \"%s\" written.",sfile.Data());
00802 }
00803
00804
00805
00806 void TParallelCoord::SavePrimitive(ostream & out, Option_t* options)
00807 {
00808
00809
00810 TString opt = options;
00811 opt.ToLower();
00812
00813
00814 const char* filename = Form("%s_parallelcoord_entries.root",fTree->GetName());
00815 SaveEntryLists(filename,kTRUE);
00816 SaveTree(fTreeFileName,kTRUE);
00817 out<<" // Create a TParallelCoord."<<endl;
00818 out<<" TFile *f = TFile::Open(\""<<fTreeFileName.Data()<<"\");"<<endl;
00819 out<<" TTree* tree = (TTree*)f->Get(\""<<fTreeName.Data()<<"\");"<<endl;
00820 out<<" TParallelCoord* para = new TParallelCoord(tree,"<<fNentries<<");"<<endl;
00821 out<<" // Load the entrylists."<<endl;
00822 out<<" TFile *entries = TFile::Open(\""<<filename<<"\");"<<endl;
00823 out<<" TEntryList *currententries = (TEntryList*)entries->Get(\"currententries\");"<<endl;
00824 out<<" tree->SetEntryList(currententries);"<<endl;
00825 out<<" para->SetInitEntries((TEntryList*)entries->Get(\"initentries\"));"<<endl;
00826 out<<" para->SetCurrentEntries(currententries);"<<endl;
00827 TIter next(fSelectList);
00828 TParallelCoordSelect* sel;
00829 out<<" TParallelCoordSelect* sel;"<<endl;
00830 out<<" para->GetSelectList()->Delete();"<<endl;
00831 while ((sel = (TParallelCoordSelect*)next())) {
00832 out<<" para->AddSelection(\""<<sel->GetTitle()<<"\");"<<endl;
00833 out<<" sel = (TParallelCoordSelect*)para->GetSelectList()->Last();"<<endl;
00834 out<<" sel->SetLineColor("<<sel->GetLineColor()<<");"<<endl;
00835 out<<" sel->SetLineWidth("<<sel->GetLineWidth()<<");"<<endl;
00836 }
00837 TIter nextbis(fVarList);
00838 TParallelCoordVar* var;
00839 TString varexp = "";
00840 while ((var = (TParallelCoordVar*)nextbis())) varexp.Append(Form(":%s",var->GetTitle()));
00841 varexp.Remove(TString::kLeading,':');
00842 out<<" tree->Draw(\""<<varexp.Data()<<"\",\"\",\"goff para\");"<<endl;
00843 out<<" TSelectorDraw* selector = (TSelectorDraw*)((TTreePlayer*)tree->GetPlayer())->GetSelector();"<<endl;
00844 nextbis.Reset();
00845 Int_t i=0;
00846 out<<" TParallelCoordVar* var;"<<endl;
00847 while ((var = (TParallelCoordVar*)nextbis())) {
00848 out<<" //***************************************"<<endl;
00849 out<<" // Create the axis \""<<var->GetTitle()<<"\"."<<endl;
00850 out<<" para->AddVariable(selector->GetVal("<<i<<"),\""<<var->GetTitle()<<"\");"<<endl;
00851 out<<" var = (TParallelCoordVar*)para->GetVarList()->Last();"<<endl;
00852 var->SavePrimitive(out,"pcalled");
00853 ++i;
00854 }
00855 out<<" //***************************************"<<endl;
00856 out<<" // Set the TParallelCoord parameters."<<endl;
00857 out<<" para->SetCurrentFirst("<<fCurrentFirst<<");"<<endl;
00858 out<<" para->SetCurrentN("<<fCurrentN<<");"<<endl;
00859 out<<" para->SetWeightCut("<<fWeightCut<<");"<<endl;
00860 out<<" para->SetDotsSpacing("<<fDotsSpacing<<");"<<endl;
00861 out<<" para->SetLineColor("<<GetLineColor()<<");"<<endl;
00862 out<<" para->SetLineWidth("<<GetLineWidth()<<");"<<endl;
00863 out<<" para->SetBit(TParallelCoord::kVertDisplay,"<<TestBit(kVertDisplay)<<");"<<endl;
00864 out<<" para->SetBit(TParallelCoord::kCurveDisplay,"<<TestBit(kCurveDisplay)<<");"<<endl;
00865 out<<" para->SetBit(TParallelCoord::kPaintEntries,"<<TestBit(kPaintEntries)<<");"<<endl;
00866 out<<" para->SetBit(TParallelCoord::kLiveUpdate,"<<TestBit(kLiveUpdate)<<");"<<endl;
00867 out<<" para->SetBit(TParallelCoord::kGlobalLogScale,"<<TestBit(kGlobalLogScale)<<");"<<endl;
00868 if (TestBit(kGlobalScale)) out<<" para->SetGlobalScale(kTRUE);"<<endl;
00869 if (TestBit(kCandleChart)) out<<" para->SetCandleChart(kTRUE);"<<endl;
00870 if (TestBit(kGlobalLogScale)) out<<" para->SetGlobalLogScale(kTRUE);"<<endl;
00871 out<<endl<<" para->Draw();"<<endl;
00872 }
00873
00874
00875
00876 void TParallelCoord::SaveTree(const char* filename, Bool_t overwrite)
00877 {
00878
00879
00880 if (!(fTreeFileName=="")) return;
00881 TString sfile = filename;
00882 if (sfile == "") sfile = Form("%s.root",fTree->GetName());
00883
00884 TFile* f = TFile::Open(sfile.Data());
00885 if (f) {
00886 Warning("SaveTree","%s already exists.", sfile.Data());
00887 if (!overwrite) return;
00888 else Warning("SaveTree","Overwriting.");
00889 f = new TFile(sfile.Data(),"RECREATE");
00890 } else {
00891 f = new TFile(sfile.Data(),"CREATE");
00892 }
00893 gDirectory = f;
00894 fTree->Write(fTreeName.Data());
00895 fTreeFileName = sfile;
00896 Info("SaveTree","File \"%s\" written.",sfile.Data());
00897 }
00898
00899
00900
00901 void TParallelCoord::SetAxesPosition()
00902 {
00903
00904
00905 if(!gPad) return;
00906 Bool_t vert = TestBit (kVertDisplay);
00907 TFrame *frame = gPad->GetFrame();
00908 if (fVarList->GetSize() > 1) {
00909 if (vert) {
00910 frame->SetX1(1.0/((Double_t)fVarList->GetSize()+1));
00911 frame->SetX2(1-frame->GetX1());
00912 frame->SetY1(0.1);
00913 frame->SetY2(0.9);
00914 gPad->RangeAxis(1.0/((Double_t)fVarList->GetSize()+1),0.1,1-frame->GetX1(),0.9);
00915 } else {
00916 frame->SetX1(0.1);
00917 frame->SetX2(0.9);
00918 frame->SetY1(1.0/((Double_t)fVarList->GetSize()+1));
00919 frame->SetY2(1-frame->GetY1());
00920 gPad->RangeAxis(0.1,1.0/((Double_t)fVarList->GetSize()+1),0.9,1-frame->GetY1());
00921 }
00922
00923 Double_t horSpace = (frame->GetX2() - frame->GetX1())/(fNvar-1);
00924 Double_t verSpace = (frame->GetY2() - frame->GetY1())/(fNvar-1);
00925 Int_t i=0;
00926 TIter next(fVarList);
00927
00928 TParallelCoordVar* var;
00929 while((var = (TParallelCoordVar*)next())){
00930 if (vert) var->SetX(gPad->GetFrame()->GetX1() + i*horSpace,TestBit(kGlobalScale));
00931 else var->SetY(gPad->GetFrame()->GetY1() + i*verSpace,TestBit(kGlobalScale));
00932 ++i;
00933 }
00934 } else if (fVarList->GetSize()==1) {
00935 frame->SetX1(0.1);
00936 frame->SetX2(0.9);
00937 frame->SetY1(0.1);
00938 frame->SetY2(0.9);
00939 if (vert) ((TParallelCoordVar*)fVarList->First())->SetX(0.5,TestBit(kGlobalScale));
00940 else ((TParallelCoordVar*)fVarList->First())->SetY(0.5,TestBit(kGlobalScale));
00941 }
00942 }
00943
00944
00945
00946 void TParallelCoord::SetAxisHistogramBinning(Int_t n)
00947 {
00948
00949
00950 TIter next(fVarList);
00951 TParallelCoordVar *var;
00952 while((var = (TParallelCoordVar*)next())) var->SetHistogramBinning(n);
00953 }
00954
00955
00956
00957 void TParallelCoord::SetAxisHistogramHeight(Double_t h)
00958 {
00959
00960
00961 TIter next(fVarList);
00962 TParallelCoordVar *var;
00963 while((var = (TParallelCoordVar*)next())) var->SetHistogramHeight(h);
00964 }
00965
00966
00967
00968 void TParallelCoord::SetGlobalLogScale(Bool_t lt)
00969 {
00970
00971
00972 if (lt == TestBit(kGlobalLogScale)) return;
00973 SetBit(kGlobalLogScale,lt);
00974 TIter next(fVarList);
00975 TParallelCoordVar* var;
00976 while ((var = (TParallelCoordVar*)next())) var->SetLogScale(lt);
00977 if (TestBit(kGlobalScale)) SetGlobalScale(kTRUE);
00978 }
00979
00980
00981
00982 void TParallelCoord::SetGlobalScale(Bool_t gl)
00983 {
00984
00985
00986 SetBit(kGlobalScale,gl);
00987 if (fCandleAxis) {
00988 delete fCandleAxis;
00989 fCandleAxis = 0;
00990 }
00991 if (gl) {
00992 Double_t min,max;
00993 min = GetGlobalMin();
00994 max = GetGlobalMax();
00995 if (TestBit(kGlobalLogScale) && min<=0) min = 0.00001*max;
00996 if (TestBit(kVertDisplay)) {
00997 if (!TestBit(kGlobalLogScale)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,min,max);
00998 else fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,min,max,510,"G");
00999 } else {
01000 if (!TestBit(kGlobalLogScale)) fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,min,max);
01001 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,min,max,510,"G");
01002 }
01003 fCandleAxis->Draw();
01004 SetGlobalMin(min);
01005 SetGlobalMax(max);
01006 TIter next(fVarList);
01007 TParallelCoordVar* var;
01008 while ((var = (TParallelCoordVar*)next())) var->GetHistogram();
01009 }
01010 gPad->Modified();
01011 gPad->Update();
01012 }
01013
01014
01015
01016 void TParallelCoord::SetAxisHistogramLineWidth(Int_t lw)
01017 {
01018
01019
01020 TIter next(fVarList);
01021 TParallelCoordVar *var;
01022 while((var = (TParallelCoordVar*)next())) var->SetHistogramLineWidth(lw);
01023 }
01024
01025
01026
01027 void TParallelCoord::SetCandleChart(Bool_t can)
01028 {
01029
01030
01031 SetBit(kCandleChart,can);
01032 SetGlobalScale(can);
01033 TIter next(fVarList);
01034 TParallelCoordVar* var;
01035 while ((var = (TParallelCoordVar*)next())) {
01036 var->SetBoxPlot(can);
01037 var->SetHistogramLineWidth(0);
01038 }
01039 if (fCandleAxis) delete fCandleAxis;
01040 fCandleAxis = 0;
01041 SetBit(kPaintEntries,!can);
01042 if (can) {
01043 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
01044 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
01045 fCandleAxis->Draw();
01046 } else {
01047 if (fCandleAxis) {
01048 delete fCandleAxis;
01049 fCandleAxis = 0;
01050 }
01051 }
01052 gPad->Modified();
01053 gPad->Update();
01054 }
01055
01056
01057
01058 void TParallelCoord::SetCurrentFirst(Long64_t f)
01059 {
01060
01061
01062 if(f<0 || f>fNentries) return;
01063 fCurrentFirst = f;
01064 if(fCurrentFirst + fCurrentN > fNentries) fCurrentN = fNentries-fCurrentFirst;
01065 TIter next(fVarList);
01066 TParallelCoordVar* var;
01067 while ((var = (TParallelCoordVar*)next())) {
01068 var->GetMinMaxMean();
01069 var->GetHistogram();
01070 if (var->TestBit(TParallelCoordVar::kShowBox)) var->GetQuantiles();
01071 }
01072 }
01073
01074
01075
01076 void TParallelCoord::SetCurrentN(Long64_t n)
01077 {
01078
01079
01080 if(n<=0) return;
01081 if(fCurrentFirst+n>fNentries) fCurrentN = fNentries-fCurrentFirst;
01082 else fCurrentN = n;
01083 TIter next(fVarList);
01084 TParallelCoordVar* var;
01085 while ((var = (TParallelCoordVar*)next())) {
01086 var->GetMinMaxMean();
01087 var->GetHistogram();
01088 if (var->TestBit(TParallelCoordVar::kShowBox)) var->GetQuantiles();
01089 }
01090 }
01091
01092
01093
01094 TParallelCoordSelect* TParallelCoord::SetCurrentSelection(const char* title)
01095 {
01096
01097
01098 if (fCurrentSelection && fCurrentSelection->GetTitle() == title) return fCurrentSelection;
01099 TIter next(fSelectList);
01100 TParallelCoordSelect* sel;
01101 while((sel = (TParallelCoordSelect*)next()) && strcmp(sel->GetTitle(),title))
01102 if (sel) fCurrentSelection = sel;
01103 return sel;
01104 }
01105
01106
01107
01108 void TParallelCoord::SetCurrentSelection(TParallelCoordSelect* sel)
01109 {
01110
01111
01112 if (fCurrentSelection == sel) return;
01113 fCurrentSelection = sel;
01114 }
01115
01116
01117
01118 void TParallelCoord::SetDotsSpacing(Int_t s)
01119 {
01120
01121
01122 if (s == fDotsSpacing) return;
01123 fDotsSpacing = s;
01124 gStyle->SetLineStyleString(11,Form("%d %d",4,s*8));
01125 }
01126
01127
01128
01129 void TParallelCoord::SetEntryList(TParallelCoord* para, TEntryList* enlist)
01130 {
01131
01132
01133 para->SetCurrentEntries(enlist);
01134 para->SetInitEntries(enlist);
01135 }
01136
01137
01138
01139 void TParallelCoord::SetGlobalMax(Double_t max)
01140 {
01141
01142
01143 TIter next(fVarList);
01144 TParallelCoordVar* var;
01145 while ((var = (TParallelCoordVar*)next())) {
01146 var->SetCurrentMax(max);
01147 }
01148 }
01149
01150
01151
01152 void TParallelCoord::SetGlobalMin(Double_t min)
01153 {
01154
01155
01156 TIter next(fVarList);
01157 TParallelCoordVar* var;
01158 while ((var = (TParallelCoordVar*)next())) {
01159 var->SetCurrentMin(min);
01160 }
01161 }
01162
01163
01164
01165 void TParallelCoord::SetLiveRangesUpdate(Bool_t on)
01166 {
01167
01168
01169 SetBit(kLiveUpdate,on);
01170 TIter next(fVarList);
01171 TParallelCoordVar* var;
01172 while((var = (TParallelCoordVar*)next())) var->SetLiveRangesUpdate(on);
01173 }
01174
01175
01176
01177 void TParallelCoord::SetVertDisplay(Bool_t vert)
01178 {
01179
01180
01181 if (vert == TestBit (kVertDisplay)) return;
01182 SetBit(kVertDisplay,vert);
01183 if (!gPad) return;
01184 UInt_t ui = 0;
01185 TFrame* frame = gPad->GetFrame();
01186 Double_t horaxisspace = (frame->GetX2() - frame->GetX1())/(fNvar-1);
01187 Double_t veraxisspace = (frame->GetY2() - frame->GetY1())/(fNvar-1);
01188 TIter next(fVarList);
01189 TParallelCoordVar* var;
01190 while ((var = (TParallelCoordVar*)next())) {
01191 if (vert) var->SetX(frame->GetX1() + ui*horaxisspace,TestBit(kGlobalScale));
01192 else var->SetY(frame->GetY1() + ui*veraxisspace,TestBit(kGlobalScale));
01193 ++ui;
01194 }
01195 if (TestBit(kCandleChart)) {
01196 if (fCandleAxis) delete fCandleAxis;
01197 if (TestBit(kVertDisplay)) fCandleAxis = new TGaxis(0.05,0.1,0.05,0.9,GetGlobalMin(),GetGlobalMax());
01198 else fCandleAxis = new TGaxis(0.1,0.05,0.9,0.05,GetGlobalMin(),GetGlobalMax());
01199 fCandleAxis->Draw();
01200 }
01201 gPad->Modified();
01202 gPad->Update();
01203 }
01204
01205
01206
01207 void TParallelCoord::UnzoomAll()
01208 {
01209
01210
01211 TIter next(fVarList);
01212 TParallelCoordVar* var;
01213 while((var = (TParallelCoordVar*)next())) var->Unzoom();
01214 }