-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinference.py
More file actions
140 lines (100 loc) · 4.03 KB
/
inference.py
File metadata and controls
140 lines (100 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""
The following is a simple example algorithm.
It is meant to run within a container.
To run the container locally, you can call the following bash script:
./do_test_run.sh
This will start the inference and reads from ./test/input and writes to ./test/output
To save the container and prep it for upload to Grand-Challenge.org you can call:
./do_save.sh
Any container that shows the same behaviour will do, this is purely an example of how one COULD do it.
Reference the documentation to get details on the runtime environment on the platform:
https://grand-challenge.org/documentation/runtime-environment/
Happy programming!
"""
from pathlib import Path
import json
from glob import glob
import SimpleITK
import numpy
INPUT_PATH = Path("/input")
OUTPUT_PATH = Path("/output")
RESOURCE_PATH = Path("resources")
def run():
# The key is a tuple of the slugs of the input sockets
interface_key = get_interface_key()
# Lookup the handler for this particular set of sockets (i.e. the interface)
handler = {
("stacked-neuron-images-with-noise",): interf0_handler,
}[interface_key]
# Call the handler
return handler()
def interf0_handler():
# Read the input
input_stacked_neuron_images_with_noise = load_image_file_as_array(
location=INPUT_PATH / "images/stacked-neuron-images-with-noise",
)
# Process the inputs: any way you'd like
_show_torch_cuda_info()
# Some additional resources might be required, include these in one of two ways.
# Option 1: part of the Docker-container image: resources/
resource_dir = Path("/opt/app/resources")
with open(resource_dir / "some_resource.txt", "r") as f:
print(f.read())
# Option 2: upload them as a separate tarball to Grand Challenge (go to your Algorithm > Models). The resources in the tarball will be extracted to `model_dir` at runtime.
model_dir = Path("/opt/ml/model")
with open(
model_dir / "a_tarball_subdirectory" / "some_tarball_resource.txt", "r"
) as f:
print(f.read())
# For now, let us make bogus predictions
output_stacked_neuron_images_with_reduced_noise = numpy.eye(4, 2)
# Save your output
write_array_as_image_file(
location=OUTPUT_PATH / "images/stacked-neuron-images-with-reduced-noise",
array=output_stacked_neuron_images_with_reduced_noise,
)
return 0
def get_interface_key():
# The inputs.json is a system generated file that contains information about
# the inputs that interface with the algorithm
inputs = load_json_file(
location=INPUT_PATH / "inputs.json",
)
socket_slugs = [sv["interface"]["slug"] for sv in inputs]
return tuple(sorted(socket_slugs))
def load_json_file(*, location):
# Reads a json file
with open(location, "r") as f:
return json.loads(f.read())
def load_image_file_as_array(*, location):
# Use SimpleITK to read a file
input_files = (
glob(str(location / "*.tif"))
+ glob(str(location / "*.tiff"))
+ glob(str(location / "*.mha"))
)
result = SimpleITK.ReadImage(input_files[0])
# Convert it to a Numpy array
return SimpleITK.GetArrayFromImage(result)
def write_array_as_image_file(*, location, array):
location.mkdir(parents=True, exist_ok=True)
# You may need to change the suffix to .tif to match the expected output
suffix = ".mha"
image = SimpleITK.GetImageFromArray(array)
SimpleITK.WriteImage(
image,
location / f"output{suffix}",
useCompression=True,
)
def _show_torch_cuda_info():
import torch
print("=+=" * 10)
print("Collecting Torch CUDA information")
print(f"Torch CUDA is available: {(available := torch.cuda.is_available())}")
if available:
print(f"\tnumber of devices: {torch.cuda.device_count()}")
print(f"\tcurrent device: { (current_device := torch.cuda.current_device())}")
print(f"\tproperties: {torch.cuda.get_device_properties(current_device)}")
print("=+=" * 10)
if __name__ == "__main__":
raise SystemExit(run())