Read v2 via TRUD Item 9
TRUD item 9, NHS Data Migration, is the route to the Read v2 maps that are
not present in current UK RF2 releases and cannot currently be recovered from
the DMWB Access pack with jetdb.
The release to use is:
| Field | Value |
|---|---|
| TRUD item | 9 |
| Archive | nhs_datamigration_29.0.0_20200401000001.zip |
| Product status | Final April 2020 production release, deprecated with support |
| Source terminologies | final 5-Byte Read v2 21.0.0, final CTV3 25.0.0 |
| SNOMED CT target | SNOMED CT 29.0.0 / 29.0.1 |
NHS Digital's bundled release note says this final release replaces previous Data Migration Pack releases and that no further scheduled releases will occur. That makes it a static historical source rather than a monthly RF2 feed.
Download
sct trud download --edition nhs_data_migration
Do not use --pipeline: this archive is not RF2. It is a zip of flat mapping
tables, documentation PDFs, primary care refsets, and legacy navigation subsets.
Import it into an existing SNOMED SQLite database with sct read2 import, or
let sct trud download --multi-terminology do both downloads and the import.
You can also use the raw item number:
sct trud list --item 9
sct trud download --item 9
What is in the archive
The files relevant to DMWB feature parity are under Mapping Tables/Updated/:
| File | Direction | Use |
|---|---|---|
Clinically Assured/rcsctmap2_uk_20200401000001.txt |
Read v2 + term code -> SNOMED CT | Primary source for Read v2 import. Carries SNOMED ConceptId, DescriptionId, IS_ASSURED, effective date, and map status. |
Not Clinically Assured/rcsctmap_uk_20200401000001.txt |
Read v2 + term code -> SNOMED CT | Older/simple table. Useful for comparison, but lacks DescriptionId and assurance metadata. |
Not Clinically Assured/rctermsctmap_uk_20200401000001.txt |
Read v2 + term text -> SNOMED CT | Fallback when the source record has text but no term code. |
Not Clinically Assured/rcmap_uk_20200401000001.txt |
Read v2 code only -> SNOMED CT | Fallback when the source record has no term code or text. Includes ambiguous MapStatus=2 rows. |
Clinically Assured/rctctv3map_uk_20200401000001.txt |
Read v2 + term code -> CTV3 | Useful for legacy Read v2 -> CTV3 migration. |
Clinically Assured/ctv3sctmap2_uk_20200401000001.txt |
CTV3 + term id -> SNOMED CT | Flat-file CTV3 source, though current UK RF2 already gives sct CTV3 maps. |
The release also includes map-specific documentation PDFs. The Read v2 ->
SNOMED CT documentation defines the active-map rule and the meaning of
IS_ASSURED.
Analysis Method
The archive is a stored zip, so it can be inspected without extraction:
unzip -l ~/.local/share/sct/releases/nhs_datamigration_29.0.0_20200401000001.zip
The primary Read v2 map header is:
MapId ReadCode TermCode ConceptId DescriptionId IS_ASSURED EffectiveDate MapStatus
Rows are tab-delimited and CR/LF terminated. The bundled documentation says:
| Column | Import meaning |
|---|---|
ReadCode |
Five-character Read v2 code. Must be treated case-sensitively. |
TermCode |
Usually two-character Read v2 term code. The ReadCode+TermCode pair identifies the source meaning. |
ConceptId |
Target SNOMED CT concept. |
DescriptionId |
Target SNOMED CT description to which assurance applies. |
IS_ASSURED |
1 clinically assured, 0 not assured. Assurance applies to the ConceptId+DescriptionId pair, not just the concept. |
EffectiveDate |
Date the MapStatus value takes effect. |
MapStatus |
1 active, 0 inactive. |
The active-map rule is the same one described in the release documentation:
- Group rows by
MapId. - Keep the row with the latest
EffectiveDateat or before the target release date. - Use it only when
MapStatus > 0. - Query distinct target concepts, because a small number of source pairs have duplicate active rows with different
MapIds but the same target concept.
For the final April 2020 release, applying that method to
rcsctmap2_uk_20200401000001.txt gives:
| Metric | Count |
|---|---|
Latest MapId rows |
159,464 |
| Active latest rows | 102,057 |
| Active assured rows | 77,079 |
| Active unassured rows | 24,978 |
| Distinct active ReadCode+TermCode pairs | 102,057 |
| Distinct target SNOMED concepts | 68,414 |
The old/simple rcsctmap_uk_20200401000001.txt gives 102,152 active latest
rows and 102,066 distinct active ReadCode+TermCode pairs, but it lacks
DescriptionId and assurance metadata. That is why sct should prefer
RcSctMap2.
Import
The easiest path is:
sct trud download --multi-terminology
If you already have the SNOMED database and item 9 archive locally:
sct read2 import \
--archive ~/.local/share/sct/releases/nhs_datamigration_29.0.0_20200401000001.zip \
--db snomed.db
The importer loads item 9 into the existing SNOMED SQLite database through
the general crossmaps table. It should not collapse Read v2 rows into only the
legacy concept_maps(code, terminology, concept_id) shape, because that loses
DescriptionId, IS_ASSURED, MapId, EffectiveDate, map status, and source
release provenance.
The import stores Read v2 -> SNOMED rows with:
source_system = 'read2'source_code = <ReadCode><TermCode>source_term_code = <TermCode>target_system = 'snomed'target_code = ConceptIdtarget_description_id = DescriptionIdmap_source = 'nhs_data_migration_item9'map_id = MapIdeffective_date = EffectiveDateactive = MapStatus > 0map_status = MapStatusis_assured = IS_ASSURED
Recommended source-code encoding for command-line input is the seven-character Read v2 source key:
<ReadCode><TermCode>
For example, 0111. + 00 becomes 0111.00, and 0.... + 11 becomes
0....11. This matches the way the release documentation writes examples such
as 9113.00.
Fallback support can come later:
RcTermSctMapwhen source records contain ReadCode plus term text but no TermCode.RcMapwhen source records contain only ReadCode. These rows are less precise and include ambiguousMapStatus=2rows, so they should be exposed explicitly rather than silently mixed into the ReadCode+TermCode map.