42 #include "TLorentzVector.h" 122 : useReco_(iConfig.getParameter<
bool>(
"useReco")),
123 doGen_(iConfig.getParameter<
bool>(
"doGen")),
124 muonEtaCut_(iConfig.getParameter<double>(
"muonEtaCut")),
125 muonPtCut_(iConfig.getParameter<double>(
"muonPtCut")),
126 muondxySigCut_(iConfig.getParameter<double>(
"muondxySigCut")),
127 minMassWindowCut_(iConfig.getParameter<double>(
"minMassWindowCut")),
128 maxMassWindowCut_(iConfig.getParameter<double>(
"maxMassWindowCut")),
129 d0CompatibilityCut_(iConfig.getParameter<double>(
"d0CompatibilityCut")),
130 z0CompatibilityCut_(iConfig.getParameter<double>(
"z0CompatibilityCut")),
131 pTthresholds_(iConfig.getParameter<
std::
vector<double>>(
"pTThresholds")),
145 genPosMuonEta_{-99.},
146 genNegMuonEta_{-99.},
147 genPosMuonPhi_{-99.},
148 genNegMuonPhi_{-99.},
150 genNegMuonPt_{-99.} {
152 tracksToken_ = mayConsume<reco::TrackCollection>(iConfig.getParameter<
edm::InputTag>(
"tracks"));
153 muonsToken_ = mayConsume<reco::MuonCollection>(iConfig.getParameter<
edm::InputTag>(
"muons"));
155 alcaRecoToken_ = mayConsume<reco::TrackCollection>(iConfig.getParameter<
edm::InputTag>(
"muonTracks"));
159 genParticlesToken_ = consumes<edm::View<reco::Candidate>>(iConfig.getParameter<
edm::InputTag>(
"genParticles"));
165 std::sort(pTthresholds_.begin(), pTthresholds_.end(), [](
const double& lhs,
const double& rhs) {
return lhs > rhs; });
168 for (
const auto& thr : pTthresholds_) {
169 edm::LogInfo(
"SagittaBiasNtuplizer") <<
" Threshold: " << thr <<
" ";
173 h_cutFlow =
fs->make<TH1F>(
"cutFlow",
"cutFlow;cut;remaining events", 9, -0.5, 8.5);
183 unsigned int count{0};
186 h_cutFlow->GetXaxis()->SetBinLabel(
count,
label.c_str());
189 h_VertexMatrix =
fs->make<TH2I>(
"VertexMatrix",
190 ";index of closest vertex to #mu_{0};index of closest vertex to #mu_{1}",
197 h_DeltaD0 =
fs->make<TH1F>(
"DeltaD0",
"#Deltad_{0};#Deltad_{0} [cm];events", 100, -0.5, 0.5);
198 h_DeltaDz =
fs->make<TH1F>(
"DeltaDz",
"#Deltad_{z};#Deltad_{z} [cm];events", 100, -1, 1);
199 h_CosOpeningAngle =
fs->make<TH1F>(
"OpeningAngle",
"cos(#gamma(#mu^{+},#mu^{-}));events", 100, -1., 1.);
201 tree_ =
fs->make<TTree>(
"tree",
"My TTree");
202 tree_->Branch(
"mass", &mass_,
"mass/F");
203 tree_->Branch(
"posTrackDz", &posTrackDz_,
"posTrackDz/F");
204 tree_->Branch(
"negTrackDz", &negTrackDz_,
"negTrackDz/F");
205 tree_->Branch(
"posTrackD0", &posTrackD0_,
"posTrackD0/F");
206 tree_->Branch(
"negTrackD0", &negTrackD0_,
"negTrackD0/F");
207 tree_->Branch(
"posTrackEta", &posTrackEta_,
"posTrackEta/F");
208 tree_->Branch(
"negTrackEta", &negTrackEta_,
"negTrackEta/F");
209 tree_->Branch(
"posTrackPhi", &posTrackPhi_,
"posTrackPhi/F");
210 tree_->Branch(
"negTrackPhi", &negTrackPhi_,
"negTrackPhi/F");
211 tree_->Branch(
"posTrackPt", &posTrackPt_,
"posTrackPt/F");
212 tree_->Branch(
"negTrackPt", &negTrackPt_,
"negTrackPt/F");
215 tree_->Branch(
"genPosMuonDz", &genPosMuonDz_,
"genPosMuonDz/F");
216 tree_->Branch(
"genNegMuonDz", &genNegMuonDz_,
"genNegMuonDz/F");
217 tree_->Branch(
"genPosMuonD0", &genPosMuonD0_,
"genPosMuonD0/F");
218 tree_->Branch(
"genNegMuonD0", &genNegMuonD0_,
"genNegMuonD0/F");
219 tree_->Branch(
"genPosMuonEta", &genPosMuonEta_,
"genPosMuonEta/F");
220 tree_->Branch(
"genNegMuonEta", &genNegMuonEta_,
"genNegMuonEta/F");
221 tree_->Branch(
"genPosMuonPhi", &genPosMuonPhi_,
"genPosMuonPhi/F");
222 tree_->Branch(
"genNegMuonPhi", &genNegMuonPhi_,
"genNegMuonPhi/F");
223 tree_->Branch(
"genPosMuonPt", &genPosMuonPt_,
"genPosMuonPt/F");
224 tree_->Branch(
"genNegMuonPt", &genNegMuonPt_,
"genNegMuonPt/F");
235 ->setComment(
"If useReco is true need to specify the muon tracks, otherwise take the ALCARECO Inner tracks");
236 desc.add<
bool>(
"doGen",
false);
241 desc.add<
double>(
"muonEtaCut", 2.5)->setComment(
"muon system acceptance");
242 desc.add<
double>(
"muonPtCut", 12.)->setComment(
"in GeV");
243 desc.add<
double>(
"muondxySigCut", 4.)->setComment(
"significance of the d0 compatibility with closest vertex");
244 desc.add<
double>(
"minMassWindowCut", 70.)->setComment(
"in GeV");
245 desc.add<
double>(
"maxMassWindowCut", 110.)->setComment(
"in GeV");
246 desc.add<
double>(
"d0CompatibilityCut", 0.01)->setComment(
"d0 compatibility between the two muons");
247 desc.add<
double>(
"z0CompatibilityCut", 0.06)->setComment(
"z0 compatibility between the two muons");
248 desc.add<std::vector<double>>(
"pTThresholds", {30., 10.});
257 std::vector<const reco::Track*> myTracks;
262 std::vector<const reco::Muon*> myGoodMuonVector;
267 if (
t->chi2() /
t->ndof() <= 2.5 &&
t->numberOfValidHits() >= 5 &&
269 myGoodMuonVector.emplace_back(&
muon);
274 LogDebug(
"SagittaBiasNtuplizer") <<
"myGoodMuonVector size: " << myGoodMuonVector.size() << std::endl;
276 return lhs->
pt() > rhs->pt();
280 for (
const auto&
muon : myGoodMuonVector) {
281 LogDebug(
"SagittaBiasNtuplizer") <<
"pT: " <<
muon->pt() <<
" ";
283 LogDebug(
"SagittaBiasNtuplizer") << std::endl;
286 if (myGoodMuonVector.size() < 2)
292 if (myGoodMuonVector[0]->
charge() * myGoodMuonVector[1]->charge() > 0)
300 std::vector<const reco::Muon*> theZMuonVector;
301 theZMuonVector.reserve(2);
302 theZMuonVector.emplace_back(myGoodMuonVector[1]);
303 theZMuonVector.emplace_back(myGoodMuonVector[0]);
307 for (
const auto&
muon : theZMuonVector) {
318 LogDebug(
"SagittaBiasNtuplizer") <<
"pushing new track: " <<
i << std::endl;
319 myTracks.emplace_back(theMatch);
324 myTracks.emplace_back(&
muon);
334 if ((myTracks.size() != 2)) {
335 LogTrace(
"SagittaBiasNtuplizer") <<
"Found " << myTracks.size() <<
" muons in the event. Skipping";
339 bool passSameVertex{
true};
340 bool passD0sigCut{
true};
341 bool passPtCut{
true};
342 bool passEtaCut{
true};
343 bool passMassWindow{
true};
344 bool passDeltaD0{
true};
345 bool passDeltaDz{
true};
346 bool passOpeningAngle{
true};
347 double d0[2] = {0., 0.};
348 double dz[2] = {0., 0.};
349 unsigned int vtxIndex[2] = {999, 999};
352 for (
const auto&
track : myTracks) {
364 vtxIndex[
i] = closestVertex.first;
365 d0[
i] =
track->dxy(closestVertex.second.position());
366 dz[
i] =
track->dz(closestVertex.second.position());
369 passD0sigCut =
false;
373 if (
track->charge() > 0) {
391 passSameVertex = (vtxIndex[0] == vtxIndex[1]);
412 TLorentzVector posTrack, negTrack, mother;
415 mother = posTrack + negTrack;
441 passOpeningAngle =
true;
443 if (!passOpeningAngle)
451 for (
const auto&
track : myTracks) {
454 for (
auto g = genPartCollection->
begin();
g != genPartCollection->
end(); ++
g) {
455 if (
g->status() != 1)
461 if (
g->charge() !=
track->charge())
466 auto const&
vtx =
g->vertex();
467 auto const& myBeamSpot =
beamSpot.position(
vtx.z());
468 const auto& theptinv2 = 1 /
g->pt() *
g->pt();
473 if (
g->charge() > 0) {
478 genPosMuonD0_ = -(-(
vtx.x() - myBeamSpot.x()) *
g->py() + (
vtx.y() - myBeamSpot.y()) *
g->px()) /
g->pt();
481 (
vtx.z() - myBeamSpot.z()) -
482 ((
vtx.x() - myBeamSpot.x()) *
g->px() + (
vtx.y() - myBeamSpot.y()) *
g->py()) *
g->pz() * theptinv2;
491 (
vtx.z() - myBeamSpot.z()) -
492 ((
vtx.x() - myBeamSpot.x()) *
g->px() + (
vtx.y() - myBeamSpot.y()) *
g->py()) *
g->pz() * theptinv2;
529 unsigned int index{0}, theIndex{999};
536 const auto& vertexToPoint = vertexPosition -
track->referencePoint();
547 return std::make_pair(theIndex, closestVertex);
const double z0CompatibilityCut_
static const std::string kSharedResource
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< reco::TrackCollection > tracksToken_
SagittaBiasNtuplizer(const edm::ParameterSet &)
double pt() const final
transverse momentum
edm::EDGetTokenT< reco::MuonCollection > muonsToken_
const double minMassWindowCut_
edm::EDGetTokenT< reco::TrackCollection > alcaRecoToken_
double px() const
x coordinate of momentum vector
double py() const
y coordinate of momentum vector
std::vector< Vertex > VertexCollection
collection of Vertex objects
std::vector< Vertex > VertexCollection
edm::EDGetTokenT< edm::View< reco::Candidate > > genParticlesToken_
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
const edm::EDGetTokenT< reco::VertexCollection > vtxToken_
static double constexpr muMass
Muon mass [GeV].
const edm::EDGetTokenT< reco::BeamSpot > bsToken_
const double maxMassWindowCut_
std::vector< double > vec1
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
double openingAngle(const reco::Track *track1, const reco::Track *track2)
Abs< T >::type abs(const T &t)
#define DEFINE_FWK_MODULE(type)
~SagittaBiasNtuplizer() override=default
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Log< level::Info, false > LogInfo
static constexpr float d0
std::pair< unsigned int, reco::Vertex > findClosestVertex(const reco::Track *track1, const reco::VertexCollection &vertices)
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
DecomposeProduct< arg, typename Div::arg > D
void analyze(const edm::Event &event, const edm::EventSetup &setup) override
XYZVectorD XYZVector
spatial vector with cartesian internal representation
XYZPointD XYZPoint
point in space with cartesian internal representation
double pz() const
z coordinate of momentum vector
const double d0CompatibilityCut_
const double muondxySigCut_
const_iterator begin() const
std::vector< double > pTthresholds_
const_iterator end() const