CMS 3D CMS Logo

AlignmentTwoBoyDecayTrackSelector.cc
Go to the documentation of this file.
1 //Framework
3 
7 
8 //DataFormats
12 
13 //STL
14 #include <cmath>
15 //ROOT
16 #include "TLorentzVector.h"
17 
19 //TODO put those namespaces into functions?
20 using namespace std;
21 using namespace edm;
22 // constructor ----------------------------------------------------------------
23 
26  LogDebug("Alignment") << "> applying two body decay Trackfilter ...";
27  theMassrangeSwitch = cfg.getParameter<bool>("applyMassrangeFilter");
28  if (theMassrangeSwitch) {
29  theMinMass = cfg.getParameter<double>("minXMass");
30  theMaxMass = cfg.getParameter<double>("maxXMass");
31  theDaughterMass = cfg.getParameter<double>("daughterMass");
32  theCandNumber = cfg.getParameter<unsigned int>("numberOfCandidates"); //Number of candidates to keep
33  secThrBool = cfg.getParameter<bool>("applySecThreshold");
34  thesecThr = cfg.getParameter<double>("secondThreshold");
35  LogDebug("Alignment") << "> Massrange min,max : " << theMinMass << "," << theMaxMass
36  << "\n> Mass of daughter Particle : " << theDaughterMass;
37 
38  } else {
39  theMinMass = 0;
40  theMaxMass = 0;
41  theDaughterMass = 0;
42  }
43  theChargeSwitch = cfg.getParameter<bool>("applyChargeFilter");
44  if (theChargeSwitch) {
45  theCharge = cfg.getParameter<int>("charge");
46  theUnsignedSwitch = cfg.getParameter<bool>("useUnsignedCharge");
47  if (theUnsignedSwitch)
49  LogDebug("Alignment") << "> Desired Charge, unsigned: " << theCharge << " , " << theUnsignedSwitch;
50  } else {
51  theCharge = 0;
52  theUnsignedSwitch = true;
53  }
54  theMissingETSwitch = cfg.getParameter<bool>("applyMissingETFilter");
55  if (theMissingETSwitch) {
56  edm::InputTag theMissingETSource = cfg.getParameter<InputTag>("missingETSource");
57  theMissingETToken = iC.consumes<reco::CaloMETCollection>(theMissingETSource);
58  LogDebug("Alignment") << "> missing Et Source: " << theMissingETSource;
59  }
60  theAcoplanarityFilterSwitch = cfg.getParameter<bool>("applyAcoplanarityFilter");
61  if (theAcoplanarityFilterSwitch) {
62  theAcoplanarDistance = cfg.getParameter<double>("acoplanarDistance");
63  LogDebug("Alignment") << "> Acoplanar Distance: " << theAcoplanarDistance;
64  }
65 }
66 
67 // destructor -----------------------------------------------------------------
68 
70 
73  return theMassrangeSwitch || theChargeSwitch || theAcoplanarityFilterSwitch;
74 }
75 
76 // do selection ---------------------------------------------------------------
77 
79  const edm::Event& iEvent,
80  const edm::EventSetup& iSetup) {
82 
83  if (theMassrangeSwitch) {
84  if (theMissingETSwitch)
85  result = checkMETMass(result, iEvent);
86  else
87  result = checkMass(result);
88  }
89 
90  LogDebug("Alignment") << "> TwoBodyDecay tracks all,kept: " << tracks.size() << "," << result.size();
91  return result;
92 }
93 
96  Tracks result;
97 
98  LogDebug("Alignment") << "> cands size : " << cands.size();
99 
100  if (cands.size() < 2)
101  return result;
102 
103  TLorentzVector track0;
104  TLorentzVector track1;
105  TLorentzVector mother;
106  typedef pair<const reco::Track*, const reco::Track*> constTrackPair;
107  typedef pair<double, constTrackPair> candCollectionItem;
108  vector<candCollectionItem> candCollection;
109 
110  for (unsigned int iCand = 0; iCand < cands.size(); iCand++) {
111  track0.SetXYZT(cands.at(iCand)->px(),
112  cands.at(iCand)->py(),
113  cands.at(iCand)->pz(),
114  sqrt(cands.at(iCand)->p() * cands.at(iCand)->p() + theDaughterMass * theDaughterMass));
115 
116  for (unsigned int jCand = iCand + 1; jCand < cands.size(); jCand++) {
117  track1.SetXYZT(cands.at(jCand)->px(),
118  cands.at(jCand)->py(),
119  cands.at(jCand)->pz(),
120  sqrt(cands.at(jCand)->p() * cands.at(jCand)->p() + theDaughterMass * theDaughterMass));
121  if (secThrBool == true && track1.Pt() < thesecThr && track0.Pt() < thesecThr)
122  continue;
123  mother = track0 + track1;
124 
125  const reco::Track* trk1 = cands.at(iCand);
126  const reco::Track* trk2 = cands.at(jCand);
127 
128  bool correctCharge = true;
129  if (theChargeSwitch)
130  correctCharge = this->checkCharge(trk1, trk2);
131 
132  bool acoplanarTracks = true;
133  if (theAcoplanarityFilterSwitch)
134  acoplanarTracks = this->checkAcoplanarity(trk1, trk2);
135 
136  if (mother.M() > theMinMass && mother.M() < theMaxMass && correctCharge && acoplanarTracks) {
137  candCollection.push_back(candCollectionItem(mother.Pt(), constTrackPair(trk1, trk2)));
138  }
139  }
140  }
141 
142  if (candCollection.empty())
143  return result;
144 
145  sort(candCollection.begin(), candCollection.end(), [](auto& a, auto& b) { return a.first > b.first; });
146 
147  std::map<const reco::Track*, unsigned int> uniqueTrackIndex;
148  std::map<const reco::Track*, unsigned int>::iterator it;
149  for (unsigned int i = 0; i < candCollection.size() && i < theCandNumber; i++) {
150  constTrackPair& trackPair = candCollection[i].second;
151 
152  it = uniqueTrackIndex.find(trackPair.first);
153  if (it == uniqueTrackIndex.end()) {
154  result.push_back(trackPair.first);
155  uniqueTrackIndex[trackPair.first] = i;
156  }
157 
158  it = uniqueTrackIndex.find(trackPair.second);
159  if (it == uniqueTrackIndex.end()) {
160  result.push_back(trackPair.second);
161  uniqueTrackIndex[trackPair.second] = i;
162  }
163  }
164 
165  return result;
166 }
167 
170  const Tracks& cands, const edm::Event& iEvent) const {
171  Tracks result;
172 
173  LogDebug("Alignment") << "> cands size : " << cands.size();
174 
175  if (cands.empty())
176  return result;
177 
178  TLorentzVector track;
179  TLorentzVector met4;
180  TLorentzVector mother;
181 
183  iEvent.getByToken(theMissingETToken, missingET);
184  if (!missingET.isValid()) {
185  LogError("Alignment") << "@SUB=AlignmentTwoBodyDecayTrackSelector::checkMETMass"
186  << "> could not optain missingET Collection!";
187  return result;
188  }
189 
190  typedef pair<double, const reco::Track*> candCollectionItem;
191  vector<candCollectionItem> candCollection;
192 
193  for (reco::CaloMETCollection::const_iterator itMET = missingET->begin(); itMET != missingET->end(); ++itMET) {
194  met4.SetXYZT((*itMET).px(), (*itMET).py(), (*itMET).pz(), (*itMET).p());
195 
196  for (unsigned int iCand = 0; iCand < cands.size(); iCand++) {
197  track.SetXYZT(cands.at(iCand)->px(),
198  cands.at(iCand)->py(),
199  cands.at(iCand)->pz(),
200  sqrt(cands.at(iCand)->p() * cands.at(iCand)->p() + theDaughterMass * theDaughterMass));
201 
202  mother = track + met4;
203 
204  const reco::Track* trk = cands.at(iCand);
205  const reco::CaloMET* met = &(*itMET);
206 
207  bool correctCharge = true;
208  if (theChargeSwitch)
209  correctCharge = this->checkCharge(trk);
210 
211  bool acoplanarTracks = true;
212  if (theAcoplanarityFilterSwitch)
213  acoplanarTracks = this->checkMETAcoplanarity(trk, met);
214 
215  if (mother.M() > theMinMass && mother.M() < theMaxMass && correctCharge && acoplanarTracks) {
216  candCollection.push_back(candCollectionItem(mother.Pt(), trk));
217  }
218  }
219  }
220 
221  if (candCollection.empty())
222  return result;
223 
224  sort(candCollection.begin(), candCollection.end(), [](auto& a, auto& b) { return a.first > b.first; });
225 
226  std::map<const reco::Track*, unsigned int> uniqueTrackIndex;
227  std::map<const reco::Track*, unsigned int>::iterator it;
228  for (unsigned int i = 0; i < candCollection.size() && i < theCandNumber; i++) {
229  it = uniqueTrackIndex.find(candCollection[i].second);
230  if (it == uniqueTrackIndex.end()) {
231  result.push_back(candCollection[i].second);
232  uniqueTrackIndex[candCollection[i].second] = i;
233  }
234  }
235 
236  return result;
237 }
238 
241  int sumCharge = trk1->charge();
242  if (trk2)
243  sumCharge += trk2->charge();
244  if (theUnsignedSwitch)
245  sumCharge = std::abs(sumCharge);
246  if (sumCharge == theCharge)
247  return true;
248  return false;
249 }
250 
253  if (fabs(deltaPhi(trk1->phi(), trk2->phi() - M_PI)) < theAcoplanarDistance)
254  return true;
255  return false;
256 }
257 
260  if (fabs(deltaPhi(trk1->phi(), met->phi() - M_PI)) < theAcoplanarDistance)
261  return true;
262  return false;
263 }
264 
265 //===================HELPERS===================
266 
269  int count = 0;
270  LogDebug("Alignment") << ">......................................";
271  for (Tracks::const_iterator it = col.begin(); it < col.end(); ++it, ++count) {
272  LogDebug("Alignment") << "> Track No. " << count << ": p = (" << (*it)->px() << "," << (*it)->py() << ","
273  << (*it)->pz() << ")\n"
274  << "> pT = " << (*it)->pt() << " eta = " << (*it)->eta()
275  << " charge = " << (*it)->charge();
276  }
277  LogDebug("Alignment") << ">......................................";
278 }
Tracks checkMETMass(const Tracks &cands, const edm::Event &iEvent) const
checks if the mass of the mother is in the mass region adding missing E_T
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
AlignmentTwoBodyDecayTrackSelector(const edm::ParameterSet &cfg, edm::ConsumesCollector &iC)
constructor
bool checkCharge(const reco::Track *trk1, const reco::Track *trk2=nullptr) const
checks if the mother has charge = [theCharge]
Log< level::Error, false > LogError
void printTracks(const Tracks &col) const
print Information on Track-Collection
U second(std::pair< T, U > const &p)
bool checkMETAcoplanarity(const reco::Track *trk, const reco::CaloMET *met) const
checks if [cands] contains a acoplanar track w.r.t missing ET (returns empty set if not) ...
int charge() const
track electric charge
Definition: TrackBase.h:596
int iEvent
Definition: GenABIO.cc:224
bool checkAcoplanarity(const reco::Track *trk1, const reco::Track *trk2) const
checks if the [cands] are acoplanar (returns empty set if not)
T sqrt(T t)
Definition: SSEVec.h:19
bool useThisFilter()
returns if any of the Filters is used.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:649
Tracks select(const Tracks &tracks, const edm::Event &iEvent, const edm::EventSetup &iSetup)
select tracks
#define M_PI
Tracks checkMass(const Tracks &cands) const
checks if the mass of the mother is in the mass region
auto const & tracks
cannot be loose
std::vector< reco::CaloMET > CaloMETCollection
collection of CaloMET objects
double b
Definition: hdecay.h:118
bool isValid() const
Definition: HandleBase.h:70
HLT enums.
double a
Definition: hdecay.h:119
col
Definition: cuy.py:1009
#define LogDebug(id)