ROOT logo

From $ROOTSYS/tutorials/tree/drawsparse.C

//*********************************************************************
// Convert a THnSparse to a TTree using efficient iteration through the THnSparse
//   and draw a THnSparse using TParallelCoord. 
//  The plot will contain one line for each filled bin,
//  with the bin's coordinates on each axis, and the bin's content on
//  the rightmost axis.
// 
//  Run as
//    .L $ROOTSYS/tutorials/tree/drawsparse.C+
// 
//  Axel.Naumann@cern.ch (2007-09-14)
// ********************************************************************

#include "TParallelCoord.h"
#include "TParallelCoordVar.h"
#include "TROOT.h"
#include "TTree.h"
#include "TLeaf.h"
#include "THnSparse.h"
#include "TAxis.h"
#include "TCanvas.h"
#include "TRandom.h"
#include "TFile.h"
#include "TH3.h"

//______________________________________________________________________________
TTree* toTree(THnSparse* h)
{
   // Creates a TTree and fills it with the coordinates of all
   // filled bins. The tree will have one branch for each dimension,
   // and one for the bin content.

   Int_t dim = h->GetNdimensions();
   TString name(h->GetName()); name += "_tree";
   TString title(h->GetTitle()); title += " tree";

   TTree* tree = new TTree(name, title);
   Double_t* x = new Double_t[dim + 1];
   memset(x, 0, sizeof(Double_t) * (dim + 1));

   TString branchname;
   for (Int_t d = 0; d < dim; ++d) {
      if (branchname.Length())
         branchname += ":";
      TAxis* axis = h->GetAxis(d);
      branchname += axis->GetName();
      branchname += "/D";
   }
   tree->Branch("coord", x, branchname);
   tree->Branch("bincontent", &x[dim], "bincontent/D");

   Int_t *bins = new Int_t[dim];
   for (Long64_t i = 0; i < h->GetNbins(); ++i) {
      x[dim] = h->GetBinContent(i, bins);
      for (Int_t d = 0; d < dim; ++d) {
         x[d] = h->GetAxis(d)->GetBinCenter(bins[d]);
      }

      tree->Fill();
   }

   delete [] bins;
   //delete [] x;
   return tree;
}


//______________________________________________________________________________
void drawsparse_draw(THnSparse* h)
{
   // Draw a THnSparse using TParallelCoord, creating a temporary TTree.

   TTree* tree = toTree(h);

   TString whatToDraw;
   TIter iLeaf(tree->GetListOfLeaves());
   const TLeaf* leaf = 0;
   while ((leaf = (const TLeaf*)iLeaf())) {
      if (whatToDraw.Length())
         whatToDraw += ":";
      whatToDraw += leaf->GetName();
   }
   tree->Draw(whatToDraw, "", "para");
   TParallelCoord* parallelCoord = (TParallelCoord*)gPad->GetListOfPrimitives()->FindObject("ParaCoord");

   TIter iVar(parallelCoord->GetVarList());
   TParallelCoordVar* var = 0;
   for (Int_t d = 0;(var = (TParallelCoordVar*) iVar()) && d < h->GetNdimensions(); ++d) {
      TAxis* axis = h->GetAxis(d);
      var->SetHistogramBinning(axis->GetNbins());
      var->SetCurrentLimits(axis->GetXmin(), axis->GetXmax());
      var->SetTitle(axis->GetTitle());
   }
   var->SetTitle("bin content");
}

