<jupyter_start><jupyter_text>Creating a baseline estimator for onset prediction based on non-contrast and perfusion CT using lesion water uptakeischemic core defined on perfusion -> measure ischemic core lesion density (Dischemic) in NCCT-> then measure symetry in normal tissue of the contralateral hemisphere (Dnormal).ROIs were segmented with semi-automatic edge detection and sampled between 20 and 80 HU.%water uptake = (1 − (Dischemic / Dnormal) × 100<jupyter_code>imaging_dataset_path = '/Users/jk1/stroke_datasets/dataset_files/perfusion_data_sets/temp_split_datasets/train_with_ncct_dataset_with_onset_to_imaging_with_core_with_penumbra.npz'
label_file_path = '/Users/jk1/OneDrive - unige.ch/stroke_research/geneva_stroke_dataset/clinical_data/multi_annual_joined_data/scope_joined_variables/onset_prediction/with_imaging_curated_completed_joined_anon_outcome_df.xlsx'

id_variable = 'pid'
outcome = 'onset_to_imaging'
channels = [0,1,2,3,4,5,6]
apply_csf_mask = False
ids = np.load(imaging_dataset_path, allow_pickle=True)['ids']

outcomes_df = pd.read_excel(label_file_path)
labels = np.array([outcomes_df.loc[outcomes_df[id_variable] == subj_id, outcome].iloc[0] for
                   subj_id in ids])

raw_images = np.load(imaging_dataset_path, allow_pickle=True)['ct_inputs'][..., channels]

if raw_images.ndim < 5:
    raw_images = np.expand_dims(raw_images, axis=-1)

# Apply masks
raw_masks = np.load(imaging_dataset_path, allow_pickle=True)['brain_masks']
raw_masks = np.expand_dims(raw_masks, axis=-1)
images = raw_images * raw_masks
n_subj = len(ids)
rCBF_over_threshold = images[..., 5]
penumbra = images[..., 6]
ncct = images[..., 4]

strict_core = rCBF_over_threshold * penumbra
from skimage.measure import label

def getLargestCC(segmentation):
    labels = label(segmentation)
    largestCC = labels == np.argmax(np.bincount(labels.flat, weights=segmentation.flat))
    return largestCC<jupyter_output><empty_output><jupyter_text>Retain only largest connected component<jupyter_code>cc_limited_core = [getLargestCC(strict_core[i]) for i in range(n_subj)]<jupyter_output><empty_output><jupyter_text>Limit core to only one half of the brain<jupyter_code>image_half = int(images.shape[1] / 2)
left_half_filter = np.zeros(images.shape[1:-1])
right_half_filter = np.zeros(images.shape[1:-1])
right_half_filter[0:image_half] = 1
left_half_filter[image_half:] = 1
x_center_of_mass = [ndimage.measurements.center_of_mass(strict_core[i])[0] for i in range(n_subj)]
laterally_limited_core = np.copy(strict_core)
for i in range(n_subj):
    # if center of core is on the left side of the image
    if x_center_of_mass[i] < image_half:
        laterally_limited_core[i] *= right_half_filter
    # if center of core is on the right side of the image
    else:
        laterally_limited_core[i] *= left_half_filter


mirrored_laterally_limited_core_mask = np.flip(laterally_limited_core, axis=1)


from gsd_pipeline.dataset_tools.add_core_map import dilation_structure_2d
from gsprep.utils.smoothing import gaussian_smoothing

dilation_structure = dilation_structure_2d

# Create CSF mask
low_bounded_ncct = ncct[ncct > 0]
up_and_low_bounded_ncct = low_bounded_ncct[low_bounded_ncct < 100]
# threshold = 20
threshold = np.percentile(up_and_low_bounded_ncct, 5)
csf_mask = gaussian_smoothing(ncct[..., None], kernel_width=3) < threshold
enlarged_csf_mask = np.array(
    [ndimage.binary_dilation(csf_mask[idx, ..., 0], structure=dilation_structure(1)) for idx in range(csf_mask.shape[0])])
inv_csf_mask = -1 * enlarged_csf_mask + 1
if apply_csf_mask:
    laterally_limited_core = laterally_limited_core * inv_csf_mask
    mirrored_laterally_limited_core_mask = mirrored_laterally_limited_core_mask * inv_csf_mask

mean_ischemic_density = [np.mean(ncct[i][np.nonzero(laterally_limited_core[i])])
                                 for i in range(n_subj)]

mean_non_ischemic_density = [np.mean(ncct[i][np.nonzero(mirrored_laterally_limited_core_mask[i])])
                                 for i in range(n_subj)]
water_uptake = (1 - np.divide(mean_ischemic_density, mean_non_ischemic_density)) * 100

sns.relplot(x=labels, y=water_uptake)

binary_labels = labels > 4.5*60

metrics.roc_auc_score(binary_labels, water_uptake)
df = pd.DataFrame(zip(labels, binary_labels, mean_ischemic_density, mean_non_ischemic_density, water_uptake),
                  columns=['onset_to_imaging', 'binary_labels', 'mean_ischemic_density', 'mean_non_ischemic_density', 'water_uptake'])
df['mean_ischemic_density'].describe()
df['mean_non_ischemic_density'].describe()
print(df[df['binary_labels'] == 0]['mean_ischemic_density'].describe())
print(df[df['binary_labels'] == 0]['mean_non_ischemic_density'].describe())
print(df[df['binary_labels'] == 0]['water_uptake'].describe())
print(df[df['binary_labels'] == 1]['mean_ischemic_density'].describe())
print(df[df['binary_labels'] == 1]['mean_non_ischemic_density'].describe())
print(df[df['binary_labels'] == 1]['water_uptake'].describe())
subj_id = 57
ids[subj_id]
mean_ischemic_density[subj_id]
mean_non_ischemic_density[subj_id]
water_uptake[subj_id]
labels[subj_id]/60
output_dir = '/Users/jk1/temp/scope_onset_exploration'

ncct_img = nib.Nifti1Image(ncct[subj_id], np.eye(4))
nib.save(ncct_img, os.path.join(output_dir, f'{ids[subj_id]}_ncct.nii'))

lesion_img = nib.Nifti1Image(laterally_limited_core[subj_id], np.eye(4))
nib.save(lesion_img, os.path.join(output_dir, f'{ids[subj_id]}_lesion.nii'))

mirrored_lesion_img = nib.Nifti1Image(mirrored_laterally_limited_core_mask[subj_id], np.eye(4))
nib.save(mirrored_lesion_img, os.path.join(output_dir, f'{ids[subj_id]}_mirrored_lesion.nii'))

csf_img = nib.Nifti1Image(enlarged_csf_mask[subj_id].astype(int), np.eye(4))
nib.save(csf_img, os.path.join(output_dir, f'{ids[subj_id]}_csf.nii'))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11846629986244842, 'fraction_numerical': 0.013239339752407153, 'mean_word_length': 6.82907133243607, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '304318', 'license': 'MIT', 'n_tokens_mistral': 2261, 'n_tokens_neox': 2129, 'n_words': 340, 'path': 'exploratory_experiments/onset/perfusion_and_native_baseline_estimator.ipynb', 'repo_name': 'JulianKlug/scop', 'size': '5816'}