Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-25 08:30:08

0001 // File: SecondaryProducer.cc
0002 // Description:  see SecondaryProducer.h
0003 // Author:  Bill Tanenbaum
0004 //
0005 //--------------------------------------------
0006 
0007 #include "IOPool/SecondaryInput/test/SecondaryProducer.h"
0008 #include "DataFormats/Common/interface/ConvertHandle.h"
0009 #include "DataFormats/Common/interface/Handle.h"
0010 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
0011 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
0012 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
0013 #include "DataFormats/Provenance/interface/ThinnedAssociationsHelper.h"
0014 #include "DataFormats/TestObjects/interface/OtherThingCollection.h"
0015 #include "DataFormats/TestObjects/interface/ThingCollection.h"
0016 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/EventPrincipal.h"
0019 #include "FWCore/Framework/interface/MakerMacros.h"
0020 #include "FWCore/Framework/interface/ProductResolversFactory.h"
0021 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
0022 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0023 #include "FWCore/Framework/interface/SignallingProductRegistry.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0026 #include "FWCore/ServiceRegistry/interface/Service.h"
0027 #include "FWCore/Sources/interface/VectorInputSource.h"
0028 #include "FWCore/Sources/interface/VectorInputSourceDescription.h"
0029 #include "FWCore/Sources/interface/VectorInputSourceFactory.h"
0030 #include "FWCore/Utilities/interface/GetPassID.h"
0031 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0032 #include "FWCore/Utilities/interface/TypeID.h"
0033 #include "FWCore/Version/interface/GetReleaseVersion.h"
0034 
0035 #include "FWCore/ServiceRegistry/interface/Service.h"
0036 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0037 #include "FWCore/Utilities/interface/Exception.h"
0038 
0039 #include <memory>
0040 #include <string>
0041 
0042 namespace CLHEP {
0043   class HepRandomEngine;
0044 }
0045 
0046 namespace edm {
0047 
0048   // Constructor
0049   // make secondary input source
0050   SecondaryProducer::SecondaryProducer(ParameterSet const& pset)
0051       : productRegistry_(new SignallingProductRegistry),
0052         secInput_(makeSecInput(pset)),
0053         processConfiguration_(new ProcessConfiguration(std::string("PROD"), getReleaseVersion(), getPassID())),
0054         eventPrincipal_(),
0055         sequential_(pset.getUntrackedParameter<bool>("seq", false)),
0056         specified_(pset.getUntrackedParameter<bool>("specified", false)),
0057         firstEvent_(true),
0058         firstLoop_(true),
0059         expectedEventNumber_(
0060             sequential_ ? pset.getParameterSet("input").getUntrackedParameter<unsigned int>("skipEvents", 0) + 1 : 1) {
0061     processConfiguration_->setParameterSetID(ParameterSet::emptyParameterSetID());
0062     processConfiguration_->setProcessConfigurationID();
0063 
0064     productRegistry_->setFrozen();
0065 
0066     produces<edmtest::ThingCollection>();
0067     produces<edmtest::OtherThingCollection>("testUserTag");
0068     consumes<edmtest::UInt64Product>(edm::InputTag{"EventNumber"});
0069   }
0070 
0071   void SecondaryProducer::beginJob() {
0072     // propagate_const<T> has no reset() function
0073     eventPrincipal_ = std::make_unique<EventPrincipal>(secInput_->productRegistry(),
0074                                                        edm::productResolversFactory::makePrimary,
0075                                                        std::make_shared<BranchIDListHelper>(),
0076                                                        std::make_shared<ThinnedAssociationsHelper>(),
0077                                                        *processConfiguration_,
0078                                                        nullptr);
0079   }
0080 
0081   // Virtual destructor needed.
0082   SecondaryProducer::~SecondaryProducer() {}
0083 
0084   // Functions that get called by framework every event
0085   void SecondaryProducer::produce(Event& e, EventSetup const&) {
0086     using std::placeholders::_1;
0087     size_t fileNameHash = 0U;
0088 
0089     if (specified_) {
0090       // Just for simplicity, we use the event ID from the primary to read the secondary.
0091       std::vector<SecondaryEventIDAndFileInfo> events(1, SecondaryEventIDAndFileInfo(e.id(), fileNameHash));
0092       secInput_->loopSpecified(*eventPrincipal_,
0093                                fileNameHash,
0094                                events.begin(),
0095                                events.end(),
0096                                std::bind(&SecondaryProducer::processOneEvent, this, _1, std::ref(e)));
0097     } else {
0098       CLHEP::HepRandomEngine* engine = nullptr;
0099       if (!sequential_) {
0100         edm::Service<edm::RandomNumberGenerator> rng;
0101         if (!rng.isAvailable()) {
0102           throw cms::Exception("Configuration")
0103               << "SecondaryProducer requires the RandomNumberGeneratorService,\n"
0104                  "which is not present in the configuration file.  You must add the service\n"
0105                  "in the configuration file or remove the modules that require it.";
0106         }
0107         engine = &rng->getEngine(e.streamID());
0108       }
0109       // Just for simplicity, we use the event ID from the primary to read the secondary.
0110       EventID id = e.id();
0111       secInput_->loopOverEvents(*eventPrincipal_,
0112                                 fileNameHash,
0113                                 1,
0114                                 std::bind(&SecondaryProducer::processOneEvent, this, _1, std::ref(e)),
0115                                 engine,
0116                                 &id);
0117     }
0118   }
0119 
0120   bool SecondaryProducer::processOneEvent(EventPrincipal const& eventPrincipal, Event& e) {
0121     typedef edmtest::ThingCollection TC;
0122     typedef Wrapper<TC> WTC;
0123 
0124     EventNumber_t en = eventPrincipal.id().event();
0125     // Check that secondary source products are retrieved from the same event as the EventAuxiliary
0126     BasicHandle bhandle = eventPrincipal.getByLabel(
0127         PRODUCT_TYPE, TypeID(typeid(edmtest::UInt64Product)), "EventNumber", "", "", nullptr, nullptr, nullptr);
0128     assert(bhandle.isValid());
0129     Handle<edmtest::UInt64Product> handle = convert_handle<edmtest::UInt64Product>(std::move(bhandle));
0130     assert(static_cast<EventNumber_t>(handle->value) == en);
0131 
0132     // Check that primary source products are retrieved from the same event as the EventAuxiliary
0133     e.getByLabel<edmtest::UInt64Product>("EventNumber", handle);
0134     assert(static_cast<EventNumber_t>(handle->value) == e.id().event());
0135 
0136     WrapperBase const* ep =
0137         eventPrincipal.getByLabel(PRODUCT_TYPE, TypeID(typeid(TC)), "Thing", "", "", nullptr, nullptr, nullptr)
0138             .wrapper();
0139     assert(ep != nullptr);
0140     WTC const* wtp = static_cast<WTC const*>(ep);
0141     assert(wtp);
0142     TC const* tp = wtp->product();
0143     auto thing = std::make_unique<TC>(*tp);
0144 
0145     // Put output into event
0146     e.put(std::move(thing));
0147 
0148     if (!sequential_ && !specified_ && firstLoop_ && en == 1) {
0149       expectedEventNumber_ = 1;
0150       firstLoop_ = false;
0151     }
0152     if (firstEvent_) {
0153       firstEvent_ = false;
0154       if (!sequential_ && !specified_) {
0155         expectedEventNumber_ = en;
0156       }
0157     }
0158     assert(expectedEventNumber_ == en);
0159     ++expectedEventNumber_;
0160 
0161     return true;
0162   }
0163 
0164   std::shared_ptr<VectorInputSource> SecondaryProducer::makeSecInput(ParameterSet const& ps) {
0165     ParameterSet const& sec_input = ps.getParameterSet("input");
0166     PreallocationConfiguration dummy;
0167     VectorInputSourceDescription desc(productRegistry(), dummy);
0168     std::shared_ptr<VectorInputSource> input_(static_cast<VectorInputSource*>(
0169         VectorInputSourceFactory::get()->makeVectorInputSource(sec_input, desc).release()));
0170     return input_;
0171   }
0172 
0173   void SecondaryProducer::endJob() { secInput_->doEndJob(); }
0174 
0175 }  // namespace edm
0176 using edm::SecondaryProducer;
0177 DEFINE_FWK_MODULE(SecondaryProducer);