CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/DQM/EcalCommon/src/UtilFunctions.cc

Go to the documentation of this file.
00001 
00009 #include "DQM/EcalCommon/interface/UtilFunctions.h"
00010 #include <cmath>
00011 #include <iostream>
00012 
00013 #include "TH1F.h"
00014 #include "TProfile.h"
00015 #include "TH2.h"
00016 #include "TClass.h"
00017 #include "TAxis.h"
00018 #include "DQMServices/Core/interface/MonitorElement.h"
00019 
00020 
00021 namespace ecaldqm {
00022 
00023   // functions implemented here are not universal in the sense that
00024   // the input variables are changed due to efficiency of memory usage.
00025 
00026 
00027   // calculated time intervals and bin locations for time varing profiles
00028 
00029   void calcBins(int binWidth, int divisor, long int start_time, long int last_time, long int current_time,
00030                 long int & binDiff, long int & diff) {
00031 
00032     // changing arguments : binDiff, diff
00033 
00034     // binWidth : time interval
00035     // divisor : time unit - for minute case divisor is 60 and for hour case 3600
00036     // start_time : initial time when the job started
00037     // last_time : the last updated time before calling the current "analyze" function
00038     // current_time : the current time inside "analyze" fucntion
00039     // binDiff : the bin difference for the current time compared to the bin location of the last time
00040     // diff : time difference between the current time and the last time
00041 
00042     long int diff_current_start = current_time - start_time;
00043     long int diff_last_start = last_time - start_time;
00044 
00045     // --------------------------------------------------
00046     // Calculate time interval and bin width
00047     // --------------------------------------------------
00048 
00049     binDiff = diff_current_start/divisor/binWidth - diff_last_start/divisor/binWidth;
00050     diff = (current_time - last_time)/divisor;
00051 
00052     if(diff >= binWidth) {
00053       while(diff >= binWidth) diff -= binWidth;
00054     }
00055 
00056   } // calcBins
00057 
00058   void shift(TH1 *h, Directions d, int bins)
00059   {
00060     if(!bins || !h) return;
00061     if(h->GetXaxis()->IsVariableBinSize()) return;
00062 
00063     if(bins < 0){
00064       bins = -bins;
00065       d = d==kRight ? kLeft : kRight;
00066     }
00067 
00068     if(!h->GetSumw2()) h->Sumw2();
00069     int nBins = h->GetXaxis()->GetNbins();
00070     if(bins >= nBins){
00071       h->Reset();
00072       return;
00073     }
00074 
00075     // the first bin goes to underflow
00076     // each bin moves to the right
00077 
00078     int firstBin, lastBin, bound, increment;
00079     switch(d){
00080     case kRight:
00081       firstBin = nBins + 1;
00082       lastBin = 0;
00083       bound = bins;
00084       increment = -1;
00085       break;
00086     case kLeft:
00087       firstBin = 0;
00088       lastBin = nBins + 1;
00089       bound = nBins - bins + 1;
00090       increment = 1;
00091       break;
00092     default:
00093       return;
00094     }
00095 
00096     int shift = increment * bins;
00097 
00098     if( h->IsA() == TClass::GetClass("TProfile") ){
00099 
00100       TProfile *p = static_cast<TProfile *>(h);
00101 
00102       // by shifting n bin to the left, the number of entries are
00103       // reduced by the number in n bins including the underflow bin.
00104       double nentries = p->GetEntries();
00105       for(int i = firstBin; i != firstBin + shift; i += increment) nentries -= p->GetBinEntries(i);
00106       p->SetEntries(nentries);
00107 
00108       TArrayD* sumw2 = p->GetSumw2();
00109 
00110       for(int i = firstBin; i != bound; i += increment){
00111         // GetBinContent returns binContent/binEntries
00112         p->SetBinContent( i, p->GetBinContent( i+shift ) * p->GetBinEntries( i+shift ) );
00113         p->SetBinEntries( i, p->GetBinEntries( i+shift ) );
00114         sumw2->SetAt( sumw2->GetAt( i+shift ), i );
00115       }
00116 
00117       for(int i = bound; i != lastBin + increment; i += increment){
00118         p->SetBinContent( i, 0 );
00119         p->SetBinEntries( i, 0 );
00120         sumw2->SetAt( 0., i );
00121       }
00122 
00123     }else if( h->InheritsFrom("TH2") ){
00124 
00125       TH2 *h2 = static_cast<TH2 *>(h);
00126       int nBinsY = h2->GetYaxis()->GetNbins();
00127 
00128       // assumes sum(binContent) == entries
00129       double nentries = h2->GetEntries();
00130       for(int i = firstBin; i != firstBin + shift; i += increment)
00131         for(int j=0 ; j<=nBinsY+1 ; j++) nentries -= h2->GetBinContent(i,j);
00132 
00133       h2->SetEntries(nentries);
00134 
00135       for(int i = firstBin; i != bound; i += increment)
00136         for(int j = 0; j <= nBinsY + 1; j++)
00137           h2->SetBinContent( i, j, h2->GetBinContent(i+shift, j) );
00138 
00139       for(int i = bound; i != lastBin + increment; i += increment)
00140         for(int j = 0; j <= nBinsY + 1; j++)
00141           h2->SetBinContent( i, j, 0 );
00142           
00143     }else if( h->InheritsFrom("TH1") ){ // any other histogram class
00144 
00145       // assumes sum(binContent) == entries
00146       double nentries = h->GetEntries();
00147       for(int i = firstBin; i != firstBin + shift; i += increment) nentries -= h->GetBinContent(i);
00148 
00149       h->SetEntries(nentries);
00150 
00151       for(int i = firstBin; i != bound; i += increment)
00152         h->SetBinContent( i, h->GetBinContent(i+shift) );
00153 
00154       for(int i = bound; i != lastBin + increment; i += increment)
00155         h->SetBinContent( i, 0 );
00156     }
00157 
00158 
00159   }
00160 
00161   void shift2Right(TH1* h, int bins)
00162   {
00163     shift(h, kRight, bins);
00164   }
00165 
00166   void shift2Left(TH1* h, int bins)
00167   {
00168     shift(h, kLeft, bins);
00169   }
00170 
00171   // shift axis of histograms keeping the bin contents
00172 
00173   void shiftAxis(TH1 *h, Directions d, double shift)
00174   {
00175     if( !h ) return;
00176     TAxis *xax = h->GetXaxis();
00177     if( h->GetXaxis()->IsVariableBinSize() ) return;
00178 
00179     double xmax = xax->GetXmax();
00180     double xmin = xax->GetXmin();
00181     int nbins = xax->GetNbins();
00182 
00183     if(d == kRight)
00184       xax->Set(nbins, xmin - shift, xmax - shift);
00185     else if(d == kLeft)
00186       xax->Set(nbins, xmin + shift, xmax + shift);
00187   }
00188 
00189   // get mean and rms of Y values from TProfile
00190 
00191   void getAverageFromTProfile(TProfile* p, double& mean, double& rms) {
00192 
00193     // changing arguments : mean, rms
00194     mean = rms = 0.0;
00195 
00196     if(!p) return;
00197 
00198     int nbins = p->GetXaxis()->GetNbins();
00199     double y = 0.0;
00200     double y2 = 0.0;
00201     for(int i=1; i<=nbins; i++){
00202       y += p->GetBinContent(i);
00203       y2 += y*y;
00204     }
00205     mean = y/nbins;
00206     rms = std::sqrt(y2/nbins - mean*mean);
00207 
00208   } // getAverageFromTProfile
00209 
00210 
00211   // get mean and rms based on two histograms' difference
00212 
00213   void getMeanRms(TObject* pre, TObject* cur, double& mean, double& rms) {
00214 
00215     // changing arguments : mean, rms
00216 
00217     mean = rms = 0.0;
00218 
00219     if(!cur) return;
00220 
00221     TString name(cur->IsA()->GetName());
00222 
00223     if(name.Contains("TProfile")) {
00224       getAverageFromTProfile((TProfile*)cur,mean,rms);
00225     }
00226     else if(name.Contains("TH2")) {
00227       if(pre) {
00228         mean = ((TH2F*)cur)->GetEntries() - ((TH2F*)pre)->GetEntries();
00229         if(mean < 0) return;
00230         rms = std::sqrt(mean);
00231       }
00232       else {
00233         mean = ((TH2F*)cur)->GetEntries();
00234         if(mean < 0) return;
00235         rms = std::sqrt(mean);
00236       }
00237       float nxybins = ((TH2F*)cur)->GetNbinsX()*((TH2F*)cur)->GetNbinsY();
00238       if(nxybins < 1.) nxybins = 1.;
00239       mean /= nxybins;
00240       rms /= nxybins;
00241     }
00242     else if(name.Contains("TH1")) {
00243       if(pre) {
00244         ((TH1F*)pre)->Sumw2();
00245         ((TH1F*)pre)->Add((TH1F*)pre,(TH1F*)cur,-1,1);
00246         mean = ((TH1F*)pre)->GetMean();
00247         rms = ((TH1F*)pre)->GetRMS();
00248       }
00249       else {
00250         mean = ((TH1F*)cur)->GetMean();
00251         rms = ((TH1F*)cur)->GetRMS();
00252       }
00253     }
00254 
00255   } // getMeanRms
00256 
00257   TObject* cloneIt(MonitorElement* me, std::string histo) {
00258 
00259     // The cloned object, ret should be deleted after using it.
00260 
00261     TObject* ret = 0;
00262 
00263     if(!me) return ret;
00264 
00265     std::string title = histo + " Clone";
00266     ret = (TObject*) (me->getRootObject()->Clone(title.c_str()));
00267 
00268     return ret;
00269   }
00270 
00271 
00272 }
00273