Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:10

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/ConstProductRegistry.h"
0018 #include "FWCore/Framework/interface/Event.h"
0019 #include "FWCore/Framework/interface/EventPrincipal.h"
0020 #include "FWCore/Framework/interface/MakerMacros.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                                                        std::make_shared<BranchIDListHelper>(),
0075                                                        std::make_shared<ThinnedAssociationsHelper>(),
0076                                                        *processConfiguration_,
0077                                                        nullptr);
0078   }
0079 
0080   // Virtual destructor needed.
0081   SecondaryProducer::~SecondaryProducer() {}
0082 
0083   // Functions that get called by framework every event
0084   void SecondaryProducer::produce(Event& e, EventSetup const&) {
0085     using std::placeholders::_1;
0086     size_t fileNameHash = 0U;
0087 
0088     if (specified_) {
0089       // Just for simplicity, we use the event ID from the primary to read the secondary.
0090       std::vector<SecondaryEventIDAndFileInfo> events(1, SecondaryEventIDAndFileInfo(e.id(), fileNameHash));
0091       secInput_->loopSpecified(*eventPrincipal_,
0092                                fileNameHash,
0093                                events.begin(),
0094                                events.end(),
0095                                std::bind(&SecondaryProducer::processOneEvent, this, _1, std::ref(e)));
0096     } else {
0097       CLHEP::HepRandomEngine* engine = nullptr;
0098       if (!sequential_) {
0099         edm::Service<edm::RandomNumberGenerator> rng;
0100         if (!rng.isAvailable()) {
0101           throw cms::Exception("Configuration")
0102               << "SecondaryProducer requires the RandomNumberGeneratorService,\n"
0103                  "which is not present in the configuration file.  You must add the service\n"
0104                  "in the configuration file or remove the modules that require it.";
0105         }
0106         engine = &rng->getEngine(e.streamID());
0107       }
0108       // Just for simplicity, we use the event ID from the primary to read the secondary.
0109       EventID id = e.id();
0110       secInput_->loopOverEvents(*eventPrincipal_,
0111                                 fileNameHash,
0112                                 1,
0113                                 std::bind(&SecondaryProducer::processOneEvent, this, _1, std::ref(e)),
0114                                 engine,
0115                                 &id);
0116     }
0117   }
0118 
0119   bool SecondaryProducer::processOneEvent(EventPrincipal const& eventPrincipal, Event& e) {
0120     typedef edmtest::ThingCollection TC;
0121     typedef Wrapper<TC> WTC;
0122 
0123     EventNumber_t en = eventPrincipal.id().event();
0124     // Check that secondary source products are retrieved from the same event as the EventAuxiliary
0125     BasicHandle bhandle = eventPrincipal.getByLabel(
0126         PRODUCT_TYPE, TypeID(typeid(edmtest::UInt64Product)), "EventNumber", "", "", nullptr, nullptr, nullptr);
0127     assert(bhandle.isValid());
0128     Handle<edmtest::UInt64Product> handle = convert_handle<edmtest::UInt64Product>(std::move(bhandle));
0129     assert(static_cast<EventNumber_t>(handle->value) == en);
0130 
0131     // Check that primary source products are retrieved from the same event as the EventAuxiliary
0132     e.getByLabel<edmtest::UInt64Product>("EventNumber", handle);
0133     assert(static_cast<EventNumber_t>(handle->value) == e.id().event());
0134 
0135     WrapperBase const* ep =
0136         eventPrincipal.getByLabel(PRODUCT_TYPE, TypeID(typeid(TC)), "Thing", "", "", nullptr, nullptr, nullptr)
0137             .wrapper();
0138     assert(ep != nullptr);
0139     WTC const* wtp = static_cast<WTC const*>(ep);
0140     assert(wtp);
0141     TC const* tp = wtp->product();
0142     auto thing = std::make_unique<TC>(*tp);
0143 
0144     // Put output into event
0145     e.put(std::move(thing));
0146 
0147     if (!sequential_ && !specified_ && firstLoop_ && en == 1) {
0148       expectedEventNumber_ = 1;
0149       firstLoop_ = false;
0150     }
0151     if (firstEvent_) {
0152       firstEvent_ = false;
0153       if (!sequential_ && !specified_) {
0154         expectedEventNumber_ = en;
0155       }
0156     }
0157     assert(expectedEventNumber_ == en);
0158     ++expectedEventNumber_;
0159 
0160     return true;
0161   }
0162 
0163   std::shared_ptr<VectorInputSource> SecondaryProducer::makeSecInput(ParameterSet const& ps) {
0164     ParameterSet const& sec_input = ps.getParameterSet("input");
0165     PreallocationConfiguration dummy;
0166     VectorInputSourceDescription desc(productRegistry(), dummy);
0167     std::shared_ptr<VectorInputSource> input_(static_cast<VectorInputSource*>(
0168         VectorInputSourceFactory::get()->makeVectorInputSource(sec_input, desc).release()));
0169     return input_;
0170   }
0171 
0172   void SecondaryProducer::endJob() { secInput_->doEndJob(); }
0173 
0174 }  // namespace edm
0175 using edm::SecondaryProducer;
0176 DEFINE_FWK_MODULE(SecondaryProducer);