CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2_patch1/src/DQM/TrigXMonitorClient/src/HLTScalersClient.cc

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