Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dailymod #7

Merged
merged 2 commits into from
May 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions darkmagic/calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,44 @@ def compute_ve(times: float):
)
return v_e

def compute_daily_modulation(
self,
threshold_meV: float = 1.0,
) -> np.array:
r"""
Computes the rate $R$ normalized by the average daily rate $\langle R \rangle$.

Args:
threshold_meV (float, optional): The threshold in meV. Defaults to 1 meV.

Returns:
np.array: the normalized rate $R / \langle R \rangle$, indexed as (time, mass)
"""

energy_bin_width = self.numerics.bin_width
time = np.sort(self.time)

# TODO: this doesn't deal with some edge cases of poorly sampled time
t_idx = np.argwhere(time < 24)[-1][0]
# TODO: Clarify this. Should ensure enough time points going from 0 to 23
if (t_max := time[t_idx]) < 23:
warnings.warn(
f"The largest time is {t_max}. Ideally you should sample the time at 1 or 2 hour intervals."
)

# Vanilla PhonoDark calcs have a threshold of 1 meV by default
# We need to account for that in the binning
bin_cutoff = int(threshold_meV * 1e-3 / energy_bin_width) - int(
self.numerics._threshold / energy_bin_width
)

# Sum the rate over the energy bins -> (time, mass) array
total_rate = np.sum(self.diff_rate[..., bin_cutoff:], axis=2)
# Average the rate over a full day -> (mass,) array
day_averaged_rate = np.mean(total_rate[:t_idx, ...], axis=0)
# Return normalized rate as a (time, mass) array
return total_rate / day_averaged_rate

def compute_reach(
self,
threshold_meV: float = 1.0,
Expand All @@ -192,19 +230,17 @@ def compute_reach(
Computes the projected reach: the 95% C.L. constraint (3 events, no background) on $\bar{sigma}_n$ or $\bar{sigma}_e$ for a given model, in units of cm2 and normalizing to the appropriate reference cross section.

Args:
filename (str): The path to the HDF5 file containing the data.
threshold_meV (float, optional): The threshold in meV. Defaults to 1.0.
exposure_kg_yr (float, optional): The exposure in kg.yr. Defaults to 1.0.
n_cut (float, optional): The number of events. Defaults to 3.0.
model (str, optional): The model to use. Defaults to None (i.e., finds the model name in the file)
threshold_meV (float, optional): The threshold in meV. Defaults to 1 meV.
exposure_kg_yr (float, optional): The exposure in kg.yr. Defaults to 1 kg.yr
n_cut (float, optional): The number of events. Defaults to 3.
model (str, optional): The model to use. Defaults to the model attribute.
time (float | str, optional): The time to use. Defaults to 0.

Returns:
np.array: the cross section.
"""

energy_bin_width = self.numerics.bin_width
threshold = self.numerics._threshold # legacy for PD support
m_chi = self.m_chi
# get time index
try:
Expand All @@ -217,7 +253,7 @@ def compute_reach(
# Vanilla PhonoDark calcs have a threshold of 1 meV by default
# We need to account for that in the binning
bin_cutoff = int(threshold_meV * 1e-3 / energy_bin_width) - int(
threshold / energy_bin_width
self.numerics._threshold / energy_bin_width
)

model_name = model if model is not None else self.model.shortname
Expand All @@ -236,7 +272,6 @@ def compute_reach(

return sigma

# @njit
@staticmethod
def _evaluate_serial(
diff_rate: np.ndarray,
Expand Down