00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
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 #include "TFileDrawMap.h"
00069 #include "TROOT.h"
00070 #include "TClass.h"
00071 #include "TFile.h"
00072 #include "TTree.h"
00073 #include "TBranch.h"
00074 #include "TLeaf.h"
00075 #include "TMath.h"
00076 #include "TVirtualPad.h"
00077 #include "TStyle.h"
00078 #include "TH1.h"
00079 #include "TBox.h"
00080 #include "TKey.h"
00081 #include "TRegexp.h"
00082 #include "TSystem.h"
00083
00084 ClassImp(TFileDrawMap)
00085
00086
00087 TFileDrawMap::TFileDrawMap() :TNamed()
00088 {
00089
00090
00091 fFile = 0;
00092 fFrame = 0;
00093 fXsize = 1000;
00094 fYsize = 1000;
00095 }
00096
00097
00098 TFileDrawMap::TFileDrawMap(const TFile *file, const char *keys, Option_t *option)
00099 : TNamed("TFileDrawMap","")
00100 {
00101
00102
00103
00104 fFile = (TFile*)file;
00105 fKeys = keys;
00106 fOption = option;
00107 fOption.ToLower();
00108 SetBit(kCanDelete);
00109
00110
00111
00112 if (file->GetEND() > 1000000) {
00113 fXsize = 1000000;
00114 } else {
00115 fXsize = 1000;
00116 }
00117 fFrame = new TH1D("hmapframe","",1000,0,fXsize);
00118 fFrame->SetDirectory(0);
00119 fFrame->SetBit(TH1::kNoStats);
00120 fFrame->SetBit(kCanDelete);
00121 fFrame->SetMinimum(0);
00122 if (fXsize > 1000) {
00123 fFrame->GetYaxis()->SetTitle("MBytes");
00124 } else {
00125 fFrame->GetYaxis()->SetTitle("KBytes");
00126 }
00127 fFrame->GetXaxis()->SetTitle("Bytes");
00128 fYsize = 1 + Int_t(file->GetEND()/fXsize);
00129 fFrame->SetMaximum(fYsize);
00130 fFrame->GetYaxis()->SetLimits(0,fYsize);
00131
00132
00133 if (gPad) {
00134 gPad->Clear();
00135
00136 }
00137 Draw();
00138 if (gPad) {
00139
00140 gPad->Update();
00141 }
00142 }
00143
00144
00145 TFileDrawMap::~TFileDrawMap()
00146 {
00147
00148
00149
00150
00151 }
00152
00153
00154 void TFileDrawMap::AnimateTree(const char *branches)
00155 {
00156
00157
00158
00159
00160
00161
00162
00163 TString ourbranches( GetName() );
00164 Ssiz_t pos = ourbranches.Index(", basket=");
00165 if (pos == kNPOS) return;
00166 ourbranches.Remove(pos);
00167 pos = ourbranches.Index(", branch=");
00168 if (pos == kNPOS) return;
00169 ourbranches[pos] = 0;
00170
00171 TTree *tree = (TTree*)fFile->Get(ourbranches.Data());
00172 if (!tree) return;
00173 TString info;
00174 if (strlen(branches) > 0) info = branches;
00175 else info = ourbranches.Data()+pos+9;
00176 printf("Animating tree, branches=%s\n",info.Data());
00177
00178
00179 Int_t nzip = 0;
00180 TBranch *branch;
00181 TObjArray list;
00182 char *comma;
00183 while((comma = strrchr((char*)info.Data(),','))) {
00184 *comma = 0;
00185 comma++;
00186 while (*comma == ' ') comma++;
00187 branch = tree->GetBranch(comma);
00188 if (branch) {
00189 nzip += (Int_t)branch->GetZipBytes();
00190 branch->SetUniqueID(0);
00191 list.Add(branch);
00192 }
00193 }
00194 comma = (char*)info.Data();
00195 while (*comma == ' ') comma++;
00196 branch = tree->GetBranch(comma);
00197 if (branch) {
00198 nzip += (Int_t)branch->GetZipBytes();
00199 branch->SetUniqueID(0);
00200 list.Add(branch);
00201 }
00202 Double_t fractionRead = Double_t(nzip)/Double_t(fFile->GetEND());
00203 Int_t nbranches = list.GetEntries();
00204
00205
00206 Int_t nentries = (Int_t)tree->GetEntries();
00207 Int_t sleep = 1;
00208 Int_t stime = (Int_t)(100./(nentries*fractionRead));
00209 if (stime < 10) {stime=1; sleep = nentries/400;}
00210 gPad->SetDoubleBuffer(0);
00211 gVirtualX->SetDrawMode(TVirtualX::kInvert);
00212 for (Int_t entry=0;entry<nentries;entry++) {
00213 for (Int_t ib=0;ib<nbranches;ib++) {
00214 branch = (TBranch*)list.At(ib);
00215 Int_t nbaskets = branch->GetListOfBaskets()->GetSize();
00216 Int_t basket = TMath::BinarySearch(nbaskets,branch->GetBasketEntry(), (Long64_t) entry);
00217 Int_t nbytes = branch->GetBasketBytes()[basket];
00218 Int_t bseek = branch->GetBasketSeek(basket);
00219 Int_t entry0 = branch->GetBasketEntry()[basket];
00220 Int_t entryn = branch->GetBasketEntry()[basket+1];
00221 Int_t eseek = (Int_t)(bseek + nbytes*Double_t(entry-entry0)/Double_t(entryn-entry0));
00222 DrawMarker(ib,branch->GetUniqueID());
00223 DrawMarker(ib,eseek);
00224 branch->SetUniqueID(eseek);
00225 gSystem->ProcessEvents();
00226 if (entry%sleep == 0) gSystem->Sleep(stime);
00227 }
00228 }
00229 }
00230
00231
00232 Int_t TFileDrawMap::DistancetoPrimitive(Int_t px, Int_t py)
00233 {
00234
00235
00236
00237 Int_t pxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00238 Int_t pxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00239 Int_t pymin = gPad->YtoAbsPixel(gPad->GetUymin());
00240 Int_t pymax = gPad->YtoAbsPixel(gPad->GetUymax());
00241 if (px > pxmin && px < pxmax && py > pymax && py < pymin) {
00242 SetName(GetObjectInfo(px,py));
00243 return 0;
00244 }
00245 return fFrame->DistancetoPrimitive(px,py);
00246 }
00247
00248
00249 void TFileDrawMap::DrawMarker(Int_t marker, Long64_t eseek)
00250 {
00251
00252
00253 Int_t iy = gPad->YtoAbsPixel(eseek/fXsize);
00254 Int_t ix = gPad->XtoAbsPixel(eseek%fXsize);
00255 Int_t d;
00256 Int_t mark = marker%4;
00257 switch (mark) {
00258 case 0 :
00259 d = 6;
00260 gVirtualX->DrawLine(ix-3*d,iy,ix,iy);
00261 gVirtualX->DrawLine(ix-d,iy+d,ix,iy);
00262 gVirtualX->DrawLine(ix-d,iy-d,ix,iy);
00263 gVirtualX->DrawLine(ix-d,iy-d,ix-d,iy+d);
00264 break;
00265 case 1 :
00266 d = 5;
00267 gVirtualX->DrawLine(ix-d,iy-d,ix+d,iy-d);
00268 gVirtualX->DrawLine(ix+d,iy-d,ix,iy+d);
00269 gVirtualX->DrawLine(ix,iy+d,ix-d,iy-d);
00270 break;
00271 case 2 :
00272 d = 5;
00273 gVirtualX->DrawLine(ix-d,iy-d,ix+d,iy-d);
00274 gVirtualX->DrawLine(ix+d,iy-d,ix+d,iy+d);
00275 gVirtualX->DrawLine(ix+d,iy+d,ix-d,iy+d);
00276 gVirtualX->DrawLine(ix-d,iy+d,ix-d,iy-d);
00277 break;
00278 case 3 :
00279 d = 8;
00280 gVirtualX->DrawLine(ix-d,iy,ix+d,iy);
00281 gVirtualX->DrawLine(ix,iy-d,ix,iy+d);
00282 break;
00283 }
00284 }
00285
00286
00287 void TFileDrawMap::DrawObject()
00288 {
00289
00290
00291 TVirtualPad *padsave = gROOT->GetSelectedPad();
00292 if (padsave == gPad) {
00293
00294 gROOT->MakeDefCanvas();
00295 } else {
00296 padsave->cd();
00297 }
00298
00299
00300 char *info = new char[fName.Length()+1];
00301 strlcpy(info,fName.Data(),fName.Length()+1);
00302 char *cbasket = (char*)strstr(info,", basket=");
00303 if (cbasket) {
00304 *cbasket = 0;
00305 char *cbranch = (char*)strstr(info,", branch=");
00306 if (!cbranch) return;
00307 *cbranch = 0;
00308 cbranch += 9;
00309 TTree *tree = (TTree*)fFile->Get(info);
00310 if (tree) tree->Draw(cbranch);
00311 return;
00312 }
00313
00314
00315 TObject *obj = GetObject();
00316 if (obj) obj->Draw();
00317 }
00318
00319
00320
00321 void TFileDrawMap::DumpObject()
00322 {
00323
00324
00325 TObject *obj = GetObject();
00326 if (obj) {
00327 obj->Dump();
00328 return;
00329 }
00330 char *centry = (char*)strstr(GetName(),"entry=");
00331 if (!centry) return;
00332 Int_t entry = 0;
00333 sscanf(centry+6,"%d",&entry);
00334 TString info(GetName());
00335 char *colon = (char*)strstr((char*)info.Data(),"::");
00336 if (!colon) return;
00337 colon--;
00338 *colon = 0;
00339 TTree *tree; fFile->GetObject(info.Data(),tree);
00340 if (tree) tree->Show(entry);
00341 }
00342
00343
00344 void TFileDrawMap::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00345 {
00346
00347
00348 fFrame->ExecuteEvent(event,px,py);
00349 }
00350
00351
00352 TObject *TFileDrawMap::GetObject()
00353 {
00354
00355
00356 if (strstr(GetName(),"entry=")) return 0;
00357 char *info = new char[fName.Length()+1];
00358 strlcpy(info,fName.Data(),fName.Length()+1);
00359 char *colon = strstr(info,"::");
00360 if (!colon) return 0;
00361 colon--;
00362 *colon = 0;
00363 return fFile->Get(info);
00364 }
00365
00366
00367 char *TFileDrawMap::GetObjectInfo(Int_t px, Int_t py) const
00368 {
00369
00370
00371
00372
00373 static TString info;
00374 GetObjectInfoDir(fFile, px, py, info);
00375 return (char*)info.Data();
00376 }
00377
00378
00379 Bool_t TFileDrawMap::GetObjectInfoDir(TDirectory *dir, Int_t px, Int_t py, TString &info) const
00380 {
00381
00382
00383
00384
00385 Double_t x = gPad->AbsPixeltoX(px);
00386 Double_t y = gPad->AbsPixeltoY(py);
00387 Int_t iy = (Int_t)y;
00388 Long64_t pbyte = (Long64_t)(fXsize*iy+x);
00389 Int_t nbytes;
00390 Long64_t bseek;
00391 TDirectory *dirsav = gDirectory;
00392 dir->cd();
00393
00394 TIter next(dir->GetListOfKeys());
00395 TKey *key;
00396 while ((key = (TKey*)next())) {
00397 TDirectory *curdir = gDirectory;
00398 TClass *cl = TClass::GetClass(key->GetClassName());
00399
00400 if (cl && cl == TDirectoryFile::Class()) {
00401 curdir->cd(key->GetName());
00402 TDirectory *subdir = gDirectory;
00403 Bool_t gotInfo = GetObjectInfoDir(subdir, px, py, info);
00404 if (gotInfo) {
00405 dirsav->cd();
00406 return kTRUE;
00407 }
00408 curdir->cd();
00409 continue;
00410 }
00411
00412 if (cl && cl->InheritsFrom(TTree::Class())) {
00413 TTree *tree = (TTree*)gDirectory->Get(key->GetName());
00414 TIter nextb(tree->GetListOfLeaves());
00415 TLeaf *leaf;
00416 while ((leaf = (TLeaf*)nextb())) {
00417 TBranch *branch = leaf->GetBranch();
00418 Int_t nbaskets = branch->GetMaxBaskets();
00419 Int_t offsets = branch->GetEntryOffsetLen();
00420 Int_t len = leaf->GetLen();
00421 for (Int_t i=0;i<nbaskets;i++) {
00422 bseek = branch->GetBasketSeek(i);
00423 if (!bseek) break;
00424 nbytes = branch->GetBasketBytes()[i];
00425 if (pbyte >= bseek && pbyte < bseek+nbytes) {
00426 Int_t entry = branch->GetBasketEntry()[i];
00427 if (!offsets) entry += (pbyte-bseek)/len;
00428 if (curdir == (TDirectory*)fFile) {
00429 info.Form("%s%s, branch=%s, basket=%d, entry=%d",curdir->GetPath(),key->GetName(),branch->GetName(),i,entry);
00430 } else {
00431 info.Form("%s/%s, branch=%s, basket=%d, entry=%d",curdir->GetPath(),key->GetName(),branch->GetName(),i,entry);
00432 }
00433 return kTRUE;
00434 }
00435 }
00436 }
00437 }
00438 nbytes = key->GetNbytes();
00439 bseek = key->GetSeekKey();
00440 if (pbyte >= bseek && pbyte < bseek+nbytes) {
00441 if (curdir == (TDirectory*)fFile) {
00442 info.Form("%s%s ::%s, nbytes=%d",curdir->GetPath(),key->GetName(),key->GetClassName(),nbytes);
00443 } else {
00444 info.Form("%s/%s ::%s, nbytes=%d",curdir->GetPath(),key->GetName(),key->GetClassName(),nbytes);
00445 }
00446 dirsav->cd();
00447 return kTRUE;
00448 }
00449 }
00450
00451 if (pbyte >= dir->GetSeekKeys() && pbyte < dir->GetSeekKeys()+dir->GetNbytesKeys()) {
00452 info.Form("%sKeys List, nbytes=%d",dir->GetPath(),dir->GetNbytesKeys());
00453 dirsav->cd();
00454 return kTRUE;
00455 }
00456 if (dir == (TDirectory*)fFile) {
00457
00458 if (pbyte >= fFile->GetSeekInfo() && pbyte < fFile->GetSeekInfo()+fFile->GetNbytesInfo()) {
00459 info.Form("%sStreamerInfo List, nbytes=%d",dir->GetPath(),fFile->GetNbytesInfo());
00460 dirsav->cd();
00461 return kTRUE;
00462 }
00463
00464 if (pbyte >= fFile->GetSeekFree() && pbyte < fFile->GetSeekFree()+fFile->GetNbytesFree()) {
00465 info.Form("%sFree List, nbytes=%d",dir->GetPath(),fFile->GetNbytesFree());
00466 dirsav->cd();
00467 return kTRUE;
00468 }
00469 }
00470 info.Form("(byte=%lld)",pbyte);
00471 dirsav->cd();
00472 return kFALSE;
00473 }
00474
00475
00476 void TFileDrawMap::InspectObject()
00477 {
00478
00479
00480 TObject *obj = GetObject();
00481 if (obj) obj->Inspect();
00482 }
00483
00484
00485 void TFileDrawMap::Paint(Option_t *)
00486 {
00487
00488
00489
00490 if (!fOption.Contains("same")) {
00491 gPad->Clear();
00492
00493 if (fFrame->GetMaximumStored() < -1000) {
00494 fFrame->SetMaximum(fYsize+1);
00495 fFrame->SetMinimum(0);
00496 fFrame->GetYaxis()->SetLimits(0,fYsize+1);
00497 }
00498 fFrame->Paint("a");
00499 }
00500
00501
00502 PaintDir(fFile, fKeys.Data());
00503
00504 fFrame->Draw("sameaxis");
00505 }
00506
00507
00508 void TFileDrawMap::PaintBox(TBox &box, Long64_t bseek, Int_t nbytes)
00509 {
00510
00511
00512 Int_t iy = bseek/fXsize;
00513 Int_t ix = bseek%fXsize;
00514 Int_t ny = 1+(nbytes+ix)/fXsize;
00515 Double_t xmin,ymin,xmax,ymax;
00516 for (Int_t j=0;j<ny;j++) {
00517 if (j == 0) xmin = (Double_t)ix;
00518 else xmin = 0;
00519 xmax = xmin + nbytes;
00520 if (xmax > fXsize) xmax = fXsize;
00521 ymin = iy+j;
00522 ymax = ymin+1;
00523 nbytes -= (Int_t)(xmax-xmin);
00524 if (xmax < gPad->GetUxmin()) continue;
00525 if (xmin > gPad->GetUxmax()) continue;
00526 if (xmin < gPad->GetUxmin()) xmin = gPad->GetUxmin();
00527 if (xmax > gPad->GetUxmax()) xmax = gPad->GetUxmax();
00528 if (ymax < gPad->GetUymin()) continue;
00529 if (ymin > gPad->GetUymax()) continue;
00530 if (ymin < gPad->GetUymin()) ymin = gPad->GetUymin();
00531 if (ymax > gPad->GetUymax()) ymax = gPad->GetUymax();
00532
00533 box.PaintBox(xmin,ymin,xmax,ymax);
00534 }
00535 }
00536
00537
00538 void TFileDrawMap::PaintDir(TDirectory *dir, const char *keys)
00539 {
00540
00541
00542 TDirectory *dirsav = gDirectory;
00543 TIter next(dir->GetListOfKeys());
00544 TKey *key;
00545 Int_t color = 0;
00546 TBox box;
00547 TRegexp re(keys,kTRUE);
00548 while ((key = (TKey*)next())) {
00549 Int_t nbytes = key->GetNbytes();
00550 Long64_t bseek = key->GetSeekKey();
00551 TClass *cl = TClass::GetClass(key->GetClassName());
00552 if (cl) {
00553 color = (Int_t)(cl->GetUniqueID()%20);
00554 } else {
00555 color = 1;
00556 }
00557 box.SetFillColor(color);
00558 box.SetFillStyle(1001);
00559 TString s = key->GetName();
00560 if (strcmp(fKeys.Data(),key->GetName()) && s.Index(re) == kNPOS) continue;
00561
00562 if (cl && cl == TDirectoryFile::Class()) {
00563 TDirectory *curdir = gDirectory;
00564 gDirectory->cd(key->GetName());
00565 TDirectory *subdir = gDirectory;
00566 PaintDir(subdir,"*");
00567 curdir->cd();
00568 }
00569 PaintBox(box,bseek,nbytes);
00570
00571 if (cl && cl->InheritsFrom(TTree::Class())) {
00572 TTree *tree = (TTree*)gDirectory->Get(key->GetName());
00573 TIter nextb(tree->GetListOfLeaves());
00574 TLeaf *leaf;
00575 while ((leaf = (TLeaf*)nextb())) {
00576 TBranch *branch = leaf->GetBranch();
00577 color = branch->GetFillColor();
00578 if (color == 0) color = 1;
00579 box.SetFillColor(color);
00580 Int_t nbaskets = branch->GetMaxBaskets();
00581 for (Int_t i=0;i<nbaskets;i++) {
00582 bseek = branch->GetBasketSeek(i);
00583 if (!bseek) break;
00584 nbytes = branch->GetBasketBytes()[i];
00585 PaintBox(box,bseek,nbytes);
00586 }
00587 }
00588 }
00589 }
00590
00591 box.SetFillColor(50);
00592 box.SetFillStyle(1001);
00593 PaintBox(box,dir->GetSeekKeys(),dir->GetNbytesKeys());
00594 if (dir == (TDirectory*)fFile) {
00595
00596 box.SetFillColor(6);
00597 box.SetFillStyle(3008);
00598 PaintBox(box,fFile->GetSeekInfo(),fFile->GetNbytesInfo());
00599
00600 box.SetFillColor(1);
00601 box.SetFillStyle(1001);
00602 PaintBox(box,fFile->GetSeekFree(),fFile->GetNbytesFree());
00603 }
00604 dirsav->cd();
00605 }