Resources are associated with functional outcome and brain morphometry in childhood cancer survivors.
The 2 matches
- [1] § Materials and methods › Outcome measures › Neuroimaging › Preprocessing and data analysis ↔ src/DeepSCAN_Anatomy_Newnet_apply.py, lines 417–487 · score 0.75 · Anatomy Segmentation, Deep Learning, Cortex Parcellation, tissue, classes, scans
- [2] § Materials and methods › Outcome measures › Neuroimaging › Preprocessing and data analysis ↔ dl+direct.sh, lines 80–155 · score 0.62 · DiReCT, Anatomy, Deep, scans, boundary, DL
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Python · 488 lines · 20 KB · BSD-3-Clause · 1 match
- import numpy as np
- import sys
- import os
- import argparse
- import csv
- import pandas as pd
- import nibabel as nib
- from collections import OrderedDict
- import torch
- import torch.nn as nn
- import torch.nn.functional as F
- from torch.nn import ModuleList, ReplicationPad2d, Dropout
- from torch.utils.data.sampler import Sampler, SequentialSampler
- from torch.utils.data.dataset import Dataset
- from torch.utils.data import DataLoader
- from numpy import require
- # Save logits of each class
- # Set to None to save all:
- # SAVE_LOGITS_FILTER = None
- # Set to empty list to disable save of logits:
- # SAVE_LOGITS_FILTER = []
- # Set to list of selected labels otherwise (e.g. for DL+DiReCT):
- # SAVE_LOGITS_FILTER = ['Left-Cerebral-White-Matter', 'Right-Cerebral-White-Matter', 'WM-hypointensities',
- # 'Left-Cerebral-Cortex', 'Right-Cerebral-Cortex',
- # 'Left-Amygdala', 'Right-Amygdala', 'Left-Hippocampus', 'Right-Hippocampus']
- SAVE_LOGITS_FILTER = ['Left-Cerebral-White-Matter', 'Right-Cerebral-White-Matter', 'WM-hypointensities',
- 'Left-Cerebral-Cortex', 'Right-Cerebral-Cortex',
- 'Left-Amygdala', 'Right-Amygdala', 'Left-Hippocampus', 'Right-Hippocampus']
- stack_depth = 7
- BATCH_SIZE = 10
- VERBOSE = True
- DIM = 216
- SCRIPT_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
- def get_label_def(label_names):
- # To generate the hard segmentations, we use the FS labels where we have a 1:1 correspondence,
- # otherwise a label above 100 (not used in FS)
- LUT = dict()
- with open('{}/fs_lut.csv'.format(SCRIPT_DIR), 'r') as file:
- csv_reader = csv.reader(file, delimiter=',')
- next(csv_reader, None) # skip the headers
- for row in csv_reader:
- LUT[row[1]] = int(row[0])
- LABELS = dict()
- for idx, label in enumerate(label_names):
- if label in LUT:
- l = LUT[label]
- else:
- l = idx + 100
- LABELS[label] = l
- return LABELS
- def get_stack(axis, volume, central_slice, first_slice=None, last_slice=None,
- stack_depth=5, size = (DIM,DIM), lower_threshold = None, upper_threshold= None, return_nonzero= True):
- image_data = np.array(np.swapaxes(volume, 0, axis), copy = True)
- mean = np.mean(image_data[image_data>0])
- sd = np.sqrt(np.var(image_data[image_data>0]))
- if lower_threshold is None:
- lower_threshold = 0
- if upper_threshold is None:
- upper_threshold = np.percentile(image_data[image_data>0], 99.9)
- image_data[image_data<lower_threshold] = lower_threshold
- image_data[image_data>upper_threshold] = upper_threshold
- if first_slice is None:
- if central_slice is not None:
- first_slice = central_slice - stack_depth//2
- last_slice = central_slice + stack_depth//2 + 1
- elif last_slice is not None:
- first_slice = last_slice - stack_depth
- elif last_slice is None:
- last_slice = min(first_slice + stack_depth, len(image_data))
- pad_up = max(0, -first_slice)
- pad_down = -min(0, len(image_data)-last_slice)
- first_slice = max(first_slice,0)
- last_slice = min(last_slice, len(image_data))
- initial_stack = image_data[first_slice:last_slice]
- initial_shape = initial_stack.shape[1:]
- shape_difference = (size[0] - initial_shape[0],size[1] - initial_shape[1])
- pad_size = ((pad_up,pad_down),
- (max(0, shape_difference[0]//2), max(0, shape_difference[0] - shape_difference[0]//2)),
- (max(0, shape_difference[1]//2), max(0, shape_difference[1] - shape_difference[1]//2))
- )
- initial_stack = np.pad(initial_stack, pad_size, mode = 'constant', constant_values = lower_threshold)
- if return_nonzero :
- nonzero_mask = (initial_stack>lower_threshold).astype(np.uint8)
- else:
- nonzero_mask = None
- return (initial_stack - mean)/sd, nonzero_mask
- def get_stack_no_augment(axis, volume, first_slice, last_slice, size=(DIM, DIM)):
- return get_stack(axis = axis, volume = volume, central_slice=None, stack_depth=None, first_slice = first_slice, last_slice = last_slice, size=size)
- def reduce_3d_depth (in_channel, out_channel, kernel_size, padding):
- layer = nn.Sequential(OrderedDict([
- ("pad1", nn.ReplicationPad3d((1,1,1,1,0,0))),
- ("conv1", nn.Conv3d(in_channel, out_channel, kernel_size=kernel_size, padding=padding)),
- ("bn1", nn.InstanceNorm3d(out_channel, affine = False)),
- ("relu1", nn.ReLU()),
- #("dropout", nn.Dropout(p=0.2))
- ]))
- return layer
- def down_layer(in_channel, out_channel, kernel_size, padding):
- layer = nn.Sequential(OrderedDict([
- ("pad1", nn.ReplicationPad2d(1)),
- ("conv1", nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, padding=padding)),
- ("bn1", nn.InstanceNorm2d(out_channel, affine = False)),
- ("relu1", nn.ReLU()),
- ("dropout1", nn.Dropout(p=0.0)),
- ("pad2", nn.ReplicationPad2d(1)),
- ("conv2", nn.Conv2d(out_channel, out_channel, kernel_size=kernel_size, padding=padding)),
- ("bn2", nn.InstanceNorm2d(out_channel, affine = False)),
- ("relu2", nn.ReLU()),
- ("dropout2", nn.Dropout(p=0.0))]))
- return layer
- def up_layer(in_channel, out_channel, kernel_size, padding):
- layer = nn.Sequential(OrderedDict([
- ("pad1", nn.ReplicationPad2d(1)),
- ("conv1", nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, padding=padding)),
- ("bn1", nn.InstanceNorm2d(out_channel, affine = False)),
- ("relu1", nn.ReLU()),
- ("dropout1", nn.Dropout(p=0.0)),
- ("pad2", nn.ReplicationPad2d(1)),
- ("conv2", nn.Conv2d(out_channel, out_channel, kernel_size=kernel_size, padding=padding)),
- ("bn2", nn.InstanceNorm2d(out_channel, affine = False)),
- ("relu2", nn.ReLU()),
- ("dropout2", nn.Dropout(p=0.0))]))
- return layer
- class DilatedDenseUnit(nn.Module):
- def __init__(self, in_channel, growth_rate , kernel_size, dilation):
- super(DilatedDenseUnit,self).__init__()
- self.layer = nn.Sequential(OrderedDict([
- ("bn1", nn.InstanceNorm2d(in_channel, affine = False)),
- ("relu1", nn.ReLU()),
- ("pad1", nn.ReplicationPad2d(dilation)),
- ("conv1", nn.Conv2d(in_channel, growth_rate, kernel_size=kernel_size, dilation = dilation,padding=0)),
- ("dropout", nn.Dropout(p=0.0))]))
- def forward(self, x):
- out = x
- out = self.layer(out)
- out = concatenate(x, out)
- return out
- class AttentionModule(nn.Module):
- def __init__(self, in_channel , intermediate_channel, out_channel, kernel_size=3):
- super(AttentionModule,self).__init__()
- self.layer = nn.Sequential(OrderedDict([
- ("bn1", nn.InstanceNorm2d(in_channel, affine = False)),
- ("relu1", nn.ReLU()),
- ("pad1", nn.ReplicationPad2d(1)),
- ("conv1", nn.Conv2d(in_channel, intermediate_channel, kernel_size=kernel_size,padding=0)),
- ("bn2", nn.InstanceNorm2d(intermediate_channel, affine = False)),
- ("relu2", nn.ReLU()),
- ("pad2", nn.ReplicationPad2d(1)),
- ("conv2", nn.Conv2d(intermediate_channel, out_channel, kernel_size=kernel_size,padding=0)),
- ("sigmoid", nn.Sigmoid())]))
- def forward(self, x):
- out = x
- out = self.layer(out)
- out = x * out
- return out
- def center_crop(layer, target_size):
- _, _, layer_width, layer_height = layer.size()
- start = (layer_width - target_size) // 2
- crop = layer[:, :, start:(start + target_size), start:(start + target_size)]
- return crop
- def concatenate(link, layer):
- concat = torch.cat([link, layer], 1)
- return concat
- def dense_atrous_bottleneck(in_channel, growth_rate = 12, depth = [4,4,4,4]):
- layer_dict = OrderedDict()
- for idx, growth_steps in enumerate(depth):
- dilation_rate = 2**idx
- for y in range(growth_steps):
- layer_dict["dilated_{}_{}".format(dilation_rate,y)] = DilatedDenseUnit(in_channel,
- growth_rate,
- kernel_size=3,
- dilation = dilation_rate)
- in_channel = in_channel + growth_rate
- layer_dict["attention_{}".format(dilation_rate)] = AttentionModule(in_channel, in_channel//4, in_channel)
- return nn.Sequential(layer_dict), in_channel
- class UNET_3D_to_2D(nn.Module):
- def __init__(self, depth, channels_in = 1,
- channels_2d_to_3d = 32, channels = 32, output_channels = 1, slices=stack_depth,
- dilated_layers = [4,4,4,4],
- growth_rate = 12):
- super(UNET_3D_to_2D, self).__init__()
- self.main_modules = []
- self.depth = depth
- self.slices = slices
- self.depth_reducing_layers = ModuleList([reduce_3d_depth(in_channel, channels_2d_to_3d, kernel_size=3, padding=0)
- for in_channel in [channels_in]+[channels_2d_to_3d]*(slices//2 - 1)])
- self.down1 = down_layer(in_channel=channels_2d_to_3d, out_channel=channels, kernel_size=3, padding=0)
- self.main_modules.append(self.down1)
- self.max1 = nn.MaxPool2d(2)
- self.down_layers = ModuleList([down_layer(in_channel = channels*(2**i),
- out_channel = channels * (2**(i+1)),
- kernel_size = 3,
- padding=0
- ) for i in range(self.depth)])
- self.main_modules.append(self.down_layers)
- self.max_layers = ModuleList([nn.MaxPool2d(2) for i in range(self.depth)])
- self.bottleneck, bottleneck_features = dense_atrous_bottleneck(channels*2**self.depth, growth_rate = growth_rate,
- depth = dilated_layers)
- self.main_modules.append(self.bottleneck)
- self.upsampling_layers = ModuleList([nn.Sequential(OrderedDict([
- ("upsampling",nn.Upsample(scale_factor=2, mode = 'bilinear', align_corners=True)),
- ("pad", nn.ReplicationPad2d(1)),
- ("conv", nn.Conv2d(in_channels= bottleneck_features,
- out_channels=bottleneck_features,
- kernel_size=3,
- padding=0))])) for i in range(self.depth, -1, -1)])
- self.main_modules.append(self.upsampling_layers)
- self.up_layers = ModuleList([up_layer(in_channel= bottleneck_features+ channels*(2**(i)),
- out_channel=bottleneck_features,
- kernel_size=3,
- padding=0) for i in range(self.depth, -1, -1)])
- self.main_modules.append(self.up_layers)
- self.last = nn.Conv2d(in_channels=bottleneck_features, out_channels=output_channels, kernel_size=1)
- self.main_modules.append(self.last)
- self.logvar = nn.Conv2d(in_channels=bottleneck_features, out_channels=output_channels, kernel_size=1)
- def forward(self, x):
- # down
- out = x
- for i in range(self.slices//2):
- out = self.depth_reducing_layers[i](out)
- out.transpose_(1, 2).contiguous()
- size = out.size()
- out = out.view((-1, size[2], size[3], size[4]))
- links = []
- out = self.down1(out)
- links.append(out)
- out = self.max1(out)
- for i in range(self.depth):
- out = self.down_layers[i](out)
- links.append(out)
- out = self.max_layers[i](out)
- out = self.bottleneck(out)
- links.reverse()
- # up
- for i in range(self.depth+1):
- out = self.upsampling_layers[i](out)
- out = concatenate(links[i], out)
- out = self.up_layers[i](out)
- pred = self.last(out)
- logvar = self.logvar(out)
- logvar = -torch.exp(logvar)
- return pred, logvar
- def apply_to_case(model, volumes, batch_size, stack_depth = stack_depth, axes=[0], size=(DIM,DIM), mask_bg = True, lowmem=False):
- volume_0 = volumes[0]
- ensemble_logits = None
- for axis in axes:
- print('Axis {}'.format(axis), end='', flush=True) if VERBOSE else False
- logit_total = []
- num_batches = volume_0.shape[axis]//(batch_size)
- if volume_0.shape[axis]%batch_size > 0:
- num_batches = num_batches + 1
- padding = stack_depth//2
- class BrainDataTest(Dataset):
- def __init__(self):
- self.length = num_batches
- def __getitem__(self, batch):
- first_slice = batch*batch_size - padding
- last_slice = np.min([(batch+1)*batch_size+padding, volume_0.shape[axis]+padding])
- extra_upper_slices = np.max([0, stack_depth - (last_slice - first_slice)])
- last_slice = last_slice + extra_upper_slices
- images_t1, nonzero_masks = get_stack_no_augment(axis = axis,
- volume = volume_0,
- first_slice=first_slice,
- last_slice=last_slice,
- size=size)
- images = np.stack([images_t1])
- if padding >0:
- nonzero_masks = nonzero_masks[padding:-(padding+extra_upper_slices)]
- return images.astype(np.float32), nonzero_masks.astype(np.float32)
- def __len__(self):
- return self.length
- test_generator = DataLoader(BrainDataTest(), sampler = SequentialSampler(BrainDataTest()),
- num_workers=0,pin_memory=True)
- for images, nonzero_masks in test_generator:
- print('.', end='', flush=True) if VERBOSE else False
- images = images.to(device)
- nonzero_mask = nonzero_masks.to(device)
- outputs, logit_flip = model(images)
- if mask_bg:
- outputs = outputs * torch.unsqueeze(nonzero_mask[0],1)
- out_cpu = outputs.cpu().data.numpy()
- if lowmem:
- out_cpu = out_cpu.astype(np.float16)
- logit_total.append(out_cpu)
- print('') if VERBOSE else False
- full_logit = np.concatenate(logit_total)
- logit_total = None
- new_shape = full_logit[:, 0, :, :].shape
- shape_difference = (new_shape[0] - np.swapaxes(volume_0,0, axis).shape[0],
- new_shape[1]-np.swapaxes(volume_0,0, axis).shape[1],
- new_shape[2]-np.swapaxes(volume_0,0, axis).shape[2])
- full_logit = np.swapaxes(full_logit, 1, 0)
- full_logit = full_logit[:, shape_difference[0]//2:new_shape[0]- (shape_difference[0] - shape_difference[0]//2),
- shape_difference[1]//2: new_shape[1]- (shape_difference[1] - shape_difference[1]//2),
- shape_difference[2]//2: new_shape[2]- (shape_difference[2] - shape_difference[2]//2)]
- full_logit = np.swapaxes(full_logit, 1, axis+1)
- if ensemble_logits is None:
- ensemble_logits = np.zeros((3,) + full_logit.shape, dtype=np.float16 if lowmem else np.float32)
- ensemble_logits[axis, ] = full_logit
- return np.mean(ensemble_logits, axis=0)
- def locate_model(model_file):
- if os.path.exists(model_file):
- return model_file
- for prefix in ['', '{}/../model/'.format(SCRIPT_DIR)]:
- for suffix in ['.pth', '_f1.pth']:
- file = '{}{}{}'.format(prefix, model_file, suffix)
- if os.path.exists(file):
- return file
- def load_checkpoint(checkpoint_file, device):
- if not os.path.exists(checkpoint_file):
- print('Error: model {} not found'.format(checkpoint_file))
- sys.exit(1)
- print('loading checkpoint {}'.format(checkpoint_file)) if VERBOSE else False
- return torch.load(checkpoint_file, weights_only=True, map_location=device)
- def validate_input(t1, t1_data):
- # input sanity check: we expect images in LIA orientation (FS space)!
- orientation = ''.join(nib.aff2axcodes(t1.affine))
- if orientation != 'LIA':
- print('\nWARNING: Invalid orientation found for {}: {}\n'.format(subject_id, orientation))
- # check for non-zero corners (background)
- corner_idx = np.ix_((0,-1),(0,-1),(0,-1))
- if not np.allclose(t1_data[corner_idx].flatten(), 0):
- print('\nWARNING: Non-zero voxels detected in background (corners). Make sure input is brain extracted (use --bet) and background intensities are exactly 0\n')
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='DeepSCAN: Deep learning based anatomy segmentation and cortex parcellation')
- parser.add_argument("--model", required=False, default='v0_f1')
- parser.add_argument("--lowmem", required=False, default=False)
- parser.add_argument("T1w")
- parser.add_argument("destination_dir")
- parser.add_argument("subject_id")
- args = parser.parse_args()
- t1_file = args.T1w
- output_dir = args.destination_dir
- model_file = locate_model(args.model)
- subject_id = args.subject_id
- if not os.path.exists(t1_file):
- print('T1w file {} not found'.format(t1_file))
- sys.exit(1)
- if not os.path.exists(output_dir):
- os.makedirs(output_dir)
- device = torch.device('cuda' if torch.cuda.is_available() else ('mps' if hasattr(torch.backends, 'mps') and torch.backends.mps.is_available() else 'cpu'))
- checkpoint = load_checkpoint(model_file, device)
- target_label_names = checkpoint['label_names']
- # number of last labels to ignore for hard segmentation (argmax), e.g. left-hemi, right-hemi, brain
- NUM_IGNORE_LABELS = checkpoint['label_num_ignore']
- LABELS = get_label_def(target_label_names)
- unet = UNET_3D_to_2D(0,channels_in=1,channels=64, growth_rate=16, dilated_layers=[4,4,4,4], output_channels=len(target_label_names)).to(device)
- unet.load_state_dict(checkpoint['state_dict'])
- unet.eval()
- t1 = nib.load(t1_file)
- t1_data = t1.get_fdata(dtype=np.float32)
- validate_input(t1, t1_data)
- # apply model
- with torch.set_grad_enabled(False):
- logit = apply_to_case(unet, volumes = [t1_data], batch_size=BATCH_SIZE, stack_depth = stack_depth, axes=[0,1,2], lowmem=args.lowmem)
- print('DONE predicting') if VERBOSE else False
- brain_tissue = logit[-1] > 0
- logit_sm = np.concatenate([logit[:-NUM_IGNORE_LABELS]], axis = 0)
- segmentation_sm = np.argmax(logit_sm, axis=0) + 1
- segmentation_sm_masked = segmentation_sm * brain_tissue
- segmentation_stacked = np.stack([segmentation_sm_masked == x for x in range(1, len(target_label_names)-NUM_IGNORE_LABELS+1)], axis=0)
- volumes = np.sum(segmentation_stacked, axis=(1,2,3))
- # re-label with FS labels
- segmentation_sm_fslabels = np.zeros_like(segmentation_sm_masked)
- for idx in range(1, len(target_label_names)):
- segmentation_sm_fslabels[segmentation_sm_masked == idx] = LABELS[target_label_names[idx-1]]
- affine = t1.affine
- nib.save(nib.Nifti1Image(segmentation_sm_fslabels.astype(np.int32), affine), '{}/softmax_seg.nii.gz'.format(output_dir))
- # save individual logits for each class
- for idx, x in enumerate(target_label_names):
- lbl_name = target_label_names[idx]
- if not SAVE_LOGITS_FILTER or lbl_name in SAVE_LOGITS_FILTER:
- nib.save(nib.Nifti1Image(logit[idx, :, :, :].astype(np.float32), affine), '{}/seg_{}.nii.gz'.format(output_dir, lbl_name))
- with open('{}/result-vol.csv'.format(output_dir), 'w') as file:
- writer = csv.writer(file, delimiter=',')
- writer.writerow(['SUBJECT'] + ['{}'.format(target_label_names[idx]) for idx in range(0, len(target_label_names)-NUM_IGNORE_LABELS)])
- writer.writerow([subject_id] + ['{}'.format(i) for i in volumes])
- # write label definitions
- pd.DataFrame([[LABELS[lbl], lbl] for lbl in LABELS], columns=['ID', 'LABEL']).to_csv('{}/label_def.csv'.format(output_dir), sep=',', index=False)
DeepSCAN_Anatomy_Newnet_apply.py at commit c750348, under BSD-3-Clause · at the source
Overview
- Division of Neuropaediatrics, Development and Rehabilitation, Department of Paediatrics, Inselspital, Bern University Hospital, University of Bern, Bern, Switzerland
- Graduate School for Health Sciences, University of Bern, Bern, Switzerland
- Institute of Sport Science, University of Bern, Bern, Switzerland
- Support Center for Advanced Neuroimaging (SCAN), University Institute of Diagnostic and Interventional Neuroradiology, Inselspital, Bern University Hospital and University of Bern, Bern, Switzerland
- Division of Paediatric Hematology and Oncology, Department of Paediatrics, Inselspital, Bern University Hospital, University of Bern, Bern, Switzerland
Abstract
Background: Childhood cancer survivors exhibit a high prevalence of long-term cognitive and motor impairments as well as structural brain alterations. Examining late effects from a multimodal perspective is essential as individual and contextual resources (e.g. self-efficacy, optimism; parental support, socioeconomic status) as well as risk factors (e.g. disease and treatment related factors) likely impact neurodevelopment such as functional outcome (cognition, motor function) and brain structure in childhood cancer survivors. It is purely understood how individual and contextual resources are associated with functional outcome and brain structure and whether resources can moderate the relationship between functional outcome and brain structure. A deeper understanding of these interrelations can help to identify components for multimodal interventions to strengthen neurodevelopment after childhood cancer in the long-term. This exploratory study investigates associations between resources (individual and contextual) and neurodevelopmental outcomes and how resources moderate functional outcome, and brain morphometry in childhood cancer survivors.
Methods: 56 childhood cancer survivors (N = 45 non central nervous system cancer survivors (non-CNS), N = 11 CNS cancer survivors (CNS)) and 45 typically developing children all aged 7–16 years; M = 10.85, SD = 2.52)) underwent structural MRI, cognitive and motor assessments and filled out questionnaires on individual and contextual resources at least one year after the end of cancer treatment. Correlations were computed, followed by principal components analysis to minimize factors (given the small sample and number of variables), and subsequent moderation analyses were conducted.
Results: More and stronger correlations occurred between resources and functional outcome as well as resources and brain morphometry in survivors (non-CNS: N correlations = 16, r = 0.32-0.61; CNS: N correlation = 9, r = 0.78-0.97) compared with typically developing children (N correlation = 2, r = 0.34-0.37), with the strongest effects in CNS cancer survivors. Interaction effects suggest that resources may moderate the associations between cognition and motor function (β=
Conclusion: These exploratory findings propose that individual and contextual resources are associated with functional outcome and brain morphometry following childhood cancer, suggesting that resource-oriented, multimodal interventions should be considered for neurodevelopmental rehabilitation.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repository
Its files are read in the Code ↔ Paper reader above, with 2 matches between paragraphs and lines of code.
SCAN-NRAD/DL-DiReCT
c750348c569f9dc1c8321048c1ab374b2daca61d, 15 October 2024Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
15 files
- batch-dl+direct.sh, Shell, 133 lines
- direct.sh, Shell, 56 lines
- dl+direct.sh, Shell, 157 lines, 1 match
- src/
DeepSCAN_Anatomy_Newnet_ , Python, 488 lines, 1 matchapply.py - src/
DiReCT.py , Python, 81 lines - src/
bet.py , Python, 92 lines - src/
conform.py , Python, 48 lines - src/
crop.py , Python, 68 lines - src/
extract_stats.py , Python, 110 lines - src/
radiomics2table.py , Python, 48 lines - src/
radiomics_extractor.py , Python, 115 lines - src/
run_script.py , Python, 10 lines - src/
stats2table.py , Python, 79 lines - LICENSE, License, 29 lines
- README.md, Text, 62 lines
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 13 scripts, each with its path and the digest of its content;
- 2 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data availability statement
All anonymized data are available from the last author on reasonable request. Requests to access these datasets should be directed to RE, .
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 3, 28 September 2026
- Funding: added Dietmar Hopp Stiftung; Fondation Gaydoul; Swiss Cancer Research Foundation: KFS-3705-08-2015, KFS-4708-02-2019
Version 1, 27 September 2026: the first record
Recorded: type, language, journal, volume, pages, dates, 4 authors, 7 keywords, 45 references.
Cite
This paper
Salzmann, S., Benzing, V., Romascano, D., & Everts, R. (2026). Resources are associated with functional outcome and brain morphometry in childhood cancer survivors. Frontiers in oncology, 16, 1886395. https://
BibTeX
@article{salzmann2026res
author = {Salzmann, Saskia and Benzing, Valentin and Romascano, David and Everts, Regula},
title = {{Resources are associated with functional outcome and brain morphometry in childhood cancer survivors}},
journal = {Frontiers in oncology},
year = {2026},
month = aug,
volume = {16},
pages = {1886395},
publisher = {Frontiers Media SA},
issn = {2234-943X},
doi = {10.3389/
url = {https://
pmid = {42625627},
pmcid = {PMC13489876}
}
RIS
TY - JOUR
AU - Salzmann, Saskia
AU - Benzing, Valentin
AU - Romascano, David
AU - Everts, Regula
TI - Resources are associated with functional outcome and brain morphometry in childhood cancer survivors
T2 - Frontiers in oncology
J2 - Front Oncol
PY - 2026
DA - 2026/
VL - 16
SP - 1886395
SN - 2234-943X
PB - Frontiers Media SA
DO - 10.3389/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.3389/
"type": "article-journal",
"title": "Resources are associated with functional outcome and brain morphometry in childhood cancer survivors",
"container-title": "Frontiers in oncology",
"author": [
{
"family": "Salzmann",
"given": "Saskia"
},
{
"family": "Benzing",
"given": "Valentin"
},
{
"family": "Romascano",
"given": "David"
},
{
"family": "Everts",
"given": "Regula"
}
],
"container-title-short":
"volume": "16",
"page": "1886395",
"DOI": "10.3389/
"PMID": "42625627",
"PMCID": "PMC13489876",
"ISSN": "2234-943X",
"publisher": "Frontiers Media SA",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
8,
6
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1038/s41598-026-55397-w [code]
- Fast surface reconstruction of human brain MRI: benchmarking deep-learning based morphometry tools.Journal: Scientific reportsIn common: PyRadiomics, SimpleITK, ANTs, 6 other tools, structural MRI / diffusion, 3 references
- [2] doi:10.1038/s41598-026-56778-x [code]
- Chiari malformation type 1 is associated with a smaller fourth ventricle volume - a multi-cohort replication study.Journal: Scientific reportsIn common: PyRadiomics, SimpleITK, ANTs, 6 other tools, structural MRI / diffusion, 1 reference
- [3] doi:10.1371/journal.pcbi.1014555 [code]
- Body surface potential driven personalisation of electrophysiological digital twins in hypertrophic cardiomyopathy.Journal: PLoS computational biologyIn common: PyRadiomics, SimpleITK, ANTs, 6 other tools, structural MRI / diffusion
- [4] doi:10.1002/alz.71649 [code]
- Postmortem brain MRI reveals differential associations of subcortical and limbic volumes with cortical thinning and neurodegenerative pathologies.Journal: Alzheimer's & dementia : the journal of the Alzheimer's AssociationIn common: SimpleITK, ANTs, scikit-image, 5 other tools, structural MRI / diffusion, other condition, 1 reference
- [5] doi:10.3390/jimaging12070276 [code]
- Hyperelastic Regularization for Near-Diffeomorphic Transformer-Based Brain MRI Registration.Journal: Journal of imagingIn common: SimpleITK, ANTs, scikit-image, 5 other tools, structural MRI / diffusion, 1 reference
- [6] doi:10.1038/s41467-026-73373-w [code]
- Mapping neuro-vascular unit communications reveals distinct angiogenic programs across developing mouse brain regions.Journal: Nature communicationsIn common: SimpleITK, ANTs, scikit-image, 5 other tools
- [7] doi:10.1016/j.crmeth.2026.101473 [code]
- AmygdalaGo-BOLT for boundary-aware segmentation of the human amygdala.Journal: Cell reports methodsIn common: SimpleITK, ANTs, scikit-image, 4 other tools, structural MRI / diffusion
- [8] doi:10.1002/advs.76596 [code]
- DDSurfer: A Weakly-Supervised Dual-Stream Deep Learning Framework for Cortical Surface Reconstruction From Diffusion MRI.Journal: Advanced science (Weinheim, Baden-Wurttemberg, Germany)In common: SimpleITK, ANTs, NiBabel, 4 other tools, structural MRI / diffusion, 1 reference
- [9] doi:10.3389/frai.2026.1771088 [code]
- Few-shot deployment of pretrained MRI transformers in brain imaging tasks.Journal: Frontiers in artificial intelligenceIn common: SimpleITK, scikit-image, NiBabel, 4 other tools, structural MRI / diffusion, 1 reference
- [10] doi:10.1186/s12880-026-02335-x [code]
- Automatic lateral ventricle and choroid plexus segmentation method in infant brain MR images.Journal: BMC medical imagingIn common: SimpleITK, scikit-image, NiBabel, 4 other tools, developmental, structural MRI / diffusion
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 13 scripts, and 2 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:e4f755fb71fbd95c…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
