Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:27:55

0001 #include "RecoTauTag/RecoTau/interface/TauDiscriminationProducerBase.h"
0002 
0003 #include <string>
0004 
0005 using namespace reco;
0006 
0007 namespace {
0008   template <class TauDiscriminator, class TauCollection>
0009   struct helper {
0010     typedef edm::RefProd<TauCollection> TauRefProd;
0011     static std::unique_ptr<TauDiscriminator> init_result_object(edm::Handle<TauCollection> taus) {
0012       return std::make_unique<TauDiscriminator>(TauRefProd(taus));
0013     }
0014   };
0015 
0016   template <class TauCollection>
0017   struct helper<TauDiscriminatorContainer, TauCollection> {
0018     static std::unique_ptr<TauDiscriminatorContainer> init_result_object(edm::Handle<TauCollection> taus) {
0019       auto result_object = std::make_unique<TauDiscriminatorContainer>();
0020       TauDiscriminatorContainer::Filler filler(*result_object);
0021       std::vector<SingleTauDiscriminatorContainer> placeholder(taus->size());
0022       filler.insert(taus, placeholder.begin(), placeholder.end());
0023       filler.fill();
0024       return result_object;
0025     }
0026   };
0027 };  // namespace
0028 
0029 // default constructor; must not be called
0030 template <class TauType, class TauDiscriminator, class TauDiscriminatorDataType, class ConsumeType>
0031 TauDiscriminationProducerBase<TauType, TauDiscriminator, TauDiscriminatorDataType, ConsumeType>::
0032     TauDiscriminationProducerBase() {
0033   throw cms::Exception("TauDiscriminationProducerBase") << " -- default ctor called; derived classes must call "
0034                                                         << "TauDiscriminationProducerBase(const ParameterSet&)";
0035 }
0036 
0037 //--- standard constructor from PSet
0038 template <class TauType, class TauDiscriminator, class TauDiscriminatorDataType, class ConsumeType>
0039 TauDiscriminationProducerBase<TauType, TauDiscriminator, TauDiscriminatorDataType, ConsumeType>::
0040     TauDiscriminationProducerBase(const edm::ParameterSet& iConfig)
0041     : moduleLabel_(iConfig.getParameter<std::string>("@module_label")) {
0042   // tau collection to discriminate
0043   TauProducer_ = iConfig.getParameter<edm::InputTag>(getTauTypeString() + "Producer");
0044   Tau_token = consumes<TauCollection>(TauProducer_);
0045 
0046   // prediscriminant operator
0047   // require the tau to pass the following prediscriminants
0048   const edm::ParameterSet& prediscriminantConfig = iConfig.getParameter<edm::ParameterSet>("Prediscriminants");
0049 
0050   // determine boolean operator used on the prediscriminants
0051   std::string pdBoolOperator = prediscriminantConfig.getParameter<std::string>("BooleanOperator");
0052   // convert string to lowercase
0053   transform(pdBoolOperator.begin(), pdBoolOperator.end(), pdBoolOperator.begin(), ::tolower);
0054 
0055   if (pdBoolOperator == "and") {
0056     andPrediscriminants_ = 0x1;  //use chars instead of bools so we can do a bitwise trick later
0057   } else if (pdBoolOperator == "or") {
0058     andPrediscriminants_ = 0x0;
0059   } else {
0060     throw cms::Exception("TauDiscriminationProducerBase")
0061         << "PrediscriminantBooleanOperator defined incorrectly, options are: AND,OR";
0062   }
0063 
0064   // get the list of prediscriminants
0065   std::vector<std::string> prediscriminantsNames = prediscriminantConfig.getParameterNamesForType<edm::ParameterSet>();
0066 
0067   for (std::vector<std::string>::const_iterator iDisc = prediscriminantsNames.begin();
0068        iDisc != prediscriminantsNames.end();
0069        ++iDisc) {
0070     const edm::ParameterSet& iPredisc = prediscriminantConfig.getParameter<edm::ParameterSet>(*iDisc);
0071     const edm::InputTag& label = iPredisc.getParameter<edm::InputTag>("Producer");
0072     double cut = iPredisc.getParameter<double>("cut");
0073 
0074     TauDiscInfo thisDiscriminator;
0075     thisDiscriminator.label = label;
0076     thisDiscriminator.cut = cut;
0077     thisDiscriminator.disc_token = consumes<ConsumeType>(label);
0078     prediscriminants_.push_back(thisDiscriminator);
0079   }
0080 
0081   prediscriminantFailValue_ = 0.;
0082 
0083   // register product
0084   produces<TauDiscriminator>();
0085 }
0086 
0087 template <class TauType, class TauDiscriminator, class TauDiscriminatorDataType, class ConsumeType>
0088 void TauDiscriminationProducerBase<TauType, TauDiscriminator, TauDiscriminatorDataType, ConsumeType>::produce(
0089     edm::Event& event, const edm::EventSetup& eventSetup) {
0090   tauIndex_ = 0;
0091   // setup function - does nothing in base, but can be overridden to retrieve PV or other stuff
0092   beginEvent(event, eventSetup);
0093 
0094   // retrieve the tau collection to discriminate
0095   edm::Handle<TauCollection> taus;
0096   event.getByToken(Tau_token, taus);
0097 
0098   edm::ProductID tauProductID = taus.id();
0099 
0100   // output product
0101   std::unique_ptr<TauDiscriminator> output = helper<TauDiscriminator, TauCollection>::init_result_object(taus);
0102 
0103   size_t nTaus = taus->size();
0104 
0105   // load prediscriminators
0106   size_t nPrediscriminants = prediscriminants_.size();
0107   for (size_t iDisc = 0; iDisc < nPrediscriminants; ++iDisc) {
0108     prediscriminants_[iDisc].fill(event);
0109 
0110     // Check to make sure the product is correct for the discriminator.
0111     // If not, throw a more informative exception.
0112     edm::ProductID discKeyId = prediscriminants_[iDisc].handle->keyProduct().id();
0113     if (tauProductID != discKeyId) {
0114       throw cms::Exception("MisconfiguredPrediscriminant")
0115           << "The tau collection with input tag " << TauProducer_ << " has product ID: " << tauProductID
0116           << " but the pre-discriminator with input tag " << prediscriminants_[iDisc].label
0117           << " is keyed with product ID: " << discKeyId << std::endl;
0118     }
0119   }
0120 
0121   // loop over taus
0122   for (size_t iTau = 0; iTau < nTaus; ++iTau) {
0123     // get reference to tau
0124     TauRef tauRef(taus, iTau);
0125 
0126     bool passesPrediscriminants = (andPrediscriminants_ ? 1 : 0);
0127     // check tau passes prediscriminants
0128     for (size_t iDisc = 0; iDisc < nPrediscriminants; ++iDisc) {
0129       // current discriminant result for this tau
0130       double discResult = (*prediscriminants_[iDisc].handle)[tauRef];
0131       uint8_t thisPasses = (discResult > prediscriminants_[iDisc].cut) ? 1 : 0;
0132 
0133       // if we are using the AND option, as soon as one fails,
0134       // the result is FAIL and we can quit looping.
0135       // if we are using the OR option as soon as one passes,
0136       // the result is pass and we can quit looping
0137 
0138       // truth table
0139       //        |   result (thisPasses)
0140       //        |     F     |     T
0141       //-----------------------------------
0142       // AND(T) | res=fails |  continue
0143       //        |  break    |
0144       //-----------------------------------
0145       // OR (F) |  continue | res=passes
0146       //        |           |  break
0147 
0148       if (thisPasses ^ andPrediscriminants_)  //XOR
0149       {
0150         passesPrediscriminants = (andPrediscriminants_ ? 0 : 1);  //NOR
0151         break;
0152       }
0153     }
0154 
0155     TauDiscriminatorDataType result = TauDiscriminatorDataType(prediscriminantFailValue_);
0156     if (passesPrediscriminants) {
0157       // this tau passes the prereqs, call our implemented discrimination function
0158       result = discriminate(tauRef);
0159       ++tauIndex_;
0160     }
0161 
0162     // store the result of this tau into our new discriminator
0163     (*output)[tauRef] = result;
0164   }
0165   event.put(std::move(output));
0166 
0167   // function to put additional information into the event - does nothing in base, but can be overridden in derived classes
0168   endEvent(event);
0169 }
0170 
0171 template <class TauType, class TauDiscriminator, class TauDiscriminatorDataType, class ConsumeType>
0172 void TauDiscriminationProducerBase<TauType, TauDiscriminator, TauDiscriminatorDataType, ConsumeType>::
0173     fillProducerDescriptions(edm::ParameterSetDescription& desc) {
0174   // helper function, it fills the description of the Producers parameter
0175   desc.add<edm::InputTag>(getTauTypeString() + "Producer", edm::InputTag("fixme"));
0176   {
0177     edm::ParameterSetDescription pset_prediscriminants;
0178     pset_prediscriminants.add<std::string>("BooleanOperator", "AND");
0179     // optional producers // will it pass if I don't specify them?
0180 
0181     {
0182       edm::ParameterSetDescription producer_params;
0183       producer_params.add<double>("cut", 0.);
0184       producer_params.add<edm::InputTag>("Producer", edm::InputTag("fixme"));
0185 
0186       pset_prediscriminants.addOptional<edm::ParameterSetDescription>("leadTrack", producer_params);
0187       pset_prediscriminants.addOptional<edm::ParameterSetDescription>("decayMode", producer_params);
0188     }
0189 
0190     desc.add<edm::ParameterSetDescription>("Prediscriminants", pset_prediscriminants);
0191   }
0192 }
0193 
0194 template <class TauType, class TauDiscriminator, class TauDiscriminatorDataType, class ConsumeType>
0195 std::string
0196 TauDiscriminationProducerBase<TauType, TauDiscriminator, TauDiscriminatorDataType, ConsumeType>::getTauTypeString() {
0197   if (std::is_same<TauType, reco::PFTau>::value)
0198     return "PFTau";
0199   if (std::is_same<TauType, pat::Tau>::value)
0200     return "PATTau";
0201   throw cms::Exception("TauDiscriminationProducerBase")
0202       << "Unsupported TauType used. You must use either PFTau or PATTau.";
0203 }
0204 
0205 // compile our desired types and make available to linker
0206 template class TauDiscriminationProducerBase<PFTau,
0207                                              TauDiscriminatorContainer,
0208                                              SingleTauDiscriminatorContainer,
0209                                              PFTauDiscriminator>;
0210 template class TauDiscriminationProducerBase<PFTau, PFTauDiscriminator>;
0211 template class TauDiscriminationProducerBase<pat::Tau,
0212                                              TauDiscriminatorContainer,
0213                                              SingleTauDiscriminatorContainer,
0214                                              pat::PATTauDiscriminator>;
0215 template class TauDiscriminationProducerBase<pat::Tau, pat::PATTauDiscriminator>;