CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/DQM/HcalMonitorClient/interface/HcalHistoUtils.h

Go to the documentation of this file.
00001 #ifndef GUARD_HCALTESTUTILS_H
00002 #define GUARD_HCALTESTUTILS_H
00003 
00004 #define UTILS_ETAMIN -44.5
00005 #define UTILS_ETAMAX 44.5
00006 #define UTILS_PHIMIN -0.5
00007 #define UTILS_PHIMAX 73.5
00008 
00009 #include "TROOT.h"
00010 #include "TStyle.h"
00011 #include "TColor.h"
00012 
00013 #include "TH1.h"
00014 #include "TCanvas.h"
00015 #include "TGaxis.h"
00016 
00017 #include "TH1F.h"
00018 #include "TH2F.h"
00019 #include "TProfile.h"
00020 #include "TFile.h"
00021 
00022 #include <iostream>
00023 #include <fstream>
00024 
00025 /******************************************************************************
00026  *
00027  * HcalTestUtils.h
00028  * v1.1
00029  * 4 May 2008
00030  * by Jeff Temple (jtemple AT fnal.gov)
00031  *
00032  *  Various template methods to grab any type of
00033  *  histogram stored as a MonitorElement, and 
00034  *  to return .gif, .html output from the histogram.
00035  *
00036  * Methods:
00037  *
00038  * myHist* getAnyHisto(myHist* hist, std::string name, std::string process, 
00039                          DQMStore* dbe_, bool verb, bool clone)  
00040  *                         
00041  * std::string getAnyIMG(int runNo,myHist* hist, int size, std::string htmlDir,
00042                          const char* xlab, const char* ylab, bool setLogy, bool setLogx) 
00043  *
00044  * void htmlAnyHisto(int runNo, myHist *hist, 
00045                      const char* xlab, const char* ylab, 
00046                      int width, ofstream& htmlFile, 
00047                      std::string htmlDir, bool setLogy, bool setLogx)
00048  
00049  *
00050  *****************************************************************************
00051  */
00052 
00053 #include "DQMServices/Core/interface/DQMStore.h"
00054 
00055 // Template class 'getAnyHisto' functions contain memory leaks somewhere.  Re-introduce getTH1F, getTH2F, getTProfile
00056 
00057 inline TH1F* getTH1F(std::string name, std::string process, std::string rootfolder, DQMStore* dbe_, bool verb, bool clone)
00058 {
00059   
00060   if (!dbe_) return NULL;
00061   std::stringstream title;
00062   title <<process.c_str()<<rootfolder.c_str()<<"/"<<name.c_str();
00063 
00064   MonitorElement* me = dbe_->get(title.str().c_str()); // get Monitor Element named 'title'
00065   
00066   if (!me) 
00067     {
00068       if (verb) std::cout <<"SORRY, COULD NOT FIND HISTOGRAM NAMED ["<< title.str().c_str()<<"]"<<std::endl;
00069       return NULL; // ME not found
00070     } // if (!me)
00071 
00072   if (verb) 
00073     std::cout << "Found '" << title.str().c_str() << "'" << std::endl;
00074 
00075   std::stringstream clonehisto;
00076   if (clone)
00077     {
00078       clonehisto<<"ME "<<name.c_str();
00079       TH1F *out = dynamic_cast<TH1F*>(me->getTH1F()->Clone(clonehisto.str().c_str()));
00080       return out;
00081     }
00082   else return (me->getTH1F());
00083 }
00084 
00085 inline TH2F* getTH2F(std::string name, std::string process, std::string rootfolder, DQMStore* dbe_, bool verb, bool clone)
00086 {
00087   if (!dbe_) return NULL;
00088   std::stringstream title;
00089   title <<process.c_str()<<rootfolder.c_str()<<"/"<<name.c_str();
00090 
00091   MonitorElement* me = dbe_->get(title.str().c_str()); // get Monitor Element named 'title'
00092   
00093   if (!me) 
00094     {
00095       if (verb) std::cout <<"SORRY, COULD NOT FIND HISTOGRAM NAMED ["<< title.str().c_str()<<"]"<<std::endl;
00096       return NULL; // ME not found
00097     } // if (!me)
00098 
00099   if (verb) 
00100     std::cout << "Found '" << title.str().c_str() << "'" << std::endl;
00101 
00102   std::stringstream clonehisto;
00103   if (clone)
00104     {
00105       clonehisto<<"ME "<<name.c_str();
00106       TH2F *out = dynamic_cast<TH2F*>(me->getTH2F()->Clone(clonehisto.str().c_str()));
00107       return out;
00108     }
00109   else return (me->getTH2F());
00110 }
00111 
00112 
00113 inline TH3F* getTH3F(std::string name, std::string process, std::string rootfolder, DQMStore* dbe_, bool verb, bool clone)
00114 {
00115   if (!dbe_) return NULL;
00116   std::stringstream title;
00117   title <<process.c_str()<<rootfolder.c_str()<<"/"<<name.c_str();
00118 
00119   MonitorElement* me = dbe_->get(title.str().c_str()); // get Monitor Element named 'title'
00120   
00121   if (!me) 
00122     {
00123       if (verb) std::cout <<"SORRY, COULD NOT FIND HISTOGRAM NAMED ["<< title.str().c_str()<<"]"<<std::endl;
00124       return NULL; // ME not found
00125     } // if (!me)
00126 
00127   if (verb) 
00128     std::cout << "Found '" << title.str().c_str() << "'" << std::endl;
00129 
00130   std::stringstream clonehisto;
00131   if (clone)
00132     {
00133       clonehisto<<"ME "<<name.c_str();
00134       TH3F *out = dynamic_cast<TH3F*>(me->getTH3F()->Clone(clonehisto.str().c_str()));
00135       return out;
00136     }
00137   else return (me->getTH3F());
00138 }
00139 
00140 inline TProfile* getTProfile(std::string name, std::string process, std::string rootfolder, DQMStore* dbe_, bool verb, bool clone)
00141 {
00142   if (!dbe_) return NULL;
00143   std::stringstream title;
00144   title <<process.c_str()<<rootfolder.c_str()<<"/"<<name.c_str();
00145 
00146   MonitorElement* me = dbe_->get(title.str().c_str()); // get Monitor Element named 'title'
00147   
00148   if (!me) 
00149     {
00150       if (verb) std::cout <<"SORRY, COULD NOT FIND HISTOGRAM NAMED ["<< title.str().c_str()<<"]"<<std::endl;
00151       return NULL; // ME not found
00152     } // if (!me)
00153 
00154   if (verb) 
00155     std::cout << "Found '" << title.str().c_str() << "'" << std::endl;
00156 
00157   std::stringstream clonehisto;
00158   if (clone)
00159     {
00160       clonehisto<<"ME "<<name.c_str();
00161       TProfile *out = dynamic_cast<TProfile*>(me->getTProfile()->Clone(clonehisto.str().c_str()));
00162       return out;
00163     }
00164   else return (me->getTProfile());
00165 }
00166 
00167 inline TProfile2D* getTProfile2D(std::string name, std::string process, std::string rootfolder, DQMStore* dbe_, bool verb, bool clone)
00168 {
00169   if (!dbe_) return NULL;
00170   std::stringstream title;
00171   title <<process.c_str()<<rootfolder.c_str()<<"/"<<name.c_str();
00172 
00173   MonitorElement* me = dbe_->get(title.str().c_str()); // get Monitor Element named 'title'
00174   
00175   if (!me) 
00176     {
00177       if (verb) std::cout <<"SORRY, COULD NOT FIND HISTOGRAM NAMED ["<< title.str().c_str()<<"]"<<std::endl;
00178       return NULL; // ME not found
00179     } // if (!me)
00180 
00181   if (verb) 
00182     std::cout << "Found '" << title.str().c_str() << "'" << std::endl;
00183 
00184   std::stringstream clonehisto;
00185   if (clone)
00186     {
00187       clonehisto<<"ME "<<name.c_str();
00188       TProfile2D *out = dynamic_cast<TProfile2D*>(me->getTProfile2D()->Clone(clonehisto.str().c_str()));
00189       return out;
00190     }
00191   else return (me->getTProfile2D());
00192 }
00193 
00194 
00195 
00196 template <class myHist>
00197 myHist* getAnyHisto(myHist* hist,
00198                     std::string name, std::string process, DQMStore* dbe_,
00199                     bool verb, bool clone)
00200 {
00201 
00202   // If subsystem folder not specified, assume that it's "Hcal"
00203   myHist* theHist=getAnyHisto(hist, name, process, "Hcal",dbe_, verb, clone);
00204   return theHist;
00205 }
00206 
00207 
00208 template <class myHist>
00209 myHist* getAnyHisto(myHist* hist,
00210                     std::string name, std::string process, std::string rootfolder, DQMStore* dbe_,
00211                     bool verb, bool clone)
00212 {
00213   /* 
00214      Method returns histogram named 'name' from DQMStore dbe_;
00215      'hist' pointer must be declared with 'new' (e.g., new TH2F())
00216      in function call so that the pointer actually points to something.
00217      Otherwise, the call to hist->ClassName() will fail.
00218      We might implement a scale functionality at some later point?
00219   */
00220 
00221   if (!dbe_) return NULL;
00222 
00223   std::stringstream clonehisto;
00224   std::stringstream title;
00225   title <<process.c_str()<<rootfolder.c_str()<<"/"<<name.c_str();
00226   //sprintf(title, "%sHcal/%s",process.c_str(),name.c_str());
00227 
00228   MonitorElement* me = dbe_->get(title.str().c_str()); // get Monitor Element named 'title'
00229   
00230   if (!me) 
00231     {
00232       if (verb) std::cout <<"SORRY, COULD NOT FIND HISTOGRAM NAMED ["<< title.str().c_str()<<"]"<<std::endl;
00233       return NULL; // ME not found
00234     } // if (!me)
00235 
00236   if (verb) 
00237     std::cout << "Found '" << title.str().c_str() << "'" << std::endl;
00238 
00239   if (clone)
00240     clonehisto<<"ME "<<name.c_str(); // set clone histogram name
00241 
00242   /* As of 25 April 2008, there are 5 histogram types associated with 
00243      Monitor Elements (TH1F, TH2F, TH3F, TProfile, and TProfile2D).
00244      Provide a separate getter for each type.  Add others if necessary.
00245   */
00246 
00247   std::string histtype = hist->ClassName();
00248   
00249   // return TH1F from ME
00250   if (histtype=="TH1F")
00251     {
00252       TH1F* out;
00253       if (clone) out = dynamic_cast<TH1F*>(me->getTH1F()->Clone(clonehisto.str().c_str()));
00254       else out = me->getTH1F();
00255       if (verb) std::cout <<"Got histogram!  Max = "<<out->GetMaximum()<<std::endl;
00256       return dynamic_cast<myHist*>(out);
00257     }
00258 
00259   // return TH2F from ME
00260   else if (histtype=="TH2F")
00261     {
00262       TH2F* out;
00263       if (clone) out = dynamic_cast<TH2F*>(me->getTH2F()->Clone(clonehisto.str().c_str()));
00264       else out = me->getTH2F();
00265 
00266       if (verb) std::cout <<"Got histogram!  Max = "<<out->GetMaximum()<<std::endl;
00267       return dynamic_cast<myHist*>(out);
00268     }
00269 
00270   // return TH3F from ME
00271   else if (histtype=="TH3F")
00272     {
00273       TH3F* out;
00274       if (clone) out = dynamic_cast<TH3F*>(me->getTH3F()->Clone(clonehisto.str().c_str()));
00275       else out = me->getTH3F();
00276       return dynamic_cast<myHist*>(out);
00277     }
00278 
00279   // return TProfile from ME
00280   else if (histtype=="TProfile")
00281     {
00282       TProfile* out;
00283       if (clone) out = dynamic_cast<TProfile*>(me->getTProfile()->Clone(clonehisto.str().c_str()));
00284       else out = me->getTProfile();
00285       return dynamic_cast<myHist*>(out);
00286     }
00287 
00288   // return TProfile2D from ME
00289   else if (histtype=="TProfile2D")
00290     {
00291       TProfile2D* out;
00292       if (clone) out = dynamic_cast<TProfile2D*>(me->getTProfile2D()->Clone(clonehisto.str().c_str()));
00293       else out = me->getTProfile2D();
00294       return dynamic_cast<myHist*>(out);
00295     }
00296 
00297   else
00298     {
00299       if (verb) 
00300         {
00301           std::cout <<"Don't know how to access histogram '"<<title;
00302           std::cout<<"' of type '"<<histtype<<"'"<<std::endl;
00303         }
00304       return NULL;
00305     }
00306 
00307   // Should never reach this point
00308   if (verb)
00309     std::cout <<"<HcalHistUtils::getAnyHisto>  YOU SHOULD NEVER SEE THIS MESSAGE!"<<std::endl;
00310   return NULL;
00311 
00312 } // myHist* getAnyHisto(...)
00313 
00314 
00315 
00316 
00317 // MAKE GIF FROM HISTOGRAM IMAGE
00318 template <class myHist>
00319 std::string getAnyIMG(int runNo,myHist* hist, int size, std::string htmlDir,
00320                       const char* xlab, const char* ylab, int debug ) 
00321 {
00322   /* 
00323      Template function draws histogram plot, and saves it as a .gif image.
00324      If size==1, thumbnail image is made.  Otherwise, full-size image is made.
00325   */
00326 
00327   if(hist==NULL)
00328     {
00329       return ""; // no histogram provided
00330     }
00331   
00332   // Grab the histogram's title, and convert it to something more palatable for use as a file name
00333   
00334   // Run cleanString algorithm  -- direct call of cleanString causes a crash 
00335   std::string name = (std::string)hist->GetTitle();
00336   if (debug>9) std::cout <<"NAME = ["<<name<<"]"<<std::endl;
00337   for ( unsigned int i = 0; i < name.size(); ++i ) {
00338     if ( name.substr(i, 6) == " - Run" ){
00339       name.replace(i, name.size()-i, "");
00340     }
00341     if ( name.substr(i, 4) == "_Run" ){
00342       name.replace(i, name.size()-i, "");
00343     }
00344     if ( name.substr(i, 5) == "__Run" ){
00345       name.replace(i, name.size()-i, "");
00346     }
00347 
00348     if (name.substr(i,1) == "(" || name.substr(i,1)==")")
00349       name.replace(i,1,"_");
00350     else if (name.substr(i,1)==",")
00351       name.replace(i,1,"_");
00352     else if (name.substr(i,1)=="<")
00353       name.replace(i,1,"_lt_");
00354     else if (name.substr(i,1)==">")
00355       name.replace(i,1,"_gt_");
00356     else if (name.substr(i,1)=="+")
00357       name.replace(i,1,"_plus_");
00358     else if (name.substr(i,1)=="#")
00359       name.replace(i,1,"");
00360     else if (name.substr(i,1)=="/")
00361       name.replace(i,1,"_div_");
00362   } // for (unsigned int i=0; i< name.size();
00363   //std::cout <<"NEWNAME = ["<<name<<"]"<<std::endl;
00364 
00365   char dest[512]; // stores name of destination .gif file
00366   if(runNo>-1) sprintf(dest,"%s - Run %d",name.c_str(),runNo);
00367   else sprintf(dest,"%s",name.c_str());
00368 
00369   //hist->SetTitle(dest); // no need to change the histogram title itself, right?
00370   std::string title = dest;
00371 
00372   int xwid = 900; 
00373   int ywid =540;
00374 
00375   if(size==1) // thumbnail specified
00376     {
00377       title = title+"_tmb";
00378       xwid = 600; 
00379       ywid = 360;
00380     }
00381 
00382   // run parseString algorithm -- calling it directly causes a crash
00383   for ( unsigned int i = 0; i < title.size(); ++i ) {
00384     if ( title.substr(i, 1) == " " ){
00385       title.replace(i, 1, "_");
00386     }
00387     if ( title.substr(i, 1) == "#" ){
00388       title.replace(i, 1, "N");
00389     }
00390     if ( title.substr(i, 1) == "-" ){
00391       title.replace(i, 1, "_");
00392     }    
00393     if ( title.substr(i, 1) == "&" ){
00394       title.replace(i, 1, "_and_");
00395     }
00396     if ( title.substr(i, 1) == "(" 
00397          || title.substr(i, 1) == ")" 
00398          )  {
00399       title.replace(i, 1, "_");
00400     } 
00401     if ( title.substr(i,1) == "="){
00402       title.replace(i,1,"_");
00403     }
00404   } // for (unsigned int i=0; i < title.size();...)
00405   
00406   std::string outName = title+".gif";
00407   std::string saveName = htmlDir + outName;
00408 
00409 
00410   // Create canvas for histogram
00411   TCanvas* can = new TCanvas(dest,dest, xwid, ywid);
00412   TAxis* xaxis=0;
00413   TAxis* yaxis=0;
00414   TLine* vert=0;
00415   TLine* horiz=0;
00416   hist->SetXTitle(xlab);
00417   hist->SetYTitle(ylab);
00418   std::string histtype=hist->ClassName();
00419   //can->GetFrame()->SetFillColor(21); // change canvas to different default color?   
00420 
00421   // Don't draw stat box for color plots
00422   if (((std::string)hist->GetOption())=="col" || 
00423       ((std::string)hist->GetOption())=="colz")
00424     hist->SetStats(false);
00425 
00426   // Draw with whatever options are set for the particular histogram
00427 
00428   hist->Draw(hist->GetOption());// I think that Draw should automatically use the GetOption() value, but include it here to be sure.
00429 
00430   // Draw Grid Lines
00431 
00432   if (histtype=="TH2F")
00433     {
00434       TAxis *xaxis = hist->GetXaxis();
00435       TAxis *yaxis=hist->GetYaxis();
00436       // Draw vertical lines
00437       //for (int xx=int(UTILS_ETAMIN);xx<=int(UTILS_ETAMAX);++xx)
00438  
00439       
00440         if (xaxis->GetXmax()==UTILS_ETAMAX && xaxis->GetXmin()==UTILS_ETAMIN 
00441          && yaxis->GetXmax()==UTILS_PHIMAX && yaxis->GetXmin()==UTILS_PHIMIN) // ad hoc method for only drawing grids for eta-phi graphs; need to be more clever later?
00442         {
00443           for (int xx=int(xaxis->GetXmin());
00444                xx<=int(xaxis->GetXmax()); ++xx)
00445             {
00446               if (xx<-42 || xx >= 42) continue;
00447               vert = new TLine(xx+0.5,0.5,xx+0.5,72.5);
00448               //if (xx%vertlinespace!=0) continue;
00449               //TLine *vert = new TLine(xx,yaxis->GetXmin(),xx,yaxis->GetXmax());
00450               
00451               vert->SetLineStyle(3);
00452               vert->Draw("same");
00453             }
00454           // Draw horizontal lines
00455           for (int yy=int(yaxis->GetXmin()); yy<int(yaxis->GetXmax());++yy)
00456             {
00457               if (yy%4==0)
00458                 horiz = new TLine(-41.5,yy+0.5,41.5,yy+0.5);
00459               else if (yy%2==0)
00460                 horiz = new TLine(-39.5,yy+0.5,39.5,yy+0.5);
00461               else
00462                 horiz = new TLine(-20.5,yy+0.5,20.5,yy+0.5);
00463               //if (yy%horizlinespace!=0) continue;
00464               //TLine *horiz = new TLine(xaxis->GetXmin(),yy,xaxis->GetXmax(),yy);
00465               horiz->SetLineStyle(3);
00466               horiz->Draw("same");
00467             }
00468         } //if (xaxis->GetXmax()==44)
00469     } // if (histtype=="TH2F")
00470 
00471   can->SaveAs(saveName.c_str());  
00472   delete can;
00473   delete vert;
00474   delete horiz;
00475   delete xaxis;
00476   delete yaxis;
00477 
00478   return outName;
00479 } // std::string getAnyIMG(...)
00480 
00481 
00482 
00483 
00484 // make HTML from histogram
00485 template <class myHist>
00486 void htmlAnyHisto(int runNo, myHist *hist, 
00487                   const char* xlab, const char* ylab, 
00488                   int width, ofstream& htmlFile, 
00489                   std::string htmlDir,
00490                   int debug=0)
00491 {
00492 
00493   /*
00494     Generates html output from any kind of input histogram
00495   */
00496 
00497   if(hist!=NULL)
00498     {    
00499       std::string histtype=hist->ClassName();
00500 
00501       // Set 2D histogram default option to "colz"
00502       if (histtype=="TH2F" && ((std::string)hist->GetOption())=="")
00503         {
00504           hist->SetOption("colz");
00505         }
00506 
00507       // Form full-sized and thumbnail .gifs from histogram
00508       //std::string imgNameTMB = "";   
00509       //std::string imgNameTMB = getAnyIMG(runNo,hist,1,htmlDir,xlab,ylab,debug);
00510       //std::string imgName = "";   
00511       std::string imgName = getAnyIMG(runNo,hist,2,htmlDir,xlab,ylab,debug);
00512       
00513       // Add thumbnail image to html code, linked to full-sized image
00514       if (imgName.size() != 0 )
00515         {
00516           // Always make width = 100% ?
00517           //htmlFile << "<td align=\"center\"><a href=\"" <<  imgName << "\"><img src=\"" <<  imgName << "\" width = \"100%\"></a><br>"<<hist->GetName()<<"</td>" << std::endl;
00518           htmlFile <<"<td align=\"center\"><a href=\"" <<imgName<<"\"><img src=\""<<imgName<<"\" width=600 height=360\"></a><br>"<<hist->GetName()<<"</td>"<<std::endl;
00519 }
00520       else
00521         {
00522           htmlFile << "<td align=\"center\"><img src=\"" << " " << "\"></td>" << std::endl;
00523         }
00524     } // (hist != NULL)
00525 
00526   else  // if no image found, make a blank table entry (maybe improve on this later? -- write an error message?)
00527     {
00528        htmlFile<<"<td align=\"center\"><br><br> Histogram does not exist in ROOT file!<br>Diagnostic flag may be off.<br>(This may be normal in online running.)</td>"<<std::endl;
00529        //htmlFile << "<td><img src=\"" << " " << "\"></td>" << std::endl;
00530     }
00531   return;
00532 } //void htmlAnyHisto(...)
00533 
00534 
00535 
00536 #endif