CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:40:54 2009 for CMSSW by  doxygen 1.5.4