Пример #1
0
 def setup(self):
     self.mean_pe_photon = self.config['mean_pe_per_photon']
     
     # Getting S1 AFT maps
     self.s1_aft_map = straxen.InterpolatingMap(
         straxen.get_resource(
             self.config['s1_aft_map'],
             fmt=self._infer_map_format(self.config['s1_aft_map'])))
                 
     # Getting optical maps
     self.s1_pattern_map = straxen.InterpolatingMap(
         straxen.get_resource(
             self.config['s1_optical_map'],
             fmt=self._infer_map_format(self.config['s1_optical_map'])))
     self.s2_pattern_map = straxen.InterpolatingMap(
         straxen.get_resource(
             self.config['s2_optical_map'],
             fmt=self._infer_map_format(self.config['s2_optical_map'])))
     
     # Getting gain model to get dead PMTs
     self.to_pe = straxen.get_correction_from_cmt(self.run_id, self.config['gain_model'])
     self.dead_PMTs = np.where(self.to_pe == 0)[0]
     self.pmtbool = ~np.in1d(np.arange(0, self.config['n_tpc_pmts']), self.dead_PMTs)
     self.pmtbool_top = self.pmtbool[:self.config['n_top_pmts']]
     self.pmtbool_bottom = self.pmtbool[self.config['n_top_pmts']:self.config['n_tpc_pmts']]
Пример #2
0
    def setup(self):
        self.electron_drift_velocity = get_correction_from_cmt(
            self.run_id, self.config['electron_drift_velocity'])
        self.electron_drift_time_gate = get_correction_from_cmt(
            self.run_id, self.config['electron_drift_time_gate'])
        self.mean_pe_photon = self.config['mean_pe_per_photon']

        # Getting S1 AFT maps
        self.s1_aft_map = straxen.InterpolatingMap(
            straxen.get_resource(self.config['s1_aft_map'],
                                 fmt=self._infer_map_format(
                                     self.config['s1_aft_map'])))

        # Getting optical maps
        self.s1_pattern_map = straxen.InterpolatingMap(
            straxen.get_resource(self.config['s1_optical_map'],
                                 fmt=self._infer_map_format(
                                     self.config['s1_optical_map'])))
        self.s2_pattern_map = straxen.InterpolatingMap(
            straxen.get_resource(self.config['s2_optical_map'],
                                 fmt=self._infer_map_format(
                                     self.config['s2_optical_map'])))

        # Getting S2 data-driven tensorflow models
        downloader = straxen.MongoDownloader()
        self.model_file = downloader.download_single(
            self.config['s2_tf_model'])
        with tempfile.TemporaryDirectory() as tmpdirname:
            tar = tarfile.open(self.model_file, mode="r:gz")
            tar.extractall(path=tmpdirname)

            import tensorflow as tf

            def _logl_loss(patterns_true, likelihood):
                return likelihood / 10.

            self.model = tf.keras.models.load_model(
                tmpdirname, custom_objects={"_logl_loss": _logl_loss})
            self.model_chi2 = tf.keras.Model(
                self.model.inputs,
                self.model.get_layer('Likelihood').output)

        # Getting gain model to get dead PMTs
        self.to_pe = straxen.get_correction_from_cmt(self.run_id,
                                                     self.config['gain_model'])
        self.dead_PMTs = np.where(self.to_pe == 0)[0]
        self.pmtbool = ~np.in1d(np.arange(0, self.config['n_tpc_pmts']),
                                self.dead_PMTs)
        self.pmtbool_top = self.pmtbool[:self.config['n_top_pmts']]
        self.pmtbool_bottom = self.pmtbool[self.config['n_top_pmts']:self.
                                           config['n_tpc_pmts']]
Пример #3
0
def make_patternmap(map_file,
                    fmt=None,
                    method='WeightedNearestNeighbors',
                    pmt_mask=None):
    """ This is special interpretation of the of previous make_map(), but designed
    for pattern map loading with provided PMT mask. This way simplifies both S1 and S2
    cases
    """
    # making tests not failing, we can probably overwrite it completel
    if isinstance(map_file, list):
        log.warning(
            f'Using dummy map with pattern mask! This has no effect here!')
        assert map_file[0] == 'constant dummy', (
            'Alternative file input can only be '
            '("constant dummy", constant: int, shape: list')
        return DummyMap(map_file[1], map_file[2])
    elif isinstance(map_file, str):
        if fmt is None:
            fmt = parse_extension(map_file)
        map_data = deepcopy(straxen.get_resource(map_file, fmt=fmt))
        # XXX: straxed deals with pointers and caches resources, it means that resources are global
        # what is bad, so we make own copy here and modify it locally
        if 'compressed' in map_data:
            compressor, dtype, shape = map_data['compressed']
            map_data['map'] = np.frombuffer(
                strax.io.COMPRESSORS[compressor]['decompress'](
                    map_data['map']),
                dtype=dtype).reshape(*shape)
            del map_data['compressed']
        if 'quantized' in map_data:
            map_data['map'] = map_data['quantized'] * map_data['map'].astype(
                np.float32)
            del map_data['quantized']
        if not (pmt_mask is None):
            assert (
                map_data['map'].shape[-1] == pmt_mask.shape[0]
            ), "Error! Pattern map and PMT gains must have same dimensions!"
            map_data['map'][..., ~pmt_mask] = 0.0
        return straxen.InterpolatingMap(map_data, method=method)
    else:
        raise TypeError("Can't handle map_file except a string or a list")
