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 //--------------------------------------------
9 
13 
17 
19 
20 
22 {
23  // Initialize global parameters
24 
25  pTcut_1_ = 0.1;
26  pTcut_2_ = 0.5; // defaults
27  distanceCut_ = config.getParameter<double>("vertexDistanceCut");
28  volumeRadius_ = config.getParameter<double>("volumeRadius");
29  volumeZ_ = config.getParameter<double>("volumeZ");
30  pTcut_1_ = config.getParameter<double>("pTcut_1");
31  pTcut_2_ = config.getParameter<double>("pTcut_2");
32 
33  PileupInfoLabel_ = consumes<PileupMixingContent>(config.getParameter<edm::InputTag>("PileupMixingLabel"));
34 
35  LookAtTrackingTruth_ = config.getUntrackedParameter<bool>("doTrackTruth");
36 
37  trackingTruthT_ = mayConsume<TrackingParticleCollection>(config.getParameter<edm::InputTag>("TrackingParticlesLabel"));
38  trackingTruthV_ = mayConsume<TrackingVertexCollection>(config.getParameter<edm::InputTag>("TrackingParticlesLabel"));
39 
40  MessageCategory_ = "PileupInformation";
41 
42  edm::LogInfo (MessageCategory_) << "Setting up PileupInformation";
43  edm::LogInfo (MessageCategory_) << "Vertex distance cut set to " << distanceCut_ << " mm";
44  edm::LogInfo (MessageCategory_) << "Volume radius set to " << volumeRadius_ << " mm";
45  edm::LogInfo (MessageCategory_) << "Volume Z set to " << volumeZ_ << " mm";
46  edm::LogInfo (MessageCategory_) << "Lower pT Threshold set to " << pTcut_1_ << " GeV";
47  edm::LogInfo (MessageCategory_) << "Upper pT Threshold set to " << pTcut_2_ << " GeV";
48 
49 
50  produces< std::vector<PileupSummaryInfo> >();
51  produces<int>("bunchSpacing");
52  //produces<PileupSummaryInfo>();
53 }
54 
55 
57 {
58 
59  std::auto_ptr<std::vector<PileupSummaryInfo> > PSIVector(new std::vector<PileupSummaryInfo>);
60 
61  edm::Handle< PileupMixingContent > MixingPileup; // Get True pileup information from MixingModule
62  event.getByToken(PileupInfoLabel_, MixingPileup);
63 
64  std::vector<int> BunchCrossings;
65  std::vector<int> Interactions_Xing;
66  std::vector<float> TrueInteractions_Xing;
67 
68  int bunchSpacing;
69 
70  const PileupMixingContent* MixInfo = MixingPileup.product();
71 
72  if(MixInfo) { // extract information - way easier than counting vertices
73 
74  const std::vector<int> bunchCrossing = MixInfo->getMix_bunchCrossing();
75  const std::vector<int> interactions = MixInfo->getMix_Ninteractions();
76  const std::vector<float> TrueInteractions = MixInfo->getMix_TrueInteractions();
77 
78  bunchSpacing = MixInfo->getMix_bunchSpacing();
79 
80  for(int ib=0; ib<(int)bunchCrossing.size(); ++ib){
81  // std::cout << " bcr, nint " << bunchCrossing[ib] << " " << interactions[ib] << std::endl;
82  BunchCrossings.push_back(bunchCrossing[ib]);
83  Interactions_Xing.push_back(interactions[ib]);
84  TrueInteractions_Xing.push_back(TrueInteractions[ib]);
85  }
86  }
87  else{ // have to throw an exception..
88 
89  throw cms::Exception("PileupInformation") << " PileupMixingContent is missing from the event.\n"
90  "There must be some breakdown in the Simulation Chain.\n"
91  "You must run the MixingModule before calling this routine.";
92  // end of cut
151  }
152 
153  //Now, get information on valid particles that look like they could be in the tracking volume
154 
155 
156  zpositions.clear();
157  sumpT_lowpT.clear();
158  sumpT_highpT.clear();
159  ntrks_lowpT.clear();
160  ntrks_highpT.clear();
161  event_index_.clear();
162 
163  int lastEvent = 0; // zero is the true MC hard-scatter event
164 
165  // int lastBunchCrossing = 0; // 0 is the true bunch crossing, should always come first.
166 
167  bool HaveTrackingParticles = false;
168 
171 
172  TrackingVertexCollection::const_iterator iVtx;
173  TrackingVertexCollection::const_iterator iVtxTest;
174  TrackingParticleCollection::const_iterator iTrackTest;
175 
176  if( LookAtTrackingTruth_ ){
177 
178  if(event.getByToken(trackingTruthT_, mergedPH) && event.getByToken(trackingTruthV_, mergedVH)) {
179 
180  HaveTrackingParticles = true;
181 
182  iVtxTest = mergedVH->begin();
183  iTrackTest = mergedPH->begin();
184  }
185 
186  }
187 
188  int nminb_vtx = 0;
189  // bool First = true;
190  // bool flag_new = false;
191 
192  std::vector<int>::iterator BXIter;
193  std::vector<int>::iterator InteractionsIter = Interactions_Xing.begin();
194  std::vector<float>::iterator TInteractionsIter = TrueInteractions_Xing.begin();
195 
196  // loop over the bunch crossings and interactions we have extracted
197 
198  for( BXIter = BunchCrossings.begin(); BXIter != BunchCrossings.end(); ++BXIter, ++InteractionsIter, ++TInteractionsIter) {
199 
200  //std::cout << "looking for BX: " << (*BXIter) << std::endl;
201 
202  if(HaveTrackingParticles) { // leave open the option of not producing TrackingParticles and just keeping # interactions
203 
204  for (iVtx = iVtxTest; iVtx != mergedVH->end(); ++iVtx) {
205 
206  if(iVtx->eventId().bunchCrossing() == (*BXIter) ) { // found first vertex in this bunch crossing
207 
208  if(iVtx->eventId().event() != lastEvent) {
209 
210  //std::cout << "BX,event " << iVtx->eventId().bunchCrossing() << " " << iVtx->eventId().event() << std::endl;
211 
212  float zpos = 0.;
213  zpos = iVtx->position().z();
214  zpositions.push_back(zpos); //save z position of each vertex
215  sumpT_lowpT.push_back(0.);
216  sumpT_highpT.push_back(0.);
217  ntrks_lowpT.push_back(0);
218  ntrks_highpT.push_back(0);
219 
220  lastEvent = iVtx->eventId().event();
221  iVtxTest = --iVtx; // just for security
222 
223  // turns out events aren't sequential... save map of indices
224 
225  event_index_.insert(myindex::value_type(lastEvent,nminb_vtx));
226 
227  ++nminb_vtx;
228 
229  continue;
230  }
231  }
232  }
233 
234  // next loop over tracks to get information
235 
236  for (TrackingParticleCollection::const_iterator iTrack = iTrackTest; iTrack != mergedPH->end(); ++iTrack)
237  {
238  bool FoundTrk = false;
239 
240  float zpos=0.;
241 
242  if(iTrack->eventId().bunchCrossing() == (*BXIter) && iTrack->eventId().event() > 0 )
243  {
244  FoundTrk = true;
245  int correct_index = event_index_[iTrack->eventId().event()];
246 
247  //std::cout << " track index, correct index " << iTrack->eventId().event() << " " << correct_index << std::endl;
248 
249  zpos = zpositions[correct_index];
250  if(iTrack->matchedHit()>0) {
251  if(fabs(iTrack->parentVertex()->position().z()-zpos)<0.1) { //make sure track really comes from this vertex
252  //std::cout << *iTrack << std::endl;
253  float Tpx = iTrack->p4().px();
254  float Tpy = iTrack->p4().py();
255  float TpT = sqrt(Tpx*Tpx + Tpy*Tpy);
256  if( TpT>pTcut_1_ ) {
257  sumpT_lowpT[correct_index]+=TpT;
258  ++ntrks_lowpT[correct_index];
259  }
260  if( TpT>pTcut_2_ ){
261  sumpT_highpT[correct_index]+=TpT;
262  ++ntrks_highpT[correct_index];
263  }
264  }
265  }
266  }
267  else{
268  if(FoundTrk) {
269 
270  iTrackTest = --iTrack; // reset so we can start over next time
271  --iTrackTest; // just to be sure
272  break;
273  }
274 
275  }
276 
277  } // end of track loop
278 
279  } // end of check that we have TrackingParticles to begin with...
280 
281 
282  // now that we have all of the track information for a given bunch crossing,
283  // make PileupSummary for this one and move on
284 
285  // std::cout << "Making PSI for bunch " << lastBunchCrossing << std::endl;
286 
287  if(!HaveTrackingParticles) { // stick in one value so we don't have empty vectors
288 
289  zpositions.push_back(-999.);
290  sumpT_lowpT.push_back(0.);
291  sumpT_highpT.push_back(0.);
292  ntrks_lowpT.push_back(0);
293  ntrks_highpT.push_back(0);
294 
295  }
296 
298  (*InteractionsIter),
299  zpositions,
300  sumpT_lowpT,
301  sumpT_highpT,
302  ntrks_lowpT,
303  ntrks_highpT,
304  (*BXIter),
305  (*TInteractionsIter),
306  bunchSpacing
307  );
308 
309  //std::cout << " " << std::endl;
310  //std::cout << "Adding Bunch Crossing, nint " << (*BXIter) << " " << (*InteractionsIter) << std::endl;
311 
312  //for(int iv = 0; iv<(*InteractionsIter); ++iv){
313 
314  // std::cout << "Z position " << zpositions[iv] << std::endl;
315  // std::cout << "ntrks_lowpT " << ntrks_lowpT[iv] << std::endl;
316  // std::cout << "sumpT_lowpT " << sumpT_lowpT[iv] << std::endl;
317  // std::cout << "ntrks_highpT " << ntrks_highpT[iv] << std::endl;
318  // std::cout << "sumpT_highpT " << sumpT_highpT[iv] << std::endl;
319  //}
320 
321  PSIVector->push_back(PSI_bunch);
322 
323  // if(HaveTrackingParticles) lastBunchCrossing = iVtx->eventId().bunchCrossing();
324 
325  event_index_.clear();
326  zpositions.clear();
327  sumpT_lowpT.clear();
328  sumpT_highpT.clear();
329  ntrks_lowpT.clear();
330  ntrks_highpT.clear();
331  nminb_vtx = 0;
332  lastEvent=0;
333 
334 
335  } // end of loop over bunch crossings
336 
337  // put our vector of PileupSummaryInfo objects into the event.
338 
339  event.put(PSIVector);
340 
341  //add bunch spacing to the event as a seperate integer for use by downstream modules
342  std::auto_ptr<int> bunchSpacingP(new int(bunchSpacing));
343  event.put(bunchSpacingP,"bunchSpacing");
344 
345 }
346 
347 
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
edm::EDGetTokenT< PileupMixingContent > PileupInfoLabel_
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
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
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_
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="")