CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoTauTag/RecoTau/src/TauDiscriminationProducerBase.cc

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