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