cTAKES USDHUBClinician documentation
Outputs and reviewTwo routine delivery filesCell parity checked

Deliver the two CSVs; keep the audit and review artifacts local

The run has two logical CSV deliverables: the 13-column concept extract and the 16-column medication extract. Their canonical roles are concepts.csv and drugs.csv, while Check output shows the exact folder-named files to send. SQLite, receipts, logs, manifests, XMI, and browser review files stay local unless the protocol owner explicitly expands the approved handoff.

Deliverconcepts.csv

The exact 13-column concept extract selected for the study.

Deliverdrugs.csv

The exact 16-column medication and RxNorm extract selected for the study.

Keep localEverything else

SQLite, JSON receipts, logs, manifests, the named-copy receipt, optional XMI, and optional browser HTML support audit, review, and recovery. They are not part of the routine handoff.

Two routine deliverables, with local evidence behind them

The two CSVs are flat, spreadsheet-friendly projections carrying exactly the requested columns. The SQLite database is the canonical structured result, contains the full source notes, and stays local so the CSV values can be reviewed and checked. XMI is the XML serialization of the CAS, the Common Analysis Structure, cTAKES' complete in-memory analysis object; it is optional and also stays local. The built-in TUI viewer reads the checked SQLite file directly and creates no second copy. JSON receipts, logs, and manifests record what was checked and which bytes ran. These supporting artifacts matter for audit and recovery, but they are not routine delivery files.

Canonical SQLite feeds the exact concept and drug CSV exports and can feed an optional offline browser export, while native XMI is registered through its own provenance receipt.
Figure 1. SQLite is the canonical structured result. XMI retains native CAS detail that the workbook CSVs do not attempt to flatten.
ArtifactRoutine handoffJobContains note-derived data
concepts.csvDeliverThe exact 13-column workbook-selected concept delivery.Identifiers and selected coded/categorical values; no free-text excerpt columns
drugs.csvDeliverThe exact 16-column workbook-selected medication/RxNorm delivery.Identifiers and selected clinical values, which can include dates; no companion text columns
annotations.sqliteKeep localCanonical source text, concepts, medications, counts, identities, and run metadata for review and audit.Full notes
xmi/Keep localThe optional native cTAKES CAS when standard mode is selected.Full notes and complete native annotations
Built-in TUI viewerLocal reviewRead-only review of the checked SQLite run; no new output file.Displays full notes from SQLite
clinician_viewer.html (optional)Keep localPortable offline browser export built from the checked SQLite run.Embeds full notes
JSON/piper/XML receipts, logs, and manifestsKeep localVersions, hashes, paths, counts, phase status, validation results, and recovery evidence.Operational identifiers and paths; some filenames contain HubID/NoteID

Every term below also gets a short gloss at its first use; the clinical glossary collects them all in one lookup table.

SQLite commits one note and its rows as one transaction

The Java writer prepares its statements once, begins one transaction per note, writes the document record, every concept row, every medication row, and the concept counts, then commits. A transaction either commits completely or rolls back completely, so an exception rolls that note back and the database never keeps a partially written document.

On a fresh run, those transactions use insert-only writes and the ten secondary indexes are deferred until ingestion finishes. After Java closes the database, the wrapper verifies the exact run identity and row scope, builds and validates the canonical ten-index set in one transaction, and runs SQLite quick_check before CSV export and final status. Append mode keeps replacement writes and live indexes because it may intentionally update an existing run database.

SQLite objectWhat it holds
run_metadataRelease, analysis, run, wrapper, cTAKES, UMLS (the Unified Medical Language System, the integrated terminology source), dictionary, pipeline, writer, WSD (word-sense disambiguation, the same-span meaning scorer), and receipt identity.
documentsDocument ID, the HubID and NoteID parsed from the strict filename, the exact source text, its SHA-256 (a fingerprint of the exact bytes), its UTF-16 length (the character-offset convention Java uses), run identity, and sequence.
conceptsSource span, CUI (the UMLS Concept Unique Identifier) and RxCUI (the RxNorm identifier for a normalized drug concept), terminology labels and semantic types, assertions, part-of-speech tags, relations, WSD fields, and version.
rxnormAtomic medication span/CUI/RxCUI rows plus canonical dose/route/frequency/form/duration/status/date values and literal text evidence.
cui_countsRun-scoped concept counts used for compact analysis.
Export viewsExact column order and value logic used by concepts.csv and drugs.csv.

