All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Kaon2HiggsFlux_tool.cc
Go to the documentation of this file.
1 /**
2  *
3  */
4 
5 // Framework Includes
6 #include "art/Framework/Core/EDProducer.h"
7 #include "art/Framework/Principal/Event.h"
8 #include "art/Framework/Principal/Handle.h"
9 #include "art/Framework/Services/Registry/ServiceHandle.h"
10 #include "art/Persistency/Common/PtrMaker.h"
11 #include "art/Utilities/ToolMacros.h"
12 #include "cetlib/cpu_timer.h"
13 #include "fhiclcpp/ParameterSet.h"
14 #include "messagefacility/MessageLogger/MessageLogger.h"
15 #include "CLHEP/Random/RandFlat.h"
16 
17 // local includes
20 
23 
24 // LArSoft includes
25 #include "nugen/EventGeneratorBase/GENIE/EvtTimeShiftFactory.h"
26 #include "nugen/EventGeneratorBase/GENIE/EvtTimeShiftI.h"
27 
28 // ROOT
29 #include "TVector3.h"
30 
31 // std includes
32 #include <string>
33 #include <iostream>
34 #include <memory>
35 
36 #include "TDatabasePDG.h"
37 
38 //------------------------------------------------------------------------------------------------------------------------------------------
39 // implementation follows
40 
41 namespace evgen {
42 namespace ldm {
43 /**
44  * @brief Kaon2HiggsFlux class definiton
45  * Implementation of model taken from:
46  * https://arxiv.org/abs/1909.11670
47  */
49 {
50 public:
51  /**
52  * @brief Constructor
53  */
54  Kaon2HiggsFlux(fhicl::ParameterSet const &pset);
55 
56  /**
57  * @brief Destructor
58  */
60 
61  bool MakeFlux(const simb::MCFlux &flux, MeVPrtlFlux &higgs, double &weight) override;
62  void configure(const fhicl::ParameterSet&) override;
63 
64  double MaxWeight() override;
65 
66 private:
67  // config
68  double fM; //!< Mass of Higgs [GeV]
69  double fMixingAngle; //!< Mixing angle of dark higgs
70  bool fKDAROnly;
71  bool fKDIFOnly;
74 
75  // branching ratios
76  double fKPBR;
77  double fKLBR;
78 };
79 
80 Kaon2HiggsFlux::Kaon2HiggsFlux(fhicl::ParameterSet const &pset):
81  IMeVPrtlStage("Kaon2HiggsFlux"),
82  IMeVPrtlFlux(pset)
83 {
84  this->configure(pset);
85 
86 }
87 
88 //------------------------------------------------------------------------------------------------------------------------------------------
89 
91 {
92 }
93 
94 double higgs_momentum(double kaon_mass, double pion_mass, double higs_mass) {
95  return sqrt(kaon_mass * kaon_mass * kaon_mass * kaon_mass
96  -2 * kaon_mass * kaon_mass * pion_mass * pion_mass
97  -2 * kaon_mass * kaon_mass * higs_mass * higs_mass
98  + pion_mass * pion_mass * pion_mass * pion_mass
99  + higs_mass * higs_mass * higs_mass * higs_mass
100  -2 * pion_mass * pion_mass * higs_mass * higs_mass) / ( 2 * kaon_mass );
101 }
102 
103 // compute branching ratios
104 double KaonPlusBranchingRatio(double higs_mass, double mixing) {
105  double kplus_mass = Constants::Instance().kplus_mass;
106  double piplus_mass = Constants::Instance().piplus_mass;
107  double tquark_mass = Constants::Instance().tquark_mass;
108  double higgs_vev = Constants::Instance().higgs_vev;
109  double abs_VtsVtd_squared = Constants::Instance().abs_VtsVtd_squared;
110 
111  // Kplus width
112  //
113  // matrix element for kplus
114  double M_KP = (1. / 2.) * ( 3. / (16. * M_PI * M_PI * higgs_vev * higgs_vev * higgs_vev)) * (kplus_mass * kplus_mass) * (tquark_mass * tquark_mass) * mixing;
115  double M_KP2 = M_KP * M_KP * abs_VtsVtd_squared;
116 
117  double kplus_width = (2 * higgs_momentum(kplus_mass, piplus_mass, higs_mass)/kplus_mass) * M_KP2 / (16 * M_PI * kplus_mass);
118 
119  // convert to partial lifetime
120  double kplus_2higgs_lifetime = Constants::Instance().hbar / kplus_width;
121 
122  // and branching ratio
123  //
124  // (this higgs decay would make a negligible contribution to the overall lifetime)
125  return Constants::Instance().kplus_lifetime / kplus_2higgs_lifetime;
126 }
127 
128 double KaonLongBranchingRatio(double higs_mass, double mixing) {
129  double klong_mass = Constants::Instance().klong_mass;
130  double pizero_mass = Constants::Instance().pizero_mass;
131  double tquark_mass = Constants::Instance().tquark_mass;
132  double higgs_vev = Constants::Instance().higgs_vev;
133  double rel_VtsVtd_squared = Constants::Instance().rel_VtsVtd_squared;
134 
135  double M_KL = (1. / 2.) * (3. / (16. * M_PI * M_PI * higgs_vev * higgs_vev * higgs_vev)) * (klong_mass * klong_mass) * (tquark_mass * tquark_mass) * mixing;
136  double M_KL2 = M_KL * M_KL * rel_VtsVtd_squared;
137 
138  double klong_width = (2 * higgs_momentum(klong_mass, pizero_mass, higs_mass) / klong_mass) * M_KL2 / (16 * M_PI * klong_mass);
139 
140  double klong_2higgs_lifetime = Constants::Instance().hbar / klong_width;
141 
142  return Constants::Instance().klong_lifetime / klong_2higgs_lifetime;
143 
144 }
145 
146 double SMKaonBR(int kaon_pdg) {
147  // The Kaons in Dk2nu file only include those that decay to neutrinos.
148  //
149  // We want all kaons -- in order to account for this, we divide by the
150  // branching-ratio of kaons to neutrinos
151  //
152  // Taken from:
153  // /cvmfs/minerva.opensciencegrid.org/minerva/beamsim/x86_64/geant4/source/particles/hadrons/mesons/src/G4KaonPlus.cc
154  // /cvmfs/minerva.opensciencegrid.org/minerva/beamsim/x86_64/geant4/source/particles/hadrons/mesons/src/G4KaonZerLong.cc
155  switch (kaon_pdg) {
156  case 321:
157  return 0.6339 /* 5 */ + 0.0559 /* 6 */ + 0.0330 /* 7 */;
158  case -321:
159  return 0.6339 /* 8 */ + 0.0559 /* 9 */ + 0.0330 /* 10 */;
160  case 130:
161  return 0.2020 /* 1 */ + 0.2020 /* 2 */ + 0.1348 /* 3 */ + 0.1348 /* 4 */;
162  default:
163  return -1;
164  }
165 }
166 
167 int PionPdg(int kaon_pdg) {
168  switch (kaon_pdg) {
169  case 321:
170  return 211;
171  case -321:
172  return -211;
173  case 130:
174  return 111;
175  default:
176  return -1;
177  }
178 }
179 
180 //------------------------------------------------------------------------------------------------------------------------------------------
181 void Kaon2HiggsFlux::configure(fhicl::ParameterSet const &pset)
182 {
183  fM = pset.get<double>("M");
184  fMixingAngle = pset.get<double>("MixingAngle");
185  fIgnoreParentDecayTime = pset.get<bool>("IgnoreParentDecayTime");
186  fKDAROnly = pset.get<bool>("KDAROnly", false);
187  fKDIFOnly = pset.get<bool>("KDIFOnly", false);
188  fKDIFandBeamline = pset.get<bool>("KDIFandBeamline", false);
189 
190  // Throw exception for a bad mass value
193  throw cet::exception("Kaon2HiggsFlux Tool: BAD MASS. Configured mass (" + std::to_string(fM) +
194  ") is larger than allowed for K+ (" + std::to_string(Constants::Instance().kplus_mass - Constants::Instance().piplus_mass) + ") and KL (" +
195  std::to_string(Constants::Instance().klong_mass - Constants::Instance().pizero_mass) + " production.");
196  }
197 
198  fKPBR = KaonPlusBranchingRatio(fM, fMixingAngle);
199  fKLBR = KaonLongBranchingRatio(fM, fMixingAngle);
200 
201  std::cout << "K+ branching ratio: " << fKPBR << std::endl;
202  std::cout << "K0 branching ratio: " << fKLBR << std::endl;
203 
204 }
205 
207  // Weight comes from the NuMi importance weight -- max is 100 (add in an epsilon)
208  //
209  // Also get the max BR
210  return 100.0001 * std::max(fKPBR / SMKaonBR(321), fKLBR / SMKaonBR(130));
211 }
212 
213 
214 bool Kaon2HiggsFlux::MakeFlux(const simb::MCFlux &flux, evgen::ldm::MeVPrtlFlux &higgs, double &weight) {
215 
216  // make the kaon parent
217  evgen::ldm::KaonParent kaon(flux);
218  if (!kaon.kaon_pdg) return false; // parent wasn't a kaon
219 
220  // select on the kaon
221  if (fKDAROnly && (kaon.mom.P() > 1e-3 || kaon.pos.Z() < 72000.)) return false; //selects KDAR from absorber only.
222  if (fKDAROnly) std::cout << "FOUND KDAR\n";
223  if (fKDIFOnly && (kaon.mom.P() <= 1e-3)){ // no KDAR allowed (from anywhere). Accepts KDIF from beamline or absorber.
224  std::cout << "found KDAR, skipping to next event\n";
225  return false;
226  }
227  if (fKDIFandBeamline && (kaon.mom.P() <= 1e-3 && kaon.pos.Z() >= 72000.)) return false; //allows for KDAR from decay-pipe, and any KDIF. This option is exactly orthogonal to "KDAROnly" option.
228 
229  TLorentzVector Beam4 = BeamOrigin();
230  // get position in detector frame
231  higgs.pos_beamcoord = kaon.pos;
232  higgs.pos = kaon.pos;
233  higgs.pos.Transform(fBeam2Det);
234  higgs.pos += Beam4;
235 
236  if (fIgnoreParentDecayTime) higgs.pos.SetT(Beam4.T());
237 
238  // get the momentum direction in the kaon parent rest frame
239  double kaon_mass = kaon.mom.M();
240  double higs_mass = fM;
241  double pion_mass = TDatabasePDG::Instance()->GetParticle(PionPdg(kaon.kaon_pdg))->Mass();
242 
243  // ignore if we can't make this higgs
244  if (kaon_mass - pion_mass < higs_mass) return false;
245 
246  // isotropic decay
247  TVector3 kaon_frame_momentum = RandomUnitVector() * higgs_momentum(kaon_mass, pion_mass, higs_mass);
248  std::cout << "Rest frame higgs P: " << higgs_momentum(kaon_mass, pion_mass, higs_mass) << std::endl;
249 
250  // boost to lab frame
251  TLorentzVector mom;
252  mom.SetVectM(kaon_frame_momentum, higs_mass);
253  mom.Boost(kaon.mom.BoostVector());
254 
255  higgs.mom_beamcoord = mom;
256  // rotate to detector frame
257  higgs.mom = mom;
258  higgs.mom.Transform(fBeam2Det);
259 
260  higgs.kmom_beamcoord = kaon.mom;
261  // also save the kaon momentum in the detector frame
262  higgs.kmom = kaon.mom;
263  higgs.kmom.Transform(fBeam2Det);
264 
265  // The weight is the importance weight times the branching-ratio weight
266  weight = kaon.weight / SMKaonBR(kaon.kaon_pdg);
267  if (kaon.kaon_pdg == 130 /* KLong */) {
268  weight = weight * fKLBR;
269  }
270  else { // KPlus or KMinus
271  weight = weight * fKPBR;
272  }
273 
274  // and save the secondary momentum
275  higgs.sec = higgs.kmom - higgs.mom;
276  higgs.sec_beamcoord = higgs.kmom_beamcoord - higgs.mom_beamcoord;
277 
278  // set the mixing
279  higgs.C1 = fMixingAngle;
280  higgs.mass = fM;
281 
282  higgs.kaon_pdg = kaon.kaon_pdg;
283  higgs.generator = 0; // kDissonantHiggs
284  higgs.secondary_pdg = PionPdg(kaon.kaon_pdg);
285  higgs.equiv_enu = EnuLab(flux.fnecm, higgs.kmom, higgs.pos);
286 
287  return true;
288 }
289 
290 DEFINE_ART_CLASS_TOOL(Kaon2HiggsFlux)
291 
292 } // namespace ldm
293 } // namespace evgen
TLorentzVector pos_beamcoord
Definition: MeVPrtlFlux.h:10
TLorentzVector sec_beamcoord
Definition: MeVPrtlFlux.h:17
double KaonLongBranchingRatio(double higs_mass, double mixing)
double abs_VtsVtd_squared
Definition: Constants.h:54
TLorentzVector mom
Definition: MeVPrtlFlux.h:14
void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
double KaonPlusBranchingRatio(double higs_mass, double mixing)
TLorentzVector mom_beamcoord
Definition: MeVPrtlFlux.h:15
Kaon2HiggsFlux(fhicl::ParameterSet const &pset)
Constructor.
double fMixingAngle
Mixing angle of dark higgs.
TLorentzVector kmom
Definition: MeVPrtlFlux.h:13
double fM
Mass of Higgs [GeV].
TLorentzVector pos
Definition: KaonParent.h:12
double higgs_momentum(double kaon_mass, double pion_mass, double higs_mass)
IMeVPrtlStage interface class definiton. General interface behind each stage. Provides random number ...
Definition: IMeVPrtlStage.h:36
TLorentzVector mom
Definition: KaonParent.h:13
static const Constants & Instance()
Definition: Constants.h:68
double rel_VtsVtd_squared
Definition: Constants.h:55
double SMKaonBR(int kaon_pdg)
TLorentzVector BeamOrigin()
Definition: IMeVPrtlFlux.h:107
Kaon2HiggsFlux class definiton Implementation of model taken from: https://arxiv.org/abs/1909.11670.
std::string to_string(WindowPattern const &pattern)
TLorentzVector pos
Definition: MeVPrtlFlux.h:11
do i e
This is an interface for an art Tool which turns MCFlux objects (which is a meson decay to neutrinos)...
double EnuLab(double enucm, TLorentzVector meson_mom, TLorentzVector meson_pos)
Definition: IMeVPrtlFlux.h:119
IMeVPrtlFlux interface class definiton.
Definition: IMeVPrtlFlux.h:39
TLorentzVector kmom_beamcoord
Definition: MeVPrtlFlux.h:12
int PionPdg(int kaon_pdg)
BEGIN_PROLOG could also be cout
bool MakeFlux(const simb::MCFlux &flux, MeVPrtlFlux &higgs, double &weight) override
TLorentzVector sec
Definition: MeVPrtlFlux.h:16