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 
12 
16 
19 
21 {
22  // Initialize global parameters
23 
24  pTcut_1_ = 0.1;
25  pTcut_2_ = 0.5; // defaults
26  distanceCut_ = config.getParameter<double>("vertexDistanceCut");
27  volumeRadius_ = config.getParameter<double>("volumeRadius");
28  volumeZ_ = config.getParameter<double>("volumeZ");
29  pTcut_1_ = config.getParameter<double>("pTcut_1");
30  pTcut_2_ = config.getParameter<double>("pTcut_2");
31 
32  PileupInfoLabel_ = config.getParameter<std::string>("PileupMixingLabel");
33 
34  trackingTruth_ = config.getParameter<std::string>("TrackingParticlesLabel");
35 
36  simHitLabel_ = config.getParameter<std::string>("simHitLabel");
37 
38  MessageCategory_ = "PileupInformation";
39 
40  edm::LogInfo (MessageCategory_) << "Setting up PileupInformation";
41  edm::LogInfo (MessageCategory_) << "Vertex distance cut set to " << distanceCut_ << " mm";
42  edm::LogInfo (MessageCategory_) << "Volume radius set to " << volumeRadius_ << " mm";
43  edm::LogInfo (MessageCategory_) << "Volume Z set to " << volumeZ_ << " mm";
44  edm::LogInfo (MessageCategory_) << "Lower pT Threshold set to " << pTcut_1_ << " GeV";
45  edm::LogInfo (MessageCategory_) << "Upper pT Threshold set to " << pTcut_2_ << " GeV";
46 
47 
48  produces< std::vector<PileupSummaryInfo> >();
49  //produces<PileupSummaryInfo>();
50 }
51 
52 
54 {
55 
56  std::auto_ptr<std::vector<PileupSummaryInfo> > PSIVector(new std::vector<PileupSummaryInfo>);
57 
58  edm::Handle< PileupMixingContent > MixingPileup; // Get True pileup information from MixingModule
59  event.getByLabel(PileupInfoLabel_, MixingPileup);
60 
61  std::vector<int> BunchCrossings;
62  std::vector<int> Interactions_Xing;
63  std::vector<float> TrueInteractions_Xing;
64 
65  const PileupMixingContent* MixInfo = MixingPileup.product();
66 
67  if(MixInfo) { // extract information - way easier than counting vertices
68 
69  const std::vector<int> bunchCrossing = MixInfo->getMix_bunchCrossing();
70  const std::vector<int> interactions = MixInfo->getMix_Ninteractions();
71  const std::vector<float> TrueInteractions = MixInfo->getMix_TrueInteractions();
72 
73 
74  for(int ib=0; ib<(int)bunchCrossing.size(); ++ib){
75  // std::cout << " bcr, nint " << bunchCrossing[ib] << " " << interactions[ib] << std::endl;
76  BunchCrossings.push_back(bunchCrossing[ib]);
77  Interactions_Xing.push_back(interactions[ib]);
78  TrueInteractions_Xing.push_back(TrueInteractions[ib]);
79  }
80  }
81  else{ //If no Mixing Truth, work with SimVertices (probably should throw an exception, but...)
82 
83  // Collect all the simvertex from the crossing frame
85  if( event.getByLabel("mix", simHitLabel_, cfSimVertexes) ) {
86 
87  // Create a mix collection from one simvertex collection
88  simVertexes_ = std::auto_ptr<MixCollection<SimVertex> >( new MixCollection<SimVertex>(cfSimVertexes.product()) );
89 
90  int index = 0;
91  // Solution to the problem of not having vertexId
92  // bool FirstL = true;
93  EncodedEventIdToIndex vertexId;
94  EncodedEventId oldEventId;
95  unsigned int oldVertexId = 0;
96  int oldBX = -1000;
97  int oldEvent = 0;
98 
99  std::vector<int> BunchCrossings2;
100  std::list<int> Interactions_Xing2;
101 
102 
103  // Loop for finding repeated vertexId (vertexId problem hack)
104  for (MixCollection<SimVertex>::MixItr iterator = simVertexes_->begin(); iterator != simVertexes_->end(); ++iterator, ++index)
105  {
106  // std::cout << " SimVtx eventid, vertexid " << iterator->eventId().event() << " " << iterator->eventId().bunchCrossing() << std::endl;
107  if (!index || iterator->eventId() != oldEventId)
108  {
109  if(iterator->eventId().bunchCrossing()==0 && iterator->eventId().event()==0){
110  continue;
111  }
112  if(iterator->eventId().bunchCrossing() != oldBX) {
113  BunchCrossings2.push_back(iterator->eventId().bunchCrossing());
114  Interactions_Xing2.push_back(iterator->eventId().event());
115  oldBX = iterator->eventId().bunchCrossing();
116  oldEvent = iterator->eventId().event();
117  }
118  else { Interactions_Xing2.pop_back();
119  Interactions_Xing2.push_back(iterator->eventId().event());
120  oldEvent = iterator->eventId().event();
121  }
122 
123 
124  oldEventId = iterator->eventId();
125  oldVertexId = iterator->vertexId();
126  continue;
127  }
128 
129  }
130 
131  std::vector<int>::iterator viter;
132  std::list<int>::iterator liter = Interactions_Xing2.begin();
133 
134  for(viter = BunchCrossings2.begin(); viter != BunchCrossings2.end(); ++viter, ++liter){
135  //std::cout << " bcr, nint from VTX " << (*viter) << " " << (*liter) << std::endl;
136  BunchCrossings.push_back((*viter));
137  Interactions_Xing.push_back((*liter));
138  TrueInteractions_Xing.push_back(-1.); // no idea what the true number is
139  }
140 
141  } // end of "did we find vertices?"
142  } // end of look at SimVertices
143 
144 
145  //Now, get information on valid particles that look like they could be in the tracking volume
146 
147 
148  zpositions.clear();
149  sumpT_lowpT.clear();
150  sumpT_highpT.clear();
151  ntrks_lowpT.clear();
152  ntrks_highpT.clear();
153  event_index_.clear();
154 
155  int lastEvent = 0; // zero is the true MC hard-scatter event
156 
157  int lastBunchCrossing = 0; // 0 is the true bunch crossing, should always come first.
158 
161 
162  bool HaveTrackingParticles = false;
163 
164  TrackingVertexCollection::const_iterator iVtx;
165  TrackingVertexCollection::const_iterator iVtxTest;
166  TrackingParticleCollection::const_iterator iTrackTest;
167 
168 
169  if(event.getByLabel(trackingTruth_, mergedPH) && event.getByLabel(trackingTruth_, mergedVH)) {
170 
171  HaveTrackingParticles = true;
172 
173  iVtxTest = mergedVH->begin();
174  iTrackTest = mergedPH->begin();
175  }
176 
177  int nminb_vtx = 0;
178  // bool First = true;
179  // bool flag_new = false;
180 
181  std::vector<int>::iterator BXIter;
182  std::vector<int>::iterator InteractionsIter = Interactions_Xing.begin();
183  std::vector<float>::iterator TInteractionsIter = TrueInteractions_Xing.begin();
184 
185  // loop over the bunch crossings and interactions we have extracted
186 
187  for( BXIter = BunchCrossings.begin(); BXIter != BunchCrossings.end(); ++BXIter, ++InteractionsIter, ++TInteractionsIter) {
188 
189  //std::cout << "looking for BX: " << (*BXIter) << std::endl;
190 
191  if(HaveTrackingParticles) { // leave open the option of not producing TrackingParticles and just keeping # interactions
192 
193  for (iVtx = iVtxTest; iVtx != mergedVH->end(); ++iVtx) {
194 
195  if(iVtx->eventId().bunchCrossing() == (*BXIter) ) { // found first vertex in this bunch crossing
196 
197  if(iVtx->eventId().event() != lastEvent) {
198 
199  //std::cout << "BX,event " << iVtx->eventId().bunchCrossing() << " " << iVtx->eventId().event() << std::endl;
200 
201  float zpos = 0.;
202  zpos = iVtx->position().z();
203  zpositions.push_back(zpos); //save z position of each vertex
204  sumpT_lowpT.push_back(0.);
205  sumpT_highpT.push_back(0.);
206  ntrks_lowpT.push_back(0);
207  ntrks_highpT.push_back(0);
208 
209  lastEvent = iVtx->eventId().event();
210  iVtxTest = --iVtx; // just for security
211 
212  // turns out events aren't sequential... save map of indices
213 
214  event_index_.insert(myindex::value_type(lastEvent,nminb_vtx));
215 
216  ++nminb_vtx;
217 
218  continue;
219  }
220  }
221  }
222 
223  // next loop over tracks to get information
224 
225  for (TrackingParticleCollection::const_iterator iTrack = iTrackTest; iTrack != mergedPH->end(); ++iTrack)
226  {
227  bool FoundTrk = false;
228 
229  float zpos=0.;
230 
231  if(iTrack->eventId().bunchCrossing() == (*BXIter) && iTrack->eventId().event() > 0 )
232  {
233  FoundTrk = true;
234  int correct_index = event_index_[iTrack->eventId().event()];
235 
236  //std::cout << " track index, correct index " << iTrack->eventId().event() << " " << correct_index << std::endl;
237 
238  zpos = zpositions[correct_index];
239  if(iTrack->matchedHit()>0) {
240  if(fabs(iTrack->parentVertex()->position().z()-zpos)<0.1) { //make sure track really comes from this vertex
241  //std::cout << *iTrack << std::endl;
242  float Tpx = iTrack->p4().px();
243  float Tpy = iTrack->p4().py();
244  float TpT = sqrt(Tpx*Tpx + Tpy*Tpy);
245  if( TpT>pTcut_1_ ) {
246  sumpT_lowpT[correct_index]+=TpT;
247  ++ntrks_lowpT[correct_index];
248  }
249  if( TpT>pTcut_2_ ){
250  sumpT_highpT[correct_index]+=TpT;
251  ++ntrks_highpT[correct_index];
252  }
253  }
254  }
255  }
256  else{
257  if(FoundTrk) {
258 
259  iTrackTest = --iTrack; // reset so we can start over next time
260  --iTrackTest; // just to be sure
261  break;
262  }
263 
264  }
265 
266  } // end of track loop
267 
268  } // end of check that we have TrackingParticles to begin with...
269 
270 
271  // now that we have all of the track information for a given bunch crossing,
272  // make PileupSummary for this one and move on
273 
274  // std::cout << "Making PSI for bunch " << lastBunchCrossing << std::endl;
275 
276  if(!HaveTrackingParticles) { // stick in one value so we don't have empty vectors
277 
278  zpositions.push_back(-999.);
279  sumpT_lowpT.push_back(0.);
280  sumpT_highpT.push_back(0.);
281  ntrks_lowpT.push_back(0);
282  ntrks_highpT.push_back(0);
283 
284  }
285 
287  (*InteractionsIter),
288  zpositions,
289  sumpT_lowpT,
290  sumpT_highpT,
291  ntrks_lowpT,
292  ntrks_highpT,
293  (*BXIter),
294  (*TInteractionsIter)
295  );
296 
297  //std::cout << " " << std::endl;
298  //std::cout << "Adding Bunch Crossing, nint " << (*BXIter) << " " << (*InteractionsIter) << std::endl;
299 
300  //for(int iv = 0; iv<(*InteractionsIter); ++iv){
301 
302  // std::cout << "Z position " << zpositions[iv] << std::endl;
303  // std::cout << "ntrks_lowpT " << ntrks_lowpT[iv] << std::endl;
304  // std::cout << "sumpT_lowpT " << sumpT_lowpT[iv] << std::endl;
305  // std::cout << "ntrks_highpT " << ntrks_highpT[iv] << std::endl;
306  // std::cout << "sumpT_highpT " << sumpT_highpT[iv] << std::endl;
307  //}
308 
309  PSIVector->push_back(PSI_bunch);
310 
311  if(HaveTrackingParticles) lastBunchCrossing = iVtx->eventId().bunchCrossing();
312 
313  event_index_.clear();
314  zpositions.clear();
315  sumpT_lowpT.clear();
316  sumpT_highpT.clear();
317  ntrks_lowpT.clear();
318  ntrks_highpT.clear();
319  nminb_vtx = 0;
320  lastEvent=0;
321 
322 
323  } // end of loop over bunch crossings
324 
325  // put our vector of PileupSummaryInfo objects into the event.
326 
327  event.put(PSIVector);
328 
329 
330 }
331 
332 
T getParameter(std::string const &) const
std::string MessageCategory_
const std::vector< float > & getMix_TrueInteractions() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
const std::vector< int > & getMix_bunchCrossing() const
std::map< EncodedEventId, unsigned int > EncodedEventIdToIndex
PileupInformation(const edm::ParameterSet &)
void produce(edm::Event &, const edm::EventSetup &)
const std::vector< int > & getMix_Ninteractions() const
T sqrt(T t)
Definition: SSEVec.h:28
int bunchCrossing() const
get the detector field from this detid
edm::InputTag PileupInfoLabel_
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
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:355
std::auto_ptr< MixCollection< SimVertex > > simVertexes_
std::vector< int > ntrks_lowpT
T const * product() const
Definition: Handle.h:74
std::vector< float > sumpT_lowpT
edm::InputTag trackingTruth_
std::vector< int > ntrks_highpT
std::string simHitLabel_
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")