Пример #4
0
def make_map(map_file, fmt=None, method='WeightedNearestNeighbors'):
    """Fetch and make an instance of InterpolatingMap based on map_file
    Alternatively map_file can be a list of ["constant dummy", constant: int, shape: list]
    return an instance of  DummyMap"""

    if isinstance(map_file, list):
        assert map_file[0] == 'constant dummy', (
            'Alternative file input can only be '
            '("constant dummy", constant: int, shape: list')
        return DummyMap(map_file[1], map_file[2])

    elif isinstance(map_file, str):
        if fmt is None:
            fmt = parse_extension(map_file)

        log.debug(f'Initialize map interpolator for file {map_file}')
        map_data = straxen.get_resource(map_file, fmt=fmt)
        return straxen.InterpolatingMap(map_data, method=method)

    else:
        raise TypeError("Can't handle map_file except a string or a list")
Пример #5
0
def make_map(map_file: str, fmt='text'):
    map_data = straxen.get_resource(map_file, fmt)
    return straxen.InterpolatingMap(map_data)
Пример #6
0
def load_corrected_positions(context,
                             run_id,
                             events,
                             cmt_version=None,
                             posrec_algos=('mlp', 'gcn', 'cnn')):
    """
    Returns the corrected position for each position algorithm available,
        without the need to reprocess event_basics, as the needed
        information is already stored in event_basics.
    
    :param cmt_version: CMT version to use (it can be a list of same
        length as posrec_algos, if different versions are required for
        different posrec algorithms, default 'ONLINE')
    :param posrec_algos: list of position reconstruction algorithms to
        use (default ['mlp', 'gcn', 'cnn'])
    """

    posrec_algos = strax.to_str_tuple(posrec_algos)

    if cmt_version is None:
        fdc_config = None
        try:
            fdc_config = context.get_single_plugin(
                run_id, 'event_positions').config['fdc_map']
            cmt_version = fdc_config[1][1]
        except IndexError as e:
            raise ValueError(
                f'CMT is not set? Your fdc config is {fdc_config}') from e

    if hasattr(cmt_version, '__len__') and not isinstance(
            cmt_version, str) and len(cmt_version) != len(posrec_algos):
        raise TypeError(
            f"cmt_version is a list but does not match the posrec_algos ({posrec_algos}) length."
        )

    cmt_version = (cmt_version, ) * len(posrec_algos) if isinstance(
        cmt_version, str) else cmt_version

    dtype = []

    for algo in posrec_algos:
        for xyzr in 'x y z r'.split():
            dtype += [
                ((f'Interaction {xyzr}-position, field-distortion corrected (cm) - '
                  f'{algo.upper()} posrec algorithm', f'{xyzr}_{algo}'),
                 np.float32),
            ]
        dtype += [((
            f'Interaction r-position using observed S2 positions directly (cm) -'
            f' {algo.upper()} posrec algorithm', f'r_naive_{algo}'),
                   np.float32),
                  ((f'Correction added to r_naive for field distortion (cm) - '
                    f'{algo.upper()} posrec algorithm',
                    f'r_field_distortion_correction_{algo}'), np.float32),
                  ((f'Interaction angular position (radians) - {algo.upper()} '
                    f'posrec algorithm', f'theta_{algo}'), np.float32)]

    dtype += [(('Interaction z-position using mean drift velocity only (cm)',
                'z_naive'), np.float32)]
    result = np.zeros(len(events), dtype=dtype)

    drift_speed = context.get_single_plugin(
        run_id, 'event_positions').config['electron_drift_velocity']
    z_obs = -drift_speed * events['drift_time']

    for algo, v_cmt in zip(posrec_algos, cmt_version):
        fdc_tmp = ('CMT_model', (f'fdc_map_{algo}', v_cmt), True)
        map_tmp = straxen.get_config_from_cmt(run_id, fdc_tmp)
        itp_tmp = straxen.InterpolatingMap(
            straxen.common.get_resource(map_tmp, fmt='binary'))
        itp_tmp.scale_coordinates([1., 1., -drift_speed])

        orig_pos = np.vstack(
            [events[f's2_x_{algo}'], events[f's2_y_{algo}'], z_obs]).T
        r_obs = np.linalg.norm(orig_pos[:, :2], axis=1)
        delta_r = itp_tmp(orig_pos)

        # apply radial correction
        with np.errstate(invalid='ignore', divide='ignore'):
            r_cor = r_obs + delta_r
            scale = r_cor / r_obs

        with np.errstate(invalid='ignore'):
            z_cor = -(z_obs**2 - delta_r**2)**0.5
            invalid = np.abs(z_obs) < np.abs(delta_r)
        z_cor[invalid] = z_obs[invalid]

        result[f'x_{algo}'] = orig_pos[:, 0] * scale
        result[f'y_{algo}'] = orig_pos[:, 1] * scale
        result[f'r_{algo}'] = r_cor
        result[f'r_naive_{algo}'] = r_obs
        result[f'r_field_distortion_correction_{algo}'] = delta_r
        result[f'theta_{algo}'] = np.arctan2(orig_pos[:, 1], orig_pos[:, 0])
        result[f'z_{algo}'] = z_cor

    result['z_naive'] = z_obs
    return result
