diff --git a/include/obscura/Direct_Detection_Ionization.hpp b/include/obscura/Direct_Detection_Ionization.hpp index abb4a91..78fb4f0 100644 --- a/include/obscura/Direct_Detection_Ionization.hpp +++ b/include/obscura/Direct_Detection_Ionization.hpp @@ -82,4 +82,4 @@ class DM_Detector_Ionization : public DM_Detector } // namespace obscura -#endif \ No newline at end of file +#endif diff --git a/include/obscura/Experiments.hpp b/include/obscura/Experiments.hpp index 5d633ce..62040ce 100644 --- a/include/obscura/Experiments.hpp +++ b/include/obscura/Experiments.hpp @@ -20,6 +20,9 @@ extern DM_Detector_Ionization_ER XENON10_S2_ER(); extern DM_Detector_Ionization_ER XENON100_S2_ER(); extern DM_Detector_Ionization_ER XENON1T_S2_ER(); extern DM_Detector_Ionization_ER DarkSide50_S2_ER(); +extern DM_Detector_Ionization_ER DarkSide50_S2_ER_2023(); +extern DM_Detector_Ionization_ER PandaX_4T_S2_ER(); +extern DM_Detector_Ionization_ER LZ_S2_ER(); //3. Electron recoil experiments - Semiconductor/crystals extern DM_Detector_Crystal protoSENSEI_at_Surface(); @@ -27,12 +30,16 @@ extern DM_Detector_Crystal protoSENSEI_at_MINOS(); extern DM_Detector_Crystal SENSEI_at_MINOS(); extern DM_Detector_Crystal CDMS_HVeV_2018(); extern DM_Detector_Crystal CDMS_HVeV_2020(); +extern DM_Detector_Crystal DAMIC_M_2023(); //4. Migdal experiments - Ionization extern DM_Detector_Ionization_Migdal XENON10_S2_Migdal(); extern DM_Detector_Ionization_Migdal XENON100_S2_Migdal(); extern DM_Detector_Ionization_Migdal XENON1T_S2_Migdal(); extern DM_Detector_Ionization_Migdal DarkSide50_S2_Migdal(); +extern DM_Detector_Ionization_Migdal DarkSide50_S2_Migdal_2023(); +extern DM_Detector_Ionization_Migdal PandaX_4T_S2_Migdal(); +extern DM_Detector_Ionization_Migdal LZ_S2_Migdal(); } // namespace obscura diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 2e915dc..10ed87d 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -492,6 +492,12 @@ void Configuration::Construct_DM_Detector() DM_detector = new DM_Detector_Ionization_ER(XENON1T_S2_ER()); else if(DD_experiment == "DarkSide-50_S2") DM_detector = new DM_Detector_Ionization_ER(DarkSide50_S2_ER()); + else if(DD_experiment == "DarkSide-50_S2_2023") + DM_detector = new DM_Detector_Ionization_ER(DarkSide50_S2_ER_2023()); + else if(DD_experiment == "PandaX-4T_S2") + DM_detector = new DM_Detector_Ionization_ER(PandaX_4T_S2_ER()); + else if(DD_experiment == "LZ_S2") + DM_detector = new DM_Detector_Ionization_ER(LZ_S2_ER()); else if(DD_experiment == "XENON10_S2_Migdal") DM_detector = new DM_Detector_Ionization_Migdal(XENON10_S2_Migdal()); @@ -501,6 +507,12 @@ void Configuration::Construct_DM_Detector() DM_detector = new DM_Detector_Ionization_Migdal(XENON1T_S2_Migdal()); else if(DD_experiment == "DarkSide-50_S2_Migdal") DM_detector = new DM_Detector_Ionization_Migdal(DarkSide50_S2_Migdal()); + else if(DD_experiment == "DarkSide-50_S2_Migdal_2023") + DM_detector = new DM_Detector_Ionization_Migdal(DarkSide50_S2_Migdal_2023()); + else if(DD_experiment == "PandaX-4T_S2_Migdal") + DM_detector = new DM_Detector_Ionization_Migdal(PandaX_4T_S2_Migdal()); + else if(DD_experiment == "LZ_S2_Migdal") + DM_detector = new DM_Detector_Ionization_Migdal(LZ_S2_Migdal()); else if(DD_experiment == "protoSENSEI@surface") DM_detector = new DM_Detector_Crystal(protoSENSEI_at_Surface()); @@ -512,6 +524,8 @@ void Configuration::Construct_DM_Detector() DM_detector = new DM_Detector_Crystal(CDMS_HVeV_2018()); else if(DD_experiment == "CDMS-HVeV_2020") DM_detector = new DM_Detector_Crystal(CDMS_HVeV_2020()); + else if(DD_experiment == "DAMIC-M_2023") + DM_detector = new DM_Detector_Crystal(DAMIC_M_2023()); else { diff --git a/src/Direct_Detection.cpp b/src/Direct_Detection.cpp index 355ea89..1c36d77 100644 --- a/src/Direct_Detection.cpp +++ b/src/Direct_Detection.cpp @@ -25,7 +25,7 @@ double DM_Detector::Log_Likelihood(DM_Particle& DM, DM_Distribution& DM_distr) double s = DM_Signals_Total(DM, DM_distr); unsigned long int n = observed_events; double b = expected_background; - // if(b < 1.0e-4 && (n > s)) b = n-s; // see eq.(29) of [arXiv:1705.07920] + if(b < 1.0e-4 && (n > s)) b = n-s; // see eq.(29) of [arXiv:1705.07920] return libphysica::Log_Likelihood_Poisson(s, n, b); } else if(statistical_analysis == "Binned Poisson") @@ -33,8 +33,8 @@ double DM_Detector::Log_Likelihood(DM_Particle& DM, DM_Distribution& DM_distr) std::vector s = DM_Signals_Binned(DM, DM_distr); std::vector n = bin_observed_events; std::vector b = bin_expected_background; - // for(unsigned int i = 0; i < b.size(); i++) - // if(b[i] < 1.0e-4 && (n[i] > s[i])) b[i] = n[i]-s[i]; // see eq.(29) of [arXiv:1705.07920] + for(unsigned int i = 0; i < b.size(); i++) + if(b[i] < 1.0e-4 && (n[i] > s[i])) b[i] = n[i]-s[i]; // see eq.(29) of [arXiv:1705.07920] return libphysica::Log_Likelihood_Poisson_Binned(s, n, b); } else if(statistical_analysis == "Maximum Gap") diff --git a/src/Direct_Detection_Ionization.cpp b/src/Direct_Detection_Ionization.cpp index d62c8d1..5a147de 100644 --- a/src/Direct_Detection_Ionization.cpp +++ b/src/Direct_Detection_Ionization.cpp @@ -396,10 +396,10 @@ void DM_Detector_Ionization::Print_Summary(int MPI_rank) const << "\tPE (S2) bins:\t\t" << (using_S2_bins ? "[x]" : "[ ]") << std::endl; if(using_S2_bins || using_S2_threshold) { - std::cout << "\tmu_PE:\t\t" << S2_mu << std::endl - << "\tsigma_PE:\t" << S2_sigma << std::endl - << "\tImported trigger efficiencies:\t" << (Trigger_Efficiency_PE.empty() ? "[ ]" : "[x]") << std::endl - << "\tImported acc. efficiencies:\t" << (Acceptance_Efficiency_PE.empty() ? "[ ]" : "[x]") << std::endl; + std::cout << "\tmu_PE:\t\t" << S2_mu << std::endl + << "\tsigma_PE:\t" << S2_sigma << std::endl + << "\tImported trigger efficiencies:\t" << (Trigger_Efficiency_PE.empty() ? "[ ]" : "[x]") << std::endl + << "\tImported acc. efficiencies:\t" << (Acceptance_Efficiency_PE.empty() ? "[ ]" : "[x]") << std::endl; if(using_S2_bins) { std::cout << "\n\t\tBin\tBin range [S2]" << std::endl; diff --git a/src/Direct_Detection_Migdal.cpp b/src/Direct_Detection_Migdal.cpp index 3de232b..2182cff 100644 --- a/src/Direct_Detection_Migdal.cpp +++ b/src/Direct_Detection_Migdal.cpp @@ -9,11 +9,11 @@ namespace obscura { using namespace libphysica::natural_units; -double vMinimal_Migdal(double ER, double Ee, double mDM, double mN) +double vMinimal_Migdal(double ER, double Ee, double mDM, double mN, double binding_energy) { //eq 5 of https://arxiv.org/pdf/1711.09906.pdf double mu = libphysica::Reduced_Mass(mDM, mN); - return sqrt(mN * ER / 2.0 / mu / mu) + Ee / sqrt(2.0 * mN * ER); + return sqrt(mN * ER / 2.0 / mu / mu) + (Ee + binding_energy) / sqrt(2.0 * mN * ER); } double dRdEe_Ionization_Migdal(double Ee, const DM_Particle& DM, DM_Distribution& DM_distr, const Isotope& isotope, Atomic_Electron& shell) @@ -21,7 +21,7 @@ double dRdEe_Ionization_Migdal(double Ee, const DM_Particle& DM, DM_Distribution double NT = 1.0 / isotope.mass; std::function ER_integrand = [Ee, &DM, &DM_distr, &isotope, &shell](double ER) { - double vMin = (ER > 0) ? vMinimal_Migdal(ER, Ee, DM.mass, isotope.mass) : 1.0e-20 * cm / sec; + double vMin = (ER > 0) ? vMinimal_Migdal(ER, Ee, DM.mass, isotope.mass, shell.binding_energy) : 1.0e-20 * cm / sec; if(vMin >= DM_distr.Maximum_DM_Speed()) return 0.0; if(DM.DD_use_eta_function && DM_distr.DD_use_eta_function) diff --git a/src/Experiments.cpp b/src/Experiments.cpp index 5354a42..6034e2f 100644 --- a/src/Experiments.cpp +++ b/src/Experiments.cpp @@ -185,6 +185,57 @@ DM_Detector_Ionization_ER DarkSide50_S2_ER() return detector; } +DM_Detector_Ionization_ER DarkSide50_S2_ER_2023() +{ + // Source: arXiv:2207.11968 + std::string target_name = "Ar"; + double exposure = 12306 * kg * day; + unsigned int ne_threshold = 4; + // Digitised from Figure 1 (x Ne x 0.25 x exposure) + std::vector observed_event_bins = {298, 372, 456, 488, 583, 775, 965, 1053, 1182, 1644, 1723, 1992, \ + 2408, 2397, 2735, 3139, 3366}; + DM_Detector_Ionization_ER detector("DarkSide-50_S2_2023", exposure, target_name); + detector.Use_Electron_Bins(ne_threshold, 17); + detector.Set_Observed_Events(observed_event_bins); + + return detector; +} + +DM_Detector_Ionization_ER PandaX_4T_S2_ER() +{ + // Source: arXiv:2308.01540 + std::string target_name = "Xe"; + double exposure = 550 * kg * year; + std::vector observed_event_bins = {34, 14, 13, 7, 11, 12, 14}; + std::vector bkg_event_bins = {57.5609, 25.1404, 23.1201, 20.1953, 17.5385, 16.9677, 13.702}; + + // Here we assume that the PE response matches indentically to number of electrons + double ne_threshold = 4; + + DM_Detector_Ionization_ER detector("PandaX-4T_S2", exposure, target_name); + detector.Use_Electron_Bins(ne_threshold, 7); + detector.Set_Observed_Events(observed_event_bins); + detector.Set_Expected_Background(bkg_event_bins); + + return detector; +} + +DM_Detector_Ionization_ER LZ_S2_ER() +{ + // Source: arXiv:2307.15753 + std::string target_name = "Ar"; + double exposure = 550 * kg * day; + + DM_Detector_Ionization_ER detector("LZ_S2", exposure, target_name); + + //TODO : There is not enough info in the experiment to reproduce the S1-S2 signal + + std::cerr << libphysica::Formatted_String("Error", "Red", true) << " in obscura::LZ_S2_ER(): Not implemented." << std::endl; + std::exit(EXIT_FAILURE); + + return detector; +} + //3. Electron recoil experiments - Semiconductor DM_Detector_Crystal protoSENSEI_at_Surface() { @@ -271,6 +322,23 @@ DM_Detector_Crystal CDMS_HVeV_2020() return detector; } +DM_Detector_Crystal DAMIC_M_2023() +{ + // Source: arXiv:2302.02372 + // Paper only reports 40% of the data, so scale exposure accordingly + double DAMIC_M_exposure = 0.4 * 85.23 * gram * day; + unsigned int DAMIC_M_Q_threshold = 1; + unsigned int DAMIC_M_N_bins = 3; + std::vector DAMIC_M_observed_events = {4216354, 11345, 19}; + + DM_Detector_Crystal detector("DAMIC-M_2023", DAMIC_M_exposure, "Si"); + detector.Use_Q_Bins(DAMIC_M_Q_threshold, DAMIC_M_N_bins); + detector.Set_Observed_Events(DAMIC_M_observed_events); + + return detector; +} + + //4. Migdal experiments - Ionization DM_Detector_Ionization_Migdal XENON10_S2_Migdal() { @@ -316,7 +384,7 @@ DM_Detector_Ionization_Migdal XENON100_S2_Migdal() DM_Detector_Ionization_Migdal XENON1T_S2_Migdal() { - // Source: arXiv:1907.11485 + // Source: arXiv:1907.11485, arXiv:1907.12771 std::string target_name = "Xe"; double exposure = 80755.2 * kg * day; std::vector observed_event_bins = {8, 7, 2, 1}; @@ -348,4 +416,54 @@ DM_Detector_Ionization_Migdal DarkSide50_S2_Migdal() return detector; } -} // namespace obscura \ No newline at end of file + +DM_Detector_Ionization_Migdal DarkSide50_S2_Migdal_2023() +{ + // Source: arXiv:2207.11967 + std::string target_name = "Ar"; + double exposure = 6786.0 * kg * day; + unsigned int ne_threshold = 4; + std::vector observed_event_bins = {74, 74, 76, 70, 73, 86, 96, 96, 99, 126, 123, 133, 151, 141, 152, 165, 168}; + DM_Detector_Ionization_Migdal detector("DarkSide-50_S2_2023", exposure, target_name); + detector.Use_Electron_Bins(ne_threshold, 17); + detector.Set_Observed_Events(observed_event_bins); + + return detector; +} + +DM_Detector_Ionization_Migdal PandaX_4T_S2_Migdal() +{ + // Source: arXiv:2308.01540 + std::string target_name = "Xe"; + double exposure = 550 * kg * year; + std::vector observed_event_bins = {34, 14, 13, 7, 11, 12, 14}; + std::vector bkg_event_bins = {57.5609, 25.1404, 23.1201, 20.1953, 17.5385, 16.9677, 13.702}; + + // Here we assume that the PE response matches indentically to number of electrons + double ne_threshold = 4; + + DM_Detector_Ionization_Migdal detector("PandaX-4T_S2", exposure, target_name); + detector.Use_Electron_Bins(ne_threshold, 7); + detector.Set_Observed_Events(observed_event_bins); + detector.Set_Expected_Background(bkg_event_bins); + + return detector; +} + +DM_Detector_Ionization_Migdal LZ_S2_Migdal() +{ + // Source: arXiv:2307.15753 + std::string target_name = "Ar"; + double exposure = 550 * kg * day; + + DM_Detector_Ionization_Migdal detector("LZ_S2", exposure, target_name); + + //TODO : There is not enough info in the experiment to reproduce the S1-S2 signal + + std::cerr << libphysica::Formatted_String("Error", "Red", true) << " in obscura::LZ_S2_Migdal(): Not implemented." << std::endl; + std::exit(EXIT_FAILURE); + + return detector; +} + +} // namespace obscura