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 int KeepTrackOfPileup = 0;
00308
00309 for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
00310 for (size_t setBcrIdx=0; setBcrIdx<workers_.size(); ++setBcrIdx) {
00311 workers_[setBcrIdx]->setBcrOffset();
00312 }
00313 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00314 (*accItr)->initializeBunchCrossing(e, setup, bunchIdx);
00315 }
00316
00317 for (size_t readSrcIdx=0; readSrcIdx<maxNbSources_; ++readSrcIdx) {
00318 boost::shared_ptr<PileUp> source = inputSources_[readSrcIdx];
00319
00320
00321
00322 for (size_t setSrcIdx=0; setSrcIdx<workers_.size(); ++setSrcIdx) {
00323 workers_[setSrcIdx]->setSourceOffset(readSrcIdx);
00324 }
00325
00326 if (!source || !source->doPileUp()) continue;
00327
00328 int NumPU_Events = 0;
00329
00330 if(readSrcIdx ==0 && !playback_) {
00331 NumPU_Events = PileupList[bunchIdx - minBunch_];
00332 } else {
00333 NumPU_Events = 1;
00334 }
00335
00336
00337 int vertexOffset = 0;
00338
00339 if (!playback_) {
00340 inputSources_[readSrcIdx]->readPileUp(e.id(), recordEventID,
00341 boost::bind(&MixingModule::pileAllWorkers, boost::ref(*this), _1, bunchIdx,
00342 _2, vertexOffset, boost::ref(setup)), NumPU_Events
00343 );
00344 playbackInfo_->setStartEventId(recordEventID, readSrcIdx, bunchIdx, KeepTrackOfPileup);
00345 KeepTrackOfPileup+=NumPU_Events;
00346 } else {
00347 int dummyId = 0;
00348 const std::vector<edm::EventID>& playEventID =
00349 playbackInfo_H->getStartEventId(readSrcIdx, bunchIdx);
00350 if(readSrcIdx == 0) {
00351 PileupList.push_back(playEventID.size());
00352 TrueNumInteractions_.push_back(playEventID.size());
00353 }
00354 inputSources_[readSrcIdx]->playPileUp(
00355 playEventID,
00356 boost::bind(&MixingModule::pileAllWorkers, boost::ref(*this), _1, bunchIdx,
00357 dummyId, vertexOffset, boost::ref(setup))
00358 );
00359 }
00360 }
00361 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00362 (*accItr)->finalizeBunchCrossing(e, setup, bunchIdx);
00363 }
00364 }
00365
00366
00367
00368 std::auto_ptr<PileupMixingContent> PileupMixing_;
00369
00370 std::vector<int> numInteractionList;
00371 std::vector<int> bunchCrossingList;
00372 std::vector<float> TrueInteractionList;
00373
00374
00375 for (int bunchCrossing=minBunch_;bunchCrossing<=maxBunch_;++bunchCrossing) {
00376 bunchCrossingList.push_back(bunchCrossing);
00377 if(!inputSources_[0] || !inputSources_[0]->doPileUp()) {
00378 numInteractionList.push_back(0);
00379 TrueInteractionList.push_back(0);
00380 }
00381 else {
00382 numInteractionList.push_back(PileupList[bunchCrossing-minBunch_]);
00383 TrueInteractionList.push_back((TrueNumInteractions_)[bunchCrossing-minBunch_]);
00384 }
00385 }
00386
00387
00388 PileupMixing_ = std::auto_ptr<PileupMixingContent>(new PileupMixingContent(bunchCrossingList,
00389 numInteractionList,
00390 TrueInteractionList));
00391
00392 e.put(PileupMixing_);
00393
00394
00395 for (unsigned int ii=0;ii<workers_.size();++ii) {
00396 workers_[ii]->setTof();
00397 workers_[ii]->put(e);
00398 }
00399 }
00400
00401 void MixingModule::put(edm::Event &e, const edm::EventSetup& setup) {
00402
00403 if (playbackInfo_) {
00404 std::auto_ptr<CrossingFramePlaybackInfoExtended> pOut(playbackInfo_);
00405 e.put(pOut);
00406 }
00407 }
00408
00409 void MixingModule::beginRun(edm::Run& run, edm::EventSetup const& setup) {
00410 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00411 (*accItr)->beginRun(run, setup);
00412 }
00413 }
00414
00415 void MixingModule::endRun(edm::Run& run, edm::EventSetup const& setup) {
00416 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00417 (*accItr)->endRun(run, setup);
00418 }
00419 }
00420
00421 void MixingModule::beginLuminosityBlock(edm::LuminosityBlock& lumi, edm::EventSetup const& setup) {
00422 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00423 (*accItr)->beginLuminosityBlock(lumi, setup);
00424 }
00425 }
00426
00427 void MixingModule::endLuminosityBlock(edm::LuminosityBlock& lumi, edm::EventSetup const& setup) {
00428 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00429 (*accItr)->endLuminosityBlock(lumi, setup);
00430 }
00431 }
00432
00433 void
00434 MixingModule::initializeEvent(edm::Event const& event, edm::EventSetup const& setup) {
00435 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00436 (*accItr)->initializeEvent(event, setup);
00437 }
00438 }
00439
00440 void
00441 MixingModule::accumulateEvent(edm::Event const& event, edm::EventSetup const& setup) {
00442 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00443 (*accItr)->accumulate(event, setup);
00444 }
00445 }
00446
00447 void
00448 MixingModule::accumulateEvent(PileUpEventPrincipal const& event, edm::EventSetup const& setup) {
00449 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00450 (*accItr)->accumulate(event, setup);
00451 }
00452 }
00453
00454 void
00455 MixingModule::finalizeEvent(edm::Event& event, edm::EventSetup const& setup) {
00456 for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
00457 (*accItr)->finalizeEvent(event, setup);
00458 }
00459 }
00460 }