TTTT Analysis  0.1
selection.hpp
Go to the documentation of this file.
1 
34 #ifndef SELECTION_HPP
35 #define SELECTION_HPP
36 
37 #include <vector>
38 #include <algorithm>
39 
40 #include "filval/filval.hpp"
41 #include "filval_root/filval_root.hpp"
42 
43 #include "analysis/common/obj_types.hpp"
44 
45 struct EventSelection{
46  ObsFilter* trilepton;
47  ObsFilter* trilepton_eemu; // OS electron pair + muon+-
48  ObsFilter* trilepton_mumue; // OS muon pair + electron+-
49  ObsFilter* b_jet3;
50  ObsFilter* z_mass_veto;
51 
52  ObsFilter* base_sel;
53 
54  ObsFilter* J4;
55  ObsFilter* J5;
56  ObsFilter* J6;
57 
58  ObsFilter* SR4j;
59  ObsFilter* SR5j;
60  ObsFilter* SR6j;
61 };
62 
63 EventSelection event_selection;
64 
65 void init_selection(){
66  auto leptons = lookup<std::vector<Particle>>("leptons");
67  auto jets = lookup<std::vector<Particle>>("jets");
68 
69  // Require *exactly* three charged leptons
70  event_selection.trilepton = obs_filter("trilepton",GenFunction::register_function<bool()>("trilepton",
71  FUNC(([leptons](){
72  return leptons->get_value().size() == 3;
73  }))));
74 
75  // Require OS electron pair and a muon
76  event_selection.trilepton_eemu = obs_filter("trilepton_eemu",GenFunction::register_function<bool()>("trilepton_eemu",
77  FUNC(([leptons](){
78  std::vector<Particle>& leps = leptons->get_value();
79  if(leps.size() != 3) return false;
80  auto check_id = [](int ref_id){
81  auto fn = [ref_id](const Particle& p){
82  return p.lepton.pdg_id == ref_id;
83  };
84  return fn;
85  };
86  bool has_ep = std::count_if(std::begin(leps), std::end(leps), check_id(-11)) == 1;
87  bool has_en = std::count_if(std::begin(leps), std::end(leps), check_id( 11)) == 1;
88  bool has_mup = std::count_if(std::begin(leps), std::end(leps), check_id(-13)) == 1;
89  bool has_mun = std::count_if(std::begin(leps), std::end(leps), check_id( 13)) == 1;
90 
91  return has_ep && has_en && (has_mup != has_mun);
92  }))));
93 
94  // Require OS muon pair and an electron
95  event_selection.trilepton_mumue = obs_filter("trilepton_mumue",GenFunction::register_function<bool()>("trilepton_mumue",
96  FUNC(([leptons](){
97  std::vector<Particle>& leps = leptons->get_value();
98  if(leps.size() != 3) return false;
99  auto check_id = [](int ref_id){
100  auto fn = [ref_id](const Particle& p){
101  return p.lepton.pdg_id == ref_id;
102  };
103  return fn;
104  };
105  bool has_ep = std::count_if(std::begin(leps), std::end(leps), check_id(-11)) == 1;
106  bool has_en = std::count_if(std::begin(leps), std::end(leps), check_id( 11)) == 1;
107  bool has_mup = std::count_if(std::begin(leps), std::end(leps), check_id(-13)) == 1;
108  bool has_mun = std::count_if(std::begin(leps), std::end(leps), check_id( 13)) == 1;
109 
110  return (has_ep != has_en) && has_mup && has_mun;
111  }))));
112 
113  // Require at least three b-jets
114  event_selection.b_jet3 = obs_filter("b_jet3",GenFunction::register_function<bool()>("b_jet3",
115  FUNC(([jets](){
116  int n_b_jets = 0;
117  for(auto jet : jets->get_value()){
118  if(jet.tag == Particle::JET && jet.jet.b_cmva > 0)
119  n_b_jets++;
120  }
121  return n_b_jets >= 3;
122  }))));
123 
124  // Require all same-flavour OS dilepton combinations are outside the Z mass
125  // window (70,105)
126  event_selection.z_mass_veto = obs_filter("z_mass_veto",GenFunction::register_function<bool()>("z_mass_veto",
127  FUNC(([leptons](){
128  auto& leps = leptons->get_value();
129  int n = leps.size();
130  for(int i = 0; i < n; i++){
131  for(int j = i+1; j < n; j++){
132  const Particle& p1 = leps[i];
133  const Particle& p2 = leps[j];
134  if(abs(p1.lepton.pdg_id) != abs(p2.lepton.pdg_id)) continue;
135  if(p1.lepton.charge == p2.lepton.charge) continue;
136  double m = (p1.v + p2.v).M();
137  if(70 < m && m < 105)
138  return false;
139  }
140  }
141  return true;
142  }))));
143 
144 
145  event_selection.J4 = obs_filter("4jet_selection",GenFunction::register_function<bool()>("4jet_selection",
146  FUNC(([jets](){
147  return jets->get_value().size() >= 4;
148  }))));
149 
150  event_selection.J5 = obs_filter("5jet_selection",GenFunction::register_function<bool()>("5jet_selection",
151  FUNC(([jets](){
152  return jets->get_value().size() >= 5;
153  }))));
154 
155  event_selection.J6 = obs_filter("6jet_selection",GenFunction::register_function<bool()>("6jet_selection",
156  FUNC(([jets](){
157  return jets->get_value().size() >= 6;
158  }))));
159 
160  /* event_selection.base_sel = ObsFilter::conj(event_selection.z_mass_veto, ObsFilter::conj(event_selection.trilepton, event_selection.b_jet3)); */
161  event_selection.base_sel = all({event_selection.z_mass_veto, event_selection.trilepton_eemu, event_selection.b_jet3});
162  event_selection.SR4j = all(event_selection.base_sel, event_selection.J4);
163  event_selection.SR5j = all(event_selection.base_sel, event_selection.J5);
164  event_selection.SR6j = all(event_selection.base_sel, event_selection.J6);
165 }
166 #endif // SELECTION_HPP
ObsFilter * all(const std::vector< ObsFilter *> &&fs)
Return a new filter that is the conjuction of a vector of source filters.
Definition: filter.hpp:60