CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoTauTag/RecoTau/src/TauDiscriminationProducerBase.cc

Go to the documentation of this file.
00001 #include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h"
00002 
00003 #include <string>
00004 
00005 using namespace reco;
00006 
00007 // default constructor; must not be called
00008 template<class TauType, class TauDiscriminator>
00009 TauDiscriminationProducerBase<TauType, TauDiscriminator>::TauDiscriminationProducerBase()
00010 {
00011    throw cms::Exception("TauDiscriminationProducerBase") << " -- default ctor called; derived classes must call " <<
00012       "TauDiscriminationProducerBase(const ParameterSet&)";
00013 }
00014 
00015 //--- standard constructor from PSet
00016 template<class TauType, class TauDiscriminator>
00017 TauDiscriminationProducerBase<TauType, TauDiscriminator>::TauDiscriminationProducerBase(const edm::ParameterSet& iConfig)
00018   : moduleLabel_(iConfig.getParameter<std::string>("@module_label"))
00019 {
00020    // tau collection to discriminate
00021    TauProducer_        = iConfig.getParameter<edm::InputTag>(getProducerString<TauType>());
00022 
00023    // prediscriminant operator
00024    // require the tau to pass the following prediscriminants
00025    const edm::ParameterSet& prediscriminantConfig = iConfig.getParameter<edm::ParameterSet>("Prediscriminants");
00026 
00027    // determine boolean operator used on the prediscriminants
00028    std::string pdBoolOperator = prediscriminantConfig.getParameter<std::string>("BooleanOperator");
00029    // convert string to lowercase
00030    transform(pdBoolOperator.begin(), pdBoolOperator.end(), pdBoolOperator.begin(), ::tolower);
00031 
00032    if( pdBoolOperator == "and" )
00033    {
00034       andPrediscriminants_ = 0x1; //use chars instead of bools so we can do a bitwise trick later
00035    }
00036    else if ( pdBoolOperator == "or" )
00037    {
00038       andPrediscriminants_ = 0x0;
00039    }
00040    else
00041    {
00042       throw cms::Exception("TauDiscriminationProducerBase") << "PrediscriminantBooleanOperator defined incorrectly, options are: AND,OR";
00043    }
00044 
00045    // get the list of prediscriminants
00046    std::vector<std::string> prediscriminantsNames = prediscriminantConfig.getParameterNamesForType<edm::ParameterSet>();
00047 
00048    for( std::vector<std::string>::const_iterator iDisc  = prediscriminantsNames.begin();
00049                                        iDisc != prediscriminantsNames.end(); ++iDisc )
00050    {
00051       const edm::ParameterSet& iPredisc = prediscriminantConfig.getParameter<edm::ParameterSet>(*iDisc);
00052       const edm::InputTag& label        = iPredisc.getParameter<edm::InputTag>("Producer");
00053       double cut                        = iPredisc.getParameter<double>("cut");
00054 
00055       TauDiscInfo thisDiscriminator;
00056       thisDiscriminator.label = label;
00057       thisDiscriminator.cut   = cut;
00058       prediscriminants_.push_back(thisDiscriminator);
00059    }
00060 
00061    prediscriminantFailValue_ = 0.;
00062 
00063    // register product
00064    produces<TauDiscriminator>();
00065 }
00066 
00067 template<class TauType, class TauDiscriminator>
00068 void TauDiscriminationProducerBase<TauType, TauDiscriminator>::produce(edm::Event& event, const edm::EventSetup& eventSetup)
00069 {
00070    // setup function - does nothing in base, but can be overridden to retrieve PV or other stuff
00071    beginEvent(event, eventSetup);
00072 
00073    // retrieve the tau collection to discriminate
00074    edm::Handle<TauCollection> taus;
00075    event.getByLabel(TauProducer_, taus);
00076 
00077    edm::ProductID tauProductID = taus.id();
00078 
00079    // output product
00080    std::auto_ptr<TauDiscriminator> output(new TauDiscriminator(TauRefProd(taus)));
00081 
00082    size_t nTaus = taus->size();
00083 
00084    // load prediscriminators
00085    size_t nPrediscriminants = prediscriminants_.size();
00086    for( size_t iDisc = 0; iDisc < nPrediscriminants; ++iDisc )
00087    {
00088       prediscriminants_[iDisc].fill(event);
00089 
00090       // Check to make sure the product is correct for the discriminator.
00091       // If not, throw a more informative exception.
00092       edm::ProductID discKeyId =
00093         prediscriminants_[iDisc].handle->keyProduct().id();
00094       if (tauProductID != discKeyId) {
00095         throw cms::Exception("MisconfiguredPrediscriminant")
00096           << "The tau collection with input tag " << TauProducer_
00097           << " has product ID: " << tauProductID
00098           << " but the pre-discriminator with input tag "
00099           << prediscriminants_[iDisc].label
00100           << " is keyed with product ID: " << discKeyId << std::endl;
00101       }
00102    }
00103 
00104    // loop over taus
00105    for( size_t iTau = 0; iTau < nTaus; ++iTau )
00106    {
00107       // get reference to tau
00108       TauRef tauRef(taus, iTau);
00109 
00110       bool passesPrediscriminants = true;
00111       // check tau passes prediscriminants
00112       for( size_t iDisc = 0; iDisc < nPrediscriminants; ++iDisc )
00113       {
00114          // current discriminant result for this tau
00115          double discResult  = (*prediscriminants_[iDisc].handle)[tauRef];
00116          uint8_t thisPasses = ( discResult > prediscriminants_[iDisc].cut ) ? 1 : 0;
00117 
00118          // if we are using the AND option, as soon as one fails,
00119          // the result is FAIL and we can quit looping.
00120          // if we are using the OR option as soon as one passes,
00121          // the result is pass and we can quit looping
00122 
00123          // truth table
00124          //        |   result (thisPasses)
00125          //        |     F     |     T
00126          //-----------------------------------
00127          // AND(T) | res=fails |  continue
00128          //        |  break    |
00129          //-----------------------------------
00130          // OR (F) |  continue | res=passes
00131          //        |           |  break
00132 
00133          if( thisPasses ^ andPrediscriminants_ ) //XOR
00134          {
00135             passesPrediscriminants = ( andPrediscriminants_ ? 0 : 1 ); //NOR
00136             break;
00137          }
00138       }
00139 
00140       double result = prediscriminantFailValue_;
00141       if( passesPrediscriminants )
00142       {
00143          // this tau passes the prereqs, call our implemented discrimination function
00144          result = discriminate(tauRef);
00145       }
00146 
00147       // store the result of this tau into our new discriminator
00148       output->setValue(iTau, result);
00149    }
00150    event.put(output);
00151 
00152    // function to put additional information into the event - does nothing in base, but can be overridden in derived classes
00153    endEvent(event);
00154 }
00155 
00156 // template specialiazation to get the correct (Calo/PF)TauProducer names
00157 template<> std::string getProducerString<PFTau>()   { return "PFTauProducer"; }
00158 template<> std::string getProducerString<CaloTau>() { return "CaloTauProducer"; }
00159 
00160 // compile our desired types and make available to linker
00161 template class TauDiscriminationProducerBase<PFTau, PFTauDiscriminator>;
00162 template class TauDiscriminationProducerBase<CaloTau, CaloTauDiscriminator>;