Skip to content

Commit 4095c95

Browse files
committed
test
1 parent 524e21e commit 4095c95

File tree

5 files changed

+226
-2
lines changed

5 files changed

+226
-2
lines changed

recipes/build.py

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
2+
3+
import json
4+
import jsonschema
5+
import base64
6+
import os
7+
8+
# Validate JSON file against OpenRecon schema and write Dockerfile
9+
toolName = os.getenv('toolName')
10+
11+
jsonFilePath = toolName + '/OpenReconLabel.json'
12+
schemaFilePath = 'OpenReconSchema_1.1.0.json'
13+
dockerfilePath = toolName + '/OpenRecon.dockerfile'
14+
baseDockerImage = os.getenv('baseDockerImage')
15+
16+
def validateJson(jsonFilePath, schemaFilePath):
17+
try:
18+
# Load the JSON data from the file
19+
with open(jsonFilePath, 'r') as jsonFile:
20+
jsonData = json.load(jsonFile)
21+
22+
# Load the JSON schema from the file
23+
with open(schemaFilePath, 'r') as schemaFile:
24+
schemaData = json.load(schemaFile)
25+
26+
# Create a JSON Schema validator
27+
validator = jsonschema.Draft7Validator(schemaData)
28+
29+
# Validate the JSON data against the schema
30+
errors = list(validator.iter_errors(jsonData))
31+
32+
if not errors:
33+
print("JSON is valid against the schema.")
34+
return True
35+
else:
36+
print("JSON is not valid against the schema. Errors:")
37+
for error in errors:
38+
print(error)
39+
return False
40+
41+
except Exception as e:
42+
print(f"An error occurred: {e}")
43+
44+
# Write Dockerfile
45+
if validateJson(jsonFilePath, schemaFilePath):
46+
with open(jsonFilePath, 'r') as jsonFile:
47+
jsonData = json.load(jsonFile)
48+
jsonString = json.dumps(jsonData, indent=2)
49+
encodedJson = base64.b64encode(jsonString.encode('utf-8')).decode('utf-8')
50+
51+
with open(dockerfilePath, 'w') as file:
52+
labelName = 'com.siemens-healthineers.magneticresonance.openrecon.metadata:1.1.0'
53+
labelStr = 'LABEL "' + labelName + '"="' + encodedJson + '"'
54+
55+
file.writelines('FROM ' + baseDockerImage)
56+
file.writelines('\n' + labelStr)
57+
print('Wrote Dockerfile:', os.path.abspath(dockerfilePath))
58+
else:
59+
raise Exception('Not writing Dockerfile because JSON is not valid')
60+
61+
# Build Docker image, save to a .tar file, and package into a .zip file for OpenRecon
62+
# The documentation must be a valid PDF!
63+
# README.pdf is autogenerated from README.md, but if it should be overwritten with a dedicated docs.pdf thats's possible
64+
if os.path.isfile('docs.pdf'):
65+
docsFile = 'docs.pdf'
66+
else:
67+
docsFile = 'README.pdf'
68+
69+
# Filename must match information contained in the JSON
70+
version = jsonData['general']['version']
71+
vendor = jsonData['general']['vendor']
72+
name = jsonData['general']['name']['en']
73+
74+
# Check documentation file exists
75+
if not os.path.isfile(docsFile):
76+
raise Exception('Could not find documentation file: ' + docsFile)
77+
78+
# Check 7-zip exists
79+
zipExe = '/usr/bin/7z'
80+
81+
if not os.path.isfile(zipExe):
82+
raise Exception('Could not find 7-Zip executable: ' + zipExe + '\nPlease download and install 7-Zip')
83+
84+
dockerImagename = ('OpenRecon_' + vendor + '_' + name + ':' + 'V' + version).lower()
85+
baseFilename = 'OpenRecon_' + vendor + '_' + name + '_V' + version
86+
87+
import subprocess
88+
import shutil
89+
90+
try:
91+
# Build Docker image docker buildx build --platform linux/amd64
92+
print('Attempting to create Docker image with tag:', dockerImagename, '...')
93+
output = subprocess.check_output(['docker', 'buildx', 'build', '--platform', 'linux/amd64', '--no-cache', '--progress=plain', '-t', dockerImagename, '-f', dockerfilePath, './'], stderr=subprocess.STDOUT)
94+
print('Docker build output:\n' + output.decode('utf-8'))
95+
96+
# Save Docker image to a .tar file
97+
print('Saving Docker image file with name:', baseFilename + '.tar', '...')
98+
output = subprocess.check_output(['docker', 'save', '-o', baseFilename + '.tar', dockerImagename], stderr=subprocess.STDOUT)
99+
print('Docker save output:\n' + output.decode('utf-8'))
100+
101+
# Copy documentation file with appropriate filename
102+
print('Copying documentation to file with name:', baseFilename + '.pdf', '...')
103+
try:
104+
shutil.copy(docsFile, baseFilename + '.pdf')
105+
print(f'File copied from {docsFile} to {baseFilename}.pdf')
106+
except IOError as e:
107+
print(f'An error occurred: {e}')
108+
109+
# Zip into a package
110+
print('Packaging files into zip with name:', baseFilename + '.zip', '...')
111+
output = subprocess.check_output([zipExe, 'a', '-tzip', '-mm=Deflate', baseFilename + '.zip', baseFilename + '.tar', baseFilename + '.pdf'], stderr=subprocess.STDOUT)
112+
print('Zip packaging output:\n' + output.decode('utf-8'))
113+
114+
except subprocess.CalledProcessError as e:
115+
# If the command returns a non-zero exit status, it will raise a CalledProcessError
116+
print('Command failed with return code:', e.returncode)
117+
print('Error output:\n' + e.output.decode('utf-8'))
118+

