CMS 3D CMS Logo

Plot2D.h

Go to the documentation of this file.
00001 #ifndef PLOT_2D__H
00002 #define PLOT_2D__H
00003 
00004 #include "PlotCompareUtility.h"
00005 #include "Plot1D.h"
00006 #include "PlotTypes.h"
00007 
00008 #include <TProfile.h>
00009 #include <TH1F.h>
00010 #include <TH2F.h>
00011 #include <TGaxis.h>
00012 #include <TLine.h>
00013 
00014 #include <iostream>
00015 #include <fstream>
00016 #include <string>
00017 #include <math.h>
00018 #include <stdio.h>
00019 
00020 template < >
00021 bool PlotCompareUtility::compare<Plot2D>(HistoData *HD) {
00022 
00023   // get the reference and comparison histograms
00024   TH2F *href2d = (TH2F *)HD->getRefHisto();
00025   TH2F *hnew2d = (TH2F *)HD->getNewHisto();
00026 
00027   // do not run comparisons if either histogram is empty/broken
00028   if (hnew2d == NULL || href2d == NULL || hnew2d->GetEntries() <= 1 || href2d->GetEntries() <= 1) {
00029     //std::cerr << HD->getName() << " error: unable to retrieve histogram (or no entries)\n";
00030     HD->setIsEmpty(true); return false;
00031   } 
00032 
00033   // prepare an overall result
00034   bool projectionsPassed = true;
00035 
00036   // loop over axes (projections on one or both may be requested)
00037   for (int axis = axisX; axis <= axisY; ++axis) {
00038 
00039     // for X: verify projections requested and proper Y binning of href2d and hnew2d
00040     if (axis == axisX && !HD->getDoProjectionsX()) continue;
00041     if (axis == axisX && href2d->GetNbinsY() != hnew2d->GetNbinsY()) {
00042       std::cerr << HD->getName() << " error: incorrect number of bins for X projection tests\n";
00043       projectionsPassed = false; continue;
00044     }
00045 
00046     // for Y: verify projections requested and proper X binning of href2d and hnew2d
00047     if (axis == axisY && !HD->getDoProjectionsY()) continue;
00048     if (axis == axisY && href2d->GetNbinsX() != hnew2d->GetNbinsX()) {
00049       std::cerr << HD->getName() << " error: incorrect number of bins for Y projection tests\n";
00050       projectionsPassed = false; continue;
00051     }
00052 
00053     // setup the rebinning variables
00054     int nBins = (axis == axisX) ? href2d->GetNbinsY() : href2d->GetNbinsX();
00055     int nProjections = (axis == axisX) ? HD->getMaxProjectionsX() : HD->getMaxProjectionsY();
00056     int nGroups = (int)ceil(float(nBins) / nProjections);
00057     bool rebinned = false;
00058 
00059     // for X projections: if required rebin a clone of href2d and hnew2d
00060     if (axis == axisX && HD->getDoAllow2DRebinningX() && nGroups > 1) {
00061       href2d = (TH2F *)(((TH2F *)(href2d->Clone()))->RebinY(nGroups));
00062       hnew2d = (TH2F *)(((TH2F *)(hnew2d->Clone()))->RebinY(nGroups));
00063       nBins = href2d->GetNbinsY();
00064       rebinned = true;
00065     }
00066 
00067     // for Y projections: if required rebin a clone of href2d and hnew2d
00068     if (axis == axisY && HD->getDoAllow2DRebinningY() && nGroups > 1) {
00069       href2d = (TH2F *)(((TH2F *)(href2d->Clone()))->RebinX(nGroups));
00070       hnew2d = (TH2F *)(((TH2F *)(hnew2d->Clone()))->RebinX(nGroups));
00071       nBins = href2d->GetNbinsX();
00072       rebinned = true;
00073     }
00074 
00075     // loop over bins in histograms (go backwords to keep in order)
00076     //for (int bin = nBins; bin >= 1; --bin) {
00077     for (int bin = 1; bin <= nBins; ++bin) {
00078 
00079       std::cout << "bin " << bin << " of " << nBins << std::endl;
00080       // create some unique identifiers for the histogram names
00081       TString projName = HD->getName() + (axis == axisX ? "_px" : "_py"); projName += bin;
00082       TString newProjName = "new_"; newProjName += projName;
00083       TString refProjName = "ref_"; refProjName += projName;
00084 
00085       // get the 1d projections for this bin out of the histogram
00086       TH1D *hnew = (axis == axisX) ? hnew2d->ProjectionX(newProjName.Data(),bin,bin) : hnew2d->ProjectionY(newProjName.Data(),bin,bin);
00087       TH1D *href = (axis == axisX) ? href2d->ProjectionX(refProjName.Data(),bin,bin) : href2d->ProjectionY(refProjName.Data(),bin,bin);
00088 
00089       // set histogram axis labels
00090       hnew->GetXaxis()->SetTitle((axis == axisX ? hnew2d->GetXaxis()->GetTitle() : hnew2d->GetYaxis()->GetTitle()));
00091       href->GetXaxis()->SetTitle((axis == axisX ? href2d->GetXaxis()->GetTitle() : href2d->GetYaxis()->GetTitle()));
00092 
00093       // allow Root to delete these histograms after display
00094       hnew->SetBit(kCanDelete);
00095       href->SetBit(kCanDelete);
00096 
00097       // create a new HistoData based on this projection
00098       HistoData *proj = (axis == axisX) ? addProjectionXData(HD,projName.Data(),Plot1D,bin,hnew,href) \
00099         : addProjectionYData(HD,projName.Data(),Plot1D,bin,hnew,href);
00100 
00101       // ignore empty bins
00102       //if (hnew->Integral() == 0 || href->Integral() == 0) continue;
00103       if (hnew->GetEntries() <= 1 || href->GetEntries() <= 1||hnew->Integral() == 0 || href->Integral() == 0) continue;
00104       
00105       // run this new HistoData through compare<Plot1D>
00106       projectionsPassed &= compare<Plot1D>(proj);
00107            
00108       // get the high and low scores from this comparison
00109       float lowScore = proj->getLowScore(); float highScore = proj->getHighScore();
00110       if (lowScore < HD->getLowScore()) HD->setLowScore(lowScore);
00111       if (highScore > HD->getHighScore()) HD->setHighScore(highScore);
00112 
00113     }
00114 
00115     // if 2d histograms were rebinned, delete the clone and re-get the original
00116     if (rebinned) {
00117       delete href2d; href2d = (TH2F *)HD->getRefHisto();
00118       delete hnew2d; hnew2d = (TH2F *)HD->getNewHisto();
00119     }
00120 
00121   }
00122 
00123   // check overall result
00124   HD->setResult(projectionsPassed);
00125   HD->setIsEmpty(false);
00126 
00127   // returns true on test passed and false on test failed
00128   return projectionsPassed;
00129 
00130 }
00131 
00132 template < >
00133 void PlotCompareUtility::makePlots<Plot2D>(HistoData *HD) {
00134 
00135   // do not make any new plot if empty
00136   if (HD->getIsEmpty()) { 
00137     HD->setResultImage("NoData_Results.gif");
00138     HD->setResultTarget("NoData_Results.gif");
00139     return;
00140   }
00141 
00142   // loop over the projections to make 1D plots
00143   std::vector<HistoData>::iterator hd;
00144   for (hd = projectionsX[HD].begin(); hd != projectionsX[HD].end(); hd++) makePlots<Plot1D>(&(*hd));
00145   for (hd = projectionsY[HD].begin(); hd != projectionsY[HD].end(); hd++) makePlots<Plot1D>(&(*hd));
00146 
00147   // make projection summaries
00148   for (int axis = axisX; axis <= axisY; ++axis) {
00149 
00150     // get the list of projections associated with this HistoData
00151     std::vector<HistoData> *proj = (axis == axisX) ? &projectionsX[HD] : &projectionsY[HD];
00152     if (proj == NULL || proj->size() == 0) continue;
00153 
00154     // get the 2d histograms
00155     TH2F *hnew2d = (TH2F *)HD->getNewHisto();
00156     TH2F *href2d = (TH2F *)HD->getRefHisto();
00157 
00158     // generate a reasonable width for the projections summary
00159     int numHistos = proj->size();
00160     int bodyWidth = int(float(numHistos * projectionsBarsThickness) * 1.5);
00161     projectionsWidth = projectionsLeftMargin + projectionsRightMargin + bodyWidth;
00162 
00163     // the canvas is rescaled during gif conversion, so add padding to Canvas dimensions
00164     int projectionsCanvasWidth = projectionsWidth + 4;
00165     int projectionsCanvasHeight = projectionsHeight + 28;
00166 
00167     // create and setup projections canvas
00168     TCanvas projectionsCanvas("projectionsCanvas","projectionsCanvas",projectionsCanvasWidth,projectionsCanvasHeight);
00169     projectionsCanvas.SetFrameFillColor(10);
00170     projectionsCanvas.SetLogy(1);
00171     projectionsCanvas.SetTopMargin(float(projectionsTopMargin) / projectionsHeight);
00172     projectionsCanvas.SetLeftMargin(float(projectionsLeftMargin) / projectionsWidth);
00173     projectionsCanvas.SetRightMargin(float(projectionsRightMargin) / projectionsWidth);
00174     projectionsCanvas.SetBottomMargin(float(projectionsBottomMargin) / projectionsHeight);
00175     projectionsCanvas.Draw();
00176 
00177     // create and setup the summary histogram
00178     TH1F projectionsSummary("projectionsSummary","Compatibility with Reference Histograms",numHistos,1,numHistos+1);
00179     projectionsSummary.GetYaxis()->SetRangeUser(getThreshold()/10,2);
00180     projectionsSummary.SetStats(0);
00181 
00182     // display histogram (take axis from original histogram)
00183     projectionsSummary.Draw("AH");
00184 
00185     // draw X axis
00186     float xMin = hnew2d->GetXaxis()->GetXmin();
00187     float xMax = hnew2d->GetXaxis()->GetXmax();
00188     int ticksNDiv = numHistos * 20 + bodyWidth / 50;//formerly *20
00189     TGaxis *xAxis = new TGaxis(1,0,numHistos + 1,0,xMin,xMax,ticksNDiv,"");
00190     if (axis == axisX) xAxis->SetTitle(hnew2d->GetYaxis()->GetTitle());
00191     if (axis == axisY) xAxis->SetTitle(hnew2d->GetXaxis()->GetTitle());
00192     xAxis->Draw();
00193 
00194     // draw Y axis
00195     float yMin = getThreshold()/10;
00196     float yMax = 2;
00197     TGaxis *yAxis = new TGaxis(1,yMin,1,yMax,yMin,yMax,510,"G");
00198     yAxis->SetTitle("Compatibility");
00199     yAxis->Draw();
00200 
00201     // loop over projections and draw result
00202     std::vector<HistoData>::iterator pd;
00203     for (pd = proj->begin(); pd != proj->end(); pd++)
00204       pd->drawResult(&projectionsSummary,true,false);
00205 
00206     // draw the pass/fail cutoff line
00207     TLine passLine(1, getThreshold(), numHistos + 1, getThreshold());
00208     passLine.SetLineColor(kRed);
00209     passLine.SetLineWidth(2);
00210     passLine.SetLineStyle(2);
00211     passLine.Draw("SAME");
00212 
00213     // create the summary image
00214     std::string gifName = HD->getName() + (axis == axisX ? "_Results_px.gif" : "_Results_py.gif");
00215     projectionsCanvas.Print(gifName.c_str());
00216 
00217     // make overall projection plot of the original 2d histogram
00218     std::string projName = HD->getName() + (axis == axisX ? "_py" : "_px");
00219     std::string newBinsProj = projName + "_new";
00220     std::string refBinsProj = projName + "_ref";
00221     TH1D *href = (axis == axisX) ? href2d->ProjectionY(refBinsProj.c_str()) : href2d->ProjectionX(refBinsProj.c_str());
00222     TH1D *hnew = (axis == axisX) ? hnew2d->ProjectionY(newBinsProj.c_str()) : hnew2d->ProjectionX(newBinsProj.c_str());
00223 
00224     // allow Root to delete these histograms after display
00225     href->SetBit(kCanDelete);
00226     hnew->SetBit(kCanDelete);
00227 
00228     // create a new HistoData based on this projection and plot it
00229     HistoData allBins(projName,Plot1D,0,hnew,href);
00230     allBins.setIsEmpty(false);
00231     allBins.setShadedFillColor(HD->getShadedFillColor());
00232     allBins.setShadedFillStyle(HD->getShadedFillStyle());
00233     allBins.setShadedLineColor(HD->getShadedLineColor());
00234     makePlots<Plot1D>(&allBins);
00235 
00236     // set the default image (axisY takes priority by default)
00237     if (HD->getResultImage() == "" || axis == axisY) HD->setResultImage(projName + "_Results.gif");
00238 
00239     // set the default target (in case additional HTML code is/was not produced)
00240     std::string currentTarget = HD->getResultTarget();
00241     std::string xImgTarget = HD->getName() + "_px_Results.gif";
00242     if (currentTarget == "" || (axis == axisY && currentTarget == xImgTarget)) HD->setResultTarget(projName + "_Results.gif");
00243 
00244   }
00245 
00246   /*
00247   // make overall profile plot of the original 2d histogram
00248   for (int axis = axisX; axis <= axisY; ++axis) {
00249 
00250     // make profile plots out of original 2D histograms
00251     TProfile *pref = (axis == axisX) ? ((TH2F *)HD->getRefHisto())->ProfileY() : ((TH2F *)HD->getRefHisto())->ProfileX();
00252     TProfile *pnew = (axis == axisX) ? ((TH2F *)HD->getNewHisto())->ProfileY() : ((TH2F *)HD->getNewHisto())->ProfileX();
00253 
00254     // renormalize results for display
00255         renormalize(pref,pnew);
00256 
00257     // do not allow Root to deallocate this memory after drawing (tries to free twice?)
00258     pref->SetBit(kCanDelete);
00259     pnew->SetBit(kCanDelete);
00260 
00261     // set drawing options on the reference histogram
00262     pref->SetStats(0);
00263     pref->SetLineColor(kBlack);
00264     pref->SetMarkerColor(kBlack);
00265 
00266     // set drawing options on the new histogram
00267     pnew->SetStats(0);
00268     pnew->SetLineColor(HD->getSolidLineColor());
00269 
00270     // place the test results as the title
00271     TString title = HD->getName();
00272 
00273     // the canvas is rescaled during gif conversion, so add padding to Canvas dimensions
00274     int plotsCanvasWidth = plotsWidth + 4;
00275     int plotsCanvasHeight = plotsHeight + 28;
00276 
00277     // setup canvas for displaying the compared histograms
00278     TCanvas hCanvas("hCanvas",title.Data(),plotsCanvasWidth,plotsCanvasHeight);
00279     hCanvas.SetTopMargin(float(plotsTopMargin) / plotsHeight);
00280     hCanvas.SetLeftMargin(float(plotsLeftMargin) / plotsWidth);
00281     hCanvas.SetRightMargin(float(plotsRightMargin) / plotsWidth);
00282     hCanvas.SetBottomMargin(float(plotsBottomMargin) / plotsHeight);
00283     hCanvas.SetFrameFillColor(10);
00284     hCanvas.SetGrid();
00285     //hCanvas.SetLogy(1);
00286     hCanvas.Draw();
00287 
00288     // draw the profiles
00289     pref->Draw();
00290     pnew->Draw("SAME");
00291     if (HD->getDoDrawErrorBars()) pnew->Draw("E1SAME");
00292  
00293     // draw a legend
00294     TLegend legend(0.15,0.01,0.3, 0.08);
00295     legend.AddEntry(pnew,"New","lF");
00296     legend.AddEntry(pref,"Reference","lF");
00297     legend.SetFillColor(kNone);
00298     legend.Draw("SAME");
00299 
00300     // create the plots overlay image
00301     std::string gifName = HD->getName() + (axis == axisX ? "_pfx.gif" : "_pfy.gif");
00302     hCanvas.Print(gifName.c_str());
00303 
00304     // set the default image (axisY takes priority by default)
00305     if (HD->getResultImage() == "" || axis == axisY) HD->setResultImage(gifName);
00306 
00307     // set the default target (in case additional HTML code is/was not produced)
00308     std::string currentTarget = HD->getResultTarget();
00309     std::string xImgTarget = HD->getName() + "_pfx.gif";
00310     if (currentTarget == "" || (axis == axisY && currentTarget == xImgTarget)) HD->setResultTarget(gifName);
00311 
00312   }
00313   */
00314 
00315 
00316 }
00317 
00318 template < >
00319 void PlotCompareUtility::makeHTML<Plot2D>(HistoData *HD) {
00320 
00321   /* at present, makeHTML<Plot1D> does nothing, so don't waste the CPU cycles
00322   // loop over projections and produce HTML
00323   std::vector<HistoData>::iterator hd;
00324   for (hd = projectionsX[HD].begin(); hd != projectionsX[HD].end(); hd++) makePlots<Plot1D>(&(*hd));
00325   for (hd = projectionsY[HD].begin(); hd != projectionsY[HD].end(); hd++) makePlots<Plot1D>(&(*hd));
00326   */
00327 
00328   // get the HistoData name for later reuse
00329   std::string Name = HD->getName();
00330 
00331   // loop over the axes to see if projections were produced
00332   bool pfDone[2] = { false, false };
00333   for (int axis = axisX; axis <= axisY; axis++) {
00334 
00335     // get the list of projections associated with this HistoData
00336     std::vector<HistoData> *proj = (axis == axisX) ? &projectionsX[HD] : &projectionsY[HD];
00337     if (proj == NULL || proj->size() == 0) continue; else pfDone[axis] = true;
00338 
00339     // setup some names, etc. for insertion into the HTML
00340     std::string gifNameProjections = Name + (axis == axisX ? "_Results_px.gif" : "_Results_py.gif");
00341     std::string gifNameAllProj = Name + (axis == axisX ? "_py_Results.gif" : "_px_Results.gif");
00342     std::string gifNameProfile = Name + (axis == axisX ? "_pfx.gif" : "_pfy.gif");
00343     std::string gifBinPrefix = Name + (axis == axisX ? "_px" : "_py");
00344 
00345     // setup some locations to put thumbnails, etc.
00346     int offset = 10;
00347     int thumbWidth = plotsWidth / 4;
00348     int thumbHeight = plotsHeight / 4;
00349     int bodyWidth = projectionsWidth - projectionsLeftMargin - projectionsRightMargin;
00350     int leftThumbPos = offset + projectionsLeftMargin + bodyWidth / 4 - thumbWidth / 2;
00351     int rightThumbPos = leftThumbPos + bodyWidth / 2;
00352     int thumbsLoc = projectionsTopMargin + thumbHeight / 2;
00353 
00354     // create the profile's HTML document
00355     std::string htmlNameProfile = Name + (axis == axisX ? "_Results_px.html" : "_Results_py.html");
00356     std::ofstream fout(htmlNameProfile.c_str());
00357 
00358     // print top portion of document
00359     fout << "<!DOCTYPE gif PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>" << std::endl
00360          << "<html>" << std::endl
00361          << "  <head>" << std::endl
00362          << "    <title>Compatibility of Projections for " << HD->getRefHisto()->GetTitle() << "</title>" << std::endl
00363          << "    <script type='text/javascript'>" << std::endl << std::endl
00364          << "      function tn(target,image,class) {" << std::endl
00365          << "        clear()" << std::endl
00366          << "        document.getElementById('thumb_div').setAttribute('class',class)" << std::endl
00367          << "        document.getElementById('thumb_div').setAttribute('className',class)" << std::endl
00368          << "        document.getElementById('thumb_link').href = target" << std::endl
00369          << "        document.getElementById('thumb_img').src = image" << std::endl
00370          << "        document.getElementById('thumb_img').width = '" << thumbWidth << "'" << std::endl
00371          << "        document.getElementById('thumb_img').height = '" <<  thumbHeight << "'" << std::endl
00372          << "        document.getElementById('thumb_img').border = '1'" << std::endl
00373          << "      }" << std::endl << std::endl
00374          << "      function clear() {" << std::endl
00375          << "        document.getElementById('thumb_link').href = '#'" << std::endl
00376          << "        document.getElementById('thumb_img').src = ''" << std::endl
00377          << "        document.getElementById('thumb_img').width = '0'" << std::endl
00378          << "        document.getElementById('thumb_img').height = '0'" << std::endl
00379          << "        document.getElementById('thumb_img').border = '0'" << std::endl
00380          << "      }" << std::endl << std::endl
00381          << "    </script>" << std::endl
00382          << "  </head>" << std::endl
00383          << "  <body onClick=\"window.location.href='index.html'\">" << std::endl
00384       //         << "<a href='index.html'>"
00385          << "    <style type='text/css'>" << std::endl
00386          << "      #thumb_div {}" << std::endl
00387          << "      div.thumb_left {position: absolute; left: " << leftThumbPos << "px; top: " << thumbsLoc << "px;}" << std::endl
00388          << "      div.thumb_right {position: absolute; left: " << rightThumbPos << "px; top: " << thumbsLoc << "px;}" << std::endl
00389                                  << "      #main_d {position: absolute; left: " << offset << "px;}" << std::endl
00390          << "      a:link {color: #000000}" << std::endl
00391          << "      a:visited {color: #000000}" << std::endl
00392          << "      a:hover {color: #000000}" << std::endl
00393          << "      a:active {color: #000000}" << std::endl
00394          << "    </style>" << std::endl
00395          << "    <div id='main_d'>" << std::endl
00396       // << " <p>" <<   HD->getRefHisto()->GetTitle() << "</p>"  //include the Title of the Plot as a title of the page
00397          << "      <img src='" << gifNameProjections << "' usemap='#results' alt=''"
00398          << " height=" << projectionsHeight << " width=" << projectionsWidth << " border=0>" << std::endl
00399          << "      <map id='#results' name='results' onMouseOut=\"clear()\">" << std::endl;
00400 
00401     // loop over projections
00402     std::vector<HistoData>::iterator pd;
00403     for (pd = proj->begin(); pd != proj->end(); pd++) {
00404 
00405       // determine map coordinates for this bin (1 pixel offset due to borders?)
00406       int bin = pd->getBin();
00407       int x1 = projectionsLeftMargin + int(float(bin * 1.5 - 1.25) * projectionsBarsThickness);
00408       int x2 = x1 + projectionsBarsThickness;
00409       int y1 = projectionsTopMargin + 1;
00410       int y2 = projectionsHeight - projectionsBottomMargin;
00411       std::string image = pd->getResultImage();
00412       std::string target = pd->getResultTarget();
00413 
00414       // add coordinates area to image map
00415       std::string tnClass = (bin - 1 >= float(proj->size()) / 2 ? "thumb_left" : "thumb_right");
00416       fout << "        <area shape='rect' alt='' coords='" << x1 << "," << y1 << "," << x2 << "," << y2 << "'"
00417            << " href='" << target << "' onMouseOver=\"tn('" << target << "','" << image << "','" << tnClass
00418            << "')\" "
00419            << "onMouseDown=\"window.location.href='" << target << "'\">" << std::endl;
00420 
00421     }
00422 
00423     fout << "        <area shape='default' nohref='nohref' onMouseDown='window.location.reload()' alt=''>" << std::endl
00424          << "      </map>" << std::endl
00425          << "      <br><img src=\"" << gifNameAllProj << "\">" << std::endl
00426          << "    </div>" << std::endl
00427          << "    <div id='thumb_div'><a href='#' id='thumb_link'><img src='' id='thumb_img' width=0 height=0 border=0></a></div>" << std::endl
00428       //         << " </a>"
00429          << "  </body>" << std::endl
00430          << "</html>" << std::endl;
00431 
00432     // close the file
00433     HD->setResultTarget(htmlNameProfile);
00434     fout.close();
00435 
00436   }
00437 
00438   // if both profile dimensions were filled, we need an additional HTML document
00439   if (pfDone[axisX] && pfDone[axisY]) {
00440   
00441     // create HTML support code for this HistoData
00442     std::string html = Name + "_Results_Profiles.html";
00443     std::ofstream fout(html.c_str());
00444 
00445     // make a simple frames portal to show both profile
00446     fout << "<html>" << std::endl
00447          << "  <frameset rows=\"50%,50%\">" << std::endl
00448          << "    <frame src=\"" << Name << "_Results_py.html\">" << std::endl
00449          << "    <frame src=\"" << Name << "_Results_px.html\">" << std::endl
00450          << "    <noframes><body>" << std::endl
00451          << "      unable to display frames -- click to select desired page" << std::endl
00452          << "      <br><a href =\"" << Name << "_Results_py.html\">Y Projections</a>" << std::endl
00453          << "      <br><a href =\"" << Name << "_Results_px.html\">X Projections</a>" << std::endl
00454          << "    </body></noframes>" << std::endl
00455          << "  </frameset>" << std::endl
00456          << "</html>" << std::endl;
00457 
00458     // close the file
00459     HD->setResultTarget(html);
00460     fout.close();
00461 
00462   }
00463 
00464 }
00465 
00466 #endif // PLOT_2D__H

Generated on Tue Jun 9 17:49:36 2009 for CMSSW by  doxygen 1.5.4