Skip to content

Lua API Reference

All globals available to Lua scripts, organized by object. For context and usage, see Lua Filter.

Availability

GlobalStorageQuery requestQuery result
dataset
route
file
study
series
query
session
request
response
queue
node
log
print
uid
include

dataset

The mutable dataset for the current image, request, or result row. Every mutating call is audit-logged.

MethodReturnsNotes
dataset:Get(path)string or nilReturns the tag value, or nil if absent
dataset:Exists(path)booleanReturns true if a tag, sequence item, or nested path exists
dataset:ToTable() / dataset:ToTable(path)table or scalarSerializes the whole dataset or a subtree into the same shape accepted by Populate() / Append()
dataset:Select(path)DatasetItem or nilSelects one sequence item
dataset:Items(path)DatasetItemListReturns zero or more sequence items
dataset:Set(path, value)Creates the tag (and any missing sequence items) if absent
dataset:Remove(path)Removes a tag, a sequence item, or a whole sequence. Silent no-op if absent.
dataset:Count(path)numberNumber of items in a sequence, or 0
dataset:Populate(table)Bulk-write from a Lua table. See Path syntax.
dataset:PopulateAt(path, table)Bulk-write into a specific path or selected sequence item
dataset:Append(sequencePath) / dataset:Append(sequencePath, table)DatasetItemAppends one new sequence item and optionally populates it

Path syntax

All path arguments follow the same syntax:

  • Plain keyword or hex: PatientName, 0010,0010, 00100010
  • Sequence index (1-based): ScheduledProcedureStepSequence[1].Modality
  • Selector: RequestAttributesSequence[ScheduledProcedureStepID='STEP1'].CodeValue — matches the item where the tag equals the value
  • Set() and Populate() auto-create missing sequences and items
  • A selector on a Set() or PopulateAt() creates the item if none matches and seeds the selector tag
  • Remove('Sequence[n]') removes the item; Remove('Sequence[n].Tag') removes only the child tag
  • Singular methods (Get, Set, Remove, PopulateAt, Exists, ToTable, Select) require selector uniqueness. If more than one item matches, Lua throws an explicit ambiguous-selector error.
  • Use Items() when you want zero or more matches, including duplicate selector values.

The same path syntax applies to request:Get(), request:Exists(), request:ToTable(), request:Select(), request:Items(), and request:Count().


request

Read-only view of the effective request dataset. Available in result hooks only.

MethodReturnsNotes
request:Get(path)string or nil
request:Exists(path)boolean
request:ToTable() / request:ToTable(path)table or scalar
request:Select(path)ReadonlyDatasetItem or nil
request:Items(path)DatasetItemList
request:Count(path)number

No mutating methods — Set, Remove, Populate, PopulateAt, Append, and Delete() are not available.


route

Controls where images are sent. Storage context only. Destinations must be defined in nodes.yml with NodeRole: Storage.

MethodNotes
route:Add(destination)Queue a copy to destination
route:Add(destination, function(ds) ... end)Queue a copy with per-destination mutations. ds is an AuditedDatasetProxy for the clone.
route:Drop()Mark the original for deletion after all entries complete

Calling route:Add() twice with the same destination replaces the previous lambda. Lambdas run after all lua.yml entries have completed, against a clone of the final dataset. If any lambda throws, no output files are written.


file

Read-only metadata about the current image. Storage context only.

PropertyTypeNotes
file.sourceAeTitlestringAE title of the system that sent this image
file.destinationAeTitlestringAE title of the destination being prepared

query

Read-only metadata about the proxied C-FIND session. Query hooks only.

PropertyTypeNotes
query.kindstring"worklist" or "qr"
query.phasestring"request" or "result"
query.callingAeTitlestringAE title of the calling SCU
query.calledAeTitlestringRaw called AE title from the association
query.nodeAeTitlestringResolved Capacitor node AE title. Used for AeTitles matching.
query.levelstringQuery level ("STUDY", "PATIENT", etc.) or "" for worklist

response

Result row control. Result hooks only.

MethodNotes
response:drop()Suppress this result row. Only an explicit drop() removes a row — script errors do not.
response.index1-based index of the current proxied result row.

session

Key-value state shared across the entire proxied query (request phase and all result rows). Query hooks only. Not persisted to disk.

lua
session.key = value   -- store
local v = session.key -- read
session.key = nil     -- delete

Values are coerced to .NET-native types on storage. Storing a Lua function throws an error.


study

Key-value state scoped to the current image's StudyInstanceUID. Storage context only. Evicted after 24 hours of inactivity. Lost on service restart.

lua
study.key = value
local v = study.key

study.queue is a StudyQueueApi instance pre-bound to the current StudyInstanceUID.


series

Key-value state scoped to the current image's SeriesInstanceUID. Storage context only. Same TTL and persistence rules as study.

lua
series.key = value
local v = series.key

queue

Read-only access to the in-memory processing queue. Available in all contexts.

Count methods

MethodReturnsNotes
queue:total()numberTotal items in the queue
queue:count(state)numberItems in a given state
queue:countByStudy(studyUID)numberItems belonging to a study
queue:countByStudy(studyUID, state)numberItems in a study with a given state
queue:countByDestination(aeTitle)numberItems destined for an AE title
queue:countByDestination(aeTitle, state)numberItems destined for an AE title in a given state

Valid state strings: "New", "Prepared", "Failed", "Rejected", "Expired".

