CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/PhysicsTools/UtilAlgos/interface/Selections.h

Go to the documentation of this file.
00001 #ifndef Selections_H
00002 #define Selections_H
00003 
00004 #include "PhysicsTools/UtilAlgos/interface/EventSelector.h"
00005 #include <cstdlib>
00006 #include <iomanip>
00007 #include <sstream>
00008 
00009 class Filter {
00010  public:
00011   Filter() : inverted_(false), selector_(0){}
00012   Filter(const edm::ParameterSet& iConfig);
00013   Filter(std::string name, edm::ParameterSet& iConfig) : 
00014     name_(name),inverted_(false), selector_(0)
00015   {
00016     dump_=iConfig.dump();
00017     if (!iConfig.empty()){
00018       const std::string d("name");
00019       iConfig.addUntrackedParameter<std::string>(d,name);
00020       std::string componentName = iConfig.getParameter<std::string>("selector");
00021       selector_ = EventSelectorFactory::get()->create(componentName, iConfig);
00022       if (iConfig.exists("description"))
00023         description_=iConfig.getParameter<std::vector<std::string> >("description");
00024       else
00025         description_=selector_->description();
00026     }
00027   }
00028   virtual ~Filter(){}
00029 
00030   const std::string & name() {return name_;}
00031   const std::string & dump() { return dump_;}
00032   const std::vector<std::string> description() { return description_;}
00033   const std::string descriptionText() { 
00034     std::string text;
00035     for (unsigned int i=0;i!=description_.size();++i) text+=description_[i]+"\n";
00036     text+=dump()+"\n";
00037     return text;}
00038 
00039   virtual  bool accept(edm::Event& iEvent)const {
00040     bool decision=false;
00041     if (selector_)
00042       decision=selector_->select(iEvent);
00043     else
00044       decision=true;
00045     if (inverted_) return !decision;
00046     else return decision;
00047   }
00048   void setInverted() {    inverted_=true; }
00049 
00050  protected:
00051   std::string name_;
00052   std::vector<std::string> description_;
00053   bool inverted_;//too allow !filter
00054   EventSelector * selector_;
00055   std::string dump_;
00056 };
00057 
00058 
00059 class FilterOR : public Filter{ 
00060  public:
00061   ~FilterOR(){}
00062   FilterOR(const std::string & filterORlist,
00063            const std::map<std::string, Filter*> & filters){
00064     std::string filterORlistCopy=filterORlist;
00065     name_ = filterORlist;
00066     std::stringstream ss;
00067     ss<<"Filter doing an OR of: ";
00068     //split the OR-separated string into vector of strings
00069     unsigned int size=0;
00070     bool OK=true;
00071     while( OK ){
00072       size_t orPos = filterORlistCopy.find("_OR_");
00073       if (orPos == std::string::npos && filterORlistCopy.size()!=0){
00074         size=filterORlistCopy.size();
00075         OK=false;
00076       }
00077       else
00078         size=orPos;
00079       
00080       std::string filter = filterORlistCopy.substr(0,size);
00081       //remove the filter name and the OR (4 characters) from the string
00082       if (OK)
00083         filterORlistCopy = filterORlistCopy.substr(0+size+4);
00084       
00085       std::map<std::string, Filter*>::const_iterator it=filters.find(filter);
00086       if (it==filters.end()){
00087         edm::LogError("FilterOR")<<"cannot do an OR of: "<<filter
00088                                  <<" OR expression is: "<<filterORlist;
00089         break;
00090       }
00091       filters_.push_back(std::make_pair(it->first, it->second));
00092       ss<<it->first<<" ";
00093     }
00094     description_.push_back(ss.str());
00095   }
00096   bool accept(edm::Event& iEvent)const {
00097     for (unsigned int i=0 ; i!=filters_.size();++i)
00098       if (filters_[i].second->accept(iEvent))
00099         return true;
00100     return false;
00101   }
00102  private:
00103   std::vector <std::pair<std::string , const Filter * > > filters_;
00104 };
00105 
00106 
00107 //forward declaration for friendship
00108 class Selections;
00109 
00110 class Selection {
00111  public:
00112   typedef std::vector<Filter*>::iterator iterator;
00113   friend class Selections;
00114 
00115   Selection(std::string name, const edm::ParameterSet& iConfig) :
00116     name_(name), 
00117     ntuplize_(iConfig.getParameter<bool>("ntuplize")),
00118     makeContentPlots_(iConfig.getParameter<bool>("makeContentPlots")),
00119     makeFinalPlots_(iConfig.getParameter<bool>("makeFinalPlots")),
00120     makeCumulativePlots_(iConfig.getParameter<bool>("makeCumulativePlots")),
00121     makeAllButOnePlots_(iConfig.getParameter<bool>("makeAllButOnePlots")),
00122     nSeen_(0),
00123     makeSummaryTable_(iConfig.getParameter<bool>("makeSummaryTable")),
00124     makeDetailledPrintout_(iConfig.exists("detailledPrintoutCategory"))
00125   {
00126     if (iConfig.exists("nMonitor"))
00127       nMonitor_=iConfig.getParameter<unsigned int>("nMonitor");
00128     else
00129       nMonitor_=0;
00130 
00131     if (makeDetailledPrintout_)
00132       detailledPrintoutCategory_ = iConfig.getParameter<std::string>("detailledPrintoutCategory");
00133   }
00134 
00135   const std::string & name() {return name_;}
00136   iterator begin() { return filters_.begin();}
00137   iterator end() { return filters_.end();}
00138 
00139   std::map<std::string, bool> accept(edm::Event& iEvent){
00140     nSeen_++;
00141     if (nMonitor_!=0 && nSeen_%nMonitor_==0){
00142       if (nSeen_==nMonitor_) print();
00143       else print(false);
00144     }
00145     std::map<std::string, bool> ret;
00146     bool global=true;
00147     for (iterator filter=begin(); filter!=end();++filter){
00148       const std::string & fName=(*filter)->name();
00149       Count & count=counts_[fName];
00150       count.nSeen_++;
00151       bool decision=(*filter)->accept(iEvent);
00152       ret[fName]=decision;
00153       if (decision) count.nPass_++;
00154       global=global && decision;
00155       if (global) count.nCumulative_++;
00156     }
00157 
00158     if (makeDetailledPrintout_){
00159       std::stringstream summary;
00160       summary<<std::setw(20)<<name().substr(0,19)<<" : "
00161              <<std::setw(10)<<iEvent.id().run()<<" : "
00162              <<std::setw(10)<<iEvent.id().event();
00163       for (iterator filter=begin(); filter!=end();++filter){
00164         const std::string & fName=(*filter)->name();
00165         summary<<" : "<<std::setw(10)<<(ret[fName]?"pass":"reject");
00166       }
00167       edm::LogVerbatim(detailledPrintoutCategory_)<<summary.str();
00168     }
00169     
00170     return ret;
00171   }
00172 
00173   void printDetailledPrintoutHeader(){
00174     if (makeDetailledPrintout_){
00175       std::stringstream summary;
00176       summary<<std::setw(20)<<" selection name "<<" : "
00177              <<std::setw(10)<<" run "<<" : "
00178              <<std::setw(10)<<" event ";
00179       for (iterator filter=begin(); filter!=end();++filter){
00180         summary<<" : "<<std::setw(10)<<(*filter)->name().substr(0,9);
00181       }
00182       edm::LogVerbatim(detailledPrintoutCategory_)<<summary.str();
00183     }
00184   }
00185   //print to LogVerbatim("Selections|<name()>")
00186   void print(bool description=true){
00187     if (!makeSummaryTable_) return;
00188 
00189     unsigned int maxFnameSize = 20;
00190     for (iterator filter=begin(); filter!=end();++filter){
00191       if ((*filter)->name().size() > maxFnameSize) maxFnameSize = (*filter)->name().size()+1;
00192     }
00193 
00194     //    const std::string category ="Selections|"+name();
00195     const std::string category ="Selections";
00196     std::stringstream summary;
00197     summary<<"   Summary table for selection: "<<name()<<" with: "<<nSeen_<<" events run."<<std::endl;
00198     if (nSeen_==0) return;
00199     if (description){
00200       for (iterator filter=begin(); filter!=end();++filter){
00201         const std::string & fName=(*filter)->name();
00202         summary<<"filter: "<<std::right<<std::setw(10)<<fName<<"\n"
00203                <<(*filter)->descriptionText()<<"\n";
00204       }
00205     }
00206     summary<<" filter stand-alone pass: "<<std::endl;
00207     summary<<std::right<<std::setw(maxFnameSize)<<"total read"<<": "
00208            <<std::right<<std::setw(10)<<nSeen_<<std::endl;
00209     for (iterator filter=begin(); filter!=end();++filter){
00210       const std::string & fName=(*filter)->name();
00211       const Count & count=counts_[fName];
00212       summary<<std::right<<std::setw(maxFnameSize)<<fName<<": "
00213              <<std::right<<std::setw(10)<<count.nPass_<<" passed events. "
00214              <<std::right<<std::setw(10)<<std::setprecision (5)<<(count.nPass_/(float)count.nSeen_)*100.<<" [%]"<<std::endl;
00215     }
00216     summary<<" filter cumulative pass:"<<std::endl;
00217     summary<<std::right<<std::setw(maxFnameSize)<<"total read"<<": "
00218            <<std::right<<std::setw(10)<<nSeen_<<std::endl;
00219     unsigned int lastCount=nSeen_;
00220     for (iterator filter=begin(); filter!=end();++filter){
00221       const std::string & fName=(*filter)->name();
00222       const Count & count=counts_[fName];
00223       summary<<std::right<<std::setw(maxFnameSize)<<fName<<": "
00224              <<std::right<<std::setw(10)<<count.nCumulative_<<" passed events. "
00225              <<std::right<<std::setw(10)<<std::setprecision (5)<<(count.nCumulative_/(float)count.nSeen_)*100.<<" [%]";
00226       if (lastCount!=0)
00227         summary<<" (to previous count) "<<std::right<<std::setw(10)<<std::setprecision (5)<<(count.nCumulative_/(float)lastCount)*100.<<" [%]";
00228       summary   <<std::endl;
00229 
00230       lastCount = count.nCumulative_;
00231     }
00232     summary<<"-------------------------------------\n";
00233     edm::LogVerbatim(category)<<summary.str();
00234     std::cout<<summary.str();
00235   };
00236 
00237 
00238   bool ntuplize() {return ntuplize_;}
00239   bool makeContentPlots() { return makeContentPlots_;}
00240   bool makeFinalPlots() { return makeFinalPlots_;}
00241   bool makeCumulativePlots() { return makeCumulativePlots_;}
00242   bool makeAllButOnePlots() { return makeAllButOnePlots_;}
00243   bool makeSummaryTable() { return makeSummaryTable_;}
00244 
00245  private:
00246   std::string name_;
00247   std::vector<Filter*> filters_;
00248   //some options
00249   bool ntuplize_;
00250   bool makeContentPlots_;
00251   bool makeFinalPlots_;
00252   bool makeCumulativePlots_;
00253   bool makeAllButOnePlots_;
00254 
00255   unsigned int nSeen_;
00256   unsigned int nMonitor_;
00257 
00258   struct Count{
00259     unsigned int nPass_;
00260     unsigned int nSeen_;
00261     unsigned int nCumulative_;
00262   };
00263   std::map<std::string, Count> counts_;
00264   bool makeSummaryTable_;
00265   bool makeDetailledPrintout_;
00266   std::string detailledPrintoutCategory_;
00267 };
00268 
00269 class Selections {
00270  public:
00271   typedef std::vector<Selection>::iterator iterator;
00272 
00273   Selections(const edm::ParameterSet& iConfig) : 
00274     filtersPSet_(iConfig.getParameter<edm::ParameterSet>("filters")),
00275     selectionPSet_(iConfig.getParameter<edm::ParameterSet>("selections"))
00276   {
00277     //FIXME. what about nested filters
00278     //make all configured filters
00279     std::vector<std::string> filterNames;
00280     unsigned int nF=filtersPSet_.getParameterSetNames(filterNames);
00281     for (unsigned int iF=0;iF!=nF;iF++){
00282       edm::ParameterSet pset = filtersPSet_.getParameter<edm::ParameterSet>(filterNames[iF]);
00283       filters_.insert(std::make_pair(filterNames[iF],new Filter(filterNames[iF],pset)));
00284     }
00285 
00286     //parse all configured selections
00287     std::vector<std::string> selectionNames;
00288     std::map<std::string, std::vector<std::string> > selectionFilters;
00289     unsigned int nS=selectionPSet_.getParameterSetNames(selectionNames);
00290     for (unsigned int iS=0;iS!=nS;iS++){
00291       edm::ParameterSet pset=selectionPSet_.getParameter<edm::ParameterSet>(selectionNames[iS]);
00292       selections_.push_back(Selection(selectionNames[iS],pset));
00293       //      selections_.insert(std::make_pair(selectionNames[iS],Selection(selectionNames[iS],pset)));
00294       //keep track of list of filters for this selection for further dependency resolution
00295       selectionFilters[selectionNames[iS]]=pset.getParameter<std::vector<std::string> >("filterOrder");
00296     }
00297 
00298 
00299     //watch out of recursive dependency
00300     //    unsigned int nestedDepth=0; //FIXME not taken care of
00301 
00302     //resolving dependencies
00303     for (std::map<std::string, std::vector<std::string> >::iterator sIt= selectionFilters.begin();sIt!=selectionFilters.end();++sIt)
00304       {
00305         //parse the vector of filterNames
00306         for (std::vector<std::string>::iterator fOrS=sIt->second.begin();fOrS!=sIt->second.end();++fOrS)
00307           {
00308             if (filters_.find(*fOrS)==filters_.end())
00309               {
00310                 //not a know filter names uncountered : either Selection of _OR_.
00311                 if (fOrS->find("_OR_") != std::string::npos){
00312                   filters_.insert(std::make_pair((*fOrS),new FilterOR((*fOrS),filters_)));
00313                 }//_OR_ filter
00314                 else{
00315                   // look for a selection name
00316                   std::map<std::string, std::vector<std::string> >::iterator s=selectionFilters.find(*fOrS);
00317                   if (s==selectionFilters.end()){
00318                     //error. 
00319                     edm::LogError("SelectionHelper")<<"unresolved filter/selection name: "<<*fOrS;
00320                   }//not a Selection name.
00321                   else{
00322                     //remove the occurence
00323                     std::vector<std::string>::iterator newLoc=sIt->second.erase(fOrS);
00324                     //insert the list of filters corresponding to this selection in there
00325                     sIt->second.insert(newLoc,s->second.begin(),s->second.end());
00326                     //decrement selection iterator to come back to it
00327                     sIt--;
00328                     break;
00329                   }//a Selection name
00330                 }
00331               }//the name is not a simple filter name : either Selection of _OR_.
00332               
00333           }//loop over the strings in "filterOrder"
00334       }//loop over all defined Selection
00335 
00336     //finally, configure the Selections
00337     //loop the selections instanciated
00338     //    for (std::map<std::string, Selection>::iterator sIt=selections_.begin();sIt!=selections_.end();++sIt)
00339     //      const std::string & sName=sIt->first;
00340     //Selection & selection =sIt->second;
00341     for (std::vector<Selection>::iterator sIt=selections_.begin();sIt!=selections_.end();++sIt){
00342       const std::string & sName=sIt->name();    
00343       Selection & selection =*sIt;
00344 
00345       //parse the vector of filterNames
00346       std::vector<std::string> & listOfFilters=selectionFilters[sName];
00347       for (std::vector<std::string>::iterator fIt=listOfFilters.begin();fIt!=listOfFilters.end();++fIt)
00348         {
00349           std::map<std::string, Filter*>::iterator filterInstance=filters_.find(*fIt);
00350           if (filterInstance==filters_.end()){
00351             //error
00352             edm::LogError("Selections")<<"cannot resolve: "<<*fIt;
00353           }
00354           else{
00355             //actually increment the filter
00356             selection.filters_.push_back(filterInstance->second);
00357           }
00358         }
00359     }
00360     
00361     for (iterator sIt = begin(); sIt!=end();++sIt)
00362       sIt->printDetailledPrintoutHeader();
00363 
00364   }
00365 
00366   iterator begin() {return selections_.begin(); }
00367   iterator end() { return selections_.end();}
00368 
00369   //print each selection 
00370   void print(){ for (std::vector<Selection>::iterator sIt=selections_.begin();sIt!=selections_.end();++sIt) sIt->print();}
00371     
00372  private:
00373   edm::ParameterSet filtersPSet_;
00374   std::map<std::string, Filter*> filters_;
00375 
00376   edm::ParameterSet selectionPSet_;
00377   //  std::map<std::string, Selection> selections_;
00378   std::vector<Selection> selections_;
00379 };
00380 
00381 
00382 #endif