CMS 3D CMS Logo

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 // Set spacing of dashed lines in 2-D plots
00010 #define UTILS_VERTLINESPACE 5
00011 #define UTILS_HORIZLINESPACE 5
00012 
00013 #include "TROOT.h"
00014 #include "TStyle.h"
00015 #include "TColor.h"
00016 
00017 #include "TH1F.h"
00018 #include "TH2F.h"
00019 #include "TFile.h"
00020 
00021 /******************************************************************************
00022  *
00023  * HcalTestUtils.h
00024  * v1.1
00025  * 4 May 2008
00026  * by Jeff Temple (jtemple AT fnal.gov)
00027  *
00028  *  Various template methods to grab any type of
00029  *  histogram stored as a MonitorElement, and 
00030  *  to return .gif, .html output from the histogram.
00031  *
00032  * Methods:
00033  *
00034  * myHist* getAnyHisto(myHist* hist, std::string name, std::string process, 
00035                          DQMStore* dbe_, bool verb, bool clone)  
00036  *                         
00037  * std::string getAnyIMG(int runNo,myHist* hist, int size, std::string htmlDir,
00038                          const char* xlab, const char* ylab, bool setLogy, bool setLogx) 
00039  *
00040  * void htmlAnyHisto(int runNo, myHist *hist, 
00041                      const char* xlab, const char* ylab, 
00042                      int width, ofstream& htmlFile, 
00043                      std::string htmlDir, bool setLogy, bool setLogx)
00044  
00045  *
00046  *****************************************************************************
00047  */
00048 
00049 #include "DQMServices/Core/interface/DQMStore.h"
00050 
00051 
00052 template <class myHist>
00053 myHist* getAnyHisto(myHist* hist,
00054                     std::string name, std::string process, DQMStore* dbe_,
00055                     bool verb, bool clone)
00056 {
00057   /* 
00058      Method returns histogram named 'name' from DQMStore dbe_;
00059      'hist' pointer must be declared with 'new' (e.g., new TH2F())
00060      in function call so that the pointer actually points to something.
00061      Otherwise, the call to hist->ClassName() will fail.
00062   */
00063 
00064   using std::cout;
00065   using std::endl;
00066 
00067   if (!dbe_) return NULL;
00068 
00069   char title[150];  // title of histogram to grab from dbe
00070   char clonehisto[150];
00071   sprintf(title, "%sHcal/%s",process.c_str(),name.c_str());
00072 
00073   MonitorElement* me = dbe_->get(title); // get Monitor Element named 'title'
00074 
00075   if (!me) 
00076     {
00077       if (verb) cout <<"SORRY, COULD NOT FIND HISTOGRAM NAMED ["<< title<<"]"<<endl;
00078       return NULL; // ME not found
00079     } // if (!me)
00080 
00081   if (verb) 
00082     cout << "Found '" << title << "'" << endl;
00083 
00084   if (clone)
00085     sprintf(clonehisto, "ME %s",name.c_str()); // set clone histogram name
00086 
00087 
00088   /* As of 25 April 2008, there are 5 histogram types associated with 
00089      Monitor Elements (TH1F, TH2F, TH3F, TProfile, and TProfile2D).
00090      Provide a separate getter for each type.  Add others if necessary.
00091   */
00092 
00093   std::string histtype = hist->ClassName();
00094 
00095   // return TH1F from ME
00096   if (histtype=="TH1F")
00097     {
00098       TH1F* out;
00099       if (clone) out = dynamic_cast<TH1F*>(me->getTH1F()->Clone(clonehisto));
00100       else out = me->getTH1F();
00101       return dynamic_cast<myHist*>(out);
00102     }
00103 
00104   // return TH2F from ME
00105   else if (histtype=="TH2F")
00106     {
00107       TH2F* out;
00108       if (clone) out = dynamic_cast<TH2F*>(me->getTH2F()->Clone(clonehisto));
00109       else out = me->getTH2F();
00110   
00111       return dynamic_cast<myHist*>(out);
00112     }
00113 
00114   // return TH3F from ME
00115   else if (histtype=="TH3F")
00116     {
00117       TH3F* out;
00118       if (clone) out = dynamic_cast<TH3F*>(me->getTH3F()->Clone(clonehisto));
00119       else out = me->getTH3F();
00120       return dynamic_cast<myHist*>(out);
00121     }
00122 
00123   // return TProfile from ME
00124   else if (histtype=="TProfile")
00125     {
00126       TProfile* out;
00127       if (clone) out = dynamic_cast<TProfile*>(me->getTProfile()->Clone(clonehisto));
00128       else out = me->getTProfile();
00129       return dynamic_cast<myHist*>(out);
00130     }
00131 
00132   // return TProfile2D from ME
00133   else if (histtype=="TProfile2D")
00134     {
00135       TProfile2D* out;
00136       if (clone) out = dynamic_cast<TProfile2D*>(me->getTProfile2D()->Clone(clonehisto));
00137       else out = me->getTProfile2D();
00138       return dynamic_cast<myHist*>(out);
00139     }
00140 
00141   else
00142     {
00143       if (verb) 
00144         {
00145           cout <<"Don't know how to access histogram '"<<title;
00146           cout<<"' of type '"<<histtype<<"'"<<endl;
00147         }
00148       return NULL;
00149     }
00150 
00151   // Should never reach this point
00152   if (verb)
00153     cout <<"<HcalHistUtils::getAnyHisto>  YOU SHOULD NEVER SEE THIS MESSAGE!"<<endl;
00154   return NULL;
00155 
00156 } // myHist* getAnyHisto(...)
00157 
00158 
00159 
00160 
00161 // MAKE GIF FROM HISTOGRAM IMAGE
00162 template <class myHist>
00163 std::string getAnyIMG(int runNo,myHist* hist, int size, std::string htmlDir,
00164                       const char* xlab, const char* ylab, bool setLogy=0, bool setLogx=0 ) 
00165 {
00166   /* 
00167      Template function draws histogram plot, and saves it as a .gif image.
00168      If size==1, thumbnail image is made.  Otherwise, full-size image is made.
00169   */
00170 
00171   if(hist==NULL)
00172     {
00173       return ""; // no histogram provided
00174     }
00175   
00176   // Grab the histogram's title, and convert it to something more palatable for use as a file name
00177   
00178   // Run cleanString algorithm  -- direct call of cleanString causes a crash 
00179   std::string name = (std::string)hist->GetTitle();
00180   //cout <<"NAME = ["<<name<<"]"<<endl;
00181   for ( unsigned int i = 0; i < name.size(); ++i ) {
00182     if ( name.substr(i, 6) == " - Run" ){
00183       name.replace(i, name.size()-i, "");
00184     }
00185     if ( name.substr(i, 4) == "_Run" ){
00186       name.replace(i, name.size()-i, "");
00187     }
00188     if ( name.substr(i, 5) == "__Run" ){
00189       name.replace(i, name.size()-i, "");
00190     }
00191 
00192     if (name.substr(i,1) == "(" || name.substr(i,1)==")")
00193       name.replace(i,1,"_");
00194     if (name.substr(i,1)==",")
00195       name.replace(i,1,"_");
00196     if (name.substr(i,1)=="<")
00197       name.replace(i,1,"_lt_");
00198     if (name.substr(i,1)==">")
00199       name.replace(i,1,"_gt_");
00200     if (name.substr(i,1)=="+")
00201       name.replace(i,1,"_plus_");
00202     if (name.substr(i,1)=="#")
00203       name.replace(i,1,"");
00204 
00205   } // for (unsigned int i=0; i< name.size();
00206   //cout <<"NEWNAME = ["<<name<<"]"<<endl;
00207 
00208   char dest[512]; // stores name of destination .gif file
00209   if(runNo>-1) sprintf(dest,"%s - Run %d",name.c_str(),runNo);
00210   else sprintf(dest,"%s",name.c_str());
00211 
00212   //hist->SetTitle(dest); // no need to change the histogram title itself, right?
00213   std::string title = dest;
00214 
00215   int xwid = 900; 
00216   int ywid =540;
00217 
00218   if(size==1) // thumbnail specified
00219     {
00220       title = title+"_tmb";
00221       xwid = 600; 
00222       ywid = 360;
00223     }
00224 
00225   // run parseString algorithm -- calling it directly causes a crash
00226   for ( unsigned int i = 0; i < title.size(); ++i ) {
00227     if ( title.substr(i, 1) == " " ){
00228       title.replace(i, 1, "_");
00229     }
00230     if ( title.substr(i, 1) == "#" ){
00231       title.replace(i, 1, "N");
00232     }
00233     if ( title.substr(i, 1) == "-" ){
00234       title.replace(i, 1, "_");
00235     }    
00236     if ( title.substr(i, 1) == "&" ){
00237       title.replace(i, 1, "_and_");
00238     }
00239     if ( title.substr(i, 1) == "(" 
00240          || title.substr(i, 1) == ")" 
00241          )  {
00242       title.replace(i, 1, "_");
00243     } 
00244     if ( title.substr(i,1) == "="){
00245       title.replace(i,1,"_");
00246     }
00247   } // for (unsigned int i=0; i < title.size();...)
00248   
00249   std::string outName = title+".gif";
00250   std::string saveName = htmlDir + outName;
00251 
00252 
00253   // Create canvas for histogram
00254   TCanvas* can = new TCanvas(dest,dest, xwid, ywid);
00255   TAxis* xaxis=0;
00256   TAxis* yaxis=0;
00257   TLine* vert=0;
00258   TLine* horiz=0;
00259   hist->SetXTitle(xlab);
00260   hist->SetYTitle(ylab);
00261   std::string histtype=hist->ClassName();
00262   //can->GetFrame()->SetFillColor(21); // change canvas to different default color?   
00263 
00264   // Don't draw stat box for color plots
00265   if (((std::string)hist->GetOption())=="col" || 
00266       ((std::string)hist->GetOption())=="colz")
00267     hist->SetStats(false);
00268 
00269   // Draw with whatever options are set for the particular histogram
00270 
00271   hist->Draw(hist->GetOption());// I think that Draw should automatically use the GetOption() value, but include it here to be sure.
00272 
00273   // Draw Grid Lines
00274   //int vertlinespace=UTILS_VERTLINESPACE;
00275   //int horizlinespace=UTILS_HORIZLINESPACE;
00276   if (histtype=="TH2F")
00277     {
00278       TAxis *xaxis = hist->GetXaxis();
00279       TAxis *yaxis=hist->GetYaxis();
00280       // Draw vertical lines
00281       //for (int xx=int(UTILS_ETAMIN);xx<=int(UTILS_ETAMAX);++xx)
00282  
00283       
00284         if (xaxis->GetXmax()==UTILS_ETAMAX && xaxis->GetXmin()==UTILS_ETAMIN 
00285          && 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?
00286         {
00287           for (int xx=int(xaxis->GetXmin());
00288                xx<=int(xaxis->GetXmax()); ++xx)
00289             {
00290               if (xx<-42 || xx >= 42) continue;
00291               vert = new TLine(xx+0.5,0.5,xx+0.5,72.5);
00292               //if (xx%vertlinespace!=0) continue;
00293               //TLine *vert = new TLine(xx,yaxis->GetXmin(),xx,yaxis->GetXmax());
00294               
00295               vert->SetLineStyle(3);
00296               vert->Draw("same");
00297             }
00298           // Draw horizontal lines
00299           for (int yy=int(yaxis->GetXmin()); yy<int(yaxis->GetXmax());++yy)
00300             {
00301               if (yy%4==0)
00302                 horiz = new TLine(-41.5,yy+0.5,41.5,yy+0.5);
00303               else if (yy%2==0)
00304                 horiz = new TLine(-39.5,yy+0.5,39.5,yy+0.5);
00305               else
00306                 horiz = new TLine(-20.5,yy+0.5,20.5,yy+0.5);
00307               //if (yy%horizlinespace!=0) continue;
00308               //TLine *horiz = new TLine(xaxis->GetXmin(),yy,xaxis->GetXmax(),yy);
00309               horiz->SetLineStyle(3);
00310               horiz->Draw("same");
00311             }
00312         } //if (xaxis->GetXmax()==44)
00313     } // if (histtype=="TH2F")
00314 
00315   
00316   // SetLogx, SetLogy don't seem to work.  Why not?
00317   if (hist->GetMaximum()>0 && hist->GetMinimum()>0)
00318     {
00319       // Don't bother with this yet until we get something useful working
00320       /*
00321       if (setLogx)
00322         can->SetLogx();
00323       if (setLogy)
00324         can->SetLogy();  
00325       */
00326     }   
00327   can->SaveAs(saveName.c_str());  
00328   delete can;
00329   delete vert;
00330   delete horiz;
00331   delete xaxis;
00332   delete yaxis;
00333 
00334   return outName;
00335 } // std::string getAnyIMG(...)
00336 
00337 
00338 
00339 
00340 // make HTML from histogram
00341 template <class myHist>
00342 void htmlAnyHisto(int runNo, myHist *hist, 
00343                   const char* xlab, const char* ylab, 
00344                   int width, ofstream& htmlFile, 
00345                   std::string htmlDir,
00346                   bool setLogy=0, bool setLogx=0)
00347 {
00348 
00349   /*
00350     Generates html output from any kind of input histogram
00351   */
00352 
00353   using std::cout;
00354   using std::endl;
00355 
00356   if(hist!=NULL)
00357     {    
00358       std::string histtype=hist->ClassName();
00359 
00360       // Set 2D histogram default option to "colz"
00361       if (histtype=="TH2F" && ((std::string)hist->GetOption())=="")
00362         {
00363           hist->SetOption("colz");
00364         }
00365 
00366       // Form full-sized and thumbnail .gifs from histogram
00367       //std::string imgNameTMB = "";   
00368       std::string imgNameTMB = getAnyIMG(runNo,hist,1,htmlDir,xlab,ylab,setLogy, setLogx); 
00369       //std::string imgName = "";   
00370       std::string imgName = getAnyIMG(runNo,hist,2,htmlDir,xlab,ylab, setLogy, setLogx);  
00371       
00372       // Add thumbnail image to html code, linked to full-sized image
00373       if (imgName.size() != 0 )
00374         {
00375         htmlFile << "<td align=\"center\"><a href=\"" <<  imgName << "\"><img src=\"" <<  imgNameTMB << "\"></a></td>" << endl;
00376         }
00377       else
00378         {
00379           htmlFile << "<td aling=\"center\"><img src=\"" << " " << "\"></td>" << endl;
00380         }
00381     } // (hist != NULL)
00382 
00383   else  // if no image found, make a blank table entry (maybe improve on this later? -- write an error message?)
00384     {
00385        htmlFile<<"<td align=\"center\"><br><br> Histogram does not exist in ROOT file!<br>Diagnostic flag may be off.<br>(This is normal in online running.)</td>"<<endl;
00386        //htmlFile << "<td><img src=\"" << " " << "\"></td>" << endl;
00387     }
00388   return;
00389 } //void htmlAnyHisto(...)
00390 
00391 #endif

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