CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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, bound, increment;
00079     switch(d){
00080     case kRight:
00081       firstBin = nBins + 1;
00082       bound = bins;
00083       increment = -1;
00084       break;
00085     case kLeft:
00086       firstBin = 0;
00087       bound = nBins - bins + 1;
00088       increment = 1;
00089       break;
00090     default:
00091       return;
00092     }
00093 
00094     int shift = increment * bins;
00095 
00096     if( h->IsA() == TClass::GetClass("TProfile") ){
00097 
00098       TProfile *p = static_cast<TProfile *>(h);
00099 
00100       // by shifting n bin to the left, the number of entries are
00101       // reduced by the number in n bins including the underflow bin.
00102       double nentries = p->GetEntries();
00103       for(int i = firstBin; i != firstBin + shift; i += increment) nentries -= p->GetBinEntries(i);
00104       p->SetEntries(nentries);
00105 
00106       TArrayD* sumw2 = p->GetSumw2();
00107 
00108       for(int i = firstBin; i != bound; i += increment){
00109         // GetBinContent returns binContent/binEntries
00110         p->SetBinContent( i, p->GetBinContent( i+shift ) * p->GetBinEntries( i+shift ) );
00111         p->SetBinEntries( i, p->GetBinEntries( i+shift ) );
00112         sumw2->SetAt( sumw2->GetAt( i+shift ), i );
00113       }
00114 
00115     }else if( h->InheritsFrom("TH2") ){
00116 
00117       TH2 *h2 = static_cast<TH2 *>(h);
00118       int nBinsY = h2->GetYaxis()->GetNbins();
00119 
00120       // assumes sum(binContent) == entries
00121       double nentries = h2->GetEntries();
00122       for(int i = firstBin; i != firstBin + shift; i += increment)
00123         for(int j=0 ; j<=nBinsY+1 ; j++) nentries -= h2->GetBinContent(i,j);
00124 
00125       h2->SetEntries(nentries);
00126 
00127       for(int i = firstBin; i != bound; i += increment)
00128         for(int j=0 ; j<=nBinsY+1 ; j++)
00129           h2->SetBinContent( i, j, h2->GetBinContent(i+shift, j) );
00130 
00131     }else if( h->InheritsFrom("TH1") ){ // any other histogram class
00132 
00133       // assumes sum(binContent) == entries
00134       double nentries = h->GetEntries();
00135       for(int i = firstBin; i != firstBin + shift; i += increment) nentries -= h->GetBinContent(i);
00136 
00137       h->SetEntries(nentries);
00138 
00139       for(int i = firstBin; i != bound; i += increment)
00140         h->SetBinContent( i, h->GetBinContent(i+shift) );
00141     }
00142 
00143 
00144   }
00145 
00146   void shift2Right(TH1* h, int bins)
00147   {
00148     shift(h, kRight, bins);
00149   }
00150 
00151   void shift2Left(TH1* h, int bins)
00152   {
00153     shift(h, kLeft, bins);
00154   }
00155 
00156   // shift axis of histograms keeping the bin contents
00157 
00158   void shiftAxis(TH1 *h, Directions d, double shift)
00159   {
00160     if( !h ) return;
00161     TAxis *xax = h->GetXaxis();
00162     if( h->GetXaxis()->IsVariableBinSize() ) return;
00163 
00164     double xmax = xax->GetXmax();
00165     double xmin = xax->GetXmin();
00166     int nbins = xax->GetNbins();
00167 
00168     if(d == kRight)
00169       xax->Set(nbins, xmin - shift, xmax - shift);
00170     else if(d == kLeft)
00171       xax->Set(nbins, xmin + shift, xmax + shift);
00172   }
00173 
00174   // get mean and rms of Y values from TProfile
00175 
00176   void getAverageFromTProfile(TProfile* p, double& mean, double& rms) {
00177 
00178     // changing arguments : mean, rms
00179     mean = rms = 0.0;
00180 
00181     if(!p) return;
00182 
00183     int nbins = p->GetXaxis()->GetNbins();
00184     double y = 0.0;
00185     double y2 = 0.0;
00186     for(int i=1; i<=nbins; i++){
00187       y += p->GetBinContent(i);
00188       y2 += y*y;
00189     }
00190     mean = y/nbins;
00191     rms = std::sqrt(y2/nbins - mean*mean);
00192 
00193   } // getAverageFromTProfile
00194 
00195 
00196   // get mean and rms based on two histograms' difference
00197 
00198   void getMeanRms(TObject* pre, TObject* cur, double& mean, double& rms) {
00199 
00200     // changing arguments : mean, rms
00201 
00202     mean = rms = 0.0;
00203 
00204     if(!cur) return;
00205 
00206     TString name(cur->IsA()->GetName());
00207 
00208     if(name.Contains("TProfile")) {
00209       getAverageFromTProfile((TProfile*)cur,mean,rms);
00210     }
00211     else if(name.Contains("TH2")) {
00212       if(pre) {
00213         mean = ((TH2F*)cur)->GetEntries() - ((TH2F*)pre)->GetEntries();
00214         rms = std::sqrt(mean);
00215       }
00216       else {
00217         mean = ((TH2F*)cur)->GetEntries();
00218         rms = std::sqrt(mean);
00219       }
00220       float nxybins = ((TH2F*)cur)->GetNbinsX()*((TH2F*)cur)->GetNbinsY();
00221       mean /= nxybins;
00222       rms /= nxybins;
00223     }
00224     else if(name.Contains("TH1")) {
00225       if(pre) {
00226         ((TH1F*)pre)->Sumw2();
00227         ((TH1F*)pre)->Add((TH1F*)pre,(TH1F*)cur,-1,1);
00228         mean = ((TH1F*)pre)->GetMean();
00229         rms = ((TH1F*)pre)->GetRMS();
00230       }
00231       else {
00232         mean = ((TH1F*)cur)->GetMean();
00233         rms = ((TH1F*)cur)->GetRMS();
00234       }
00235     }
00236 
00237   } // getMeanRms
00238 
00239   TObject* cloneIt(MonitorElement* me, std::string histo) {
00240 
00241     // The cloned object, ret should be deleted after using it.
00242 
00243     TObject* ret = 0;
00244 
00245     if(!me) return ret;
00246 
00247     std::string title = histo + " Clone";
00248     ret = (TObject*) (me->getRootObject()->Clone(title.c_str()));
00249 
00250     return ret;
00251   }
00252 
00253 
00254 }
00255