Source code for alphadia.search.scoring.features.precursor_features

"""Feature extraction for precursor ions."""

import numba as nb
import numpy as np

from alphadia.search.scoring.features.features_utils import (
    weighted_center_mean_2d,
)
from alphadia.search.scoring.utils import save_corrcoeff, tile
from alphadia.utils import USE_NUMBA_CACHING


[docs] @nb.njit(cache=USE_NUMBA_CACHING) def precursor_features( isotope_mz: np.ndarray, isotope_intensity: np.ndarray, dense_precursors: np.ndarray, observation_importance, template: np.ndarray, feature_array: np.ndarray, ): n_isotopes = isotope_intensity.shape[0] n_observations = dense_precursors.shape[2] # ============= PRECURSOR FEATURES ============= # (1, n_observations) observation_importance_reshaped = observation_importance.reshape(1, -1) # (n_isotopes, n_observations) sum_precursor_intensity = np.sum( np.sum(dense_precursors[0], axis=-1), axis=-1 ).astype(np.float32) # (n_isotopes) weighted_sum_precursor_intensity = np.sum( sum_precursor_intensity * observation_importance_reshaped, axis=-1 ).astype(np.float32) # mono_ms1_intensity feature_array[4] = weighted_sum_precursor_intensity[0] # top_ms1_intensity feature_array[5] = weighted_sum_precursor_intensity[np.argmax(isotope_intensity)] # sum_ms1_intensity feature_array[6] = np.sum(weighted_sum_precursor_intensity) # weighted_ms1_intensity feature_array[7] = np.sum(weighted_sum_precursor_intensity * isotope_intensity) expected_scan_center = tile( dense_precursors.shape[3], n_isotopes * n_observations ).reshape(n_isotopes, -1) expected_frame_center = tile( dense_precursors.shape[2], n_isotopes * n_observations ).reshape(n_isotopes, -1) # (n_isotopes) observed_precursor_height = weighted_center_mean_2d( dense_precursors[0], expected_scan_center, expected_frame_center )[:, 0] # (n_isotopes) observed_precursor_mz = weighted_center_mean_2d( dense_precursors[1], expected_scan_center, expected_frame_center )[:, 0] mz_mask = observed_precursor_mz > 0 # (n_isotopes) mass_error_array = (observed_precursor_mz - isotope_mz) / isotope_mz * 1e6 weighted_mass_error = np.sum(mass_error_array[mz_mask] * isotope_intensity[mz_mask]) # weighted_mass_deviation feature_array[8] = weighted_mass_error # weighted_mass_error feature_array[9] = np.abs(weighted_mass_error) # mz_observed feature_array[10] = isotope_mz[0] + weighted_mass_error * 1e-6 * isotope_mz[0] # mono_ms1_height feature_array[11] = observed_precursor_height[0] # top_ms1_height feature_array[12] = observed_precursor_height[np.argmax(isotope_intensity)] # sum_ms1_height feature_array[13] = np.sum(observed_precursor_height) # weighted_ms1_height feature_array[14] = np.sum(observed_precursor_height * isotope_intensity) # isotope_intensity_correlation feature_array[15] = save_corrcoeff( isotope_intensity, np.sum(sum_precursor_intensity, axis=-1) ) # isotope_height_correlation feature_array[16] = save_corrcoeff(isotope_intensity, observed_precursor_height)