CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DQM/TrigXMonitorClient/src/HLTScalersClient.cc

Go to the documentation of this file.
00001 // $Id: HLTScalersClient.cc,v 1.19 2010/07/20 02:58:27 wmtan Exp $
00002 // 
00003 // $Log: HLTScalersClient.cc,v $
00004 // Revision 1.19  2010/07/20 02:58:27  wmtan
00005 // Add missing #include files
00006 //
00007 // Revision 1.18  2010/04/02 20:48:12  wittich
00008 // updates to scale entries by received number of FU's
00009 //
00010 // Revision 1.17  2010/03/17 20:56:19  wittich
00011 // Check for good updates based on mergeCount values
00012 // add code for rates normalized per FU
00013 //
00014 // Revision 1.16  2010/03/16 22:19:19  wittich
00015 // updates for per-LS normalization for variable
00016 // number of FU's sending information back to the clients.
00017 //
00018 // Revision 1.15  2010/02/11 23:55:18  wittich
00019 // - adapt to shorter Lumi Section length
00020 // - fix bug in how history of counts was filled
00021 //
00022 // Revision 1.14  2010/02/02 11:44:20  wittich
00023 // more diagnostics for online scalers
00024 //
00025 // Revision 1.13  2009/12/15 20:41:16  wittich
00026 // better hlt scalers client
00027 //
00028 // Revision 1.12  2009/11/22 13:33:05  puigh
00029 // clean beginJob
00030 //
00031 // Revision 1.11  2009/11/07 03:35:05  lorenzo
00032 // fixed binning
00033 //
00034 // Revision 1.10  2009/11/04 06:00:05  lorenzo
00035 // changed folders
00036 //
00037 
00039 
00040 #include <cassert>
00041 #include <numeric>
00042 
00043 #include "DQM/TrigXMonitorClient/interface/HLTScalersClient.h"
00044 
00045 #include "FWCore/ServiceRegistry/interface/Service.h"
00046 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00047 #include "FWCore/Framework/interface/LuminosityBlock.h"
00048 #include "FWCore/Framework/interface/Event.h"
00049 #include "FWCore/Framework/interface/Run.h"
00050 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00051 
00052 
00053 #include "DQMServices/Core/interface/DQMStore.h"
00054 #include "DQMServices/Core/interface/MonitorElement.h"
00055 
00056 
00057 using edm::LogInfo;
00058 using edm::LogWarning;
00059 
00060 // I am not sure this is right at more than 10%
00061 #define SECS_PER_LUMI_SECTION 23.31
00062 const int kPerHisto = 20;
00063 
00064 
00065 
00066 
00068 HLTScalersClient::HLTScalersClient(const edm::ParameterSet& ps):
00069   dbe_(0),
00070   nLumi_(0),
00071   currentRate_(0),
00072   currentLumiBlockNumber_(0),
00073   first_(true), missingPathNames_(true),
00074   folderName_(ps.getUntrackedParameter<std::string>("dqmFolder", 
00075                                                     "HLT/HLScalers_EvF")),
00076   kRateIntegWindow_(ps.getUntrackedParameter<unsigned int>("rateIntegWindow", 
00077                                                            3)),
00078   processName_(ps.getParameter<std::string>("processName")),
00079   ignores_(),
00080   debug_(ps.getUntrackedParameter<bool>("debugDump", false)),
00081   maxFU_(ps.getUntrackedParameter<unsigned int>("maxFU", false)),
00082   recentOverallCountsPerLS_(kRateIntegWindow_),
00083   recentNormedOverallCountsPerLS_(2)
00084 {
00085   LogDebug("HLTScalersClient") << "constructor" ;
00086   if ( debug_ ) {
00087     textfile_.open("debug.txt");
00088     if ( ! textfile_ ) {
00089       std::cout << "constructor: can't open text file" << std::endl;
00090     }
00091   }
00092   // get back-end interface
00093   dbe_ = edm::Service<DQMStore>().operator->();
00094   dbe_->setVerbose(1);
00095   dbe_->setCurrentFolder(folderName_);
00096 
00097 
00098   std::string rawdir(folderName_ + "/raw");
00099   dbe_->setCurrentFolder(rawdir);
00100   hltRate_ = dbe_->book1D("hltRate", "Overall HLT Accept rate vs LS", 
00101                           MAX_LUMI_SEG_HLT, -0.5, MAX_LUMI_SEG_HLT-0.5);
00102   dbe_->setCurrentFolder(folderName_);
00103   hltNormRate_ = dbe_->book1D("hltRateNorm", 
00104                               "Overall HLT Accept rate vs LS, scaled", 
00105                               MAX_LUMI_SEG_HLT, -0.5, MAX_LUMI_SEG_HLT-0.5);
00106   hltCount_= dbe_->book1D("hltCount", "Overall HLT Counts vs LS", 
00107                           MAX_LUMI_SEG_HLT, -0.5, MAX_LUMI_SEG_HLT-0.5);
00108 //   hltCountN_= dbe_->book1D("hltCountN", "Overall HLT Counts per LS vs LS", 
00109 //                        MAX_LUMI_SEG_HLT, -0.5, MAX_LUMI_SEG_HLT-0.5);
00110   mergeCount_= dbe_->book1D("mergeCount", "Number of merge counts vs LS", 
00111                             MAX_LUMI_SEG_HLT, -0.5, MAX_LUMI_SEG_HLT-0.5);
00112 
00113 
00114 
00115   updates_ = dbe_->book1D("updates", "Status of Updates", 2, 0, 2);
00116   updates_->setBinLabel(1, "Good Updates");
00117   updates_->setBinLabel(2, "Incomplete Updates");
00118 
00119 
00120 } // end constructor
00121 
00122 
00124 void HLTScalersClient::beginJob(void)
00125 {
00126   LogDebug("HLTScalersClient") << "beingJob" ;
00127   if (dbe_) {
00128     dbe_->setCurrentFolder(folderName_);
00129   }
00130   first_ = true;
00131   missingPathNames_ = true;
00132 }
00133 
00134 
00136 void HLTScalersClient::beginRun(const edm::Run& run, const edm::EventSetup& c)
00137 {
00138   missingPathNames_ = true;
00139   first_ = true;
00140   LogDebug("HLTScalersClient") << "beginRun, run " << run.id();
00141 
00142 } // beginRun
00143 
00145 void HLTScalersClient::endRun(const edm::Run& run, const edm::EventSetup& c)
00146 {
00147   missingPathNames_ = true;
00148   first_ = true;
00149 }
00150 
00151 
00154 void HLTScalersClient::endLuminosityBlock(const edm::LuminosityBlock& lumiSeg, 
00155                         const edm::EventSetup& c)
00156 {
00157   nLumi_ = lumiSeg.id().luminosityBlock();
00158   // PWDEBUG
00159   if ( first_ && debug_)
00160     dbe_->showDirStructure();
00161   // PWDEBUG END
00162 
00163   // get raw data
00164   std::string scalHisto = folderName_ + "/raw/hltScalers";
00165   MonitorElement *scalers = dbe_->get(scalHisto);
00166   if ( scalers == 0 ) {
00167     LogDebug("HLTScalersClient") << "cannot get hlt scalers histogram, "
00168                                  << "bailing out.";
00169     if ( debug_ )
00170       std::cout << "No scalers ? Looking for " 
00171                 << scalHisto
00172                 << std::endl;
00173     return;
00174   }
00175 
00176 
00177   int npaths = scalers->getNbinsX();
00178   if ( npaths > MAX_PATHS ) npaths = MAX_PATHS; // HARD CODE FOR NOW
00179   LogDebug("HLTScalersClient") << "I see " << npaths << " paths. ";
00180 
00181   // set the bin labels on the first go-through
00182   // I need to do this here because we don't have the paths yet
00183   // on begin-run. I should do this in a less ugly way (see FV?)
00184   if ( first_) {
00185     std::string rawdir(folderName_ + "/raw");
00186 
00187     LogDebug("HLTScalersClient") << "Setting up paths on first endLumiBlock "
00188                                  << npaths;
00189     dbe_->setCurrentFolder(rawdir);
00190     currentRate_ = dbe_->book1D("cur_rate", 
00191                                 "current lumi section rate per path",
00192                                 npaths, -0.5, npaths-0.5);
00193     currentNormRate_ = dbe_->book1D("cur_rate_norm", 
00194                                     "current norm. lumi section rate per path",
00195                                     npaths, -0.5, npaths-0.5);
00196     recentPathCountsPerLS_.reserve(npaths);
00197     recentNormedPathCountsPerLS_.reserve(npaths);
00198     char rates_subfolder[256]; snprintf(rates_subfolder, 256, "%s/RateHistory",
00199                                         folderName_.c_str());
00200     char counts_subfolder[256]; snprintf(counts_subfolder, 256, 
00201                                          "%s/CountHistory", 
00202                                          folderName_.c_str());
00203 
00204     hltCurrentRate_.    reserve(npaths);
00205     rateHistories_.     reserve(npaths);
00206     countHistories_.    reserve(npaths);
00207     hltCurrentNormRate_.reserve(npaths);
00208     rateNormHistories_. reserve(npaths);
00209 
00210     dbe_->setCurrentFolder(folderName_); // these belong in top-level
00211     for (int i = 0; i < npaths; ++i ) {
00212       dbe_->setCurrentFolder(std::string(rates_subfolder)+"/raw");
00213 
00214       char name[256]; snprintf(name, 256, "raw_rate_p%03d", i);
00215       //     LogDebug("HLTScalersClient") << "name " << i << " is " << name ;
00216       rateHistories_.push_back(dbe_->book1D(name, name, MAX_LUMI_SEG_HLT, 
00217                                             -0.5, MAX_LUMI_SEG_HLT-0.5));
00218       snprintf(name, 256, "norm_rate_p%03d", i);
00219       dbe_->setCurrentFolder(rates_subfolder);
00220       rateNormHistories_.push_back(dbe_->book1D(name, name, MAX_LUMI_SEG_HLT, 
00221                                                 -0.5, MAX_LUMI_SEG_HLT-0.5));
00222       dbe_->setCurrentFolder(counts_subfolder);
00223       snprintf(name, 256, "counts_p%03d", i);
00224       countHistories_.push_back(dbe_->book1D(name, name, MAX_LUMI_SEG_HLT, 
00225                                              -0.5, MAX_LUMI_SEG_HLT-0.5));
00226       // prefill the data structures
00227       recentPathCountsPerLS_.push_back(CountLSFifo_t(kRateIntegWindow_));
00228       recentNormedPathCountsPerLS_.push_back(CountLSFifo_t(2));
00229     }
00230     dbe_->setCurrentFolder(folderName_);
00231 
00232 
00233     // split hlt scalers up into groups of 20
00234     const int maxlen = 40;
00235     char metitle[maxlen]; //histo name
00236     char mename[maxlen]; //ME name
00237     int numHistos = int(npaths/kPerHisto); // this hasta be w/o remainders
00238     
00239     int remainder = npaths%kPerHisto; 
00240     if ( remainder ) numHistos += 1;
00241 
00242     for( int k = 0; k < numHistos; k++ ) {
00243       int npath_low = kPerHisto*k;
00244       int npath_high = kPerHisto*(k+1)-1;
00245       snprintf(mename, maxlen, "hltScalers_%0d", k);
00246       snprintf(metitle, maxlen, "HLT scalers - Paths %d to %d", npath_low, 
00247                npath_high);
00248       dbe_->setCurrentFolder(rawdir);
00249       hltCurrentRate_.push_back(dbe_->book1D(mename, metitle, kPerHisto, 
00250                                              -0.5 + npath_low, npath_high+0.5));
00251       dbe_->setCurrentFolder(folderName_); // these belong in top-level
00252       snprintf(mename, maxlen, "hltScalersNorm_%0d", k);
00253       snprintf(metitle, maxlen, 
00254                "HLT Rate (scaled) - Paths %d to %d", npath_low, npath_high);
00255       hltCurrentNormRate_.push_back(dbe_->book1D(mename, metitle, kPerHisto, 
00256                                                  -0.5 + npath_low, 
00257                                                  npath_high+0.5));
00258     }
00259 
00260     first_ = false;
00261 
00262 
00263 
00264   }
00265 
00266   if ( missingPathNames_) {
00267     // first try the scalers histogram and see if the bin names are set
00268     for ( int i = 0; i < npaths; ++i ) {
00269       // needs to be i+1 since root bins start at 1
00270       const char* name = scalers->getTH1()->GetXaxis()->GetBinLabel(i+1);
00271       if ( name && (strlen(name) > 0)) {
00272         if ( debug_ ) {
00273           std::cout << "path " << i << " name is " << name << std::endl;
00274         }
00275         int whichHisto = i/kPerHisto;
00276         int whichBin = i%kPerHisto + 1;
00277         char pname[256];
00278         hltCurrentRate_[whichHisto]->setBinLabel(whichBin, name);
00279         hltCurrentNormRate_[whichHisto]->setBinLabel(whichBin, name);
00280         snprintf(pname, 256, "Rate - path %s (Path # %03d)", name, i);
00281         rateHistories_[i] ->setTitle(pname);
00282         rateNormHistories_[i]->setTitle(pname);
00283         snprintf(pname, 256, "Counts - path %s (Path # %03d)", name, i);
00284         countHistories_[i]->setTitle(pname);
00285 
00286         currentRate_->setBinLabel(i+1, name);
00287         currentNormRate_->setBinLabel(i+1, name);
00288 
00289         missingPathNames_ = false;
00290       }
00291     }
00292 
00293   }
00294   // MEGA-HACK
00295   if ( missingPathNames_) {
00296     // if that didn't work we load 'em from a text file. damn straight.
00297     int ipath = 1;
00298     std::ifstream names("names.dat");
00299     if ( ! names ) {
00300       if ( debug_ )  {
00301         std::ostringstream msg;
00302         msg << "open of " << "names.dat";
00303         perror(msg.str().c_str());
00304       }
00305     } 
00306     else { // open succeeded
00307       missingPathNames_ = false;
00308       std::string line;
00309       while ( ! names.eof() ) {
00310         getline(names, line);
00311         std::istringstream fnames(line);
00312         std::string label; int bin;
00313         if ( fnames.str().find("#") == 0 )  // skip comment lines
00314           continue;
00315         if ( fnames >> bin >> label  ) {
00316           if ( debug_ ) {
00317             std::cout << bin << "--" << label << "(" << ipath << ")"
00318                       << std::endl;
00319           }
00320           currentRate_->setBinLabel(ipath, label);
00321           currentNormRate_->setBinLabel(ipath, label);
00322           countHistories_[ipath-1]->setTitle(label);
00323           rateHistories_[ipath-1]->setTitle(label);
00324           rateNormHistories_[ipath-1]->setTitle(label);
00325           int whichHisto = (ipath-1)/kPerHisto;
00326           int whichBin = (ipath-1)%kPerHisto +1;
00327           hltCurrentRate_[whichHisto]->setBinLabel(whichBin, label);
00328           hltCurrentNormRate_[whichHisto]->setBinLabel(whichBin, label);
00329           ++ipath;
00330           if ( ipath > npaths )
00331             break;
00332         } //
00333       } // loop lines
00334     } // open ok
00335   }
00336 
00337 
00338   // END SETUP
00339 
00340   std::string nLumiHisto(folderName_ + "/nLumiBlock");
00341   MonitorElement *nLumi = dbe_->get(nLumiHisto);
00342   if ( nLumi == 0 ) {
00343     nLumiHisto = folderName_ + "/raw/nLumiBlock";
00344     nLumi = dbe_->get(nLumiHisto);
00345   }
00346   int testval = (nLumi!=0?nLumi->getIntValue():-1);
00347   LogDebug("HLTScalersClient") << "Lumi Block from DQM: "
00348                         << testval
00349                         << ", local is " << nLumi_;
00350   int nL = (nLumi!=0?nLumi->getIntValue():nLumi_);
00351   if ( nL > MAX_LUMI_SEG_HLT ) {
00352     LogDebug("HLTScalersClient") << "Too many Lumi segments, "
00353                                  << nL << " is greater than MAX_LUMI_SEG_HLT,"
00354                                  << " wrapping to " 
00355                                  << (nL%MAX_LUMI_SEG_HLT);
00356     //nL = MAX_LUMI_SEG_HLT;
00357     nL = nL%MAX_LUMI_SEG_HLT;
00358   }
00359 
00360   // merging counts
00361   double num_fu = -1.0;
00362   std::string mergeName(folderName_ + "/raw/hltMerge");
00363   MonitorElement *merge = dbe_->get(mergeName);
00364   if ( merge != 0 ) {
00365     num_fu = merge->getBinContent(1);
00366     if ( debug_ ) {
00367       std::cout << "Number of received entries: " << num_fu
00368                 << std::endl;
00369     }
00370     mergeCount_->Fill(nL,num_fu);
00371   }
00372   // end 
00373 
00374 
00375   // evaluate the data
00376   // loop over current counts
00377 
00378   // this gets filled for all times. Mainly for debugging.
00379   for ( int i = 1; i <= npaths; ++i ) { // bins start at 1
00380     double current_count = scalers->getBinContent(i);
00381     // nb that this will now _overwrite_ some settings
00382     countHistories_[i-1]->setBinContent(nL, current_count); // good or bad
00383   }
00384 
00385   std::string overallScalerName(folderName_ + "/raw/hltOverallScaler");
00386   MonitorElement *hltScaler = dbe_->get(overallScalerName);
00387   if ( hltScaler != 0 ) {
00388     double current_count = hltScaler->getBinContent(1);
00389     hltCount_->setBinContent(nL,current_count);
00390     recentOverallCountsPerLS_.update(CountLS_t(nL,current_count));
00391     std::pair<double,double> sl =  getSlope_(recentOverallCountsPerLS_);
00392     double slope = sl.first; double slope_err = sl.second;
00393     if ( slope > 0 ) {
00394       hltRate_->setBinContent(nL,slope);
00395       if ( ! std::isnan(slope_err ) && (slope_err >= 0 )  )
00396         hltRate_->setBinError(nL,slope_err);
00397     }
00398   } // found  histo
00399 
00400 
00401 
00402   if ( num_fu >= 0.95*maxFU_ ) {
00403     if ( num_fu > maxFU_ ) {
00404       maxFU_ = num_fu;
00405       if ( debug_ ) 
00406         std::cout << "maxFU is now " << maxFU_ << std::endl;
00407     }
00408     // good data
00409     for ( int i = 1; i <= npaths; ++i ) { // bins start at 1
00410       double current_count = scalers->getBinContent(i);
00411       // DEBUG
00412       if ( ! recentPathCountsPerLS_[i-1].empty() && debug_ ) 
00413           std::cout << i << "\t-> good one: new => cnt, ls = " 
00414                     << current_count << ", " << nL
00415                     << ", old = "
00416                     << recentPathCountsPerLS_[i-1].back().second << "\t"
00417                     << recentPathCountsPerLS_[i-1].back().first 
00418                     << std::endl;
00419       // END DEBUG
00420       recentPathCountsPerLS_[i-1].update(CountLS_t(nL,current_count));
00421 
00422       // NB: we do not fill a new entry in the rate histo if we can't 
00423       // calculate it
00424       std::pair<double,double> sl =  getSlope_(recentPathCountsPerLS_[i-1]);
00425       double slope = sl.first; double slope_err = sl.second;
00426       //rateHistories_[i-1]->Fill(nL,slope);
00427       if ( slope > 0 ) {
00428         rateHistories_[i-1]->setBinContent(nL,slope);
00429         // set the current rate(s)
00430         hltCurrentRate_[(i-1)/kPerHisto]->setBinContent(i%kPerHisto, slope);
00431         currentRate_->setBinContent(i, slope);
00432         if ( ! std::isnan(slope_err ) && (slope_err >= 0 ) ) {
00433           currentRate_->setBinError(i, slope_err);
00434           hltCurrentRate_[(i-1)/kPerHisto]->setBinError(i%kPerHisto, slope_err);
00435           rateHistories_[i-1]->setBinError(nL,slope_err);
00436         }
00437       }
00440       
00441     } // loop over paths
00442 
00443     // ---------------------------- overall rate, absolute counts
00444     std::string overallScalerName(folderName_ + "/raw/hltOverallScaler");
00445     MonitorElement *hltScaler = dbe_->get(overallScalerName);
00446     if ( hltScaler != 0 ) {
00447       double current_count = hltScaler->getBinContent(1);
00448       hltCount_->setBinContent(nL,current_count);
00449       recentOverallCountsPerLS_.update(CountLS_t(nL,current_count));
00450       std::pair<double,double> sl =  getSlope_(recentOverallCountsPerLS_);
00451       double slope = sl.first; double slope_err = sl.second;
00452       if ( slope >= 0 ) {
00453         hltRate_->setBinContent(nL,slope);
00454         if ( ! std::isnan(slope_err ) && (slope_err >= 0 )  )
00455           hltRate_->setBinError(nL,slope_err);
00456       }
00457     } // found  histo
00458     updates_->Fill(0); // good
00459   } // check on number of FU's - good data
00460   else {
00461     updates_->Fill(1); // missing updates
00462   }
00463   
00464   // PW DEBUG
00465   if ( debug_ ) {
00466     textfile_ << nL << "\t"
00467               << npaths << "\t";
00468     for ( int i = 0; i < npaths ; ++i ) {
00469       textfile_ << scalers->getBinContent(i) << " ";
00470     }
00471     textfile_ << std::endl;
00472   }
00473   // end DEBUG
00474 
00475 
00476 #ifdef LATER
00477   // ------ overall rate normalized - all data
00478   overallScalerName = std::string(folderName_ + "/raw/hltOverallScalerN");
00479   hltScaler = dbe_->get(overallScalerName);
00480   if ( hltScaler != 0 ) {
00481     double cnt = hltScaler->getBinContent(1);
00482 //     hltCountN_->setBinContent(nL,cnt);
00483     if ( debug_ ) {
00484       std::cout << "Overall Norm: new => cnt, ls = " 
00485                 << cnt << ", " << nL
00486                 << ", num_fu = " << num_fu 
00487                 << std::endl;
00488     }
00489     recentNormedOverallCountsPerLS_.update(CountLS_t(nL, cnt/num_fu));
00490     cnt = recentNormedOverallCountsPerLS_.getCount(nL); // for dupes/partials
00491     double slope = cnt / num_fu / SECS_PER_LUMI_SECTION;
00492     if ( debug_ )  {
00493       std::cout << "Normalized slope = " << slope << std::endl;
00494     }
00495     if ( slope > 0 ) 
00496       hltNormRate_->setBinContent(nL,slope);
00497   }
00498   // 
00499   std::string scalHistoNorm = folderName_ + "/raw/hltScalersN";
00500   MonitorElement *scalersN = dbe_->get(scalHistoNorm);
00501   if ( scalersN ) {
00502     for (int i = 0; i < npaths ; ++i ) {
00503       double cnt = scalersN->getBinContent(i);
00504       double slope = cnt / num_fu / SECS_PER_LUMI_SECTION;
00505       if ( slope > 0 ) {
00506         rateNormHistories_[i-1]->setBinContent(nL,slope);
00507         // set the current rate(s)
00508         hltCurrentNormRate_[(i-1)/kPerHisto]->setBinContent(i%kPerHisto, slope);
00509         currentNormRate_->setBinContent(i, slope);
00510       }
00511     }
00512   }
00513 #else // NOT LATER
00514   // ------ overall rate normalized - all data
00515   overallScalerName = std::string(folderName_ + "/raw/hltOverallScaler");
00516   hltScaler = dbe_->get(overallScalerName);
00517   if ( hltScaler != 0 ) {
00518     double cnt = hltScaler->getBinContent(1);
00519 //     hltCountN_->setBinContent(nL,cnt);
00520     float sf = num_fu/maxFU_;
00521     if ( debug_ ) {
00522       std::cout << "Overall Norm: new => cnt, ls = " 
00523                 << cnt << ", " << nL
00524                 << ", num_fu = " << num_fu << ", sf = " << sf
00525                 << std::endl;
00526     }
00527     recentNormedOverallCountsPerLS_.update(CountLS_t(nL, cnt/sf));
00528     cnt = recentNormedOverallCountsPerLS_.getCount(nL); // for dupes/partials
00529     std::pair<double,double> sl =  getSlope_(recentNormedOverallCountsPerLS_);
00530     double slope = sl.first; double slope_err = sl.second;
00531     if ( debug_ )  {
00532       std::cout << "Normalized slope = " << slope << std::endl;
00533     }
00534     if ( slope > 0 ) {
00535       hltNormRate_->setBinContent(nL,slope);
00536       if ( cnt > 0 ) slope_err = slope*sqrt( 2./num_fu + 2./cnt);
00537       if ( ! std::isnan(slope_err ) && (slope_err >= 0 )  )
00538         hltNormRate_->setBinError(nL,slope_err);
00539     }
00540   }
00541   // 
00542   std::string scalHistoNorm = folderName_ + "/raw/hltScalers";
00543   MonitorElement *scalersN = dbe_->get(scalHistoNorm);
00544   if ( scalersN ) {
00545     double sf = num_fu /maxFU_;
00546     for (int i = 1; i <= npaths ; ++i ) {
00547       double cnt = scalersN->getBinContent(i);
00548       recentNormedPathCountsPerLS_[i-1].update(CountLS_t(nL,cnt/sf));
00549       std::pair<double,double> sl =  getSlope_(recentNormedPathCountsPerLS_[i-1]);
00550       double slope = sl.first; double slope_err = sl.second;
00551       if ( slope >= 0 ) {
00552         rateNormHistories_[i-1]->setBinContent(nL,slope);
00553         // set the current rate(s)
00554         hltCurrentNormRate_[(i-1)/kPerHisto]->setBinContent(i%kPerHisto, slope);
00555         currentNormRate_->setBinContent(i, slope);
00556         if ( slope_err <= 0 && cnt > 0) {
00557           // ignores error on prev point, so scale by sqrt(2)
00558           slope_err = slope*sqrt( 2./num_fu + 2./cnt);
00559           if ( debug_ ) {
00560             std::cout << "Slope err " << i << " = " << slope_err << std::endl;
00561           }
00562         }
00563         if ( ! std::isnan(slope_err ) && (slope_err >= 0 )  ) {
00564           rateNormHistories_[i-1]->setBinError(nL,slope_err);
00565           // set the current rate(s)
00566           hltCurrentNormRate_[(i-1)/kPerHisto]->setBinError(i%kPerHisto, slope_err);
00567           currentNormRate_->setBinError(i, slope_err);
00568           
00569         }
00570 
00571       }
00572     }
00573   }
00574 
00575 #endif // LATER
00576   //
00577 
00578     
00579 
00580 }
00581 
00582 // unused
00583 void HLTScalersClient::analyze(const edm::Event& e, const edm::EventSetup& c ) 
00584 {
00585   // nothing to do here
00586 }
00587 
00588 // this is probably overkill. Do a least-squares fit to get slope
00589 // note that the data is in units of counts, ls number
00590 // but we return a value in Hz...
00591 std::pair<double,double>
00592 HLTScalersClient::getSlope_(HLTScalersClient::CountLSFifo_t points)
00593 {
00594   double slope, sigma_m;
00595   if ( points.size() < points.targetSize() ) {
00596     return std::pair<double,double>(-1,-1);
00597   }
00598   // just do a delta if we just want two bins
00599   else if ( points.size() == 2 ) {
00600     // just do diff and be done with it 
00601     double delta_ls = points.front().first - points.back().first;
00602     double delta_cnt = points.front().second - points.back().second;
00603     slope = delta_cnt / delta_ls ;
00604     sigma_m = -1;
00605   }
00606   else { // do a fit
00607     double xy = 0;
00608     double x = 0;
00609     double xsq = 0;
00610     double y = 0;
00611     double n = double(points.size());
00612     for ( CountLSFifo_t::iterator i(points.begin());
00613           i != points.end(); ++i ) {
00614        if ( debug_ ) 
00615          std::cout << "x = " << i->first << ", y = " << i->second 
00616                    << std::endl;
00617       xy += i->first * i->second;
00618       x += i->first;
00619       xsq += i->first*i->first;
00620       y += i->second;
00621     }
00622     slope = (n*xy - x*y)/(n*xsq - x*x);
00623 
00624     // now get the uncertainty on the slope. Need intercept for this.
00625     double intercept = (xsq*y - xy*x)/(n*xsq-x*x);
00626     double sigma_ysq = 0;
00627     for ( CountLSFifo_t::iterator i(points.begin());
00628           i != points.end(); ++i ) {
00629       sigma_ysq += pow(( i->second - slope * i->first  - intercept),2.);
00630     }
00631 //     if ( debug_ ) 
00632 //       std::cout << "chi^2 = " << sigma_ysq << std::endl;
00633     sigma_ysq *= 1./(n-2.);
00634 
00635     sigma_m = sqrt( n*sigma_ysq/(n*xsq - x*x));
00636   }
00637 
00638   //  std::cout << "Slope is " << slope << std::endl;
00639   slope /= SECS_PER_LUMI_SECTION;
00640   if ( sigma_m >0 ) 
00641     sigma_m /= SECS_PER_LUMI_SECTION;
00642 //   if ( debug_ ) {
00643 //     std::cout << "Slope = " << slope << " +- " << sigma_m 
00644 //            << std::endl;
00645 //   std::cout << "intercept is " << intercept
00646 //          << std::endl;
00647 //  }
00648 
00649 
00650   return std::pair<double,double>(slope, sigma_m);
00651 }