/*
<img src="gif/filedrawmap.gif">
*/
//End_Html
#include "TFileDrawMap.h"
#include "TROOT.h"
#include "TClass.h"
#include "TFile.h"
#include "TTree.h"
#include "TBranch.h"
#include "TLeaf.h"
#include "TMath.h"
#include "TVirtualPad.h"
#include "TStyle.h"
#include "TH1.h"
#include "TBox.h"
#include "TKey.h"
#include "TRegexp.h"
#include "TSystem.h"
ClassImp(TFileDrawMap)
TFileDrawMap::TFileDrawMap() :TNamed()
{
   fFile   = 0;
   fFrame  = 0;
}
TFileDrawMap::TFileDrawMap(const TFile *file, const char *keys, Option_t *option)
         : TNamed("TFileDrawMap","")
{
   fFile     = (TFile*)file;
   fKeys     = keys;
   fOption   = option;
   fOption.ToLower();
   SetBit(kCanDelete);
   
   if (file->GetEND() > 1000000) {
      fXsize = 1000000;
   } else {
      fXsize = 1000;
   }
   fFrame = new TH1D("hmapframe","",1000,0,fXsize);
   fFrame->SetDirectory(0);
   fFrame->SetBit(TH1::kNoStats);
   fFrame->SetBit(kCanDelete);
   fFrame->SetMinimum(0);
   if (fXsize > 1000) {
      fFrame->GetYaxis()->SetTitle("MBytes");
   } else {
      fFrame->GetYaxis()->SetTitle("KBytes");
   }
   fFrame->GetXaxis()->SetTitle("Bytes");
   fYsize = 1 + Int_t(file->GetEND()/fXsize);
   fFrame->SetMaximum(fYsize);
   fFrame->GetYaxis()->SetLimits(0,fYsize);
   
   if (gPad) {
      gPad->Clear();
      
   }
   Draw();
   if (gPad) {
      
      gPad->Update();
   }
}
TFileDrawMap::~TFileDrawMap()
{
   
}
void  TFileDrawMap::AnimateTree(const char *branches)
{
   char info[512];
   strcpy(info,GetName());
   char *cbasket = strstr(info,", basket=");
   if (!cbasket) return;
   *cbasket = 0;
   char *cbranch = strstr(info,", branch=");
   if (!cbranch) return;
   *cbranch = 0;
   cbranch += 9;
   TTree *tree = (TTree*)fFile->Get(info);
   if (!tree) return;
   if (strlen(branches) > 0) strcpy(info,branches);
   else                      strcpy(info,cbranch);
   printf("Animating tree, branches=%s\n",info);
   
   Int_t nzip = 0;
   TBranch *branch;
   TObjArray list;
   char *comma;
   while((comma = strrchr(info,','))) {
      *comma = 0;
      comma++;
      while (*comma == ' ') comma++;
      branch = tree->GetBranch(comma);
      if (branch) {
         nzip += (Int_t)branch->GetZipBytes();
         branch->SetUniqueID(0);
         list.Add(branch);
      }
   }
   comma = info;
   while (*comma == ' ') comma++;
   branch = tree->GetBranch(comma);
   if (branch) {
      nzip += (Int_t)branch->GetZipBytes();
      branch->SetUniqueID(0);
      list.Add(branch);
   }
   Double_t fractionRead = Double_t(nzip)/Double_t(fFile->GetEND());
   Int_t nbranches = list.GetEntries();
   
   Int_t nentries = (Int_t)tree->GetEntries();
   Int_t sleep = 1;
   Int_t stime = (Int_t)(100./(nentries*fractionRead));
   if (stime < 10) {stime=1; sleep = nentries/400;}
   gPad->SetDoubleBuffer(0);             
   gVirtualX->SetDrawMode(TVirtualX::kInvert);  
   for (Int_t entry=0;entry<nentries;entry++) {
      for (Int_t ib=0;ib<nbranches;ib++) {
         branch = (TBranch*)list.At(ib);
         Int_t nbaskets = branch->GetListOfBaskets()->GetSize();
         Int_t basket = TMath::BinarySearch(nbaskets,branch->GetBasketEntry(),entry);
         Int_t nbytes = branch->GetBasketBytes()[basket];
         Int_t bseek  = branch->GetBasketSeek(basket);
         Int_t entry0 = branch->GetBasketEntry()[basket];
         Int_t entryn = branch->GetBasketEntry()[basket+1];
         Int_t eseek  = (Int_t)(bseek + nbytes*Double_t(entry-entry0)/Double_t(entryn-entry0));
         DrawMarker(ib,branch->GetUniqueID());
         DrawMarker(ib,eseek);
         branch->SetUniqueID(eseek);
         gSystem->ProcessEvents();
         if (entry%sleep == 0) gSystem->Sleep(stime);
      }
   }
}
Int_t TFileDrawMap::DistancetoPrimitive(Int_t px, Int_t py)
{
   Int_t pxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
   Int_t pxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
   Int_t pymin = gPad->YtoAbsPixel(gPad->GetUymin());
   Int_t pymax = gPad->YtoAbsPixel(gPad->GetUymax());
   if (px > pxmin && px < pxmax && py > pymax && py < pymin) {
      SetName(GetObjectInfo(px,py));
      return 0;
   }
   return fFrame->DistancetoPrimitive(px,py);
}
void TFileDrawMap::DrawMarker(Int_t marker, Long64_t eseek)
{
   Int_t iy = gPad->YtoAbsPixel(eseek/fXsize);
   Int_t ix = gPad->XtoAbsPixel(eseek%fXsize);
   Int_t d;
   Int_t mark = marker%4;
   switch (mark) {
      case 0 : 
         d = 6; 
         gVirtualX->DrawLine(ix-3*d,iy,ix,iy);
         gVirtualX->DrawLine(ix-d,iy+d,ix,iy);
         gVirtualX->DrawLine(ix-d,iy-d,ix,iy);
         gVirtualX->DrawLine(ix-d,iy-d,ix-d,iy+d);
         break;
      case 1 : 
         d = 5; 
         gVirtualX->DrawLine(ix-d,iy-d,ix+d,iy-d);
         gVirtualX->DrawLine(ix+d,iy-d,ix,iy+d);
         gVirtualX->DrawLine(ix,iy+d,ix-d,iy-d);
         break;
      case 2 : 
         d = 5; 
         gVirtualX->DrawLine(ix-d,iy-d,ix+d,iy-d);
         gVirtualX->DrawLine(ix+d,iy-d,ix+d,iy+d);
         gVirtualX->DrawLine(ix+d,iy+d,ix-d,iy+d);
         gVirtualX->DrawLine(ix-d,iy+d,ix-d,iy-d);
         break;
      case 3 : 
         d = 8; 
         gVirtualX->DrawLine(ix-d,iy,ix+d,iy);
         gVirtualX->DrawLine(ix,iy-d,ix,iy+d);
         break;
   }
}
void TFileDrawMap::DrawObject()
{
   TVirtualPad *padsave = gROOT->GetSelectedPad();
   if (padsave == gPad) {
      
      gROOT->MakeDefCanvas();
   } else {
      padsave->cd();
   }
   
   char info[512];
   strcpy(info,GetName());
   char *cbasket = (char*)strstr(info,", basket=");
   if (cbasket) {
      *cbasket = 0;
      char *cbranch = (char*)strstr(info,", branch=");
      if (!cbranch) return;
      *cbranch = 0;
      cbranch += 9;
      TTree *tree = (TTree*)fFile->Get(info);
      if (tree) tree->Draw(cbranch);
      return;
   }
   
   TObject *obj = GetObject();
   if (obj) obj->Draw();
}
void TFileDrawMap::DumpObject()
{
   TObject *obj = GetObject();
   if (obj) {
      obj->Dump();
      return;
   }
   char *centry = (char*)strstr(GetName(),"entry=");
   if (!centry) return;
   Int_t entry = 0;
   sscanf(centry+6,"%d",&entry);
   char info[512];
   strcpy(info,GetName());
   char *colon = (char*)strstr(info,"::");
   if (!colon) return;
   colon--;
   *colon = 0;
   TTree *tree = (TTree*)fFile->Get(info);
   if (tree) tree->Show(entry);
}
void TFileDrawMap::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   fFrame->ExecuteEvent(event,px,py);
}
TObject *TFileDrawMap::GetObject()
{
   if (strstr(GetName(),"entry=")) return 0;
   char info[512];
   strcpy(info,GetName());
   char *colon = strstr(info,"::");
   if (!colon) return 0;
   colon--;
   *colon = 0;
   return fFile->Get(info);
}
char *TFileDrawMap::GetObjectInfo(Int_t px, Int_t py) const
{
   static char info[512];
   GetObjectInfoDir(fFile, px, py, info);
   return info;
}
Bool_t TFileDrawMap::GetObjectInfoDir(TDirectory *dir, Int_t px, Int_t py, char *info) const
{
   Double_t x = gPad->AbsPixeltoX(px);
   Double_t y = gPad->AbsPixeltoY(py);
   Int_t iy   = (Int_t)y;
   Long64_t pbyte = (Long64_t)(fXsize*iy+x);
   Int_t nbytes;
   Long64_t bseek;
   TDirectory *dirsav = gDirectory;
   dir->cd();
   TIter next(dir->GetListOfKeys());
   TKey *key;
   while ((key = (TKey*)next())) {
      TDirectory *curdir = gDirectory;
      TClass *cl = TClass::GetClass(key->GetClassName());
      
      if (cl && cl == TDirectoryFile::Class()) {
         curdir->cd(key->GetName());
         TDirectory *subdir = gDirectory;
         Bool_t gotInfo = GetObjectInfoDir(subdir, px, py, info);
         if (gotInfo) {
            dirsav->cd();
            return kTRUE;
         }
         curdir->cd();
         continue;
      }
      
      if (cl && cl->InheritsFrom(TTree::Class())) {
         TTree *tree = (TTree*)gDirectory->Get(key->GetName());
         TIter nextb(tree->GetListOfLeaves());
         TLeaf *leaf;
         while ((leaf = (TLeaf*)nextb())) {
            TBranch *branch = leaf->GetBranch();
            Int_t nbaskets = branch->GetMaxBaskets();
            Int_t offsets = branch->GetEntryOffsetLen();
            Int_t len = leaf->GetLen();
            for (Int_t i=0;i<nbaskets;i++) {
               bseek = branch->GetBasketSeek(i);
               if (!bseek) break;
               nbytes = branch->GetBasketBytes()[i];
               if (pbyte >= bseek && pbyte < bseek+nbytes) {
                  Int_t entry = branch->GetBasketEntry()[i];
                  if (!offsets) entry += (pbyte-bseek)/len;
                  if (curdir == (TDirectory*)fFile) {
                     sprintf(info,"%s%s, branch=%s, basket=%d, entry=%d",curdir->GetPath(),key->GetName(),branch->GetName(),i,entry);
                  } else {
                     sprintf(info,"%s/%s, branch=%s, basket=%d, entry=%d",curdir->GetPath(),key->GetName(),branch->GetName(),i,entry);
                  }
                  return kTRUE;
               }
            }
         }
      }
      nbytes = key->GetNbytes();
      bseek = key->GetSeekKey();
      if (pbyte >= bseek && pbyte < bseek+nbytes) {
         if (curdir == (TDirectory*)fFile) {
            sprintf(info,"%s%s ::%s, nbytes=%d",curdir->GetPath(),key->GetName(),key->GetClassName(),nbytes);
         } else {
            sprintf(info,"%s/%s ::%s, nbytes=%d",curdir->GetPath(),key->GetName(),key->GetClassName(),nbytes);
         }
         dirsav->cd();
         return kTRUE;
      }
   }
   
   if (pbyte >= dir->GetSeekKeys() && pbyte < dir->GetSeekKeys()+dir->GetNbytesKeys()) {
      sprintf(info,"%sKeys List, nbytes=%d",dir->GetPath(),dir->GetNbytesKeys());
      dirsav->cd();
      return kTRUE;
   }
   if (dir == (TDirectory*)fFile) {
      
      if (pbyte >= fFile->GetSeekInfo() && pbyte < fFile->GetSeekInfo()+fFile->GetNbytesInfo()) {
         sprintf(info,"%sStreamerInfo List, nbytes=%d",dir->GetPath(),fFile->GetNbytesInfo());
         dirsav->cd();
         return kTRUE;
      }
      
      if (pbyte >= fFile->GetSeekFree() && pbyte < fFile->GetSeekFree()+fFile->GetNbytesFree()) {
         sprintf(info,"%sFree List, nbytes=%d",dir->GetPath(),fFile->GetNbytesFree());
         dirsav->cd();
         return kTRUE;
      }
   }
   sprintf(info,"(byte=%lld)",pbyte);
   dirsav->cd();
   return kFALSE;
}
void TFileDrawMap::InspectObject()
{
   TObject *obj = GetObject();
   if (obj) obj->Inspect();
}
void TFileDrawMap::Paint(Option_t *)
{
   
   if (!fOption.Contains("same")) {
      gPad->Clear();
      
      if (fFrame->GetMaximumStored() < -1000) {
         fFrame->SetMaximum(fYsize+1);
         fFrame->SetMinimum(0);
         fFrame->GetYaxis()->SetLimits(0,fYsize+1);
      }
      fFrame->Paint("a");
   }
   
   PaintDir(fFile, fKeys.Data());
   fFrame->Draw("sameaxis");
}
void TFileDrawMap::PaintBox(TBox &box, Long64_t bseek, Int_t nbytes)
{
   Int_t iy = bseek/fXsize;
   Int_t ix = bseek%fXsize;
   Int_t ny = 1+(nbytes+ix)/fXsize;
   Double_t xmin,ymin,xmax,ymax;
   for (Int_t j=0;j<ny;j++) {
      if (j == 0) xmin = (Double_t)ix;
      else        xmin = 0;
      xmax = xmin + nbytes;
      if (xmax > fXsize) xmax = fXsize;
      ymin = iy+j;
      ymax = ymin+1;
      nbytes -= (Int_t)(xmax-xmin);
      if (xmax < gPad->GetUxmin()) continue;
      if (xmin > gPad->GetUxmax()) continue;
      if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
      if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
      if (ymax < gPad->GetUymin()) continue;
      if (ymin > gPad->GetUymax()) continue;
      if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
      if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
      
      box.PaintBox(xmin,ymin,xmax,ymax);
   }
}
void TFileDrawMap::PaintDir(TDirectory *dir, const char *keys)
{
   TDirectory *dirsav = gDirectory;
   TIter next(dir->GetListOfKeys());
   TKey *key;
   Int_t color = 0;
   TBox box;
   TRegexp re(keys,kTRUE);
   while ((key = (TKey*)next())) {
      Int_t nbytes = key->GetNbytes();
      Long64_t bseek = key->GetSeekKey();
      TClass *cl = TClass::GetClass(key->GetClassName());
      if (cl) {
         color = (Int_t)(cl->GetUniqueID()%20);
      } else {
         color = 1;
      }
      box.SetFillColor(color);
      box.SetFillStyle(1001);
      TString s = key->GetName();
      if (strcmp(fKeys.Data(),key->GetName()) && s.Index(re) == kNPOS) continue;
      
      if (cl && cl == TDirectoryFile::Class()) {
         TDirectory *curdir = gDirectory;
         gDirectory->cd(key->GetName());
         TDirectory *subdir = gDirectory;
         PaintDir(subdir,"*");
         curdir->cd();
      }
      PaintBox(box,bseek,nbytes);
      
      if (cl && cl->InheritsFrom(TTree::Class())) {
         TTree *tree = (TTree*)gDirectory->Get(key->GetName());
         TIter nextb(tree->GetListOfLeaves());
         TLeaf *leaf;
         while ((leaf = (TLeaf*)nextb())) {
            TBranch *branch = leaf->GetBranch();
            color = branch->GetFillColor();
            if (color == 0) color = 1;
            box.SetFillColor(color);
            Int_t nbaskets = branch->GetMaxBaskets();
            for (Int_t i=0;i<nbaskets;i++) {
               Long64_t bseek = branch->GetBasketSeek(i);
               if (!bseek) break;
               Int_t nbytes = branch->GetBasketBytes()[i];
               PaintBox(box,bseek,nbytes);
            }
         }
      }
   }
   
   box.SetFillColor(50);
   box.SetFillStyle(1001);
   PaintBox(box,dir->GetSeekKeys(),dir->GetNbytesKeys());
   if (dir == (TDirectory*)fFile) {
      
      box.SetFillColor(6);
      box.SetFillStyle(3008);
      PaintBox(box,fFile->GetSeekInfo(),fFile->GetNbytesInfo());
      
      box.SetFillColor(1);
      box.SetFillStyle(1001);
      PaintBox(box,fFile->GetSeekFree(),fFile->GetNbytesFree());
   }
   dirsav->cd();
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.