# LUA calling external application, processing result

**URL:** https://discourse.orthanc-server.org/t/lua-calling-external-application-processing-result/208
**Category:** Google Groups archive
**Created:** [July 19, 2015, 11:36pm UTC](https://discourse.orthanc-server.org/t/lua-calling-external-application-processing-result/208 "2015-07-19T23:36:36Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![ozpacs](https://discourse.orthanc-server.org/letter_avatar_proxy/v4/letter/o/6bbea6/32.png) [@ozpacs](https://discourse.orthanc-server.org/u/ozpacs)
#### Post date: [July 19, 2015, 11:36pm UTC](https://discourse.orthanc-server.org/t/lua-calling-external-application-processing-result/208/1 "2015-07-19T23:36:36Z")

</div>

Hi All,

Has anyone had any experience in getting Orthanc to call an external application and process it’s response?

I’m using Orthanc to route images to a PACS, but would like Orthanc to check the PACS to see if an order exists for the images first.

I’m thinking of the following:

- Radiographers “should” be entering an order into a RIS, which sends a HL7 message to PACS (creating a placeholder for images).
- Orthanc receives an image from a modality
- LUA script calls something like DCM4CHE and queries the PACS based on accessionnumber.
- LUA processes the response to see if there is the placeholder in PACS already
- If the response is “yes”, let the images through. If it’s a “No” reject.

Anyone?

---

<div class="post-metadata">

### Author: ![Emsy\_Chan](https://discourse.orthanc-server.org/letter_avatar_proxy/v4/letter/e/a9adbd/32.png) [@Emsy\_Chan](https://discourse.orthanc-server.org/u/Emsy_Chan)
#### Post date: [July 23, 2015, 8:54am UTC](https://discourse.orthanc-server.org/t/lua-calling-external-application-processing-result/208/2 "2015-07-23T08:54:49Z")

</div>

Hi,

I’ve used a LUA to call a PHP script everytime Orthanc stores an instance, but haven’t used it as part of a IF in LUA yet.

I think you can call a PHP script to get Orthanc to query the PACS to check whether the accessionnumber exists and return the result, but I’ve never tried something like that (I know that LUA can read the PHP response, but not sure whether it will wait the time for PHP to perform the query).

- no experience in RIS & HL7 yet… 😛 \*

Em

---

<div class="post-metadata">

### Author: ![ozpacs](https://discourse.orthanc-server.org/letter_avatar_proxy/v4/letter/o/6bbea6/32.png) [@ozpacs](https://discourse.orthanc-server.org/u/ozpacs)
#### Post date: [July 24, 2015, 2:56am UTC](https://discourse.orthanc-server.org/t/lua-calling-external-application-processing-result/208/3 "2015-07-24T02:56:12Z")

</div>

I think i’ve answered my own question here…

Here is an LUA script that queries a RIS to see if an accessionnumber exsits before passing the images on.

> - Obviously, the query function and query itself would need to be adjusted for each RIS.

> -It creates a temporary cache (with timeout) of prior queries to prevent multiple RIS queries in the event of CT’s etc

> -Any images NOT passed on are held and can be viewed/resent in Orthanc, but are deleted if RIS is sorted out and images re-sent.

> - i’ve left a lot of the logging in for now so that i can work out what functions are being called etc etc.

No guarantee on the quality of this code, but it works for me. Hope this helps someone.

`

—Set location of Cache text file to hold RIS query results  
cachefile=“c:/Orthanc/Plug/CheckRIS/CheckRIS\_CacheFile.txt”  
–Set a timeout for subsequent image send events (prevents multiple RIS queries in the event of things like CT slices etc)  
querytimeout=60

function OnStoredInstance(instanceId, tags, metadata, remoteAet, calledAet)

function file\_check(file\_name)  
local file\_found=io.open(file\_name, “r”)

if file\_found==nil then  
io.open(cachefile,“w”)  
io.close()  
else  
end  
end

function sleep(sec)  
local ntime = os.time() + sec  
repeat until os.time() \> ntime  
end

function writetocache(accn,status)  
ts = os.date(‘%Y%m%d %H%M%S’, os.time())  
fh,err = io.open(cachefile,“a”)  
fh:write(“\n”)  
fh:write(accn …" " … status … " " … ts)  
end

function updatecache(accn,status)  
s=‘’  
newfile=‘’  
newline=‘’  
tm = os.date(‘%Y%m%d %H%M%S’, os.time())  
f = io.open (cachefile,“r”)  
repeat  
s = f:read (“\*l”) – read one line  
if s then – if not end of file (EOF)  
if string.find(s,accn…" “) then  
newline = string.gsub(s, s, accn…” “…status…” “…tm)  
else  
newline = s  
end  
newfile = newfile…newline…”\n"  
end  
until not s  
f:close ()  
f = io.open (cachefile,“w+”)  
f:write(newfile:sub(1,#newfile-1))  
sleep(2)  
io.close(f)  
end

function queryRIS(accn)  
–Create and execute an SQL query on RIS to check if placeholder exists down stream. SQL query should return Passthrough1 if yes, Passthrough0 if no.  
qry,err = io.open(“c:/orthanc/plug/CheckRIS/CheckRIS\_Query.sql”,“w “)  
qry:write(“SET HEADING OFF \nSET TRIMOUT ON \nSET HEADING OFF \n SET PAGESIZE 0 \nSET TRIMSPOOL ON \nSET NEWPAGE NONE \nSELECT ‘Passthrough’ || TRIM(COUNT(ACCESSIONNUMBER)) AS T FROM USER.EXAMRECORD WHERE ACCESSIONNUMBER LIKE '”…accn…”';”)  
qry:close()  
n = os.tmpname ()  
os.execute (“echo EXIT | C:\oracleinstantclient\sqlplus -s USERNAME/PASSWORD@DATASOURCE @c:/orthanc/plug/CheckRIS/CheckRIS\_Query.sql \>” … n)  
status=‘’  
–Check SQL query result  
for sqlline in io.lines(n) do  
if string.find(sqlline,‘Passthrough1’) then  
status=‘allowed’  
print(“queryRIS says SEND SOMEIMAGES”)  
return(status)  
elseif string.find(sqlline,‘Passthrough0’) then  
status=‘deny’  
print(“queryRIS says DONT SEND SOMEIMAGES”)  
return(status)  
else  
status=‘deny’  
print(“SQLPLUS Query is not happening”)  
return(status)  
end  
end  
os.remove (n)  
end

function sendimages(accn)  
print("sendimages says SEND THIS IMAGE - "…instanceId)  
Delete(SendToModality(instanceId, ‘TestDestination’, remoteAet))  
end

function deleteimages(accn)  
print(“Holding Images - goto WebViewer to view - [http://orthancserver:8042](http://orthancserver:8042)”)  
end

function checkRIS(accn)  
if queryRIS(accn) == ‘allowed’ then  
print(‘checkRIS found something - SEND SOME IMAGES’)  
writetocache(accn,‘allowed’)  
sendimages(accn)  
else  
print(‘checkRIS didnt find anything - DONT SEND SOME IMAGES’)  
writetocache(accn,‘deny’)  
sleep(3)  
deleteimages(accn)  
end  
end

function recheckRIS(accn)  
if queryRIS(accn) ==‘allowed’ then  
print(‘reckeckRIS found something - SEND SOME IMAGES’)  
updatecache(accn,‘allowed’)  
sendimages(accn)  
else  
print(‘recheckRIS didnt find anything - DONT SEND SOME IMAGES’)  
updatecache(accn,‘deny’)  
deleteimages(accn)  
end  
end

function foundallowed(accn)  
print(“found in cache and allowed - send some images (foundandallowed)”)  
sendimages(accn)  
end

function foundnotallowed(accn)  
print(“found and denied - dont send images (foundandnotallowed)”)  
deleteimages(accn)  
end

function secdiff(line)  
local lineyr=string.sub(line,-15,-12)  
local linemt=string.sub(line,-11,-10)  
local linedy=string.sub(line,-9,-7)  
local linehh=string.sub(line,-6,-5)  
local linemm=string.sub(line,-4,-3)  
local liness=string.sub(line,-2)  
local convertedTimestamp = os.time({year = lineyr, month = linemt, day = linedy, hour = linehh, min = linemm, sec = liness})  
now = os.time()  
timeDifference = now - convertedTimestamp  
return (timeDifference)  
end

function search(accn)

file\_check(cachefile)  
status = ‘’  
fh,err = io.open(cachefile)  
if err then print(“Cant open cache file”); return; end  
while true do  
line = fh:read()  
if line == nil then  
print(“Not found in cached log - goto checkRIS”)  
checkRIS(accn)  
break end  
if string.find(line,accn…" “) and string.find(line,“allowed”) then  
print(“Found in cached log and allowed - goto foundallowed”)  
foundallowed(accn)  
break  
elseif string.find(line,accn…” “) and string.find(line,“deny”) and secdiff(line) \> querytimeout then  
print(“Denied in cache log, but old, re-check - goto recheckRIS”)  
recheckRIS(accn)  
break  
elseif string.find(line,accn…” “) and string.find(line,“deny”) and secdiff(line) \< querytimeout then  
print(“Denied in cache log not long ago - goto foundnotallowed”)  
foundnotallowed(accn)  
break  
elseif string.find(line,accn…” ") and not (string.find(line,“deny”) or string.find(line,“allowed”)) then  
print(“Partially found in cache log, re-check - goto recheckRIS”)  
recheckRIS(accn)  
break  
end  
end  
fh:close()  
end

if tags[‘AccessionNumber’] == ‘’ or tags[‘AccessionNumber’] == nil then  
accn = ‘empty’ else  
accn = tags[‘AccessionNumber’]  
end  
print(“\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_START INSTANCE “…accn…”\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_”)  
search(accn)  
end

`

Ultimately i’d like to do something similar to prevent Orthanc accepting the images in the first place (so the user knows they’ve been rejected), but haven’t worked that bit out yet.
