示例#1
0
文件: memstat.C 项目: My-Source/root
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;
}