Find methods

MethodReturns
queue:findByStudy(studyUID)QueueItemList
queue:findByState(state)QueueItemList
queue:findByDestination(aeTitle)QueueItemList
queue:findByDestination(aeTitle, state)QueueItemList

study.queue

Same query methods as queue, automatically scoped to the current image's StudyInstanceUID. Storage context only. nil if the image has no StudyInstanceUID.

MethodReturns
study.queue:totalCount()number
study.queue:countByState(state)number
study.queue:items()QueueItemList
study.queue:itemsByState(state)QueueItemList
study.queue:destinations()string[] — distinct destination AE titles
study.queue:modalities()string[] — distinct modalities

destinations() and modalities() return .NET string arrays. Iterate with a numeric for loop using .Length (0-based) or treat as a Lua table with integer keys starting at 1 depending on how NLua exposes them — prefer items() and reading .destinationAeTitle / .modality from each item for portability.


QueueItemList

Returned by queue:find*() and study.queue:items*() methods.

MethodReturnsNotes
list:count()numberTotal items
list:get(i)QueueItemResult or nil1-based index
lua
local items = queue:findByState('Failed')
for i = 1, items:count() do
    local item = items:get(i)
    print(item.destinationAeTitle, item.lastError)
end

DatasetItemList

Returned by dataset:Items(...) and request:Items(...).

MethodReturnsNotes
list:count()numberTotal selected items
list:get(i)DatasetItem, ReadonlyDatasetItem, or nil1-based index

DatasetItem

Mutable sequence item proxy returned by dataset:Select(...), dataset:Append(...), and dataset:Items(...):get(i).

MethodReturnsNotes
item:Get(path)string or nil
item:Exists(path)boolean
item:ToTable() / item:ToTable(path)table or scalar
item:Select(path)DatasetItem or nil
item:Items(path)DatasetItemList
item:Count(path)number
item:Set(path, value)
item:Remove(path)
item:Populate(table)
item:PopulateAt(path, table)
item:Append(sequencePath) / item:Append(sequencePath, table)DatasetItem
item:Delete()Removes the current sequence item from its parent sequence

ReadonlyDatasetItem

Read-only sequence item proxy returned by request:Select(...) and request:Items(...):get(i).

MethodReturnsNotes
item:Get(path)string or nil
item:Exists(path)boolean
item:ToTable() / item:ToTable(path)table or scalar
item:Select(path)ReadonlyDatasetItem or nil
item:Items(path)DatasetItemList
item:Count(path)number

QueueItemResult

Returned by QueueItemList:get(i). All fields are read-only strings or numbers.

FieldTypeNotes
idnumberInternal record ID
statestring"New", "Prepared", "Failed", "Rejected", or "Expired"
sourceAeTitlestring
destinationAeTitlestring
studyInstanceUIDstring
seriesInstanceUIDstring
sopInstanceUIDstring
sopClassUIDstring
modalitystring
patientIDstring
patientNamestring
accessionNumberstring
attemptCountnumber
lastErrorstringLast error message, or nil
formatstring"dcm", "json", or "yml"
pendingStatestringDeferred state change, or nil
createdAtstringISO 8601
updatedAtstringISO 8601

node

Node health and delivery statistics. Available in all contexts.

node:stats(aeTitle)

Returns a delivery statistics snapshot for the named node as a Lua table.

FieldTypeNotes
successnumberTotal successful deliveries
failednumberTotal failures
timedOutnumberTotal timeouts
recentSuccessnumberSuccesses in the recent window
recentFailednumberFailures in the recent window
recentTimedOutnumberTimeouts in the recent window
recentWindowMinutesnumberSize of the recent window in minutes
avgTransferMsnumberAverage transfer time in milliseconds
lastSuccessAtstringISO 8601, present only if a success has been recorded
lastFailuretablePresent only if a failure has been recorded. Fields: at (ISO 8601), error (string)
lastEchotablePresent only if an echo has been performed. Fields: success (bool), latencyMs (number), at (ISO 8601)

node:echo(aeTitle)

Sends a C-ECHO to the named node and returns the result. Results are cached for 60 seconds. Blocks the Lua script while the echo is in flight.

FieldTypeNotes
successbooleanWhether the echo succeeded
latencyMsnumberRound-trip time in milliseconds
messagestring"cached" for a cached result, or an error message on failure
lua
local result = node:echo('ARCHIVE')
if not result.success then
    log:warn('ARCHIVE unreachable:', result.message)
    error('fail: destination unreachable')
end

log

Writes to the common application log (visible on the Logs page). All contexts.

MethodNotes
log:info(...)Informational
log:warn(...)Warning
log:error(...)Error
log:debug(...)Debug — only visible at debug log level

Arguments are coerced to strings and joined with tabs. All messages are prefixed with [lua].


print

Global function. Writes to the per-item or per-query-session log only — not the common application log. Arguments are coerced to strings and joined with tabs.

lua
print('value:', dataset:Get('PatientName'))

uid

Global function. Generates a new globally unique DICOM UID.

lua
local newUID = uid()  -- e.g. "2.25.123456789..."

include

Global function. Loads and executes a .lua file from the config directory. Each file is loaded at most once per image or query session (deduplicated by canonical path).

lua
include('libs/phi.lua')   -- loads config-dir/libs/phi.lua

Constraints: path must be relative, must end in .lua, must not contain .., and must not escape the config directory.