I mentioned this in previous posts, but at least now it seems that there is a way to recreate the problem, even though I haven’t seen a specific error message in the log, just a hang or a crash. I added an if statement to check if the study isStable or not as part of the debugging process and it returns the Busy message if the study is being modified and not stable, and otherwise works fine.
The crash/hang occurs when the method is called (it is a Python Plug-in script) while jobs that are modifying other series that are part of the study are running. It seems that the create-dicom call is the problematic ones, although possibly one of the earlier ones.
Just wondering why that is, and if it might be possible to call /tools/create-dicom Asynchronously so it runs as a job, or otherwise does not cause a crash.
def MakeKeyImage(output, uri, **request):
POST has {“StudyInstanceUID”:“StudyInstanceUID”",“data-url”:“data-url”,“ImageComments”:“Some Info”})
if request[‘method’] != ‘POST’:
output.SendMethodNotAllowed(‘POST’)
else:
response = dict();
query = json.loads(request[‘body’])
study = json.loads(orthanc.RestApiPost(‘/tools/lookup’, query[‘StudyInstanceUID’]))[0] # assume a unique StudyInstancUID on server and that it exists
study = json.loads(orthanc.RestApiGet(‘/studies/%s’ % study[‘ID’]))
if study[‘IsStable’] == True:
series = json.loads(orthanc.RestApiGet(‘/studies/’ + study[“ID”] + ‘/series’)) # get the series uuid’s, there has to be at least one
keyimagesID = False
instancenumber = 1
for seriesitem in series:
Check to see if the ‘KEY_IMAGES’ series already exists, sort of assumes that this will always be unqiue on this system
if ‘SeriesDescription’ in seriesitem[‘MainDicomTags’] and seriesitem[‘MainDicomTags’][‘SeriesDescription’] == ‘KEY_IMAGES’:
keyimagesID = seriesitem[‘ID’]
instancenumber = len(seriesitem[‘Instances’]) + 1
dicomdata = dict()
1.2.840.10008.5.1.4.1.1.7 is SOPClassUID for Secondary Capture Image Storage
Set things up to add to an existing series, or create one if it does not already exist
if keyimagesID:
parent = keyimagesID
dicomdata[‘Tags’] = {“ImageComments”:query[‘ImageComments’],“SOPClassUID”:“1.2.840.10008.5.1.4.1.1.7.4”,“InstanceNumber”: str(instancenumber)}
else:
parent = study[“ID”]
dicomdata[‘Tags’] = {“Modality”:“OT”,“SeriesDescription”: “KEY_IMAGES”,“SequenceName” : “KEY_IMAGES”,“ImageComments”:query[‘ImageComments’],“SeriesNumber”:“0”,“SOPClassUID”:“1.2.840.10008.5.1.4.1.1.7.4”,“InstanceNumber”: str(instancenumber)}
dicomdata[‘Parent’] = parent
image to save is html converted to a jpeg image using wkhtmltoimage.
https://pypi.org/project/imgkit/
options = {
‘format’: ‘jpeg’,
‘encoding’: “UTF-8”
}
False means to store it to a variable rather than to a file on disk
jpegimage = imgkit.from_string(query[‘html’], False, options=options)
Need to be a data-url in base64
jpegimage = base64.b64encode(jpegimage).decode()
jpegimage = ‘data:image/jpeg;base64,’+jpegimage
jpegimage = query[‘data_url’]
logging.info(jpegimage)
dicomdata[‘Content’] = jpegimage
dicom = json.loads(orthanc.RestApiPost(‘/tools/create-dicom’, json.dumps(dicomdata)))
response[‘keyimagesID’] = keyimagesID
response[‘status’] = study
response[‘create-dicom’] = dicom
else:
response[‘status’] = “Unstable”
output.AnswerBuffer(json.dumps(response), ‘application/json’)
orthanc.RegisterRestCallback(‘/make_key_image’, MakeKeyImage)
Stephen D. Scotti