def _update_handler(self, metadata): # as a first step, try to set the detector_name, skip if detector_name is empty detector_name = metadata.get("detector_name") if detector_name and detector_name.startswith("JF"): # check if jungfrau data handler is already set for this detector if self.handler is None or self.handler.detector_name != detector_name: try: self.handler = JFDataHandler(detector_name) except KeyError: logging.exception( f"Error creating data handler for detector {detector_name}" ) self.handler = None return else: self.handler = None return # gain file gain_file = metadata.get("gain_file", "") try: self.handler.gain_file = gain_file except Exception: logging.exception(f"Error loading gain file {gain_file}") self.handler.gain_file = "" # pedestal file pedestal_file = metadata.get("pedestal_file", "") try: self.handler.pedestal_file = pedestal_file except Exception: logging.exception(f"Error loading pedestal file {pedestal_file}") self.handler.pedestal_file = "" # module map module_map = metadata.get("module_map") self.handler.module_map = None if ( module_map is None) else np.array(module_map) # highgain daq_rec = metadata.get("daq_rec") self.handler.highgain = False if (daq_rec is None) else bool(daq_rec & 0b1)
def test_handler_init_fail(detector_name): with pytest.raises(KeyError): JFDataHandler(detector_name)
def _empty_handler(): empty_handler = JFDataHandler(DETECTOR_NAME) yield empty_handler
class StreamAdapter: def __init__(self): # a placeholder for jf data handler to be initiated with detector name self.handler = None def process(self, image, metadata, mask=True, gap_pixels=True, double_pixels="keep", geometry=True): """Perform jungfrau detector data processing on an image received via stream. Args: image (ndarray): An image to be processed. metadata (dict): A corresponding image metadata. Returns: ndarray: Resulting image. """ # Eiger workaround detector_name = metadata.get("detector_name") if detector_name and re.match("(^[A-Za-z]*).EG([0-9A-Za-z]*)", detector_name): return np.copy(np.flipud(image)) # parse metadata self._update_handler(metadata) if self.handler is None or image.dtype != np.uint16: return image.astype(np.float32, copy=True) # skip conversion step if jungfrau data handler cannot do it, thus avoiding Exception raise conversion = self.handler.can_convert() proc_image = self.handler.process( image, conversion=conversion, mask=False, gap_pixels=gap_pixels, double_pixels=double_pixels, geometry=geometry, ) if mask: proc_image = self._apply_mask(proc_image, gap_pixels, double_pixels, geometry) return proc_image def get_gains(self, image, metadata, mask=True, gap_pixels=True, double_pixels="keep", geometry=True): # parse metadata self._update_handler(metadata) if self.handler is None or image.dtype != np.uint16: return np.zeros((2, 2), dtype="float32") gains = self.handler.get_gains(image, mask=mask, gap_pixels=gap_pixels, double_pixels=double_pixels, geometry=geometry) if mask: if double_pixels == "interp": double_pixels = "keep" gains = self._apply_mask(gains, gap_pixels, double_pixels, geometry) return gains def _update_handler(self, metadata): # as a first step, try to set the detector_name, skip if detector_name is empty detector_name = metadata.get("detector_name") if detector_name and detector_name.startswith("JF"): # check if jungfrau data handler is already set for this detector if self.handler is None or self.handler.detector_name != detector_name: try: self.handler = JFDataHandler(detector_name) except KeyError: logging.exception( f"Error creating data handler for detector {detector_name}" ) self.handler = None return else: self.handler = None return # gain file gain_file = metadata.get("gain_file", "") try: self.handler.gain_file = gain_file except Exception: logging.exception(f"Error loading gain file {gain_file}") self.handler.gain_file = "" # pedestal file pedestal_file = metadata.get("pedestal_file", "") try: self.handler.pedestal_file = pedestal_file except Exception: logging.exception(f"Error loading pedestal file {pedestal_file}") self.handler.pedestal_file = "" # module map module_map = metadata.get("module_map") self.handler.module_map = None if ( module_map is None) else np.array(module_map) # highgain daq_rec = metadata.get("daq_rec") self.handler.highgain = False if (daq_rec is None) else bool(daq_rec & 0b1) def _apply_mask(self, image, gap_pixels, double_pixels, geometry): # assign masked values to np.nan if self.handler.pixel_mask is not None: mask = self.handler.get_pixel_mask(gap_pixels=gap_pixels, double_pixels=double_pixels, geometry=geometry) # cast to np.float32 in case there was no conversion, but mask should still be applied if image.dtype != np.float32: image = image.astype(np.float32) if image.shape == mask.shape: _apply_mask_njit(image, mask) else: raise ValueError("Image and mask shapes are not the same") return image