CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/PerfTools/EdmEvent/src/EdmEventSize.cc

Go to the documentation of this file.
00001 
00005 #include "PerfTools/EdmEvent/interface/EdmEventSize.h"
00006 #include <valarray>
00007 #include <functional>
00008 #include <algorithm>
00009 #include <boost/bind.hpp>
00010 #include <ostream>
00011 #include <limits>
00012 #include <assert.h>
00013 
00014 #include "Rtypes.h"
00015 #include "TROOT.h"
00016 #include "TFile.h"
00017 #include "TTree.h"
00018 #include "TStyle.h"
00019 #include "TObjArray.h"
00020 #include "TBranch.h"
00021 #include "TH1.h"
00022 #include "TCanvas.h"
00023 #include "Riostream.h"
00024 // #include "FWCore/FWLite/src/AutoLibraryLoader.h"
00025 
00026 #include "TBufferFile.h"
00027 
00028 namespace {
00029 
00030   typedef std::valarray<Long64_t> size_type; 
00031 
00032   size_type getBasketSize( TBranch *);
00033   
00034   size_type getBasketSize( TObjArray * branches) {
00035     size_type result(static_cast<Long64_t>(0),2);
00036     size_t n = branches->GetEntries();
00037     for( size_t i = 0; i < n; ++ i ) {
00038       TBranch * b = dynamic_cast<TBranch*>( branches->At( i ) );
00039       assert( b != 0 );
00040       result += getBasketSize(b);
00041     }
00042     return result;
00043   }
00044   
00045   size_type getBasketSize( TBranch * b) {
00046     size_type result(static_cast<Long64_t>(0),2);
00047     if ( b != 0 ) {
00048       if ( b->GetZipBytes() > 0 ) {
00049         result[0]  = b->GetTotBytes();  result[1] = b->GetZipBytes();
00050       } else {
00051         result[0] = b->GetTotalSize(); result[1] = b->GetTotalSize();
00052       }
00053       result += getBasketSize( b->GetListOfBranches() );
00054     }
00055     return result;
00056   }
00057 
00058 
00059   size_type getTotalSize( TBranch * br) {
00060     TBufferFile buf( TBuffer::kWrite, 10000 );
00061     TBranch::Class()->WriteBuffer( buf, br );
00062     size_type size = getBasketSize(br);
00063     if ( br->GetZipBytes() > 0 )
00064       size[0] += buf.Length();
00065     return size;
00066   }
00067 }
00068 
00069 namespace perftools {
00070 
00071   EdmEventSize::EdmEventSize() : 
00072     m_nEvents(0) {}
00073   
00074   EdmEventSize::EdmEventSize(std::string const & fileName, std::string const & treeName ) : 
00075     m_nEvents(0) {
00076     parseFile(fileName);
00077   }
00078   
00079   void EdmEventSize::parseFile(std::string const & fileName, std::string const & treeName) {
00080     m_fileName = fileName;
00081     m_branches.clear();
00082 
00083     TFile * file = TFile::Open( fileName.c_str() );
00084     if( file==0  || ( !(*file).IsOpen() ) )
00085       throw Error( "unable to open data file " + fileName, 7002);
00086     
00087     TObject * o = file->Get(treeName.c_str() );
00088     if ( o == 0 )
00089       throw Error("no object \"" + treeName + "\" found in file: " + fileName, 7003);
00090     
00091     TTree * events = dynamic_cast<TTree*> (o);
00092     if ( events == 0 )
00093       throw Error("object \"" + treeName + "\" is not a TTree in file: " + fileName, 7004);
00094     
00095     m_nEvents = events->GetEntries();
00096     if ( m_nEvents == 0 )
00097       throw Error("tree \"" + treeName + "\" in file " + fileName + " contains no Events", 7005);
00098 
00099 
00100     TObjArray * branches = events->GetListOfBranches();
00101     if ( branches == 0 )
00102       throw Error("tree \"" + treeName+ "\" in file " + fileName + " contains no branches", 7006);
00103     
00104     const size_t n =  branches->GetEntries();
00105     m_branches.reserve(n);
00106     for( size_t i = 0; i < n; ++i ) {
00107       TBranch * b = dynamic_cast<TBranch*>( branches->At( i ) );
00108       if (b==0) continue;
00109       std::string const name( b->GetName() );
00110       if ( name == "EventAux" ) continue;
00111       size_type s = getTotalSize(b);
00112       m_branches.push_back( BranchRecord(name, double(s[0])/double(m_nEvents), double(s[1])/double(m_nEvents)) );
00113     }
00114     std::sort(m_branches.begin(),m_branches.end(), 
00115               boost::bind(std::greater<double>(),
00116                           boost::bind(&BranchRecord::compr_size,_1),
00117                           boost::bind(&BranchRecord::compr_size,_2))
00118               );
00119 
00120   }
00121   
00122   void EdmEventSize::sortAlpha() {
00123     std::sort(m_branches.begin(),m_branches.end(), 
00124               boost::bind(std::less<std::string>(),
00125                           boost::bind(&BranchRecord::name,_1),
00126                           boost::bind(&BranchRecord::name,_2))
00127               );
00128 
00129   }
00130 
00131   namespace detail {
00132     // format as product:label (type)
00133     void shorterName(EdmEventSize::BranchRecord & br) {
00134       size_t b = br.fullName.find('_');
00135       size_t e = br.fullName.rfind('_');
00136       if (b==e) br.name=br.fullName;
00137       else {
00138         // remove type and process
00139         br.name = br.fullName.substr(b+1,e-b-1);
00140         // change label separator in :
00141         e = br.name.rfind('_');
00142         if (e!=std::string::npos) br.name.replace(e,1,":");
00143         // add the type name
00144         br.name.append(" ("+br.fullName.substr(0,b)+")");
00145       }
00146     }
00147 
00148   }
00149   
00150   void EdmEventSize::formatNames() {
00151     std::for_each(m_branches.begin(),m_branches.end(),
00152                   &detail::shorterName);
00153   }
00154 
00155 
00156 
00157   namespace detail {
00158 
00159     void dump(ostream& co, EdmEventSize::BranchRecord const & br) {
00160       co << br.name << " " <<  br.compr_size <<  " " << br.uncompr_size << "\n"; 
00161     }
00162   }
00163 
00164   
00165   void EdmEventSize::dump(std::ostream & co, bool header) const {
00166     if (header) 
00167       co << "File " << m_fileName << " Events " << m_nEvents << "\n";
00168     std::for_each(m_branches.begin(),m_branches.end(),
00169                   boost::bind(detail::dump,boost::ref(co),_1));
00170   }
00171 
00172   namespace detail {
00173 
00174     struct Hist {
00175 
00176       explicit Hist(int itop) : 
00177         top(itop),
00178         uncompressed( "uncompressed", "branch sizes", top, -0.5, - 0.5 + top ),
00179         compressed( "compressed", "branch sizes", top, -0.5, - 0.5 + top ),
00180         cxAxis(compressed.GetXaxis()),
00181         uxAxis(uncompressed.GetXaxis()),
00182         x(0) {}
00183       
00184       void fill(EdmEventSize::BranchRecord const & br) {
00185         if ( x < top ) {
00186           cxAxis->SetBinLabel( x + 1, br.name.c_str() );
00187           uxAxis->SetBinLabel( x + 1, br.name.c_str() );
00188           compressed.Fill( x, br.compr_size );
00189           uncompressed.Fill( x, br.uncompr_size );
00190           x++;
00191         }
00192       }
00193 
00194       void finalize() {
00195         double mn = std::numeric_limits<double>::max();
00196         for( int i = 1; i <= top; ++i ) {
00197           double cm = compressed.GetMinimum( i ), um = uncompressed.GetMinimum( i );
00198           if ( cm > 0 && cm < mn ) mn = cm;
00199           if ( um > 0 && um < mn ) mn = um;
00200         }
00201         mn *= 0.8;
00202         double mx = max( compressed.GetMaximum(), uncompressed.GetMaximum() );
00203         mx *= 1.2;
00204         uncompressed.SetMinimum( mn );
00205         uncompressed.SetMaximum( mx );
00206         compressed.SetMinimum( mn );
00207         //  compressed.SetMaximum( mx );
00208         cxAxis->SetLabelOffset( -0.32 );
00209         cxAxis->LabelsOption( "v" );
00210         cxAxis->SetLabelSize( 0.03 );
00211         uxAxis->SetLabelOffset( -0.32 );
00212         uxAxis->LabelsOption( "v" );
00213         uxAxis->SetLabelSize( 0.03 );
00214         compressed.GetYaxis()->SetTitle( "Bytes" );
00215         compressed.SetFillColor( kBlue );
00216         compressed.SetLineWidth( 2 );
00217         uncompressed.GetYaxis()->SetTitle( "Bytes" );
00218         uncompressed.SetFillColor( kRed );
00219         uncompressed.SetLineWidth( 2 );
00220         
00221       }
00222       
00223       int top;
00224       TH1F uncompressed;
00225       TH1F compressed;
00226       TAxis * cxAxis;
00227       TAxis * uxAxis;
00228       
00229       int x;
00230     };
00231   
00232   }
00233   
00234   void EdmEventSize::produceHistos(std::string const & plot, std::string const & file, int top) const {
00235     if (top==0) top = m_branches.size();
00236     detail::Hist h(top);
00237     std::for_each(m_branches.begin(),m_branches.end(),
00238                   boost::bind(&detail::Hist::fill,boost::ref(h),_1));
00239     h.finalize();
00240     if( !plot.empty() ) {
00241       gROOT->SetStyle( "Plain" );
00242       gStyle->SetOptStat( kFALSE );
00243       gStyle->SetOptLogy();
00244       TCanvas c;
00245       h.uncompressed.Draw();
00246       h.compressed.Draw( "same" );
00247       c.SaveAs( plot.c_str() );
00248     }
00249     if ( !file.empty() ) {
00250       TFile f( file.c_str(), "RECREATE" );
00251       h.compressed.Write();
00252       h.uncompressed.Write();
00253       f.Close();
00254     }
00255 
00256   }
00257 
00258 }