PRAGMA user_version=8 identifies the schema, the eighth revision of the table layout, recorded inside the database itself. The sanity checker reads the database in run scope, so append mode cannot mix earlier rows into a new delivery view.

Read the transaction and schema: tools/reporting/uima/AnnotationSqliteWriter.java.

The workbook field decisions are visible in the two CSV headers

Column B in the study workbook, the field-selection spreadsheet agreed for delivery, is the outbound selection. A value of 1 includes the field, a blank excludes it, and column C value 0 excludes the legacy Medication* field even when column B contains 1. Applying those decisions leaves 13 concept fields and 16 medication fields. Contract ctakes-fields-v02-selected-r2 also uses CUI/RxCUI consistently and replaces the remaining concept-name colons with underscores so database columns do not need special quoting.

Concepts CSV header, 13 columns
core_Document,HubID,NoteID,CUI,RxCUI,assertion_Polarity,assertion_Uncertainty,assertion_Conditional,assertion_Generic,assertion_Subject,wsd_Disambiguated,wsd_Score,cTAKES_version
Drugs CSV header, 16 columns
Document,HubID,NoteID,CUI,RxCUI,Dose,TotalDose,DosageCount,Route,Frequency,Form,Duration,StatusChange,StartDate,EndDate,cTAKES_version

The standard folder-named handoff is automatic

During the passing sanity check, the controller compares both CSV streams with the accepted SQLite views and records each CSV hash. It then creates one owner-only folder-named copy for each logical CSV and hashes the copy while writing it. Nothing is uploaded or sent.

Check output rowMeaningOperator action
concepts.csv (canonical) → batch…--concepts.csv (file to send)The left name is the fixed internal role used by validation and recovery. The right name is the verified handoff file.Send the name on the right.
drugs.csv (canonical) → batch…--drugs.csv (file to send)The two names describe one logical medication result and its handoff copy.Send the name on the right.

Check output is the single place that records both mappings. Technical files keeps the fixed run artifacts available for local review and reports AUTOMATIC CSV COPIES READY without repeating the folder-named files. It shows Retry automatic CSV copies only when the deterministic copy needs attention, or Prepare automatic CSV copies for a verified older run without that record. An exceptional extra labeled copy is CLI-only: ./ctakes handoff <job-id> --name <safe-label>. Never put PHI in the label.

The TUI walkthrough shows this step in the complete run sequence.

Blank values still carry meaning

Blank fieldInterpretation
Blank polaritycTAKES left it unassigned. It is not serialized as positive.
Blank subjectThe model did not supply a subject. The wrapper does not force patient.
Blank WSD fieldsThe mention was a singleton, WSD was explicitly disabled, or the model abstained.
Blank medication valueStock Drug NER (the medication named-entity recognizer) did not attach that selected value.

For a blank WSD pair, read run_metadata.wsd_enabled first. A value of 0 means the run used the explicit WSD-off comparison. A value of 1 means WSD ran; a same-span group with more than one distinct CUI and blank WSD cells is an abstention, while a singleton, a span with only one candidate meaning, had nothing to disambiguate. The run metadata prevents those three cases from being collapsed into one undocumented blank.

Read the exact export views and cell comparison: scripts/export_results.py and scripts/check_run.py.

XMI is the native cTAKES analysis, not another CSV representation

XMI is written only when the run is started with --writers standard; the full command sits on the run step of Getting started. Each XMI file serializes the full UIMA CAS (UIMA is the Apache framework cTAKES runs on), including source text, tokens, syntax, concepts, assertions, relations, medication features, and native metadata. It can contain features that the agreed workbook does not request.

xmi_provenance.json records one expected XMI per document, parse success, bytes, SHA-256, release/analysis/run identity, dictionary hashes, pipeline hash, and WSD provenance. The wrapper does not claim that every native XMI feature has a one-to-one CSV field.

Read the XMI register: scripts/write_xmi_provenance.py.

Three identities keep human versioning separate from exact reproducibility

The completed run records three identifiers with different jobs, and each answers a different review question: which software-and-terminology version ran, which exact extraction definition ran, and which single execution produced these files.

