void memstat(double update=0.01, const char* fname="*") { // Open the memstat data file, then call TTree::Draw to precompute // the arrays of positions and nbytes per entry. // update is the time interval in the data file in seconds after which // the display is updated. For example is the job producing the memstat.root file // took 100s to execute, an update of 0.1s will generate 1000 time views of // the memory use. // if fname=="*" (default), the most recent file memstat*.root will be taken. TString s; if (!fname || strlen(fname) <5 || strstr(fname,"*")) { //take the most recent file memstat*.root s = gSystem->GetFromPipe("ls -lrt memstat*.root"); Int_t ns = s.Length(); fname = strstr(s.Data()+ns-25,"memstat"); } printf("Analyzing file: %s\n",fname); f = TFile::Open(fname); if (!f) { printf("Cannot open file %s\n",fname); return; } T = (TTree*)f->Get("T"); if (!T) { printf("cannot find the TMemStat TTree named T in file %s\n",fname); return; } if (update <= 0) { printf("Illegal update value %g, changed to 0.01\n",update); update = 0.01; } if (update < 0.001) printf("Warning update parameter is very small, processing may be slow\n"); Long64_t nentries = T->GetEntries(); T->SetEstimate(nentries+10); Long64_t nsel = T->Draw("pos:nbytes:time:btid","","goff"); //now we compute the best binning for the histogram Int_t nbytes; Double_t pos; V1 = T->GetV1(); V2 = T->GetV2(); V3 = T->GetV3(); V4 = T->GetV4(); Long64_t imean = (Long64_t)TMath::Mean(nsel,V1); Long64_t irms = (Long64_t)TMath::RMS(nsel,V1); //Long64_t bw = 10000; Long64_t bw = 1000; imean = imean - imean%bw; irms = irms -irms%bw; Int_t nbins = Int_t(4*irms/bw); Long64_t ivmin = imean -bw*nbins/2; Long64_t ivmax = ivmin+bw*nbins; if (ivmax > 2000000000 && ivmin <2000000000) { //the data set has been likely generated on a 32 bits machine //we are mostly interested by the small allocations, so we select //only values below 2 GBytes printf("memory locations above 2GBytes will be ignored\n"); nsel = T->Draw("pos:nbytes:time:btid","pos <2e9","goff"); V1 = T->GetV1(); V2 = T->GetV2(); V3 = T->GetV3(); V4 = T->GetV4(); imean = (Long64_t)TMath::Mean(nsel,V1); irms = (Long64_t)TMath::RMS(nsel,V1); bw = 10000; imean = imean - imean%bw; irms = irms -irms%bw; nbins = Int_t(4*irms/bw); ivmin = imean -bw*nbins/2; ivmax = ivmin+bw*nbins; } update *= 0.0001*V3[nsel-1]; //convert time per cent in seconds Long64_t nvm = Long64_t(ivmax-ivmin+1); Long64_t *nbold = new Long64_t[nvm]; Int_t *ientry = new Int_t[nvm]; memset(nbold,0,nvm*8); Double_t dv = (ivmax-ivmin)/nbins; h = new TH1D("h",Form("%s;pos;per cent of pages used",fname),nbins,ivmin,ivmax); TAxis *axis = h->GetXaxis(); gStyle->SetOptStat("ie"); h->SetFillColor(kRed); h->SetMinimum(0); h->SetMaximum(100); halloc = new TH1D("halloc",Form("%s;pos;number of mallocs",fname),nbins,ivmin,ivmax); hfree = new TH1D("hfree", Form("%s;pos;number of frees",fname),nbins,ivmin,ivmax); //open a canvas and draw the empty histogram TCanvas *c1 = new TCanvas("c1","c1",1200,600); c1->SetFrameFillColor(kYellow-3); c1->SetGridx(); c1->SetGridy(); h->Draw(); //create a TPaveText to show the summary results TPaveText *pvt = new TPaveText(.5,.9,.75,.99,"brNDC"); pvt->Draw(); //create a TPaveLabel to show the time TPaveLabel *ptime = new TPaveLabel(.905,.7,.995,.76,"time","brNDC"); ptime->SetFillColor(kYellow-3); ptime->Draw(); //draw producer identifier TNamed *named = (TNamed*)T->GetUserInfo()->FindObject("SysInfo"); TText tmachine; tmachine.SetTextSize(0.02); tmachine.SetNDC(); if (named) tmachine.DrawText(0.01,0.01,named->GetTitle()); //start loop on selected rows Int_t bin,nb=0,j; Long64_t ipos; Double_t dbin,rest,time; Double_t updateLast = 0; Int_t nleaks = 0; Int_t i; for (i=0;i<nsel;i++) { pos = V1[i]; ipos = (Long64_t)(pos-ivmin); nbytes = (Int_t)V2[i]; time = 0.0001*V3[i]; bin = axis->FindBin(pos); if (bin<1 || bin>nbins) continue; dbin = axis->GetBinUpEdge(bin)-pos; if (nbytes > 0) { halloc->Fill(pos); if (dbin > nbytes) dbin = nbytes; //fill bytes in the first page h->AddBinContent(bin,100*dbin/dv); //fill bytes in full following pages nb = Int_t((nbytes-dbin)/dv); if (bin+nb >nbins) nb = nbins-bin; for (j=1;j<=nb;j++) h->AddBinContent(bin+j,100); //fill the bytes remaining in last page rest = nbytes-nb*dv-dbin; if (rest > 0) h->AddBinContent(bin+nb+1,100*rest/dv); //we save nbytes at pos. This info will be used when we free this slot if (nbold[ipos] > 0) printf("reallocating %d bytes (was %lld) at %lld, entry=%d\n",nbytes,nbold[ipos],ipos,i); if (nbold[ipos] == 0) { nleaks++; //save the Tree entry number where we made this allocation ientry[ipos] = i; } nbold[ipos] = nbytes; } else { hfree->Fill(pos); nbytes = nbold[ipos]; if (bin+nb >nbins) nb = nbins-bin; nbold[ipos] = 0; nleaks--; if (nbytes <= 0) continue; //fill bytes free in the first page if (dbin > nbytes) dbin = nbytes; h->AddBinContent(bin,-100*dbin/dv); //fill bytes free in full following pages nb = Int_t((nbytes-dbin)/dv); if (bin+nb >nbins) nb = nbins-bin; for (j=1;j<=nb;j++) h->AddBinContent(bin+j,-100); //fill the bytes free in in last page rest = nbytes-nb*dv-dbin; if (rest > 0) h->AddBinContent(bin+nb+1,-100*rest/dv); } if (time -updateLast > update) { //update canvas at regular intervals updateLast = time; h->SetEntries(i); c1->Modified(); pvt->GetListOfLines()->Delete(); Double_t mbytes = 0; Int_t nonEmpty = 0; Double_t w; for (Int_t k=1;k<nbins;k++) { w = h->GetBinContent(k); if (w > 0) { nonEmpty++; mbytes += 0.01*w*dv; } } Double_t occupancy = mbytes/(nonEmpty*0.01*dv); pvt->AddText(Form("memory used = %g Mbytes",mbytes*1e-6)); pvt->AddText(Form("page occupancy = %f per cent",occupancy)); pvt->AddText("(for non empty pages only)"); ptime->SetLabel(Form("%g sec",time)); c1->Update(); gSystem->ProcessEvents(); } } h->SetEntries(nsel); Int_t nlmax = nleaks; nleaks += 1000; Int_t *lindex = new Int_t[nleaks]; Int_t *entry = new Int_t[nleaks]; Int_t *ileaks = new Int_t[nleaks]; nleaks =0; for (Int_t ii=0;ii<nvm;ii++) { if (nbold[ii] > 0) { ileaks[nleaks] = (Int_t)nbold[ii]; entry[nleaks] = ientry[ii]; nleaks++; if (nleaks > nlmax) break; } } TMath::Sort(nleaks,ileaks,lindex); hentry = new TH1I("hentry","leak entry index",nleaks,0,nleaks); hleaks = new TH1I("hleaks","leaks;leak number;nbytes in leak",nleaks,0,nleaks); for (Int_t k=0;k<nleaks;k++) { Int_t kk = lindex[k]; i = entry[kk]; hentry->SetBinContent(k+1,i); hleaks->SetBinContent(k+1,ileaks[kk]); } hentry->SetEntries(nleaks); hleaks->SetEntries(nleaks); //open a second canvas and draw the histogram with leaks in decreasing order TCanvas *c2 = new TCanvas("c2","c2",1200,600); c2->SetFrameFillColor(kCyan-6); c2->SetGridx(); c2->SetGridy(); c2->SetLogy(); hleaks->SetFillColor(kRed-3); if (nleaks > 1000) hleaks->GetXaxis()->SetRange(1,1000); hleaks->Draw(); //draw producer identifier if (named) tmachine.DrawText(0.01,0.01,named->GetTitle()); //construct the tooltip TRootCanvas *rc = (TRootCanvas *)c2->GetCanvasImp(); TGMainFrame *frm = dynamic_cast<TGMainFrame *>(rc); // create the tooltip with a timeout of 250 ms if (!gTip) gTip = new TGToolTip(gClient->GetDefaultRoot(), frm, "", 250); c2->Connect("ProcessedEvent(Int_t, Int_t, Int_t, TObject*)", 0, 0, "EventInfo(Int_t, Int_t, Int_t, TObject*)"); }
int main(int argc, char** argv){ TString chfile; TString chfileref; TString DirectoryLast; TString labelData; TString labelRef; int ntrueargs = 0; bool logyFlag = true; bool normalize = false; for (int i=1; i<argc; ++i) { if (argv[i][0] == '-') { if (argv[i][1]=='l') logyFlag = false; else if (argv[i][1]=='b') gROOT->SetBatch(); else if (argv[i][1]=='h') return printUsage(); else if (argv[i][1]=='n') normalize=true; else if (argv[i][1]=='D') labelData = argv[i+1]; else if (argv[i][1]=='R') labelRef= argv[i+1]; } else { ntrueargs += 1; if (ntrueargs==1) chfile = argv[i]; else if (ntrueargs==2) chfileref = argv[i]; else if (ntrueargs==3) DirectoryLast = argv[i]; } } if (ntrueargs<3) return printUsage(); TRint* app = new TRint("CMS Root Application", 0, 0); TString cmssw_version = gSystem->Getenv("CMSSW_VERSION"); TString chsample = "EWKMu"; TString chtitle = chsample + " validation for " + cmssw_version; //TCanvas* c1 = new TCanvas("c1",chtitle.Data()); TCanvas* c1 = new TCanvas("c1",chtitle.Data(),0,0,1024,768); c1->SetFillColor(0); TPaveLabel* paveTitle = new TPaveLabel(0.1,0.93,0.9,0.99, chtitle.Data()); paveTitle->Draw(); paveTitle->SetFillColor(0); gStyle->SetOptLogy(logyFlag); gStyle->SetPadGridX(true); gStyle->SetPadGridY(true); gStyle->SetOptStat(0); // gStyle->SetFillColor(0); TPad* pad[4]; pad[0] = new TPad("pad_tl","The top-left pad",0.01,0.48,0.49,0.92); pad[0]->SetFillColor(0); pad[1] = new TPad("pad_tr","The top-right pad",0.51,0.48,0.99,0.92); pad[1]->SetFillColor(0); pad[2] = new TPad("pad_bl","The bottom-left pad",0.01,0.01,0.49,0.46); pad[2]->SetFillColor(0); pad[3] = new TPad("pad_br","The bottom-right pad",0.51,0.01,0.99,0.46); pad[3]->SetFillColor(0); for (unsigned int i=0; i<4; ++i) pad[i]->Draw(); TLegend* leg = new TLegend(0.6041667,0.7487715,0.9861111,0.9576167); leg->SetFillColor(0); TFile* input_file = new TFile(chfile.Data(),"READONLY"); TFile* input_fileref = new TFile(chfileref.Data(),"READONLY"); bool first_plots_done = false; TString directory = DirectoryLast + "/BeforeCuts"; TDirectory* dir_before = input_file->GetDirectory(directory); TDirectory* dirref_before = input_fileref->GetDirectory(directory); TList* list_before = dir_before->GetListOfKeys(); list_before->Print(); unsigned int list_before_size = list_before->GetSize(); TString auxTitle = chtitle + ": BEFORE CUTS"; for (unsigned int i=0; i<list_before_size; i+=4) { if (first_plots_done==true) c1->DrawClone(); paveTitle->SetLabel(auxTitle.Data()); for (unsigned int j=0; j<4; ++j) { pad[j]->cd(); pad[j]->Clear(); if ((i+j)>=list_before_size) continue; TH1D* h1 = (TH1D*)dir_before->Get(list_before->At(i+j)->GetName()); // h1->SetLineColor(kBlue); // h1->SetMarkerColor(kBlue); h1->SetMarkerStyle(21); h1->SetLineStyle(1); h1->SetLineWidth(3); h1->SetTitleSize(0.05,"X"); h1->SetTitleSize(0.05,"Y"); TString title=(TString)dir_before->Get(list_before->At(i+j)->GetName())->GetTitle(); TString name=(TString)dir_before->Get(list_before->At(i+j)->GetName())->GetName(); TString nameD =name+"_MC"; h1->SetXTitle(title); h1->SetName(nameD); h1->SetYTitle(""); h1->SetTitle(""); h1->SetTitleOffset(0.85,"X"); TH1D* hr = (TH1D*)dirref_before->Get(list_before->At(i+j)->GetName()); hr->SetLineColor(kPink-4); // hr->SetLineStyle(2); hr->SetLineWidth(3); hr->SetTitleSize(0.05,"X"); hr->SetTitleSize(0.05,"Y"); hr->SetFillColor(kPink-4); hr->SetFillStyle(3001); hr->SetXTitle(title); TString nameMC =name+"_Data"; h1->SetName(nameMC); hr->SetYTitle(""); hr->SetTitle(""); hr->SetTitleOffset(0.85,"X"); if(normalize) {hr->DrawNormalized("hist",h1->Integral());} else{hr->Draw("hist");} h1->Draw("sames,p,E"); int max1=h1->GetMaximum(); int maxr=hr->GetMaximum(); if(!normalize){ if(max1 >= maxr) { hr->SetMaximum(max1*1.2); h1->SetMaximum(max1*1.2);} else {hr->SetMaximum(maxr*1.2); h1->SetMaximum(maxr*1.2);} } else if (normalize){ hr->GetYaxis()->SetRangeUser(h1->GetMinimum()*0.1,max1*1.2); } leg->Clear(); leg->AddEntry(h1,labelData.Data(),"Lp"); leg->AddEntry(hr,labelRef.Data() ,"f"); leg->Draw(); } first_plots_done = true; c1->Modified(); c1->Update(); char chplot[80]; sprintf(chplot,"%sValidation_%s_BEFORECUTS_%d.root",chsample.Data(),cmssw_version.Data(),i/4); c1->SaveAs(chplot); sprintf(chplot,"%sValidation_%s_BEFORECUTS_%d.gif",chsample.Data(),cmssw_version.Data(),i/4); c1->SaveAs(chplot); } TString directory2 = DirectoryLast + "/LastCut"; TDirectory* dir_lastcut = input_file->GetDirectory(directory2); TDirectory* dirref_lastcut = input_fileref->GetDirectory(directory2); TList* list_lastcut = dir_lastcut->GetListOfKeys(); list_lastcut->Print(); unsigned int list_lastcut_size = list_lastcut->GetSize(); auxTitle = chtitle + ": AFTER N-1 CUTS"; for (unsigned int i=0; i<list_lastcut_size; i+=4) { if (first_plots_done==true) c1->DrawClone(); paveTitle->SetLabel(auxTitle.Data()); for (unsigned int j=0; j<4; ++j) { pad[j]->cd(); pad[j]->Clear(); if ((i+j)>=list_lastcut_size) continue; TH1D* h1 = (TH1D*)dir_lastcut->Get(list_lastcut->At(i+j)->GetName()); // h1->SetLineColor(kBlue); // h1->SetMarkerColor(kBlue); h1->SetMarkerStyle(21); h1->SetLineWidth(3); h1->SetTitleSize(0.05,"X"); h1->SetTitleSize(0.05,"Y"); TString name=(TString)dir_lastcut->Get(list_lastcut->At(i+j)->GetName())->GetName(); TString title=(TString)dir_lastcut->Get(list_lastcut->At(i+j)->GetName())->GetTitle(); TString nameD=name+"_Data"; h1->SetXTitle(title); h1->SetName(nameD); h1->SetYTitle(""); h1->SetTitle(""); h1->SetTitleOffset(0.85,"X"); TH1D* hr = (TH1D*)dirref_lastcut->Get(list_lastcut->At(i+j)->GetName()); hr->SetLineColor(kAzure+5); // hr->SetLineStyle(2); hr->SetLineWidth(3); hr->SetTitleSize(0.05,"X"); hr->SetTitleSize(0.05,"Y"); hr->SetFillColor(kAzure+5); hr->SetFillStyle(3001); hr->SetXTitle(title); TString nameMC=name+"_Data"; h1->SetName(nameMC); hr->SetYTitle(""); hr->SetTitle(""); hr->SetTitleOffset(0.85,"X"); if(normalize) {hr->DrawNormalized("hist",h1->Integral());} else{hr->Draw("hist");} h1->Draw("sames,p,E"); int max1=h1->GetMaximum(); int maxr=hr->GetMaximum(); if(!normalize){ if(max1 >= maxr) { hr->SetMaximum(max1*1.2); h1->SetMaximum(max1*1.2);} else {hr->SetMaximum(maxr*1.2); h1->SetMaximum(maxr*1.2);} } else if (normalize){ hr->GetYaxis()->SetRangeUser(h1->GetMinimum()*0.1,max1*1.2); } leg->Clear(); leg->AddEntry(h1,labelData.Data(),"lp"); leg->AddEntry(hr,labelRef.Data(),"f"); leg->Draw(); } first_plots_done = true; c1->Modified(); c1->Update(); char chplot[80]; sprintf(chplot,"%sValidation_%s_LASTCUT_%d.root",chsample.Data(),cmssw_version.Data(),i/4); c1->SaveAs(chplot); sprintf(chplot,"%sValidation_%s_LASTCUT_%d.gif",chsample.Data(),cmssw_version.Data(),i/4); c1->SaveAs(chplot); } if (!gROOT->IsBatch()) app->Run(); return 0; }