Skip to content
This repository has been archived by the owner on Mar 21, 2024. It is now read-only.

ENH: Switch recommonmark to MyST-parser #787

Merged
merged 25 commits into from
Aug 18, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
267d4e8
📝 Create basic for ML API
peterhessey Aug 5, 2022
806f261
📝 Add ML/configs base doc files
peterhessey Aug 5, 2022
0cbd7c7
📝 Finish ML/configs API
peterhessey Aug 8, 2022
f5c82cf
📝 Update augmentations
peterhessey Aug 8, 2022
ac0171a
📝 Add ML/dataset API docs
peterhessey Aug 8, 2022
e9fff6a
📝 Add rst skeleton for ML/models
peterhessey Aug 8, 2022
4fd8de4
📝 Fix docstring missing newlines
peterhessey Aug 8, 2022
6371548
Remove script
peterhessey Aug 8, 2022
27e7784
📝 Finish ML/models API docs
peterhessey Aug 8, 2022
6a1273f
📝 Start ML/SSL API. Fix some formatting issues
peterhessey Aug 9, 2022
562173b
📝 Correct whitespace issues in `:param`
peterhessey Aug 9, 2022
416e907
📝 Fix whitespace errors on `:return` statements
peterhessey Aug 9, 2022
a778dac
📝 Fix :return: statements
peterhessey Aug 9, 2022
33b557c
📝 Finish ML/SSL API
peterhessey Aug 9, 2022
7d4f466
📝 Add ML/utils API docs
peterhessey Aug 9, 2022
19ab5b2
📝 Add visualizer docs, fix `:raise` indents
peterhessey Aug 9, 2022
67169af
📝 Fix more issues with the `:raises:` formatting
peterhessey Aug 9, 2022
7619004
♻️ Restructuring folders
peterhessey Aug 9, 2022
bdc2a51
📝 Limit API `toctree` depth
peterhessey Aug 9, 2022
56c3a52
📝 Add primary InnerEye/ML files API to docs
peterhessey Aug 9, 2022
e9e5ee8
📝 Fix and add `InnerEye/ML/*.py` docs
peterhessey Aug 9, 2022
c1d84a8
⚰️ Remove weird `settings.json` change
peterhessey Aug 9, 2022
933bc7b
📌 Switch recommonmark to MyST-parser
peterhessey Aug 15, 2022
6e610b0
📌 Add myst-parser to `environment.yml`, lock env
peterhessey Aug 16, 2022
a9a5278
Fix conflicts merging main
peterhessey Aug 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
📝 Fix whitespace errors on :return statements
  • Loading branch information
