OHDSI tool execution for OMOP CDM data on BigQuery. Deployed as Cloud Run service + jobs.
Executes OHDSI data quality and characterization tools on BigQuery OMOP datasets:
- DQD (DataQualityDashboard) - Data quality validation with 4,000+ checks
- Achilles - Database characterization and descriptive statistics for ATLAS.
- PASS (Profile of Analytic Suitability Score) - Evaluates data fitness-for-purpose across six dimensions (accessibility, provenance, standards, concept diversity, source diversity, temporal)
- Cloud Run Service - REST API for health checks, Atlas table creation, and report generation
- Cloud Run Jobs - Long-running tool executions (up to 24h):
ccc-omop-analyzer-dqd-jobccc-omop-analyzer-achilles-jobccc-omop-analyzer-pass-job
- Airflow Integration - Jobs triggered via
CloudRunExecuteJobOperator
Project IDs with hyphens require special handling:
- Achilles: Pass dataset name only (e.g.,
"ehr_synthea"). JDBC connection'sDefaultDatasetparameter handles qualification. - DQD: Use double-quoted fully qualified names (e.g.,
'"project-id".dataset'). SqlRender translates to backticks. - PASS: Uses
project.datasetformat directly (e.g.,"project-id.ehr_synthea").
The PASS job evaluates data quality across six evidence-based dimensions:
- Accessibility - Whether clinical data is present and accessible for analysis
- Provenance - Information preservation and traceability through mapping
- Standards - Use of standardized vocabularies for interoperable research
- Concept Diversity - Variety of distinct clinical concepts in the data
- Source Diversity - Variety of data source types (EHR, claims, registries)
- Temporal - Data distribution over time (span, density, consistency)
Default Settings (configured in constants.R):
METRICS = "all"- All six metrics are calculatedCALCULATE_COMPOSITE = TRUE- Weighted composite score is generatedVERBOSE_MODE = TRUE- Detailed logging enabled
Outputs: Five CSV files uploaded to GCS containing field-level, table-level, and overall scores with 95% confidence intervals.
| File | Purpose |
|---|---|
Dockerfile |
Container image with R, DQD, Achilles, PASS, and dependencies |
cloudbuild.yaml |
Cloud Build config for service + jobs (DQD, Achilles, PASS) |
plumber_api.R |
REST API with health check, Atlas table creation, and report generation |
entrypoint.sh |
Container entrypoint; execs the CMD (auth is via the attached runtime service account, no key file) |
| Path | Purpose |
|---|---|
ref/atlas_results_tables.sql |
DDL for Atlas results tables (executed by /create_atlas_results_tables) |
ref/achilles_concept_counts.sql |
Post-Achilles SQL that produces the *_concept_counts BigQuery tables |
bq_drivers/ |
Simba BigQuery JDBC driver + transitive JARs; required by DQD and Achilles via DATABASECONNECTOR_JAR_FOLDER=/app/bq_drivers |
| File | Purpose |
|---|---|
constants.R |
Configuration constants (DQD, Achilles, PASS) |
utils.R |
Helper functions (GCS, JDBC, authentication, SQL) |
run_dqd.R |
DQD execution logic |
run_dqd_job.R |
DQD job entrypoint |
run_achilles.R |
Achilles execution logic |
run_achilles_job.R |
Achilles job entrypoint |
run_pass.R |
PASS execution logic |
run_pass_job.R |
PASS job entrypoint |
run_create_atlas_results_tables.R |
Atlas results table creation |
run_generate_delivery_report.R |
OMOP delivery report generation |
gcloud builds submit --config cloudbuild.yamlRegion is hardcoded to us-central1. The build requires the following substitutions to be provided (via --substitutions or trigger config): _IMAGE_NAME, _ARTIFACT_GCS_BUCKET, SERVICE_ACCOUNT_EMAIL.
Deploys:
- Service:
ccc-omop-analyzer(4 CPU, 8GB RAM, 1h timeout,--concurrency=1) - Jobs (all
--max-retries=0):ccc-omop-analyzer-dqd-jobandccc-omop-analyzer-achilles-job(4 CPU, 8GB RAM, 2h task timeout, configurable to 24h)ccc-omop-analyzer-pass-job(4 CPU, 16GB RAM, 2h task timeout)
All jobs require PROJECT_ID, CDM_DATASET_ID, and GCS_ARTIFACT_PATH. Additional variables per job:
DQD job (all required):
ANALYTICS_DATASET_ID- Target dataset for resultsCDM_VERSION- OMOP CDM version (e.g., "5.4")CDM_SOURCE_NAME- Source identifier
Achilles job:
ANALYTICS_DATASET_ID(required) - Target dataset for resultsCDM_VERSION(optional) - OMOP CDM version (e.g., "5.4")CDM_SOURCE_NAME(optional) - Source identifier
PASS job: No additional variables required.
SERVICE_ACCOUNT_EMAIL is set on every deployed resource by cloudbuild.yaml as the Cloud Run runtime service account (--service-account). That attached identity is what all BigQuery/GCS access runs as (see Authentication). It is still passed as an env var, but the R code no longer reads it — the BigQuery JDBC connection now uses Application Default Credentials (OAuthType=3) rather than a service-account email + key path.
Jobs are triggered from Airflow via CloudRunExecuteJobOperator. Each job:
- Authenticates with BigQuery/GCS
- Executes tool logic (
run_dqd(),run_achilles(), orrun_pass()) - Uploads results to GCS and/or BigQuery
- Exits with status code (0=success, 1=failure)
| Tool | Artifacts |
|---|---|
| DQD | GCS: dqdashboard_results.{json,csv} (plus any per-check error files under errors/) BigQuery: {analytics_dataset_id}.dqdashboard_results (written manually from the CSV by upload_dqd_results_to_bq; the DQD package's own writeToTable is disabled in constants.R due to a BigQuery write bug) |
| Achilles | GCS: achilles_results.csv, results/*.json (ARES) BigQuery: {analytics_dataset_id}.achilles_* (written by Achilles), {analytics_dataset_id}.*_concept_counts (written by ref/achilles_concept_counts.sql) |
| PASS | GCS: pass_overall.csv (scores by metric with CIs), pass_table_level.csv (scores by table), pass_field_level.csv (field-level detail), pass_composite_overall.csv (composite score), pass_composite_components.csv (metric contributions) |
| Endpoint | Method | Parameters | Purpose |
|---|---|---|---|
/heartbeat |
GET | - | Health check |
/create_atlas_results_tables |
POST | project_id, cdm_dataset_id, analytics_dataset_id |
Create Atlas results tables in BigQuery |
/generate_delivery_report |
POST | delivery_report_path, dqd_results_path, output_gcs_path, pass_results_path (optional) |
Generate HTML report from delivery metrics, DQD results, and (optionally) PASS results |
Every Cloud Run resource runs as the service account given by SERVICE_ACCOUNT_EMAIL (--service-account). All jobs (DQD, Achilles, PASS) and the service authenticate to BigQuery and GCS via Application Default Credentials — short-lived tokens fetched from the GCP metadata server for that attached identity. No exported service-account key is involved:
bigrquery/googleCloudStorageR:bq_auth/gcs_authwithgargle::credentials_gce()- BigQuery JDBC (DQD, Achilles, PASS):
OAuthType=3(ADC)
Required permissions (on the runtime service account):
- BigQuery read/write
- GCS write