Source code for ctapipe.utils.index_finder

import bisect
import numpy as np
import warnings


__all__ = ["IndexFinder"]


[docs]class IndexFinder: """ Helper class to find the index of the closest matching value in an array/list/..., used to locate the pointing of an event based on the trigger time. This searches using pythons bisect module. Duplicated values will result in the first value being returned. Explanations can be found here: https://stackoverflow.com/questions/9706041/finding-index-of-an-item-closest-to-the-value-in-a-list-thats-not-entirely-sort Since we only need the searching part, the code has been cut down slightly. """ def __init__(self, values): if len(np.unique(values)) != len(values): warnings.warn("Duplicated values in IndexFinder") self.numindexes = dict((val, n) for n, val in enumerate(values)) self.nums = sorted(self.numindexes) def _rank(self, target): """ Searches for the closest match in the ordered self.nums list and returns the index relative to this list. To find the index relative to the original values, use the `closest` method. """ rank = bisect.bisect(self.nums, target) if rank == 0: pass elif len(self.nums) == rank: rank -= 1 else: dist1 = target - self.nums[rank - 1] dist2 = self.nums[rank] - target if dist1 < dist2: rank -= 1 return rank
[docs] def closest(self, target): """ Given a value, that is comparable to the associated ``values`` list, return the index of the closest matching entry relative to the unordered list, that was given at construction. """ if len(self.nums) == 1: return 0 try: return self.numindexes[self.nums[self._rank(target)]] except IndexError: return 0