CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/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     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];   // this looks like we create
00319                                                                         // new PileUp objects for each
00320                                                                         // source for each event?
00321                                                                         // Why?
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         }  // non-minbias pileup only gets one event for now. Fix later if desired.
00335 
00336         //        int eventId = 0;
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     // Keep track of pileup accounting...
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     //Makin' a list: Basically, we don't care about the "other" sources at this point.
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     // we have to do the ToF transformation for PSimHits once all pileup has been added
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 }//edm