recipes/build.sh

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/bin/bash
22
set -e
3-
4-
3+
#This script will run inside the tool directory
54

65
# check and install dependencies
76
if ! command -v pip3 &> /dev/null; then
@@ -43,5 +42,12 @@ python3 ../checkDockerVersion.py
4342
# build pdf file from README.md
4443
mdpdf README.md
4544

45+
# source tool-specific parameters
46+
source params.sh
47+
48+
current_dir=$(pwd)
49+
export toolName=$(basename "$current_dir")
50+
4651
# build zip file
52+
cd ..
4753
python3 build.py
+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"general": {
3+
"name": { "en": "vesselboost" },
4+
"version": "1.0.1",
5+
"vendor": "neurodesk",
6+
"information": { "en": "Vesselboost pipeline." },
7+
"id": "vesselboost",
8+
"regulatory_information": {
9+
"device_trade_name":"vesselboost",
10+
"production_identifier":"1.0.1",
11+
"manufacturer_address":"Erlangen, Germany",
12+
"made_in":"DE",
13+
"manufacture_date":"2023/02/14",
14+
"material_number":"vesselboost_1.0.1",
15+
"gtin":"00860000171212",
16+
"udi":"(01)00860000171212(21)1.3.0",
17+
"safety_advices":"",
18+
"special_operating_instructions":"Open Recon vesselboost pipeline",
19+
"additional_relevant_information":""
20+
}
21+
},
22+
"reconstruction": {
23+
"transfer_protocol": {
24+
"protocol": "ISMRMRD",
25+
"version": "1.4.1"
26+
},
27+
"port": 9002,
28+
"emitter": "image",
29+
"injector": "image",
30+
"can_process_adjustment_data": false,
31+
"can_use_gpu": false,
32+
"min_count_required_gpus": 0,
33+
"min_required_gpu_memory": 2048,
34+
"min_required_memory": 4096,
35+
"min_count_required_cpu_cores": 1,
36+
"content_qualification_type": "PRODUCT"
37+
},
38+
"parameters": [
39+
{
40+
"id": "config",
41+
"label": { "en": "config" },
42+
"type": "choice",
43+
"values": [
44+
{
45+
"id": "invertcontrast",
46+
"name": { "en": "invertcontrast" }
47+
}
48+
],
49+
"default": "invertcontrast",
50+
"information": { "en": "Define the config to be executed by MRD server" }
51+
},
52+
{
53+
"id": "customconfig",
54+
"label": { "en":"Custom Config" },
55+
"type": "string",
56+
"default": "",
57+
"information": { "en": "Custom config file not listed in drop-down menu" }
58+
},
59+
{
60+
"id": "options",
61+
"label": { "en": "options" },
62+
"type": "choice",
63+
"values": [
64+
{
65+
"id": "none",
66+
"name": { "en": "none" }
67+
},
68+
{
69+
"id": "roi",
70+
"name": { "en": "roi" }
71+
},
72+
{
73+
"id": "colormap",
74+
"name": { "en": "colormap" }
75+
}
76+
],
77+
"default": "none",
78+
"information": { "en": "Define additional options" }
79+
},
80+
{
81+
"id": "double",
82+
"label": { "en": "double" },
83+
"type": "double",
84+
"minimum": 0,
85+
"maximum": 100,
86+
"default": 1.0,
87+
"information": { "en": "A double parameter" }
88+
},
89+
{
90+
"id": "freetext",
91+
"label": { "en":"freetext" },
92+
"type": "string",
93+
"default": "",
94+
"information": { "en": "Free text data" }
95+
}
96+
]
97+
}

recipes/vesselboost/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Vesselboost will segment an MRA TOF and output the segmentation.

recipes/vesselboost/params.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export baseImage=vnmd/vesselboost_1.0.1
2+

0 commit comments

Comments
 (0)