Пример #7
0
def load_corrected_positions(context,
                             run_id,
                             events,
                             alt_s1=False,
                             alt_s2=False,
                             cmt_version=None,
                             posrec_algos=('mlp', 'gcn', 'cnn')):
    """
    Returns the corrected position for each position algorithm available,
        without the need to reprocess event_basics, as the needed
        information is already stored in event_basics.
    
    :param alt_s1: False by default, if True it uses alternative S1 as main one
    :param alt_s2: False by default, if True it uses alternative S2 as main one
    :param cmt_version: CMT version to use (it can be a list of same
        length as posrec_algos, if different versions are required for
        different posrec algorithms, default 'local_ONLINE')
    :param posrec_algos: list of position reconstruction algorithms to
        use (default ['mlp', 'gcn', 'cnn'])
    """

    posrec_algos = strax.to_str_tuple(posrec_algos)

    if cmt_version is None:
        fdc_config = context.get_single_plugin(
            run_id, 'event_positions').config['fdc_map']
        if isinstance(fdc_config, str) and 'cmt://' in fdc_config:
            cmt_version = straxen.URLConfig.split_url_kwargs(fdc_config)
        elif straxen.is_cmt_option(fdc_config):
            cmt_version = fdc_config[1]
        else:
            raise ValueError(
                'FDC map is not a CMT option, cannot infer cmt version.')

    if (isinstance(cmt_version, (tuple, list))
            and len(cmt_version) != len(posrec_algos)):
        raise TypeError(f"cmt_version is a list but does not match the "
                        f"posrec_algos ({posrec_algos}) length.")

    cmt_version = ((cmt_version, ) * len(posrec_algos) if isinstance(
        cmt_version, str) else cmt_version)

    # Get drift from CMT
    ep = context.get_single_plugin(run_id, 'event_positions')
    drift_speed = ep.electron_drift_velocity
    drift_time_gate = ep.electron_drift_time_gate

    dtype = load_dtypes(posrec_algos)
    result = np.zeros(len(events), dtype=dtype)

    s1_pre = 'alt_' if alt_s1 else ''
    s2_pre = 'alt_' if alt_s2 else ''
    drift_time = events['drift_time'] if not (alt_s1 or alt_s2) else events[
        s2_pre + 's2_center_time'] - events[s1_pre + 's1_center_time']

    z_obs = -drift_speed * drift_time

    for algo, v_cmt in zip(posrec_algos, cmt_version):
        fdc_tmp = (f'fdc_map_{algo}', v_cmt, True)
        map_tmp = straxen.get_correction_from_cmt(run_id, fdc_tmp)
        itp_tmp = straxen.InterpolatingMap(
            straxen.common.get_resource(map_tmp, fmt='binary'))
        itp_tmp.scale_coordinates([1., 1., -drift_speed])

        orig_pos = np.vstack([
            events[f'{s2_pre}s2_x_{algo}'], events[f'{s2_pre}s2_y_{algo}'],
            z_obs
        ]).T
        r_obs = np.linalg.norm(orig_pos[:, :2], axis=1)
        delta_r = itp_tmp(orig_pos)
        z_obs = z_obs + drift_speed * drift_time_gate

        # apply radial correction
        with np.errstate(invalid='ignore', divide='ignore'):
            r_cor = r_obs + delta_r
            scale = r_cor / r_obs

        with np.errstate(invalid='ignore'):
            z_cor = -(z_obs**2 - delta_r**2)**0.5
            invalid = np.abs(z_obs) < np.abs(delta_r)
        z_cor[invalid] = z_obs[invalid]

        result[f'x_{algo}'] = orig_pos[:, 0] * scale
        result[f'y_{algo}'] = orig_pos[:, 1] * scale
        result[f'r_{algo}'] = r_cor
        result[f'r_naive_{algo}'] = r_obs
        result[f'r_field_distortion_correction_{algo}'] = delta_r
        result[f'theta_{algo}'] = np.arctan2(orig_pos[:, 1], orig_pos[:, 0])
        result[f'z_{algo}'] = z_cor

    result['z_naive'] = z_obs
    return result
Пример #8
0
def load_map(some_map, method='WeightedNearestNeighbors', **kwargs):
    """Make an InterpolatingMap"""
    return straxen.InterpolatingMap(some_map, method=method, **kwargs)