Skip to content
Open
Show file tree
Hide file tree
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
28 changes: 24 additions & 4 deletions fuse/context_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ def modify_s2_pattern_map(
return s2_pattern_map


@URLConfig.register("lce_from_pattern_map")
def lce_from_pattern_map(map, pmt_mask):
"""Build a S1 lce correction map from a S1 pattern map."""

lcemap = deepcopy(map)
lcemap.data["map"] = np.sum(lcemap.data["map"][:][:][:], axis=3, keepdims=True, where=pmt_mask)
lcemap.__init__(lcemap.data)
return lcemap



# Probably not needed!
@URLConfig.register("simple_load")
def load(data):
Expand All @@ -130,15 +141,24 @@ def from_config(config_name, key):
raise ValueError(f"Key {key} not found in {config_name}")
return config[key]


class DummyMap:
"""Return constant results with length equal to that of the input and
second dimensions (constand correction) user-defined."""

def __init__(self, const, shape=()):
self.const = float(const)
self.shape = shape
self.data = {"map": np.ones(shape)}

# The normal case where the user provides a single number for the constant correction
if isinstance(const, str):
self.const = float(const)
self.shape = shape
self.data = {"map": np.ones(shape) * self.const}

# The case where the map was modified outside, e.g. to build a LCE map from s1 pattern map
if isinstance(const, dict):
# Just pick the first value of map as the constant, since all values should be the same after modification
self.const = const["map"].flat[0]
self.shape = const["map"].shape
self.data = {"map": const["map"]}

def __call__(self, x, **kwargs):
shape = [len(x)] + list(self.shape)
Expand Down
11 changes: 6 additions & 5 deletions fuse/plugins/detector_physics/electron_drift.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,12 @@ def _rz_map(z, xy, **kwargs):

self.diffusion_longitudinal_map = _rz_map

csys = self.fdc_map_fuse.coordinate_system
rmin, rmax = csys[:, 0].min(), csys[:, 0].max()
zmin, zmax = csys[:, 1].min(), csys[:, 1].max()
self.fdc_map_r_bounds = (rmin, rmax)
self.fdc_map_z_bounds = (zmin, zmax)
if self.field_distortion_model == "comsol":
csys = self.fdc_map_fuse.coordinate_system
rmin, rmax = csys[:, 0].min(), csys[:, 0].max()
zmin, zmax = csys[:, 1].min(), csys[:, 1].max()
self.fdc_map_r_bounds = (rmin, rmax)
self.fdc_map_z_bounds = (zmin, zmax)

def compute(self, interactions_in_roi):
# Just apply this to clusters with photons
Expand Down
17 changes: 8 additions & 9 deletions fuse/plugins/detector_physics/s1_photon_hits.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ class S1PhotonHits(FuseBasePlugin):
help="S1 LCE correction map",
)

s1_lce_correction_map = straxen.URLConfig(
default="lce_from_pattern_map:plugin.s1_pattern_map?"
"&pmt_mask=plugin.pmt_mask",
cache=True,
help="S1 LCE correction map",
)


p_double_pe_emision = straxen.URLConfig(
default="take://resource://"
"SIMULATION_CONFIG_FILE.json?&fmt=json"
Expand Down Expand Up @@ -103,15 +111,6 @@ def setup(self):

self.pmt_mask = np.array(self.gains) > 0 # Converted from to pe (from xedocs by default)

# Build LCE map from s1 pattern map
lcemap = deepcopy(self.s1_pattern_map)
# AT: this scaling with mast is redundant to `make_patternmap`, but keep it in for now
lcemap.data["map"] = np.sum(
lcemap.data["map"][:][:][:], axis=3, keepdims=True, where=self.pmt_mask
)
lcemap.__init__(lcemap.data)
self.s1_lce_correction_map = lcemap

def compute(self, interactions_in_roi):
# Just apply this to clusters with photons
mask = interactions_in_roi["photons"] > 0
Expand Down
4 changes: 2 additions & 2 deletions fuse/plugins/detector_physics/s2_photon_propagation.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ def singlet_triplet_delays(self, size, singlet_ratio):
t1, t3 = 0, 0

delay = self.rng.choice([t1, t3], size, replace=True, p=[singlet_ratio, 1 - singlet_ratio])
return self.rng.exponential(1, size) * delay
return (self.rng.exponential(1, size) * delay).astype(np.int64)

def photon_timings(self, positions, n_photons, _photon_channels):
raise NotImplementedError
Expand Down Expand Up @@ -798,4 +798,4 @@ def _luminescence_timings_simple(
# linear interp on monotonic CDF y/y[-1] → t
emission_time[s:e] = np.interp(probs, y / y[-1], t)

return emission_time
return emission_time.astype(np.int64)
Loading