IdentityCurrent shapeChanges when
release_id2.1.19_2026AA.r1_6.0.0Wrapper version, UMLS release, dictionary revision, or cTAKES version changes.
analysis_idanalysis-<24 hex>Exact wrapper source, normalized effective recipe (the ordered engine list the run actually used), dictionary DB, SQLite schema, or WSD model/profile changes.
run_idctakes-<UTC time>-<nonce>Every execution, even when release and analysis are identical.

UMLS 2026AA is recorded separately in the manifest, the strict inventory naming the expected hashes, and in SQLite. It is also bound to the dictionary through the strict manifest and database hash. Runtime path, thread count, heap, and elapsed time do not change the semantic analysis ID.

The batch reaches complete only after its outputs are read back

Eight receipts cover the batch from the filename gate to the final storage measurement, so a completed run can be audited without rerunning it.

ReceiptProducerAccepted state
filename_validation.jsonPre-Java filename gateStrict policy, zero errors, expected document count
run_dictionary.manifest.jsonCopied strict dictionary manifestRelease/UMLS/descriptor/database hashes match runtime
wsd_validation.jsonPre-Java WSD validatorModel/receipt/dictionary binding and SQLite checks pass
run_manifest.jsonRunner lifecyclestatus=complete
sanity_report.jsonAutomatic post-run checkerstatus=pass
xmi_provenance.jsonStandard-mode XMI registerAll expected files parse and hashes match
storage_report.jsonStorage analyzerObserved categories and ratios recorded
timing_report.jsonMonotonic event analyzerStartup/note/drain/final timings internally consistent

The sanity pass checks the document set, source hashes/UTF-16 spans, nonblank concept and atomic medication identities, literal medication evidence, duplicate rows, exact CSV headers/cells, WSD invariants, XMI receipts, and version agreement.

The handoff condition is literal: manifest status=complete and sanity status=pass. The two read-back commands that check it sit on the acceptance step of Getting started.

Review the SQLite result inside the TUI

From Runs & cTAKES logs, select a completed run and choose Open built-in viewer. It verifies the accepted run receipts before reading annotations.sqlite, then pages through documents, concepts, and medications. Extracted annotations stay underlined in the full note, and selecting a row gives its exact source phrase the stronger focus. Technical files gives each fixed artifact a short plain-language purpose, colors JSON keys and values by type, and opens the fixed CSV and safe SQLite views without an arbitrary SQL prompt.

Optional browser export

python3 viewer/build_viewer.py \
  --sqlite /approved/usdhub/results/annotations.sqlite \
  --output /approved/usdhub/results/clinician_viewer.html

Use this only when a self-contained browser handoff is useful. The builder requires schema 8, manifest complete, sanity pass, matching release/analysis/run IDs, and valid source hashes and spans. It compresses the completed payload, embeds it in one HTML file, and records an integrity hash so changed payload bytes can be detected when the export opens. The file works without a server or network connection.

Synthetic browser export
One hand-authored note, four concept rows, one medication row, and fake codes.

Open in its own tab

The embedded example demonstrates the same evidence-review pattern with fictional data. A clinical HTML export contains full source notes and remains under the same controls as SQLite and XMI.

Read the optional browser-export build and validation: viewer/build_viewer.py.

The output format does not make the clinical data less sensitive

ControlRequired handling
StorageApproved encrypted clinical-data volume, restricted service account, and verified access-control list (ACL) inheritance.
NetworkRun Release 2.1.19 setup before notes arrive. It downloads and verifies the main cTAKES/dictionary asset, the separate WSD asset, and SQLite JDBC; extraction then uses the staged local runtime with no UMLS key.
TransferMove only protocol-approved artifacts through the approved clinical transfer process.
RetentionApply the schedule to source, work copies, failure shards, logs, CSV, SQLite, XMI, viewer, and backups.
Issues/supportDo not attach note text, CSV rows, SQLite, XMI, or the viewer to a public issue.
Release runtime assetsThe exact cTAKES 6.0.0 and 2026AA dictionary bundle is approved. WSD is approved and published as its own checksum-pinned asset with its exact model, receipt, review, and notices. Raw UMLS files, notes, samples, and old assets remain outside both.
Complete repository gateRelease 2.1.19 carries the Apache-2.0 license, NOTICE, sample/Git-history decisions, and approved public-release review. Passing that publication gate does not establish clinical production approval.
Nextthe same recorded analysis at more than one siteMulti-site use