//______________________________________________________________________________
void drawsparse()
{
   // create a THnSparse and draw it.

#ifdef __CINT__
   printf("For performance reasons we advise to run \".x drawsparse.C+\"\n");
#endif

   const Int_t ndims = 8;
   Int_t bins[ndims] = {10, 10, 5, 30, 10, 4, 18, 12};
   Double_t xmin[ndims] = {-5., -10., -1000., -3., 0.,   0., 0., 0.};
   Double_t xmax[ndims] = {10., 70., 3000.,   3.,   5.,  2., 2., 5.};
   THnSparse* hs = new THnSparseD("hs", "Sparse Histogram", ndims, bins, xmin, xmax);
   
   // fill it
   Double_t x[ndims];
   for (Long_t i = 0; i < 100000; ++i) {
      for (Int_t d = 0; d < ndims; ++d) {
         switch (d) {
         case 0: x[d] = gRandom->Gaus()*2 + 3.; break;
         case 1:
         case 2: 
         case 3: x[d] = (x[d-1]*x[d-1] - 1.5)/1.5 + (0.5*gRandom->Rndm()); break;
         default: x[d] = sin(gRandom->Gaus()*i/1000.) + 1.;
         }
      }
      hs->Fill(x);
   }


   TFile* f = new TFile("drawsparse.root","RECREATE");

   TCanvas* canv = new TCanvas("hDrawSparse", "Drawing a sparse hist");
   canv->Divide(2);

   // draw it
   canv->cd(1);
   drawsparse_draw(hs);

   // project it
   canv->cd(2);
   TH3D* h3proj = hs->Projection(2, 3, 6);
   h3proj->SetLineColor(kOrange);
   h3proj->SetDirectory(0);
   h3proj->Draw("lego1");

   // save everything to a file
   canv->Write();
   hs->Write();
   h3proj->Write();

   delete f;
}
 drawsparse.C:1
 drawsparse.C:2
 drawsparse.C:3
 drawsparse.C:4
 drawsparse.C:5
 drawsparse.C:6
 drawsparse.C:7
 drawsparse.C:8
 drawsparse.C:9
 drawsparse.C:10
 drawsparse.C:11
 drawsparse.C:12
 drawsparse.C:13
 drawsparse.C:14
 drawsparse.C:15
 drawsparse.C:16
 drawsparse.C:17
 drawsparse.C:18
 drawsparse.C:19
 drawsparse.C:20
 drawsparse.C:21
 drawsparse.C:22
 drawsparse.C:23
 drawsparse.C:24
 drawsparse.C:25
 drawsparse.C:26
 drawsparse.C:27
 drawsparse.C:28
 drawsparse.C:29
 drawsparse.C:30
 drawsparse.C:31
 drawsparse.C:32
 drawsparse.C:33
 drawsparse.C:34
 drawsparse.C:35
 drawsparse.C:36
 drawsparse.C:37
 drawsparse.C:38
 drawsparse.C:39
 drawsparse.C:40
 drawsparse.C:41
 drawsparse.C:42
 drawsparse.C:43
 drawsparse.C:44
 drawsparse.C:45
 drawsparse.C:46
 drawsparse.C:47
 drawsparse.C:48
 drawsparse.C:49
 drawsparse.C:50
 drawsparse.C:51
 drawsparse.C:52
 drawsparse.C:53
 drawsparse.C:54
 drawsparse.C:55
 drawsparse.C:56
 drawsparse.C:57
 drawsparse.C:58
 drawsparse.C:59
 drawsparse.C:60
 drawsparse.C:61
 drawsparse.C:62
 drawsparse.C:63
 drawsparse.C:64
 drawsparse.C:65
 drawsparse.C:66
 drawsparse.C:67
 drawsparse.C:68
 drawsparse.C:69
 drawsparse.C:70
 drawsparse.C:71
 drawsparse.C:72
 drawsparse.C:73
 drawsparse.C:74
 drawsparse.C:75
 drawsparse.C:76
 drawsparse.C:77
 drawsparse.C:78
 drawsparse.C:79
 drawsparse.C:80
 drawsparse.C:81
 drawsparse.C:82
 drawsparse.C:83
 drawsparse.C:84
 drawsparse.C:85
 drawsparse.C:86
 drawsparse.C:87
 drawsparse.C:88
 drawsparse.C:89
 drawsparse.C:90
 drawsparse.C:91
 drawsparse.C:92
 drawsparse.C:93
 drawsparse.C:94
 drawsparse.C:95
 drawsparse.C:96
 drawsparse.C:97
 drawsparse.C:98
 drawsparse.C:99
 drawsparse.C:100
 drawsparse.C:101
 drawsparse.C:102
 drawsparse.C:103
 drawsparse.C:104
 drawsparse.C:105
 drawsparse.C:106
 drawsparse.C:107
 drawsparse.C:108
 drawsparse.C:109
 drawsparse.C:110
 drawsparse.C:111
 drawsparse.C:112
 drawsparse.C:113
 drawsparse.C:114
 drawsparse.C:115
 drawsparse.C:116
 drawsparse.C:117
 drawsparse.C:118
 drawsparse.C:119
 drawsparse.C:120
 drawsparse.C:121
 drawsparse.C:122
 drawsparse.C:123
 drawsparse.C:124
 drawsparse.C:125
 drawsparse.C:126
 drawsparse.C:127
 drawsparse.C:128
 drawsparse.C:129
 drawsparse.C:130
 drawsparse.C:131
 drawsparse.C:132
 drawsparse.C:133
 drawsparse.C:134
 drawsparse.C:135
 drawsparse.C:136
 drawsparse.C:137
 drawsparse.C:138
 drawsparse.C:139
 drawsparse.C:140
 drawsparse.C:141
 drawsparse.C:142
 drawsparse.C:143
 drawsparse.C:144
 drawsparse.C:145
 drawsparse.C:146
 drawsparse.C:147
 drawsparse.C:148
 drawsparse.C:149
 drawsparse.C:150
 drawsparse.C:151