From 760c2b87e5445a14847103d88703b72e509466ab Mon Sep 17 00:00:00 2001 From: Hitendrasinh Rathod Date: Fri, 26 Dec 2025 21:02:08 +0000 Subject: [PATCH] feat: Add radiology AI anomaly detection example with cleaned files --- .../fixtures/radiology_anomaly_detection.cql | 19 ++++ tests/fixtures/radiology_anomaly_test.go | 86 +++++++++++++++++++ tests/fixtures/radiology_sample_bundle.json | 33 +++++++ 3 files changed, 138 insertions(+) create mode 100644 tests/fixtures/radiology_anomaly_detection.cql create mode 100644 tests/fixtures/radiology_anomaly_test.go create mode 100644 tests/fixtures/radiology_sample_bundle.json diff --git a/tests/fixtures/radiology_anomaly_detection.cql b/tests/fixtures/radiology_anomaly_detection.cql new file mode 100644 index 0000000..dd09106 --- /dev/null +++ b/tests/fixtures/radiology_anomaly_detection.cql @@ -0,0 +1,19 @@ +library RadiologyAnomalyDetection version '1.0.0' +using FHIR version '4.0.1' +include FHIRHelpers version '4.0.1' + +context Patient + +define "RelevantRadiologyReports": + [DiagnosticReport] DR + where DR.status.value in {'final', 'amended', 'corrected'} + and exists (DR.category C where exists (C.coding Coding where Coding.code.value = 'RAD')) + +define "FlaggedAnomalies": + "RelevantRadiologyReports" DR + where exists (DR.conclusionCode.coding C + where C.system.value = 'http://snomed.info/sct' and C.code.value = '386661006') + +define "FinalDecision": + if exists("FlaggedAnomalies") then 'Prioritize for Urgent AI-Assisted Review' + else 'Standard Workflow' diff --git a/tests/fixtures/radiology_anomaly_test.go b/tests/fixtures/radiology_anomaly_test.go new file mode 100644 index 0000000..3850856 --- /dev/null +++ b/tests/fixtures/radiology_anomaly_test.go @@ -0,0 +1,86 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fixtures + +import ( + "context" + "fmt" + "os" + "time" + + log "github.com/golang/glog" + "github.com/google/cql" + "github.com/google/cql/result" + "github.com/google/cql/retriever/local" +) + +// Example_radiologyAnomalyDetection demonstrates using CQL for AI-assisted clinical decision support in radiology. +func Example_radiologyAnomalyDetection() { + // Load FHIR data model and helpers + fhirDataModel, fhirHelpers, err := cql.FHIRDataModelAndHelpersLib("4.0.1") + if err != nil { + log.Fatal(err) + } + + // Read the CQL library from file + cqlContent, err := os.ReadFile("radiology_anomaly_detection.cql") + if err != nil { + log.Fatalf("Failed to read CQL file: %v", err) + } + + // Read the FHIR bundle from file + bundleData, err := os.ReadFile("radiology_sample_bundle.json") + if err != nil { + log.Fatalf("Failed to read bundle file: %v", err) + } + + libs := []string{string(cqlContent), fhirHelpers} + + // Parse the libraries with FHIR data model + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) + defer cancel() + + elm, err := cql.Parse(ctx, libs, cql.ParseConfig{DataModels: [][]byte{fhirDataModel}}) + if err != nil { + log.Fatalf("Failed to parse radiology CQL: %v", err) + } + + // Use local retriever with the sample bundle + retriever, err := local.NewRetrieverFromR4Bundle(bundleData) + if err != nil { + log.Fatalf("Failed to build retriever: %v", err) + } + + // Evaluate the CQL + results, err := elm.Eval(ctx, retriever, cql.EvalConfig{}) + if err != nil { + log.Fatalf("Failed to evaluate: %v", err) + } + + // Print the final decision + decision := results[result.LibKey{Name: "RadiologyAnomalyDetection", Version: "1.0.0"}]["FinalDecision"] + if result.IsNull(decision) { + fmt.Println("FinalDecision: null") + } else { + str, err := result.ToString(decision) + if err != nil { + log.Fatal(err) + } + fmt.Printf("FinalDecision: %s\n", str) + } + + // Output: + // FinalDecision: Prioritize for Urgent AI-Assisted Review +} diff --git a/tests/fixtures/radiology_sample_bundle.json b/tests/fixtures/radiology_sample_bundle.json new file mode 100644 index 0000000..d581bad --- /dev/null +++ b/tests/fixtures/radiology_sample_bundle.json @@ -0,0 +1,33 @@ +{ + "resourceType": "Bundle", + "type": "transaction", + "entry": [ + { + "fullUrl": "fullUrl", + "resource": { + "resourceType": "Patient", + "id": "example-patient" + } + }, + { + "fullUrl": "fullUrl", + "resource": { + "resourceType": "DiagnosticReport", + "id": "normal-report", + "status": "final", + "category": [{"coding": [{"code": "RAD"}]}], + "conclusionCode": [{"coding": [{"system": "http://snomed.info/sct", "code": "260385009"}]}] + } + }, + { + "fullUrl": "fullUrl", + "resource": { + "resourceType": "DiagnosticReport", + "id": "anomalous-report", + "status": "final", + "category": [{"coding": [{"code": "RAD"}]}], + "conclusionCode": [{"coding": [{"system": "http://snomed.info/sct", "code": "386661006"}]}] + } + } + ] +}