CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/SimGeneral/MixingModule/plugins/MixingModule.cc

Go to the documentation of this file.
00001 // File: MixingModule.cc
00002 // Description:  see MixingModule.h
00003 // Author:  Ursula Berthon, LLR Palaiseau, Bill Tanenbaum
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   // Constructor
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; //to allow replacement by empty pset
00060       std::string object = pset.getParameter<std::string>("type");
00061       std::vector<InputTag> tags=pset.getParameter<std::vector<InputTag> >("input");
00062 
00063       //if (!mixProdStep2_) {
00064 
00065           InputTag tagCF = InputTag();
00066           std::string labelCF = " ";
00067 
00068           //SimTracks
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             //            std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
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             //            std::cout <<"Will mix "<<object<<"s with InputTag "<<tag.encode()<<", label will be "<<label<<std::endl;
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             //            std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
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               //              std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
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               //              std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
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       //} //if for mixProdStep2
00159     }//while over the mixObjects parameters
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     // Create and configure digitizers
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         // Create appropriate DigiAccumulator
00181         if(accumulator.get() != 0) {
00182           digiAccumulators_.push_back(accumulator.release());
00183         }
00184     }
00185   }
00186 
00187   void MixingModule::reload(const edm::EventSetup & setup){
00188     //change the basic parameters.
00189     edm::ESHandle<MixingModuleConfig> config;
00190     setup.get<MixingRcd>().get(config);
00191     minBunch_=config->minBunch();
00192     maxBunch_=config->maxBunch();
00193     bunchSpace_=config->bunchSpace();
00194     //propagate to change the workers
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     //if useCurrentProcessOnly, we have to change the input tag
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     //create playback info
00226     playbackInfo_=new CrossingFramePlaybackInfoExtended(minBunch_,maxBunch_,maxNbSources_);
00227     //and CrossingFrames
00228     for (unsigned int ii=0;ii<workers_.size();++ii){
00229       workers_[ii]->createnewEDProduct();
00230     }
00231   }
00232 
00233   // Virtual destructor needed.
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     // fill in signal part of CrossingFrame
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       //      std::cout <<"PILEALLWORKERS merging Event:  id " << eventPrincipal.id() << std::endl;
00267 
00268         workers_[ii]->addPileups(bunchCrossing,eventPrincipal, eventId, vertexoffset);
00269     }
00270   }
00271 
00272   void MixingModule::doPileUp(edm::Event &e, const edm::EventSetup& setup) {
00273     // Don't allocate because PileUp will do it for us.
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     // source[0] is "real" pileup.  Check to see that this is what we are doing.
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       //    if((!inputSources_[0] || !inputSources_[0]->doPileUp()) && !playback_ ) 
00296 
00297       // Pre-calculate all pileup distributions before we go fishing for events
00298 
00299       source0->CalculatePileup(minBunch_, maxBunch_, PileupList, TrueNumInteractions_);
00300 
00301     }
00302 
00303     //    for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
00304     //  std::cout << " bunch ID, Pileup, True " << bunchIdx << " " << PileupList[bunchIdx-minBunch_] << " " <<  TrueNumInteractions_[bunchIdx-minBunch_] << std::endl;
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];   // this looks like we create
00317                                                                         // new PileUp objects for each
00318                                                                         // source for each event?
00319                                                                         // Why?
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         }  // non-minbias pileup only gets one event for now. Fix later if desired.
00333 
00334         //        int eventId = 0;
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     // Keep track of pileup accounting...
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     //Makin' a list: Basically, we don't care about the "other" sources at this point.
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     // we have to do the ToF transformation for PSimHits once all pileup has been added
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 }//edm