CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PileupInformation.cc
Go to the documentation of this file.
1 // File: PileupInformation.cc
2 // Description: adds pileup information object to event
3 // Author: Mike Hildreth
4 //
5 // Adds a vector of PileupSummaryInfo objects to the event.
6 // One for each bunch crossing.
7 //
8 //--------------------------------------------
16 
18 
19 
21 {
22  // Initialize global parameters
23 
24  pTcut_1_ = 0.1;
25  pTcut_2_ = 0.5; // defaults
26  isPreMixed_ = config.getParameter<bool>("isPreMixed");
27 
28  if ( !isPreMixed_ ) {
29  distanceCut_ = config.getParameter<double>("vertexDistanceCut");
30  volumeRadius_ = config.getParameter<double>("volumeRadius");
31  volumeZ_ = config.getParameter<double>("volumeZ");
32  pTcut_1_ = config.getParameter<double>("pTcut_1");
33  pTcut_2_ = config.getParameter<double>("pTcut_2");
34 
35  PileupInfoLabel_ = consumes<PileupMixingContent>(config.getParameter<edm::InputTag>("PileupMixingLabel"));
36 
37  PileupVtxLabel_ = consumes<PileupVertexContent>(config.getParameter<edm::InputTag>("PileupMixingLabel"));
38 
39  LookAtTrackingTruth_ = config.getUntrackedParameter<bool>("doTrackTruth");
40 
41  trackingTruthT_ = mayConsume<TrackingParticleCollection>(config.getParameter<edm::InputTag>("TrackingParticlesLabel"));
42  trackingTruthV_ = mayConsume<TrackingVertexCollection>(config.getParameter<edm::InputTag>("TrackingParticlesLabel"));
43 
44  MessageCategory_ = "PileupInformation";
45 
46  edm::LogInfo (MessageCategory_) << "Setting up PileupInformation";
47  edm::LogInfo (MessageCategory_) << "Vertex distance cut set to " << distanceCut_ << " mm";
48  edm::LogInfo (MessageCategory_) << "Volume radius set to " << volumeRadius_ << " mm";
49  edm::LogInfo (MessageCategory_) << "Volume Z set to " << volumeZ_ << " mm";
50  edm::LogInfo (MessageCategory_) << "Lower pT Threshold set to " << pTcut_1_ << " GeV";
51  edm::LogInfo (MessageCategory_) << "Upper pT Threshold set to " << pTcut_2_ << " GeV";
52  }
53  else{
54  pileupSummaryToken_=consumes<std::vector<PileupSummaryInfo> >(config.getParameter<edm::InputTag>("PileupSummaryInfoInputTag"));
55  bunchSpacingToken_=consumes<int>(config.getParameter<edm::InputTag>("BunchSpacingInputTag"));
56  }
57 
58  produces< std::vector<PileupSummaryInfo> >();
59  produces<int>("bunchSpacing");
60  //produces<PileupSummaryInfo>();
61 }
62 
63 
65 {
66 
67  std::auto_ptr<std::vector<PileupSummaryInfo> > PSIVector(new std::vector<PileupSummaryInfo>);
68 
69  if ( isPreMixed_ ) {
71  event.getByToken(pileupSummaryToken_,psiInput);
72 
73  std::vector<PileupSummaryInfo>::const_iterator PSiter;
74 
75  for(PSiter = psiInput.product()->begin(); PSiter != psiInput.product()->end(); PSiter++){
76 
77  PSIVector->push_back(*PSiter);
78  }
79 
80 
81  edm::Handle< int> bsInput;
82  event.getByToken(bunchSpacingToken_,bsInput);
83  int bunchSpacing=*(bsInput.product());
84 
85  event.put(PSIVector);
86 
87  //add bunch spacing to the event as a seperate integer for use by downstream modules
88  std::auto_ptr<int> bunchSpacingP(new int(bunchSpacing));
89  event.put(bunchSpacingP,"bunchSpacing");
90 
91  return;
92  }
93 
94  edm::Handle< PileupMixingContent > MixingPileup; // Get True pileup information from MixingModule
95  event.getByToken(PileupInfoLabel_, MixingPileup);
96 
97  std::vector<int> BunchCrossings;
98  std::vector<int> Interactions_Xing;
99  std::vector<float> TrueInteractions_Xing;
100  std::vector< std::vector<edm::EventID> > eventInfoList_Xing;
101 
102  int bunchSpacing;
103 
104  const PileupMixingContent* MixInfo = MixingPileup.product();
105 
106  if(MixInfo) { // extract information - way easier than counting vertices
107 
108  const std::vector<int> bunchCrossing = MixInfo->getMix_bunchCrossing();
109  const std::vector<int> interactions = MixInfo->getMix_Ninteractions();
110  const std::vector<float> TrueInteractions = MixInfo->getMix_TrueInteractions();
111  const std::vector<edm::EventID> eventInfoList= MixInfo->getMix_eventInfo();
112 
113  bunchSpacing = MixInfo->getMix_bunchSpacing();
114  unsigned int totalIntPU=0;
115 
116  for(int ib=0; ib<(int)bunchCrossing.size(); ++ib){
117  // std::cout << " bcr, nint " << bunchCrossing[ib] << " " << interactions[ib] << std::endl;
118  BunchCrossings.push_back(bunchCrossing[ib]);
119  Interactions_Xing.push_back(interactions[ib]);
120  TrueInteractions_Xing.push_back(TrueInteractions[ib]);
121 
122  std::vector<edm::EventID> eventInfos;
123  eventInfos.reserve( interactions[ib] );
124  for ( int pu=0; pu< interactions[ib]; pu++) {
125  eventInfos.push_back(eventInfoList[totalIntPU+pu]);
126  }
127  totalIntPU+=(interactions[ib]);
128  eventInfoList_Xing.push_back(eventInfos);
129 
130  }
131  }
132  else{ // have to throw an exception..
133 
134  throw cms::Exception("PileupInformation") << " PileupMixingContent is missing from the event.\n"
135  "There must be some breakdown in the Simulation Chain.\n"
136  "You must run the MixingModule before calling this routine.";
137 
138  }
139 
140  // store information from pileup vertices, if it's in the event. Have to loop on interactions again.
141 
142  edm::Handle< PileupVertexContent > MixingPileupVtx; // Get True pileup information from MixingModule
143  event.getByToken(PileupVtxLabel_, MixingPileupVtx);
144 
145  const PileupVertexContent* MixVtxInfo = MixingPileupVtx.product();
146 
147  std::vector< std::vector<float> > ptHatList_Xing;
148  std::vector< std::vector<float> > zPosList_Xing;
149 
150  bool Have_pThats = false;
151 
152  if(MixVtxInfo) { // extract information - way easier than counting vertices
153 
154 
155  Have_pThats = true;
156 
157  const std::vector<int> bunchCrossing = MixInfo->getMix_bunchCrossing();
158  const std::vector<int> interactions = MixInfo->getMix_Ninteractions();
159 
160  const std::vector<float> PtHatInput = MixVtxInfo->getMix_pT_hats();
161  const std::vector<float> ZposInput = MixVtxInfo->getMix_z_Vtxs();
162 
163  // store information from pileup vertices, if it's in the event:
164 
165  unsigned int totalIntPU=0;
166 
167  for(int ib=0; ib<(int)bunchCrossing.size(); ++ib){
168  // std::cout << " bcr, nint " << bunchCrossing[ib] << " " << interactions[ib] << std::endl;
169 
170  std::vector<float> zposBX;
171  std::vector<float> pthatBX;
172  zposBX.reserve( interactions[ib] );
173  pthatBX.reserve( interactions[ib] );
174  for ( int pu=0; pu< interactions[ib]; pu++) {
175  zposBX.push_back(ZposInput[totalIntPU+pu]);
176  pthatBX.push_back(PtHatInput[totalIntPU+pu]);
177  }
178  totalIntPU+=(interactions[ib]);
179  zPosList_Xing.push_back(zposBX);
180  ptHatList_Xing.push_back(pthatBX);
181 
182  }
183  } // end of VertexInfo block
184 
185 
186  //Now, get information on valid particles that look like they could be in the tracking volume
187 
188 
189  zpositions.clear();
190  sumpT_lowpT.clear();
191  sumpT_highpT.clear();
192  ntrks_lowpT.clear();
193  ntrks_highpT.clear();
194  event_index_.clear();
195 
196  int lastEvent = 0; // zero is the true MC hard-scatter event
197 
198  // int lastBunchCrossing = 0; // 0 is the true bunch crossing, should always come first.
199 
200  bool HaveTrackingParticles = false;
201 
204 
205  TrackingVertexCollection::const_iterator iVtx;
206  TrackingVertexCollection::const_iterator iVtxTest;
207  TrackingParticleCollection::const_iterator iTrackTest;
208 
209  if( LookAtTrackingTruth_ ){
210 
211  if(event.getByToken(trackingTruthT_, mergedPH) && event.getByToken(trackingTruthV_, mergedVH)) {
212 
213  HaveTrackingParticles = true;
214 
215  iVtxTest = mergedVH->begin();
216  iTrackTest = mergedPH->begin();
217  }
218 
219  }
220 
221  int nminb_vtx = 0;
222  // bool First = true;
223  // bool flag_new = false;
224 
225  std::vector<int>::iterator BXIter;
226  std::vector<int>::iterator InteractionsIter = Interactions_Xing.begin();
227  std::vector<float>::iterator TInteractionsIter = TrueInteractions_Xing.begin();
228  std::vector< std::vector<edm::EventID> >::iterator TEventInfoIter = eventInfoList_Xing.begin();
229 
230  std::vector< std::vector<float> >::iterator zPosIter;
231  std::vector< std::vector<float> >::iterator pThatIter;
232 
233  if(Have_pThats) {
234  zPosIter = zPosList_Xing.begin();
235  pThatIter = ptHatList_Xing.begin();
236  }
237 
238  // loop over the bunch crossings and interactions we have extracted
239 
240  for( BXIter = BunchCrossings.begin(); BXIter != BunchCrossings.end(); ++BXIter, ++InteractionsIter, ++TInteractionsIter, ++TEventInfoIter) {
241 
242  //std::cout << "looking for BX: " << (*BXIter) << std::endl;
243 
244  if(HaveTrackingParticles) { // leave open the option of not producing TrackingParticles and just keeping # interactions
245 
246  for (iVtx = iVtxTest; iVtx != mergedVH->end(); ++iVtx) {
247 
248  if(iVtx->eventId().bunchCrossing() == (*BXIter) ) { // found first vertex in this bunch crossing
249 
250  if(iVtx->eventId().event() != lastEvent) {
251 
252  //std::cout << "BX,event " << iVtx->eventId().bunchCrossing() << " " << iVtx->eventId().event() << std::endl;
253 
254  float zpos = 0.;
255  zpos = iVtx->position().z();
256  zpositions.push_back(zpos); //save z position of each vertex
257  sumpT_lowpT.push_back(0.);
258  sumpT_highpT.push_back(0.);
259  ntrks_lowpT.push_back(0);
260  ntrks_highpT.push_back(0);
261 
262  lastEvent = iVtx->eventId().event();
263  iVtxTest = --iVtx; // just for security
264 
265  // turns out events aren't sequential... save map of indices
266 
267  event_index_.insert(myindex::value_type(lastEvent,nminb_vtx));
268 
269  ++nminb_vtx;
270 
271  continue;
272  }
273  }
274  }
275 
276  // next loop over tracks to get information
277 
278  for (TrackingParticleCollection::const_iterator iTrack = iTrackTest; iTrack != mergedPH->end(); ++iTrack)
279  {
280  bool FoundTrk = false;
281 
282  float zpos=0.;
283 
284  if(iTrack->eventId().bunchCrossing() == (*BXIter) && iTrack->eventId().event() > 0 )
285  {
286  FoundTrk = true;
287  int correct_index = event_index_[iTrack->eventId().event()];
288 
289  //std::cout << " track index, correct index " << iTrack->eventId().event() << " " << correct_index << std::endl;
290 
291  zpos = zpositions[correct_index];
292  if(iTrack->matchedHit()>0) {
293  if(fabs(iTrack->parentVertex()->position().z()-zpos)<0.1) { //make sure track really comes from this vertex
294  //std::cout << *iTrack << std::endl;
295  float Tpx = iTrack->p4().px();
296  float Tpy = iTrack->p4().py();
297  float TpT = sqrt(Tpx*Tpx + Tpy*Tpy);
298  if( TpT>pTcut_1_ ) {
299  sumpT_lowpT[correct_index]+=TpT;
300  ++ntrks_lowpT[correct_index];
301  }
302  if( TpT>pTcut_2_ ){
303  sumpT_highpT[correct_index]+=TpT;
304  ++ntrks_highpT[correct_index];
305  }
306  }
307  }
308  }
309  else{
310  if(FoundTrk) {
311 
312  iTrackTest = --iTrack; // reset so we can start over next time
313  --iTrackTest; // just to be sure
314  break;
315  }
316 
317  }
318 
319  } // end of track loop
320 
321  } // end of check that we have TrackingParticles to begin with...
322 
323 
324  // now that we have all of the track information for a given bunch crossing,
325  // make PileupSummary for this one and move on
326 
327  // std::cout << "Making PSI for bunch " << lastBunchCrossing << std::endl;
328 
329  if(!HaveTrackingParticles) { // stick in one value so we don't have empty vectors
330 
331  zpositions.push_back(-999.);
332  sumpT_lowpT.push_back(0.);
333  sumpT_highpT.push_back(0.);
334  ntrks_lowpT.push_back(0);
335  ntrks_highpT.push_back(0);
336 
337  }
338 
339  if(Have_pThats) {
340 
342  (*InteractionsIter),
343  (*zPosIter),
344  sumpT_lowpT,
345  sumpT_highpT,
346  ntrks_lowpT,
347  ntrks_highpT,
348  (*TEventInfoIter),
349  (*pThatIter),
350  (*BXIter),
351  (*TInteractionsIter),
352  bunchSpacing
353  );
354  PSIVector->push_back(PSI_bunch);
355 
356  zPosIter++;
357  pThatIter++;
358  }
359  else{
360 
361  std::vector<float> zposZeros( (*TEventInfoIter).size(), 0);
362  std::vector<float> pThatZeros( (*TEventInfoIter).size(), 0);
363 
365  (*InteractionsIter),
366  zposZeros,
367  sumpT_lowpT,
368  sumpT_highpT,
369  ntrks_lowpT,
370  ntrks_highpT,
371  (*TEventInfoIter),
372  pThatZeros,
373  (*BXIter),
374  (*TInteractionsIter),
375  bunchSpacing
376  );
377 
378  PSIVector->push_back(PSI_bunch);
379  }
380  //std::cout << " " << std::endl;
381  //std::cout << "Adding Bunch Crossing, nint " << (*BXIter) << " " << (*InteractionsIter) << std::endl;
382 
383  //for(int iv = 0; iv<(*InteractionsIter); ++iv){
384 
385  // std::cout << "Z position " << zpositions[iv] << std::endl;
386  // std::cout << "ntrks_lowpT " << ntrks_lowpT[iv] << std::endl;
387  // std::cout << "sumpT_lowpT " << sumpT_lowpT[iv] << std::endl;
388  // std::cout << "ntrks_highpT " << ntrks_highpT[iv] << std::endl;
389  // std::cout << "sumpT_highpT " << sumpT_highpT[iv] << std::endl;
390  //std::cout << iv << " " << PSI_bunch.getPU_EventID()[iv] << std::endl;
391  //}
392 
393 
394 
395  // if(HaveTrackingParticles) lastBunchCrossing = iVtx->eventId().bunchCrossing();
396 
397  event_index_.clear();
398  zpositions.clear();
399  sumpT_lowpT.clear();
400  sumpT_highpT.clear();
401  ntrks_lowpT.clear();
402  ntrks_highpT.clear();
403  nminb_vtx = 0;
404  lastEvent=0;
405 
406 
407  } // end of loop over bunch crossings
408 
409  // put our vector of PileupSummaryInfo objects into the event.
410 
411  event.put(PSIVector);
412 
413  //add bunch spacing to the event as a seperate integer for use by downstream modules
414  std::auto_ptr<int> bunchSpacingP(new int(bunchSpacing));
415  event.put(bunchSpacingP,"bunchSpacing");
416 
417 }
418 
419 
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
edm::EDGetTokenT< PileupMixingContent > PileupInfoLabel_
edm::EDGetTokenT< std::vector< PileupSummaryInfo > > pileupSummaryToken_
int ib
Definition: cuy.py:660
std::string MessageCategory_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:462
const std::vector< float > & getMix_TrueInteractions() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
const std::vector< int > & getMix_bunchCrossing() const
const std::vector< float > & getMix_pT_hats() const
edm::EDGetTokenT< int > bunchSpacingToken_
void produce(edm::Event &, const edm::EventSetup &) override
PileupInformation(const edm::ParameterSet &)
const std::vector< int > & getMix_Ninteractions() const
T sqrt(T t)
Definition: SSEVec.h:18
std::vector< float > sumpT_highpT
const std::vector< edm::EventID > getMix_eventInfo() 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
std::vector< float > zpositions
T const * product() const
Definition: Handle.h:81
std::vector< int > ntrks_lowpT
edm::EDGetTokenT< TrackingParticleCollection > trackingTruthT_
edm::EDGetTokenT< PileupVertexContent > PileupVtxLabel_
const std::vector< float > & getMix_z_Vtxs() const
std::vector< float > sumpT_lowpT
const int & getMix_bunchSpacing() const
edm::EDGetTokenT< TrackingVertexCollection > trackingTruthV_
std::vector< int > ntrks_highpT
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")