CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MixingModule.cc
Go to the documentation of this file.
1 // File: MixingModule.cc
2 // Description: see MixingModule.h
3 // Author: Ursula Berthon, LLR Palaiseau, Bill Tanenbaum
4 //
5 //--------------------------------------------
6 
7 #include "MixingModule.h"
8 #include "MixingWorker.h"
9 
26 
27 namespace edm {
28 
29  // Constructor
31  BMixingModule(ps_mix),
32  inputTagPlayback_(),
33  mixProdStep2_(ps_mix.getParameter<bool>("mixProdStep2")),
34  mixProdStep1_(ps_mix.getParameter<bool>("mixProdStep1")),
35  digiAccumulators_()
36  {
37  if (!mixProdStep1_ && !mixProdStep2_) LogInfo("MixingModule") << " The MixingModule was run in the Standard mode.";
38  if (mixProdStep1_) LogInfo("MixingModule") << " The MixingModule was run in the Step1 mode. It produces a mixed secondary source.";
39  if (mixProdStep2_) LogInfo("MixingModule") << " The MixingModule was run in the Step2 mode. It uses a mixed secondary source.";
40 
42  if (ps_mix.exists("useCurrentProcessOnly")) {
43  useCurrentProcessOnly_=ps_mix.getParameter<bool>("useCurrentProcessOnly");
44  LogInfo("MixingModule") <<" using given Parameter 'useCurrentProcessOnly' ="<<useCurrentProcessOnly_;
45  }
46  std::string labelPlayback;
47  if (ps_mix.exists("LabelPlayback")) {
48  labelPlayback = ps_mix.getParameter<std::string>("LabelPlayback");
49  }
50  if (labelPlayback.empty()) {
51  labelPlayback = ps_mix.getParameter<std::string>("@module_label");
52  }
53  inputTagPlayback_ = InputTag(labelPlayback, "");
54 
55  ParameterSet ps=ps_mix.getParameter<ParameterSet>("mixObjects");
56  std::vector<std::string> names = ps.getParameterNames();
57  for(std::vector<std::string>::iterator it=names.begin();it!= names.end();++it) {
58  ParameterSet pset=ps.getParameter<ParameterSet>((*it));
59  if (!pset.exists("type")) continue; //to allow replacement by empty pset
60  std::string object = pset.getParameter<std::string>("type");
61  std::vector<InputTag> tags=pset.getParameter<std::vector<InputTag> >("input");
62 
63  //if (!mixProdStep2_) {
64 
65  InputTag tagCF = InputTag();
66  std::string labelCF = " ";
67 
68  if (object=="SimTrack") {
69  InputTag tag;
70  if (tags.size()>0) tag=tags[0];
72 
73  branchesActivate(TypeID(typeid(std::vector<SimTrack>)).friendlyClassName(),std::string(""),tag,label);
74  bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
75  if(makeCrossingFrame) {
77  produces<CrossingFrame<SimTrack> >(label);
78  }
79 
80  LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
81  // std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
82 
83  } else if (object=="RecoTrack") {
84  InputTag tag;
85  if (tags.size()>0) tag=tags[0];
87 
88  branchesActivate(TypeID(typeid(std::vector<reco::Track>)).friendlyClassName(),std::string(""),tag,label);
89  // note: no crossing frame is foreseen to be used for this object type
90 
91  LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
92  //std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
93 
94  } else if (object=="SimVertex") {
95  InputTag tag;
96  if (tags.size()>0) tag=tags[0];
98 
99  branchesActivate(TypeID(typeid(std::vector<SimVertex>)).friendlyClassName(),std::string(""),tag,label);
100  bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
101  if(makeCrossingFrame) {
103  produces<CrossingFrame<SimVertex> >(label);
104  }
105 
106  LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag "<<tag.encode()<<", label will be "<<label;
107  // std::cout <<"Will mix "<<object<<"s with InputTag "<<tag.encode()<<", label will be "<<label<<std::endl;
108 
109  } else if (object=="HepMCProduct") {
110  InputTag tag;
111  if (tags.size()>0) tag=tags[0];
113 
114  branchesActivate(TypeID(typeid(HepMCProduct)).friendlyClassName(),std::string(""),tag,label);
115  bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
116  if(makeCrossingFrame) {
118  produces<CrossingFrame<HepMCProduct> >(label);
119  }
120 
121  LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
122  // std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
123 
124  } else if (object=="PCaloHit") {
125  std::vector<std::string> subdets=pset.getParameter<std::vector<std::string> >("subdets");
126  std::vector<std::string> crossingFrames=pset.getUntrackedParameter<std::vector<std::string> >("crossingFrames", std::vector<std::string>());
127  sort_all(crossingFrames);
128  for (unsigned int ii=0;ii<subdets.size();++ii) {
129  InputTag tag;
130  if (tags.size()==1) tag=tags[0];
131  else if(tags.size()>1) tag=tags[ii];
133 
134  branchesActivate(TypeID(typeid(std::vector<PCaloHit>)).friendlyClassName(),subdets[ii],tag,label);
135  if(binary_search_all(crossingFrames, tag.instance())) {
136  workersObjects_.push_back(new MixingWorker<PCaloHit>(minBunch_,maxBunch_,bunchSpace_,subdets[ii],label,labelCF,maxNbSources_,tag,tagCF));
137  produces<CrossingFrame<PCaloHit> >(label);
138  }
139 
140  LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
141  // std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
142 
143  }
144 
145  } else if (object=="PSimHit") {
146  std::vector<std::string> subdets=pset.getParameter<std::vector<std::string> >("subdets");
147  std::vector<std::string> crossingFrames=pset.getUntrackedParameter<std::vector<std::string> >("crossingFrames", std::vector<std::string>());
148  sort_all(crossingFrames);
149  for (unsigned int ii=0;ii<subdets.size();++ii) {
150  InputTag tag;
151  if (tags.size()==1) tag=tags[0];
152  else if(tags.size()>1) tag=tags[ii];
154 
155  branchesActivate(TypeID(typeid(std::vector<PSimHit>)).friendlyClassName(),subdets[ii],tag,label);
156  if(binary_search_all(crossingFrames, tag.instance())) {
157  workersObjects_.push_back(new MixingWorker<PSimHit>(minBunch_,maxBunch_,bunchSpace_,subdets[ii],label,labelCF,maxNbSources_,tag,tagCF));
158  produces<CrossingFrame<PSimHit> >(label);
159  }
160 
161  LogInfo("MixingModule") <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label;
162  // std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
163  }
164  } else {
165  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!";
166  }
167  //} //if for mixProdStep2
168  }//while over the mixObjects parameters
169 
171  for (unsigned int branch=0;branch<wantedBranches_.size();++branch) LogDebug("MixingModule")<<"Will keep branch "<<wantedBranches_[branch]<<" for mixing ";
173 
174  produces<PileupMixingContent>();
175 
176  produces<CrossingFramePlaybackInfoExtended>();
177 
178  // Create and configure digitizers
179  createDigiAccumulators(ps_mix);
180  }
181 
182 
184  ParameterSet const& digiPSet = mixingPSet.getParameterSet("digitizers");
185  std::vector<std::string> digiNames = digiPSet.getParameterNames();
186  for(auto const& digiName : digiNames) {
187  ParameterSet const& pset = digiPSet.getParameterSet(digiName);
188  std::auto_ptr<DigiAccumulatorMixMod> accumulator = std::auto_ptr<DigiAccumulatorMixMod>(DigiAccumulatorMixModFactory::get()->makeDigiAccumulator(pset, *this));
189  // Create appropriate DigiAccumulator
190  if(accumulator.get() != 0) {
191  digiAccumulators_.push_back(accumulator.release());
192  }
193  }
194  }
195 
197  //change the basic parameters.
199  setup.get<MixingRcd>().get(config);
200  minBunch_=config->minBunch();
201  maxBunch_=config->maxBunch();
202  bunchSpace_=config->bunchSpace();
203  //propagate to change the workers
204  for (unsigned int ii=0;ii<workersObjects_.size();++ii){
205  workersObjects_[ii]->reload(setup);
206  }
207  }
208 
210 
211  label=tag.label()+tag.instance();
212  wantedBranches_.push_back(friendlyName + '_' +
213  tag.label() + '_' +
214  tag.instance());
215 
216  //if useCurrentProcessOnly, we have to change the input tag
219  tag = InputTag(tag.label(),tag.instance(),processName);
220  }
221  }
222 
224  if (workers_.empty()){
225  for (unsigned int ii=0;ii<workersObjects_.size();++ii){
226  if (workersObjects_[ii]->checkSignal(e)){
227  workers_.push_back(workersObjects_[ii]);
228  }
229  }
230  }
231  }
232 
234  //create playback info
236  //and CrossingFrames
237  for (unsigned int ii=0;ii<workers_.size();++ii){
238  workers_[ii]->createnewEDProduct();
239  }
240  }
241 
242  // Virtual destructor needed.
244  for (unsigned int ii=0;ii<workersObjects_.size();++ii){
245  delete workersObjects_[ii];
246  }
247 
248  std::vector<DigiAccumulatorMixMod*>::const_iterator accItr = digiAccumulators_.begin();
249  std::vector<DigiAccumulatorMixMod*>::const_iterator accEnd = digiAccumulators_.end();
250  for (; accItr != accEnd; ++accItr) {
251  delete *accItr;
252  }
253  }
254 
256 
257  LogDebug("MixingModule")<<"===============> adding signals for "<<e.id();
258 
259  accumulateEvent(e, setup);
260  // fill in signal part of CrossingFrame
261  for (unsigned int ii=0;ii<workers_.size();++ii) {
262  workers_[ii]->addSignals(e);
263  }
264  }
265 
266  void MixingModule::pileAllWorkers(EventPrincipal const& eventPrincipal,
267  int bunchCrossing, int eventId,
268  int& vertexOffset,
269  const edm::EventSetup& setup) {
270  PileUpEventPrincipal pep(eventPrincipal, bunchCrossing, bunchSpace_, eventId, vertexOffset);
271  accumulateEvent(pep, setup);
272 
273  for (unsigned int ii=0;ii<workers_.size();++ii) {
274  LogDebug("MixingModule") <<" merging Event: id " << eventPrincipal.id();
275  // std::cout <<"PILEALLWORKERS merging Event: id " << eventPrincipal.id() << std::endl;
276 
277  workers_[ii]->addPileups(bunchCrossing,eventPrincipal, eventId, vertexoffset);
278  }
279  }
280 
282  // Don't allocate because PileUp will do it for us.
283  std::vector<edm::EventID> recordEventID;
285  if (playback_) {
286  bool got = e.getByLabel(inputTagPlayback_, playbackInfo_H);
287  if (!got) {
288  throw cms::Exception("MixingProductNotFound") << " No "
289  "CrossingFramePlaybackInfoExtended on the input file, but playback "
290  "option set!!!!! Please change the input file if you really want "
291  "playback!!!!!!" << std::endl;
292  }
293  }
294 
295  // source[0] is "real" pileup. Check to see that this is what we are doing.
296 
297  std::vector<int> PileupList;
298  PileupList.clear();
299  TrueNumInteractions_.clear();
300 
301  boost::shared_ptr<PileUp> source0 = inputSources_[0];
302 
303  if((source0 && source0->doPileUp() ) && !playback_) {
304  // if((!inputSources_[0] || !inputSources_[0]->doPileUp()) && !playback_ )
305 
306  // Pre-calculate all pileup distributions before we go fishing for events
307 
308  source0->CalculatePileup(minBunch_, maxBunch_, PileupList, TrueNumInteractions_);
309 
310  }
311 
312  // for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
313  // std::cout << " bunch ID, Pileup, True " << bunchIdx << " " << PileupList[bunchIdx-minBunch_] << " " << TrueNumInteractions_[bunchIdx-minBunch_] << std::endl;
314  //}
315 
316  int KeepTrackOfPileup = 0;
317 
318  for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
319  for (size_t setBcrIdx=0; setBcrIdx<workers_.size(); ++setBcrIdx) {
320  workers_[setBcrIdx]->setBcrOffset();
321  }
322  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
323  (*accItr)->initializeBunchCrossing(e, setup, bunchIdx);
324  }
325 
326  for (size_t readSrcIdx=0; readSrcIdx<maxNbSources_; ++readSrcIdx) {
327  boost::shared_ptr<PileUp> source = inputSources_[readSrcIdx]; // this looks like we create
328  // new PileUp objects for each
329  // source for each event?
330  // Why?
331  for (size_t setSrcIdx=0; setSrcIdx<workers_.size(); ++setSrcIdx) {
332  workers_[setSrcIdx]->setSourceOffset(readSrcIdx);
333  }
334 
335  if (!source || !source->doPileUp()) continue;
336 
337  int NumPU_Events = 0;
338 
339  if(readSrcIdx ==0 && !playback_) {
340  NumPU_Events = PileupList[bunchIdx - minBunch_];
341  } else {
342  NumPU_Events = 1;
343  } // non-minbias pileup only gets one event for now. Fix later if desired.
344 
345  // int eventId = 0;
346  int vertexOffset = 0;
347 
348  if (!playback_) {
349  inputSources_[readSrcIdx]->readPileUp(e.id(), recordEventID,
350  boost::bind(&MixingModule::pileAllWorkers, boost::ref(*this), _1, bunchIdx,
351  _2, vertexOffset, boost::ref(setup)), NumPU_Events
352  );
353  playbackInfo_->setStartEventId(recordEventID, readSrcIdx, bunchIdx, KeepTrackOfPileup);
354  KeepTrackOfPileup+=NumPU_Events;
355  } else {
356  int dummyId = 0;
357  const std::vector<edm::EventID>& playEventID =
358  playbackInfo_H->getStartEventId(readSrcIdx, bunchIdx);
359  if(readSrcIdx == 0) {
360  PileupList.push_back(playEventID.size());
361  TrueNumInteractions_.push_back(playEventID.size());
362  }
363  inputSources_[readSrcIdx]->playPileUp(
364  playEventID,
365  boost::bind(&MixingModule::pileAllWorkers, boost::ref(*this), _1, bunchIdx,
366  dummyId, vertexOffset, boost::ref(setup))
367  );
368  }
369  }
370  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
371  (*accItr)->finalizeBunchCrossing(e, setup, bunchIdx);
372  }
373  }
374 
375  // Keep track of pileup accounting...
376 
377  std::auto_ptr<PileupMixingContent> PileupMixing_;
378 
379  std::vector<int> numInteractionList;
380  std::vector<int> bunchCrossingList;
381  std::vector<float> TrueInteractionList;
382 
383  //Makin' a list: Basically, we don't care about the "other" sources at this point.
384  for (int bunchCrossing=minBunch_;bunchCrossing<=maxBunch_;++bunchCrossing) {
385  bunchCrossingList.push_back(bunchCrossing);
386  if(!inputSources_[0] || !inputSources_[0]->doPileUp()) {
387  numInteractionList.push_back(0);
388  TrueInteractionList.push_back(0);
389  }
390  else {
391  numInteractionList.push_back(PileupList[bunchCrossing-minBunch_]);
392  TrueInteractionList.push_back((TrueNumInteractions_)[bunchCrossing-minBunch_]);
393  }
394  }
395 
396 
397  PileupMixing_ = std::auto_ptr<PileupMixingContent>(new PileupMixingContent(bunchCrossingList,
398  numInteractionList,
399  TrueInteractionList));
400 
401  e.put(PileupMixing_);
402 
403  // we have to do the ToF transformation for PSimHits once all pileup has been added
404  for (unsigned int ii=0;ii<workers_.size();++ii) {
405  workers_[ii]->setTof();
406  workers_[ii]->put(e);
407  }
408  }
409 
411 
412  if (playbackInfo_) {
413  std::auto_ptr<CrossingFramePlaybackInfoExtended> pOut(playbackInfo_);
414  e.put(pOut);
415  }
416  }
417 
419  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
420  (*accItr)->beginRun(run, setup);
421  }
422  }
423 
425  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
426  (*accItr)->endRun(run, setup);
427  }
428  }
429 
431  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
432  (*accItr)->beginLuminosityBlock(lumi, setup);
433  }
434  }
435 
437  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
438  (*accItr)->endLuminosityBlock(lumi, setup);
439  }
440  }
441 
442  void
444  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
445  (*accItr)->initializeEvent(event, setup);
446  }
447  }
448 
449  void
451  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
452  (*accItr)->accumulate(event, setup);
453  }
454  }
455 
456  void
458  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
459  (*accItr)->accumulate(event, setup);
460  }
461  }
462 
463  void
465  for(Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end(); accItr != accEnd; ++accItr) {
466  (*accItr)->finalizeEvent(event, setup);
467  }
468  }
469 }//edm
#define LogDebug(id)
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
void pileAllWorkers(EventPrincipal const &ep, int bcr, int id, int &offset, const edm::EventSetup &setup)
virtual void reload(const edm::EventSetup &)
virtual ~MixingModule()
MixingModule(const edm::ParameterSet &ps)
Definition: MixingModule.cc:30
static int vertexoffset
Definition: BMixingModule.h:78
virtual void beginLuminosityBlock(LuminosityBlock const &l1, EventSetup const &c) override
static const HistoName names[]
virtual void createnewEDProduct()
tuple lumi
Definition: fjr2json.py:35
std::vector< float > TrueNumInteractions_
Definition: BMixingModule.h:90
virtual void addSignals(const edm::Event &e, const edm::EventSetup &es)
EventID const & id() const
bool exists(std::string const &parameterName) const
checks if a parameter exists
int ii
Definition: cuy.py:588
std::string encode() const
Definition: InputTag.cc:164
virtual void put(edm::Event &e, const edm::EventSetup &es)
void setStartEventId(const std::vector< edm::EventID > &id, const unsigned int s, const int bcr, const int start)
virtual void checkSignal(const edm::Event &e)
std::string friendlyName(std::string const &iFullName)
virtual void endLuminosityBlock(LuminosityBlock const &l1, EventSetup const &c) override
std::vector< MixingWorkerBase * > workers_
Definition: MixingModule.h:91
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:94
Accumulators digiAccumulators_
Definition: MixingModule.h:97
static DigiAccumulatorMixModFactory * get()
static const unsigned int maxNbSources_
Definition: BMixingModule.h:87
std::vector< MixingWorkerBase * > workersObjects_
Definition: MixingModule.h:92
virtual void beginRun(Run const &r1, EventSetup const &c) override
std::vector< std::string > getParameterNames() const
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:361
bool useCurrentProcessOnly_
Definition: MixingModule.h:94
virtual void branchesActivate(const std::string &friendlyName, const std::string &subdet, InputTag &tag, std::string &label)
tuple tags
Definition: o2o.py:248
void finalizeEvent(Event &event, EventSetup const &setup)
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
Definition: Algorithms.h:120
ParameterSet const & getParameterSet(std::string const &) const
constexpr char const * subdets[11]
const T & get() const
Definition: EventSetup.h:55
std::vector< std::string > wantedBranches_
Definition: MixingModule.h:93
InputTag inputTagPlayback_
Definition: MixingModule.h:86
std::string const & label() const
Definition: InputTag.h:42
std::vector< boost::shared_ptr< PileUp > > inputSources_
Definition: BMixingModule.h:95
std::auto_ptr< DigiAccumulatorMixMod > makeDigiAccumulator(ParameterSet const &, EDProducer &) const
edm::EventID id() const
Definition: EventBase.h:56
void accumulateEvent(Event const &event, EventSetup const &setup)
bool binary_search_all(ForwardSequence const &s, Datum const &d)
wrappers for std::binary_search
Definition: Algorithms.h:76
CrossingFramePlaybackInfoExtended * playbackInfo_
Definition: MixingModule.h:89
void dropUnwantedBranches(std::vector< std::string > const &wantedBranches)
void initializeEvent(Event const &event, EventSetup const &setup)
std::string const & instance() const
Definition: InputTag.h:43
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
Definition: Run.h:36
virtual void doPileUp(edm::Event &e, const edm::EventSetup &es)
void createDigiAccumulators(const edm::ParameterSet &mixingPSet)
virtual void endRun(Run const &r1, EventSetup const &c) override