Skip to content

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:

  1. Group rows by MapId.
  2. Keep the row with the latest EffectiveDate at or before the target release date.
  3. Use it only when MapStatus > 0.
  4. 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 = ConceptId
  • target_description_id = DescriptionId
  • map_source = 'nhs_data_migration_item9'
  • map_id = MapId
  • effective_date = EffectiveDate
  • active = MapStatus > 0
  • map_status = MapStatus
  • is_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:

  • RcTermSctMap when source records contain ReadCode plus term text but no TermCode.
  • RcMap when source records contain only ReadCode. These rows are less precise and include ambiguous MapStatus=2 rows, so they should be exposed explicitly rather than silently mixed into the ReadCode+TermCode map.