00001
00002
00003
00004
00005
00006
00007 #include "MixingModule.h"
00008 #include "MixingWorker.h"
00009 #include "Adjuster.h"
00010
00011 #include "CondFormats/RunInfo/interface/MixingModuleConfig.h"
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 #include "FWCore/Utilities/interface/EDMException.h"
00014 #include "FWCore/Utilities/interface/Algorithms.h"
00015 #include "FWCore/Framework/interface/ESHandle.h"
00016 #include "FWCore/Framework/interface/EventSetup.h"
00017 #include "FWCore/Framework/interface/TriggerNamesService.h"
00018 #include "FWCore/ServiceRegistry/interface/Service.h"
00019 #include "DataFormats/Common/interface/Handle.h"
00020 #include "DataFormats/Provenance/interface/Provenance.h"
00021 #include "DataFormats/Provenance/interface/BranchDescription.h"
00022 #include "SimDataFormats/CrossingFrame/interface/CrossingFramePlaybackInfoExtended.h"
00023 #include "FWCore/Utilities/interface/TypeID.h"
00024 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixMod.h"
00025 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixModFactory.h"
00026 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
00027
00028 namespace edm {
00029
00030
00031 MixingModule::MixingModule(const edm::ParameterSet& ps_mix) :
00032 BMixingModule(ps_mix),
00033 inputTagPlayback_(),
00034 mixProdStep2_(ps_mix.getParameter<bool>("mixProdStep2")),
00035 mixProdStep1_(ps_mix.getParameter<bool>("mixProdStep1")),
00036 digiAccumulators_()
00037 {
00038 if (!mixProdStep1_ && !mixProdStep2_) LogInfo("MixingModule") << " The MixingModule was run in the Standard mode.";
00039 if (mixProdStep1_) LogInfo("MixingModule") << " The MixingModule was run in the Step1 mode. It produces a mixed secondary source.";
00040 if (mixProdStep2_) LogInfo("MixingModule") << " The MixingModule was run in the Step2 mode. It uses a mixed secondary source.";
00041
00042 useCurrentProcessOnly_=false;
00043 if (ps_mix.exists("useCurrentProcessOnly")) {
00044 useCurrentProcessOnly_=ps_mix.getParameter<bool>("useCurrentProcessOnly");
00045 LogInfo("MixingModule") <<" using given Parameter 'useCurrentProcessOnly' ="<<useCurrentProcessOnly_;
00046 }
00047 std::string labelPlayback;
00048 if (ps_mix.exists("LabelPlayback")) {
00049 labelPlayback = ps_mix.getParameter<std::string>("LabelPlayback");
00050 }
00051 if (labelPlayback.empty()) {
00052 labelPlayback = ps_mix.getParameter<std::string>("@module_label");
00053 }
00054 inputTagPlayback_ = InputTag(labelPlayback, "");
00055
00056 ParameterSet ps=ps_mix.getParameter<ParameterSet>("mixObjects");
00057 std::vector<std::string> names = ps.getParameterNames();
00058 for(std::vector<std::string>::iterator it=names.begin();it!= names.end();++it) {
00059 ParameterSet pset=ps.getParameter<ParameterSet>((*it));
00060 if (!pset.exists("type")) continue;
00061 std::string object = pset.getParameter<std::string>("type");
00062 std::vector<InputTag> tags=pset.getParameter<std::vector<InputTag> >("input");
00063
00064
00065
00066 InputTag tagCF = InputTag();
00067 std::string labelCF = " ";
00068
00069 if (object=="SimTrack") {
00070 InputTag tag;
00071 if (tags.size()>0) tag=tags[0];
00072 std::string label;
00073
00074 branchesActivate(TypeID(typeid(std::vector<SimTrack>)).friendlyClassName(),std::string(""),tag,label);
00075 adjustersObjects_.push_back(new Adjuster<SimTrack>(tag));
00076 bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
00077 if(makeCrossingFrame) {
00078 workersObjects_.push_back(new MixingWorker<SimTrack>(minBunch_,maxBunch_,bunchSpace_,std::string(""),label,labelCF,maxNbSources_,tag,tagCF));
00079 produces<CrossingFrame<SimTrack> >(label);
00080 }
00081
00082 LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
00083
00084
00085 } else if (object=="RecoTrack") {
00086 InputTag tag;
00087 if (tags.size()>0) tag=tags[0];
00088 std::string label;
00089
00090 branchesActivate(TypeID(typeid(std::vector<reco::Track>)).friendlyClassName(),std::string(""),tag,label);
00091
00092
00093 LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
00094
00095
00096 } else if (object=="SimVertex") {
00097 InputTag tag;
00098 if (tags.size()>0) tag=tags[0];
00099 std::string label;
00100
00101 branchesActivate(TypeID(typeid(std::vector<SimVertex>)).friendlyClassName(),std::string(""),tag,label);
00102 adjustersObjects_.push_back(new Adjuster<SimVertex>(tag));
00103 bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
00104 if(makeCrossingFrame) {
00105 workersObjects_.push_back(new MixingWorker<SimVertex>(minBunch_,maxBunch_,bunchSpace_,std::string(""),label,labelCF,maxNbSources_,tag,tagCF));
00106 produces<CrossingFrame<SimVertex> >(label);
00107 }
00108
00109 LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag "<<tag.encode()<<", label will be "<<label;
00110
00111
00112 } else if (object=="HepMCProduct") {
00113 InputTag tag;
00114 if (tags.size()>0) tag=tags[0];
00115 std::string label;
00116
00117 branchesActivate(TypeID(typeid(HepMCProduct)).friendlyClassName(),std::string(""),tag,label);
00118 bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
00119 if(makeCrossingFrame) {
00120 workersObjects_.push_back(new MixingWorker<HepMCProduct>(minBunch_,maxBunch_,bunchSpace_,std::string(""),label,labelCF,maxNbSources_,tag,tagCF));
00121 produces<CrossingFrame<HepMCProduct> >(label);
00122 }
00123
00124 LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
00125
00126
00127 } else if (object=="PCaloHit") {
00128 std::vector<std::string> subdets=pset.getParameter<std::vector<std::string> >("subdets");
00129 std::vector<std::string> crossingFrames=pset.getUntrackedParameter<std::vector<std::string> >("crossingFrames", std::vector<std::string>());
00130 sort_all(crossingFrames);
00131 for (unsigned int ii=0;ii<subdets.size();++ii) {
00132 InputTag tag;
00133 if (tags.size()==1) tag=tags[0];
00134 else if(tags.size()>1) tag=tags[ii];
00135 std::string label;
00136
00137 branchesActivate(TypeID(typeid(std::vector<PCaloHit>)).friendlyClassName(),subdets[ii],tag,label);
00138 adjustersObjects_.push_back(new Adjuster<PCaloHit>(tag));
00139 if(binary_search_all(crossingFrames, tag.instance())) {
00140 workersObjects_.push_back(new MixingWorker<PCaloHit>(minBunch_,maxBunch_,bunchSpace_,subdets[ii],label,labelCF,maxNbSources_,tag,tagCF));
00141 produces<CrossingFrame<PCaloHit> >(label);
00142 }
00143
00144 LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
00145
00146
00147 }
00148
00149 } else if (object=="PSimHit") {
00150 std::vector<std::string> subdets=pset.getParameter<std::vector<std::string> >("subdets");
00151 std::vector<std::string> crossingFrames=pset.getUntrackedParameter<std::vector<std::string> >("crossingFrames", std::vector<std::string>());
00152 sort_all(crossingFrames);
00153 for (unsigned int ii=0;ii<subdets.size();++ii) {
00154 InputTag tag;
00155 if (tags.size()==1) tag=tags[0];
00156 else if(tags.size()>1) tag=tags[ii];
00157 std::string label;
00158
00159 branchesActivate(TypeID(typeid(std::vector<PSimHit>)).friendlyClassName(),subdets[ii],tag,label);
00160 adjustersObjects_.push_back(new Adjuster<PSimHit>(tag));
00161 if(binary_search_all(crossingFrames, tag.instance())) {
00162 workersObjects_.push_back(new MixingWorker<PSimHit>(minBunch_,maxBunch_,bunchSpace_,subdets[ii],label,labelCF,maxNbSources_,tag,tagCF));
00163 produces<CrossingFrame<PSimHit> >(label);
00164 }
00165
00166 LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
00167
00168 }
00169 } else {
00170 LogWarning("MixingModule") <<"You have asked to mix an unknown type of object("<<object<<").\n If you want to include it in mixing, please contact the authors of the MixingModule!";
00171 }
00172
00173 }
00174
00175 sort_all(wantedBranches_);
00176 for (unsigned int branch=0;branch<wantedBranches_.size();++branch) LogDebug("MixingModule")<<"Will keep branch "<<wantedBranches_[branch]<<" for mixing ";
00177 dropUnwantedBranches(wantedBranches_);
00178
00179 produces<PileupMixingContent>();
00180
00181 produces<CrossingFramePlaybackInfoExtended>();
00182
00183
00184 createDigiAccumulators(ps_mix);
00185 }
00186
00187
00188 void MixingModule::createDigiAccumulators(const edm::ParameterSet& mixingPSet) {
00189 ParameterSet const& digiPSet = mixingPSet.getParameterSet("digitizers");
00190 std::vector<std::string> digiNames = digiPSet.getParameterNames();
00191 for(auto const& digiName : digiNames) {
00192 ParameterSet const& pset = digiPSet.getParameterSet(digiName);
00193 std::auto_ptr<DigiAccumulatorMixMod> accumulator = std::auto_ptr<DigiAccumulatorMixMod>(DigiAccumulatorMixModFactory::get()->makeDigiAccumulator(pset, *this));
00194
00195 if(accumulator.get() != 0) {
00196 digiAccumulators_.push_back(accumulator.release());
00197 }
00198 }
00199 }
00200
00201 void MixingModule::reload(const edm::EventSetup & setup){
00202
00203 edm::ESHandle<MixingModuleConfig> config;
00204 setup.get<MixingRcd>().get(config);
00205 minBunch_=config->minBunch();
00206 maxBunch_=config->maxBunch();
00207 bunchSpace_=config->bunchSpace();
00208
00209 for (unsigned int ii=0;ii<workersObjects_.size();++ii){
00210 workersObjects_[ii]->reload(setup);
00211 }
00212 }
00213
00214 void MixingModule::branchesActivate(const std::string &friendlyName, const std::string &subdet, InputTag &tag, std::string &label) {
00215
00216 label=tag.label()+tag.instance();
00217 wantedBranches_.push_back(friendlyName + '_' +
00218 tag.label() + '_' +
00219 tag.instance());
00220
00221
00222 if (useCurrentProcessOnly_) {
00223 const std::string processName = edm::Service<edm::service::TriggerNamesService>()->getProcessName();
00224 tag = InputTag(tag.label(),tag.instance(),processName);
00225 }
00226 }
00227
00228 void MixingModule::checkSignal(const edm::Event &e){
00229 if (adjusters_.empty()){
00230 for (auto const& adjuster : adjustersObjects_) {
00231 if (adjuster->checkSignal(e)){
00232 adjusters_.push_back(adjuster);
00233 }
00234 }
00235 }
00236
00237 if (workers_.empty()){
00238 for (auto const& worker : workersObjects_) {
00239 if (worker->checkSignal(e)){
00240 workers_.push_back(worker);
00241 }
00242 }
00243 }
00244 }
00245
00246 void MixingModule::createnewEDProduct() {
00247
00248 playbackInfo_=new CrossingFramePlaybackInfoExtended(minBunch_,maxBunch_,maxNbSources_);
00249
00250 for (unsigned int ii=0;ii<workers_.size();++ii){
00251 workers_[ii]->createnewEDProduct();
00252 }
00253 }
00254
00255
00256 MixingModule::~MixingModule() {
00257 for (auto& worker : workersObjects_) {
00258 delete worker;
00259 }
00260
00261 for (auto& adjuster : adjustersObjects_) {
00262 delete adjuster;
00263 }
00264
00265 for (auto& digiAccumulator : digiAccumulators_) {
00266 delete digiAccumulator;
00267 }
00268 }
00269
00270 void MixingModule::addSignals(const edm::Event &e, const edm::EventSetup& setup) {
00271
00272 LogDebug("MixingModule")<<"===============> adding signals for "<<e.id();
00273
00274 accumulateEvent(e, setup);
00275
00276 for (unsigned int ii=0;ii<workers_.size();++ii) {
00277 workers_[ii]->addSignals(e);
00278 }
00279 }
00280
00281 void MixingModule::pileAllWorkers(EventPrincipal const& eventPrincipal,
00282 int bunchCrossing, int eventId,
00283 int& vertexOffset,
00284 const edm::EventSetup& setup) {
00285 for (auto const& adjuster : adjusters_) {
00286 adjuster->doOffset(bunchSpace_, bunchCrossing, eventPrincipal, eventId, vertexOffset);
00287 }
00288 PileUpEventPrincipal pep(eventPrincipal, bunchCrossing);
00289 accumulateEvent(pep, setup);
00290
00291 for (auto const& worker : workers_) {
00292 LogDebug("MixingModule") <<" merging Event: id " << eventPrincipal.id();
00293
00294
00295 worker->addPileups(eventPrincipal, eventId);
00296 }
00297 }
00298
00299 void MixingModule::doPileUp(edm::Event &e, const edm::EventSetup& setup) {
00300
00301 std::vector<edm::EventID> recordEventID;
00302 edm::Handle<CrossingFramePlaybackInfoExtended> playbackInfo_H;
00303 if (playback_) {
00304 bool got = e.getByLabel(inputTagPlayback_, playbackInfo_H);
00305 if (!got) {
00306 throw cms::Exception("MixingProductNotFound") << " No "
00307 "CrossingFramePlaybackInfoExtended on the input file, but playback "
00308 "option set!!!!! Please change the input file if you really want "
00309 "playback!!!!!!" << std::endl;
00310 }
00311 }
00312
00313
00314
00315 std::vector<int> PileupList;
00316 PileupList.clear();
00317 TrueNumInteractions_.clear();
00318
00319 boost::shared_ptr<PileUp> source0 = inputSources_[0];
00320
00321 if((source0 && source0->doPileUp() ) && !playback_) {
00322
00323
00324
00325
00326 source0->CalculatePileup(minBunch_, maxBunch_, PileupList, TrueNumInteractions_);
00327
00328 }
00329
00330
00331
00332
00333
00334 int KeepTrackOfPileup = 0;
00335
00336 for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
00337 for (size_t setBcrIdx=0; setBcrIdx<workers_.size(); ++setBcrIdx) {
00338 workers_[setBcrIdx]->setBcrOffset();
00339 }
00340 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00341 (*accItr)->initializeBunchCrossing(e, setup, bunchIdx);
00342 }
00343
00344 for (size_t readSrcIdx=0; readSrcIdx<maxNbSources_; ++readSrcIdx) {
00345 boost::shared_ptr<PileUp> source = inputSources_[readSrcIdx];
00346
00347
00348
00349 for (size_t setSrcIdx=0; setSrcIdx<workers_.size(); ++setSrcIdx) {
00350 workers_[setSrcIdx]->setSourceOffset(readSrcIdx);
00351 }
00352
00353 if (!source || !source->doPileUp()) continue;
00354
00355 int NumPU_Events = 0;
00356
00357 if(readSrcIdx ==0 && !playback_) {
00358 NumPU_Events = PileupList[bunchIdx - minBunch_];
00359 } else {
00360 NumPU_Events = 1;
00361 }
00362
00363
00364 int vertexOffset = 0;
00365
00366 if (!playback_) {
00367 inputSources_[readSrcIdx]->readPileUp(e.id(), recordEventID,
00368 boost::bind(&MixingModule::pileAllWorkers, boost::ref(*this), _1, bunchIdx,
00369 _2, vertexOffset, boost::ref(setup)), NumPU_Events
00370 );
00371 playbackInfo_->setStartEventId(recordEventID, readSrcIdx, bunchIdx, KeepTrackOfPileup);
00372 KeepTrackOfPileup+=NumPU_Events;
00373 } else {
00374 int dummyId = 0;
00375 const std::vector<edm::EventID>& playEventID =
00376 playbackInfo_H->getStartEventId(readSrcIdx, bunchIdx);
00377 if(readSrcIdx == 0) {
00378 PileupList.push_back(playEventID.size());
00379 TrueNumInteractions_.push_back(playEventID.size());
00380 }
00381 inputSources_[readSrcIdx]->playPileUp(
00382 playEventID,
00383 boost::bind(&MixingModule::pileAllWorkers, boost::ref(*this), _1, bunchIdx,
00384 dummyId, vertexOffset, boost::ref(setup))
00385 );
00386 }
00387 }
00388 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00389 (*accItr)->finalizeBunchCrossing(e, setup, bunchIdx);
00390 }
00391 }
00392
00393
00394
00395 std::auto_ptr<PileupMixingContent> PileupMixing_;
00396
00397 std::vector<int> numInteractionList;
00398 std::vector<int> bunchCrossingList;
00399 std::vector<float> TrueInteractionList;
00400
00401
00402 for (int bunchCrossing=minBunch_;bunchCrossing<=maxBunch_;++bunchCrossing) {
00403 bunchCrossingList.push_back(bunchCrossing);
00404 if(!inputSources_[0] || !inputSources_[0]->doPileUp()) {
00405 numInteractionList.push_back(0);
00406 TrueInteractionList.push_back(0);
00407 }
00408 else {
00409 numInteractionList.push_back(PileupList[bunchCrossing-minBunch_]);
00410 TrueInteractionList.push_back((TrueNumInteractions_)[bunchCrossing-minBunch_]);
00411 }
00412 }
00413
00414
00415 PileupMixing_ = std::auto_ptr<PileupMixingContent>(new PileupMixingContent(bunchCrossingList,
00416 numInteractionList,
00417 TrueInteractionList));
00418
00419 e.put(PileupMixing_);
00420
00421
00422 for (unsigned int ii=0;ii<workers_.size();++ii) {
00423 workers_[ii]->setTof();
00424 workers_[ii]->put(e);
00425 }
00426 }
00427
00428 void MixingModule::put(edm::Event &e, const edm::EventSetup& setup) {
00429
00430 if (playbackInfo_) {
00431 std::auto_ptr<CrossingFramePlaybackInfoExtended> pOut(playbackInfo_);
00432 e.put(pOut);
00433 }
00434 }
00435
00436 void MixingModule::beginRun(edm::Run const& run, edm::EventSetup const& setup) {
00437 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00438 (*accItr)->beginRun(run, setup);
00439 }
00440 }
00441
00442 void MixingModule::endRun(edm::Run const& run, edm::EventSetup const& setup) {
00443 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00444 (*accItr)->endRun(run, setup);
00445 }
00446 }
00447
00448 void MixingModule::beginLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) {
00449 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00450 (*accItr)->beginLuminosityBlock(lumi, setup);
00451 }
00452 }
00453
00454 void MixingModule::endLuminosityBlock(edm::LuminosityBlock const & lumi, edm::EventSetup const& setup) {
00455 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00456 (*accItr)->endLuminosityBlock(lumi, setup);
00457 }
00458 }
00459
00460 void
00461 MixingModule::initializeEvent(edm::Event const& event, edm::EventSetup const& setup) {
00462 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00463 (*accItr)->initializeEvent(event, setup);
00464 }
00465 }
00466
00467 void
00468 MixingModule::accumulateEvent(edm::Event const& event, edm::EventSetup const& setup) {
00469 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00470 (*accItr)->accumulate(event, setup);
00471 }
00472 }
00473
00474 void
00475 MixingModule::accumulateEvent(PileUpEventPrincipal const& event, edm::EventSetup const& setup) {
00476 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00477 (*accItr)->accumulate(event, setup);
00478 }
00479 }
00480
00481 void
00482 MixingModule::finalizeEvent(edm::Event& event, edm::EventSetup const& setup) {
00483 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00484 (*accItr)->finalizeEvent(event, setup);
00485 }
00486 }
00487 }
00488