peterhessey committed Aug 9, 2022
commit 416e90735e45947c991223ad7f5c9747fc076125
2 changes: 1 addition & 1 deletion InnerEye/Azure/azure_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def create_dataset_configs(azure_config: AzureConfig,
:param all_dataset_mountpoints: When using the datasets in AzureML, these are the per-dataset mount points.
:param all_local_datasets: The paths for all local versions of the datasets.
:return: A list of DatasetConfig objects, in the same order as datasets were provided in all_azure_dataset_ids,
omitting datasets with an empty name.
omitting datasets with an empty name.
"""
datasets: List[DatasetConfig] = []
num_local = len(all_local_datasets)
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/Azure/run_pytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def run_pytest(pytest_mark: str, outputs_folder: Path) -> Tuple[bool, Path]:
:param pytest_mark: The PyTest mark to use for filtering out the tests to run.
:param outputs_folder: The folder into which the test result XML file should be written.
:return: True if PyTest found tests to execute and completed successfully, False otherwise.
Also returns the path to the generated PyTest results file.
Also returns the path to the generated PyTest results file.
"""
from _pytest.main import ExitCode
_outputs_file = outputs_folder / PYTEST_RESULTS_FILE
Expand Down
4 changes: 2 additions & 2 deletions InnerEye/Azure/secrets_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def read_all_settings(project_settings_file: Optional[Path] = None,
:param project_settings_file: The first YAML settings file to read.
:param project_root: The folder that can contain a 'InnerEyePrivateSettings.yml' file.
:return: A dictionary mapping from string to variable value. The dictionary key is the union of variable names
found in the two settings files.
found in the two settings files.
"""
private_settings_file = None
if project_root and project_root.is_dir():
Expand All @@ -126,7 +126,7 @@ def read_settings_and_merge(project_settings_file: Optional[Path] = None,
:param project_settings_file: The first YAML settings file to read.
:param private_settings_file: The second YAML settings file to read. Settings in this file has higher priority.
:return: A dictionary mapping from string to variable value. The dictionary key is the union of variable names
found in the two settings files.
found in the two settings files.
"""
result = dict()
if project_settings_file:
Expand Down
6 changes: 3 additions & 3 deletions InnerEye/Common/Statistics/mann_whitney_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def roc_value(lst1: List[float], lst2: List[float]) -> float:
:param lst1: a list of numbers
:param lst2: another list of numbers
:return: the proportion of pairs (x, y), where x is from lst1 and y is from lst2, for which
x < y, with x == y counting as half an instance.
x < y, with x == y counting as half an instance.
"""
if len(lst1) == 0 or len(lst2) == 0:
return 0.5
Expand Down Expand Up @@ -273,7 +273,7 @@ def compare_scores_across_institutions(metrics_file: str, splits_to_use: str = "
:param splits_to_use: a comma-separated list of split names
:param mode_to_use: test, validation etc
:return: a list of comparison lines between pairs of splits. If splits_to_use is non empty,
only pairs involving at least one split from that set are compared.
only pairs involving at least one split from that set are compared.
"""
valid_splits = set(splits_to_use.split(",")) if splits_to_use else None
metrics = pd.read_csv(metrics_file)
Expand Down Expand Up @@ -330,7 +330,7 @@ def get_arguments(arglist: List[str] = None) -> Tuple[Optional[argparse.Namespac
The value of the "-a" switch is one or more split names; pairs of splits not including these
will not be compared.
:return: parsed arguments and identifier for pattern (1, 2, 3 as above), or None, None if none of the
patterns are followed
patterns are followed
"""
# Use argparse because we want to have mandatory non-switch arguments, which GenericConfig doesn't support.
parser = argparse.ArgumentParser("Run Mann-Whitney tests")
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/Common/Statistics/report_structure_extremes.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def extent_list(presence: np.array, max_value: int) -> Tuple[List[int], List[str
:param presence: a 1-D array of distinct integers in increasing order.
:param max_value: any integer, not necessarily related to presence
:return: two tuples: (1) a list of the minimum and maximum values of presence, and max_value;
(2) a list of strings, each denoting a missing range of values within "presence".
(2) a list of strings, each denoting a missing range of values within "presence".
"""
if len(presence) == 0:
return [-1, -1, max_value], []
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/Common/Statistics/wilcoxon_signed_rank_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def difference_counts(values1: List[float], values2: List[float]) -> Tuple[int,
:param values1: list of values
:param values2: list of values, same length as values1
:return: number of pairs in which first value is greater than second, and number of pairs
in which second is greater than first
in which second is greater than first
"""
n1 = 0
n2 = 0
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/Common/spawn_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def spawn_and_monitor_subprocess(process: str,
:param env: The environment variables that the new process will run with. If not provided, copy the
environment from the current process.
:return: Return code after the process has finished, and the list of lines that were written to stdout by the
subprocess.
subprocess.
"""
if env is None:
env = dict(os.environ.items())
Expand Down
6 changes: 3 additions & 3 deletions InnerEye/ML/SSL/lightning_containers/ssl_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@ def _create_ssl_data_modules(self, is_ssl_encoder_module: bool) -> InnerEyeVisio

:param is_ssl_encoder_module: whether to return the data module for SSL training or for linear head. If true,
:return transforms with two views per sample (batch like (img_v1, img_v2, label)). If False, return only one
view per sample but also return the index of the sample in the dataset (to make sure we don't use twice the same
batch in one training epoch (batch like (index, img_v1, label), as classifier dataloader expected to be shorter
than SSL training, hence CombinedDataloader might loop over data several times per epoch).
view per sample but also return the index of the sample in the dataset (to make sure we don't use twice the same
batch in one training epoch (batch like (index, img_v1, label), as classifier dataloader expected to be shorter
than SSL training, hence CombinedDataloader might loop over data several times per epoch).
"""
datamodule_args = self.datamodule_args[SSLDataModuleType.ENCODER] if is_ssl_encoder_module else \
self.datamodule_args[SSLDataModuleType.LINEAR_HEAD]
Expand Down
6 changes: 3 additions & 3 deletions InnerEye/ML/baselines_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ def download_and_compare_scores(outputs_folder: Path, azure_config: AzureConfig,
:param model_dataset_df: dataframe containing contents of dataset.csv for the current model
:param model_metrics_df: dataframe containing contents of metrics.csv for the current model
:return: a dataframe for all the data (current model and all baselines); whether any comparisons were
done, i.e. whether a valid baseline was found; and the text lines to be written to the Wilcoxon results
file.
done, i.e. whether a valid baseline was found; and the text lines to be written to the Wilcoxon results
file.
"""
comparison_baselines = get_comparison_baselines(outputs_folder, azure_config, comparison_blob_storage_paths)
result = perform_score_comparisons(model_dataset_df, model_metrics_df, comparison_baselines)
Expand Down Expand Up @@ -261,7 +261,7 @@ def compare_folder_contents(expected_folder: Path,
:param csv_relative_tolerance: When comparing CSV files, use this as the maximum allowed relative discrepancy.
If 0.0, do not allow any discrepancy.
:return: A list of human readable error messages, with message and file path. If no errors are found, the list is
empty.
empty.
"""
messages = []
if run and is_offline_run_context(run):
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/ML/dataset/scalar_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ def load_item(self, item: ScalarDataSource) -> ScalarItem:

:param item: The item to load.
:return: A ClassificationItem instances with the loaded images, and the labels and non-image features copied
from the argument.
from the argument.
"""
sample = item.load_images(
root_path=self.args.local_dataset,
Expand Down
4 changes: 2 additions & 2 deletions InnerEye/ML/dataset/scalar_sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def load_images(self,
:param image_size: If given, all loaded images will be reshaped to the size given here, prior to the
center crop.
:return: An instance of ClassificationItem, with the same label and numerical_non_image_features fields,
and all images loaded.
and all images loaded.
"""
full_channel_files = self.get_all_image_filepaths(root_path=root_path,
file_mapping=file_mapping)
Expand All @@ -160,7 +160,7 @@ def is_valid(self) -> bool:
be not None, and none of the non imaging features may be NaN or infinity.

:return: True if channel files is a list with not-None entries, and all non imaging features are finite
floating point numbers.
floating point numbers.
"""
return self.files_valid() and super().is_valid()

Expand Down
8 changes: 4 additions & 4 deletions InnerEye/ML/deep_learning_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,10 +855,10 @@ def load_checkpoint_and_modify(self, path_to_checkpoint: Path) -> Dict[str, Any]

:param path_to_checkpoint: Path to the checkpoint file.
:return: Dictionary with model and optimizer state dicts. The dict should have at least the following keys:
1. Key ModelAndInfo.MODEL_STATE_DICT_KEY and value set to the model state dict.
2. Key ModelAndInfo.EPOCH_KEY and value set to the checkpoint epoch.
Other (optional) entries corresponding to keys ModelAndInfo.OPTIMIZER_STATE_DICT_KEY and
ModelAndInfo.MEAN_TEACHER_STATE_DICT_KEY are also supported.
1. Key ModelAndInfo.MODEL_STATE_DICT_KEY and value set to the model state dict.
2. Key ModelAndInfo.EPOCH_KEY and value set to the checkpoint epoch.
Other (optional) entries corresponding to keys ModelAndInfo.OPTIMIZER_STATE_DICT_KEY and
ModelAndInfo.MEAN_TEACHER_STATE_DICT_KEY are also supported.
"""
return load_checkpoint(path_to_checkpoint=path_to_checkpoint, use_gpu=self.use_gpu)

Expand Down
2 changes: 1 addition & 1 deletion InnerEye/ML/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def compute_dice_across_patches(segmentation: torch.Tensor,
:param allow_multiple_classes_for_each_pixel: If set to False, ground-truth tensor has
to contain only one foreground label for each pixel.
:return A torch tensor of size (Patches, Classes) with the Dice scores. Dice scores are computed for
all classes including the background class at index 0.
all classes including the background class at index 0.
"""
check_size_matches(segmentation, ground_truth, 4, 5, [0, -3, -2, -1],
arg1_name="segmentation", arg2_name="ground_truth")
Expand Down
4 changes: 2 additions & 2 deletions InnerEye/ML/model_config_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def create_data_loaders(self) -> Dict[ModelExecutionMode, Any]:
"""
Creates the torch DataLoaders that supply the training and the validation set during training only.
:return: A dictionary, with keys ModelExecutionMode.TRAIN and ModelExecutionMode.VAL, and their respective
data loaders.
data loaders.
"""
logging.info("Starting to read and parse the datasets.")
if self._datasets_for_training is None:
Expand Down Expand Up @@ -185,7 +185,7 @@ def get_cross_validation_dataset_splits(self, dataset_split: DatasetSplits) -> D

:param dataset_split: The full dataset, split into training, validation and test section.
:return: The dataset split with training and validation sections shuffled according to the current
cross validation index.
cross validation index.
"""
splits = dataset_split.get_k_fold_cross_validation_splits(self.number_of_cross_validation_splits)
return splits[self.cross_validation_split_index]
Expand Down
4 changes: 2 additions & 2 deletions InnerEye/ML/model_training.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ def model_train(checkpoint_path: Optional[Path],
:param container: A container object that holds the training data in PyTorch Lightning format
and the model to train.
:return: A tuple of [Trainer, StoringLogger]. Trainer is the Lightning Trainer object that was used for fitting
the model. The StoringLogger object is returned when training an InnerEye built-in model, this is None when
fitting other models.
the model. The StoringLogger object is returned when training an InnerEye built-in model, this is None when
fitting other models.
"""
lightning_model = container.model

Expand Down
4 changes: 2 additions & 2 deletions InnerEye/ML/pipelines/ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def aggregate_results(results: Iterable[InferencePipeline.Result],

:param aggregation_type: aggregation function to use to combine the results.
:return: InferenceResult: contains a Segmentation for each of the classes and their posterior
probabilities.
probabilities.
"""
if aggregation_type != EnsembleAggregationType.Average:
raise NotImplementedError(f"Ensembling is not implemented for aggregation type: {aggregation_type}")
Expand Down Expand Up @@ -86,7 +86,7 @@ def predict_whole_image(self, image_channels: np.ndarray,
:param mask: A binary image used to ignore results outside it in format: Z x Y x X.
:param patient_id: The identifier of the patient this image belongs to.
:return InferenceResult: that contains Segmentation for each of the classes and their posterior
probabilities.
probabilities.
"""
logging.info(f"Ensembling inference pipelines ({self._get_pipeline_ids()}) "
f"predictions for patient: {patient_id}, "
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/ML/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def plot_val_dice_per_epoch(metrics: Dict[str, Any]) -> int:

:param metrics:
:return: The number of series that were plotted in the graph. Can return 0 if the metrics dictionary
does not contain any validation Dice score.
does not contain any validation Dice score.
"""
plt.clf()
series_count = 0
Expand Down
4 changes: 2 additions & 2 deletions InnerEye/ML/reports/classification_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ def plot_scores_and_summary(all_labels_and_model_outputs: Sequence[LabelsAndPred

:param ax: Axes object onto which to plot (default: use current axes).
:return: A tuple of `(line_handles, summary_handle)` to use in setting a legend for the plot: `line_handles` is a
list corresponding to the curves for each `LabelsAndPredictions`, and `summary_handle` references the median line
and shaded CI area.
list corresponding to the curves for each `LabelsAndPredictions`, and `summary_handle` references the median line
and shaded CI area.
"""
if ax is None:
ax = plt.gca()
Expand Down
4 changes: 2 additions & 2 deletions InnerEye/ML/run_ml.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ def register_model(self,
:param checkpoint_paths: Checkpoint paths to register.
:param model_proc: whether it's a single or ensemble model.
:returns Tuple element 1: AML model object, or None if no model could be registered.
Tuple element 2: The result of running the model_deployment_hook, or None if no hook was supplied.
Tuple element 2: The result of running the model_deployment_hook, or None if no hook was supplied.
"""
if self.is_offline_run:
raise ValueError("Cannot register models when InnerEye is running outside of AzureML.")
Expand Down Expand Up @@ -731,7 +731,7 @@ def are_sibling_runs_finished(self) -> bool:
or cancelled.

:return: True if all sibling runs of the current run have finished (they either completed successfully,
or failed). False if any of them is still pending (running or queued).
or failed). False if any of them is still pending (running or queued).
"""
if (not self.is_offline_run) \
and (azure_util.is_cross_validation_child_run(RUN_CONTEXT)):
Expand Down
4 changes: 2 additions & 2 deletions InnerEye/ML/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def run(self) -> Tuple[Optional[DeepLearningConfig], AzureRunInfo]:
The main entry point for training and testing models from the commandline. This chooses a model to train
via a commandline argument, runs training or testing, and writes all required info to disk and logs.
:return: If submitting to AzureML, returns the model configuration that was used for training,
including commandline overrides applied (if any).
including commandline overrides applied (if any).
"""
# Usually, when we set logging to DEBUG, we want diagnostics about the model
# build itself, but not the tons of debug information that AzureML submissions create.
Expand Down Expand Up @@ -450,7 +450,7 @@ def run(project_root: Path,
The main entry point for training and testing models from the commandline. This chooses a model to train
via a commandline argument, runs training or testing, and writes all required info to disk and logs.
:return: If submitting to AzureML, returns the model configuration that was used for training,
including commandline overrides applied (if any). For details on the arguments, see the constructor of Runner.
including commandline overrides applied (if any). For details on the arguments, see the constructor of Runner.
"""
runner = Runner(project_root, yaml_config_file, post_cross_validation_hook, model_deployment_hook)
return runner.run()
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/ML/utils/device_aware_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self) -> None:
def get_devices(self) -> List[torch.device]:
"""
:return a list of device ids on which this module
is deployed.
is deployed.
"""
return list({x.device for x in self.parameters()})

Expand Down
2 changes: 1 addition & 1 deletion InnerEye/ML/utils/features_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def from_data_sources(sources: List[ScalarDataSource]) -> FeatureStatistics:

:param sources: list of data sources
:return: a Feature Statistics object storing mean and standard deviation for each non-imaging feature of
the dataset.
the dataset.
"""
if len(sources) == 0:
raise ValueError("sources must have a length greater than 0")
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/ML/utils/hdf5_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def parse_acquisition_date(date: str) -> Optional[datetime]:

:param date: string representing a date
:return: converted date, None if the string is invalid for
date conversion.
date conversion.
"""
try:
return datetime.strptime(date, DATE_FORMAT)
Expand Down
6 changes: 3 additions & 3 deletions InnerEye/ML/utils/image_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def posteriors_to_segmentation(posteriors: NumpyOrTorch) -> NumpyOrTorch:
:param posteriors: Confidence maps [0,1] for each patch per class in format: Batches x Class x Z x Y x X
or Class x Z x Y x X for non-batched input
:returns segmentation: argmaxed posteriors with each voxel belonging to a single class: Batches x Z x Y x X
or Z x Y x X for non-batched input
or Z x Y x X for non-batched input
"""

if posteriors is None:
Expand Down Expand Up @@ -507,7 +507,7 @@ def compute_uncertainty_map_from_posteriors(posteriors: np.ndarray) -> np.ndarra
:param posteriors: Normalized probability distribution in range [0, 1] for each class,
in shape: Class x Z x Y x X
:return: Shannon Entropy for each voxel, shape: Z x Y x X expected range is [0,1] where 1 represents
low confidence or uniform posterior distribution across classes.
low confidence or uniform posterior distribution across classes.
"""
check_if_posterior_array(posteriors)

Expand Down Expand Up @@ -569,7 +569,7 @@ def segmentation_to_one_hot(segmentation: torch.Tensor,

:param result_dtype: The torch data type that the result tensor should have. This would be either float16 or float32
:return: A torch tensor with one-hot encoding of the segmentation of shape
[B, C*HDF5_NUM_SEGMENTATION_CLASSES, Z, Y, X]
[B, C*HDF5_NUM_SEGMENTATION_CLASSES, Z, Y, X]
"""

def to_cuda(x: torch.Tensor) -> torch.Tensor:
Expand Down
2 changes: 1 addition & 1 deletion InnerEye/ML/utils/io_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def load_images_and_stack(files: Iterable[Path],

:param image_size: If supplied, all loaded images will be resized immediately after loading.
:return: A wrapper class that contains the loaded images, and if load_segmentation is True, also the segmentations
that were present in the files.
that were present in the files.
"""
images = []
segmentations = []
Expand Down
Loading