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