Skip to main content
Skip table of contents

Using Data Filters on Event Subscriptions

When creating Event Subscriptions for a production environment, consider setting restrictive filter constraints in order to guard against unintended Action execution. The Event Subscription creation dialog includes a field called "Event Payload Filter" that allows you to define which specific data attributes to look for before triggering an action. This Event Payload is written in JSONPath notation, using the attributes of each class of event trigger.

Filtered vs Unfiltered Subscriptions

Unfiltered Subscription

The following subscription (created by a site admin) will be triggered on any type of scan creation across all projects on a site. Note the lack of content in the Event Payload Filter field, and the "Apply to All Projects" selector.

Filtered Subscription

Restricting subscriptions to individual projects is as simple as selecting projects in the multi-select menu. But an additional step of including a payload filter will restrict this subscription behavior even further.

The full JSONPath payload filter in this subscription is

CODE
(@.xsiType == "xnat:mrScanData" && @.resources.length() > 0 && "DICOM" in @.resources[*].label)

This means that this event subscription will only apply to newly created scans if all of the following conditions are true: 

  • the scan is of the xnat:mrScanData datatype
  • the scan contains resource files
  • at least one of those resources is labeled DICOM.

Not only does this more restrictive subscription ensure the selected Action will have the resources it needs, it reduces undesirable Event Service and Container Service processing.

How JSONPath Filters Work

Payload Capture

The "payload" of the event refers to the XNAT data object that triggered the subscription evaluation process. Payload filtering works by applying a JSONPath filter to the serialized payload object associated with this event. There are several examples of payloads provided in the Event Trigger documentation, but the serialized version of a particular payload can be found by following the Default Logging Action example, adjusting for the event of interest.

For example, to build a filter for a particular type of scan: create a subscription for Scan Created events, with the Logging Action selected:

Then, trigger this event by uploading or creating a scan on the selected project.

After scan creation is complete, browse to the Event Service History page.

Select the appropriate history item to view details.

Note the serialized Scan object, represented in JSON format, listed below "status-message". Here is an abridged and cleaned view of that serialized object:

Serialized Scan Payload (abridged)

CODE
{
    "id": "4",
    "label": "4 - t1_mpr_1mm_p2_pos50",
    "xsiType": "xnat:mrScanData",
    "uri": "/archive/experiments/XNAT6_E00030/scans/4",
    "resources": [
        {
            "type": "Resource",
            "id": "DICOM",
            "label": "DICOM",
            "xsiType": "xnat:resourceCatalog",
            "uri": "/archive/experiments/XNAT6_E00030/scans/4/resources/DICOM",
            "directory": "/data/xnat/archive/Fruit_Struct/arc001/Grape_MR1/SCANS/4/DICOM",
            "integer-id": 90
        }
    ],
    "directory": "/data/xnat/archive/Fruit_Struct/arc001/Grape_MR1/SCANS/4",
    "frames": 176,
    "modality": "MR",
    "quality": "usable",
    "scanner": "MEDPC",
    "uid": "1.3.12.2.1107.5.2.32.35177.3.2006121409284535196417894.0.0.0",
    "integer-id": 75,
    "scan-type": "t1_mpr_1mm_p2_pos50",
    "project-id": "Fruit_Struct",
    "session-id": "XNAT6_E00030",
    "scanner-manufacturer": "SIEMENS",
    "scanner-model": "TrioTim",
    "series-description": "t1_mpr_1mm_p2_pos50",
    "start-time": "09:37:11"
}

Link to full sample here.

JSONPath Filter Testing

XNAT Event Service filters use the Java-based Jayway JSONPath library to filter serialized payload objects. Online JsonPath evaluators, such as this one, allow for interactive JSONPath filter development. Using the full or abridged Scan payload JSON above, experiment with JSONPath filter strings. Filters that return any non-empty result will indicate a Subscription 'match'.

NOTE: Be aware that serialized payload objects are likely to include PHI for data that has not been properly anonymized. This data should not be submitted to an online evaluator. Use only properly de-identified data for this step of filter development.

When evaluating the above payload, consider the behavior of the following filter strings: 

Positive Match: scan is of type "xnat:mrScanData"

CODE
$[?(@.xsiType == "xnat:mrScanData")]



Positive Match: scan is of "MR" modality and has a "usable" quality setting

CODE
$[?(@.modality == "MR" && @.quality == "usable")]


No Match. Scan is not of "CT" modality

CODE
$[?(@.modality == "CT")]

When an empty result is returned, this indicates a Subscription 'mismatch'. Only Subscriptions with filters that 'match' an Event payload will result in an Action.


Writing a Subscription Filter Definition

Event Service filters should be entered into the XNAT Event Subscription dialog without the $[? ... ] bracketing. The $[? notation indicates a JSONPath filter string, which is the default and only mode of JSONPath parsing for this parameter.

Raw JsonPath FilterEvent Payload Filter
$[?(@.xsiType == "xnat:mrScanData")](@.xsiType == "xnat:mrScanData")
$[?(@.modality == "MR" && @.quality == "usable")](@.modality == "MR" && @.quality == "usable")

After validating your JSONPath filter using an online tool, edit your subscription to include the adjusted Event Payload Filter. 

Example JSONPath Filters

Event PayloadFilter DescriptionXNAT JSONPath Filter
Scan

Scan xsiType is xnat:mrScanData

(@.xsiType == "xnat:mrScanData")


Scan modality is MR and quality is usable

(@.modality == "MR" && @.quality == "usable")


Scan xsiType is xnat:mrScanData and

greater than zero resources and

at least one of those resources is labeled DICOM

(@.xsiType == "xnat:mrScanData" && @.resources.length() > 0 && "DICOM" in @.resources[*].label)


Scan with "modality==RTSTRUCT"

(@.modality == "RTSTRUCT")


Scan with

  • regular expression "modality == .*MRScanData" ignoring case,

  • having greater then 100 frames,

  • regular expression "scanner-manufacturer == siemens" ignoring case,

  • and regular expression "scanner-model == TRIOTIM" ignoring case.

(@.xsiType =~ /.*MRScanData/i && @.frames  > 100 && @.scanner-manufacturer =~ /siemens/i && @.scanner-model =~ /TRIOTIM/i)




SessionSession with and at least one scan(@.scans.length() > 0)

Session with "subject-id == XNAT_S00001" and "modality == MR" for at least one of the contained scans(@.subject-id == "XNAT_S00001" && "MR" in @.modalities-in-study)

Session with at least one scan element with "modality == RTSTRUCT"
   

or the equivalent

("RTSTRUCT" in @.scans[*].modality)


("RTSTRUCT" in @.modalities-in-study)




SubjectSubject with Project ID matched by a regular expression.(@.project-id =~ /[optionalString]?.*theproject.*[anotherOptionalString]?/i)



Project

Projects titled with: "TheProjectTitle"

(@.label == "TheProjectTitle")


Projects with a title that matches a regular expression
"the.*[title]+[optional]?", ignoring case

(@.label =~ /the.*[title]+[optional]?/i)




JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.