Documentation
Common Data Model (CDM)
Convert Database to CDM (ETL)
Tool Specific Documentation
Common Data Model (CDM)
Convert Database to CDM (ETL)
Tool Specific Documentation
This is an old revision of the document!
!! This cookbook is outdated - do not follow these instructions !!
Vocabulary Users download vocabularies from Athena: https://athena.ohdsi.org/
The CDM Vocabulary is maintained by the Athena vocabulary team led by Christian Reich.
This page provides a high level guide or “cookbook” for the ETL process that they follow to periodically update the CDM vocabulary when new source vocabulary data sets are released.
This ETL process will be improved and extended with new vocabulary sources over time. It is somewhat complex, it has very specific pre-requisites, it requires a good knowledge of the CDM schema & source vocabulary data sets and it includes some manual steps.
This ETL is not intended to be executed by typical users of the CDM Vocabulary. If you just need a copy of the CDM Vocabulary then go to the CDM vocabulary download website here: http://www.ohdsi.org/web/athena/.
Internet access is required to download source dataset files from external websites and to download the ETL source code from github: https://github.com/OHDSI/Vocabulary-v5.0
A zip file decompression program is required (e.g. 7-zip for windows or gzip/gunzip for linux)
An Oracle 12 DBMS is required.
Notes. Oracle XE cannot be used because it has an 11 GB database size limitation. In order to minimize network latency for database loads and data transformation SQL scripts, it is recommended to host the Oracle DBMS and the data set files to be loaded on the same server.
* Create a database/user called PRODV5. This database schema is used for data set and concept staging tables and is where the final output V5 CDM vocabulary tables will be created and populated.
* Create a database/user called PRODV4. This database schema is where the final output V4 CDM vocabulary tables will be created and populated.
* Create a database/user called umls. This database schema is for the UMLS data feed staging tables.
* Note. As a general principle to be followed when running the create_source_tables.sql scripts in this ETL process: You will get the best performance by first running the create table statements, then loading the tables and then running the create index statements. The reason is that it is faster to add an index to a populated table than to load data into a table that already has an existing index.
2 Gig of RAM on server (minimum) 400 GB disk space for database and source files
This ETL process is an update process which merges new data into an existing populated vocabulary database. If you want to refresh V4 vocabulary data you will need both V4 and V5 vocabularies (V4 is refreshed from V5). If you only want to refresh V5 vocabulary data then V4 is not required and you can skip the V4 update step in the ETL process.
If you have no existing Vocabulary data you can begin by downloading the V4 and/or V5 vocabulary export files from here: http://www.ohdsi.org/web/athena/.
V4.5 Oracle DDL and CTL statements can be found here: https://github.com/OHDSI/CommonDataModel/tree/master/Version4/Oracle
V5 Oracle DDL and CTL statements can be found here: https://github.com/OHDSI/CommonDataModel/tree/master/Oracle
Note. The Oracle CTL statements for the vocabulary data loads are in the vocabimport sub-directories.
This table shows the web sites to visit and the files to download for this ETL process.
Create a directory e.g. called /vocabETL on your server (on a Windows server use the name C:\vocabETL - make similar windows file path substitutions in subsequent instructions in this document) Use a web browser or the command-line program wget to download the following zip file into the vocabETL directory: https://github.com/OHDSI/Vocabulary-v5.0/archive/master.zip unzip the master.zip file using 7-Zip on Windows or unzip on Linux.
This will result in the following directory structure:
/Vocabulary-v5.0-master/
There is one sub-directory containing the ETL scripts for each data feed, plus 3 additional sub-directories explained below.
There are a number of scripts in this sub-directory (Also see the process overview diagram later in this document).
The 2 scripts in this sub-directory are run to populate the CONCEPT_ANCESTOR and DRUG_STRENGTH CDM vocabulary tables from the staging tables.
The ‘Conversion_from_v4’ scripts are NOT part of the ongoing vocabulary ETL process and should NOT be run.
The UMLS knowledge sources, SNOMED and RxNorm are the core set of vocabularies that must be loaded first. The processing of the other vocabularies is dependent on first having those three vocabularies loaded. See the diagram below for a high level overview of the process.
Download, the UML datasets from the UMLS website. Decompress the gzipped files. Run the ETL script to create the UML database staging tables schema and load the datasets into the UMLS staging tables.
Note. There are multiple sets of extracted files. Each set of files must be concatenated together to create a single file.
A. Linux commands to unzip and concatenate files (run in shell):
cd /VOCABETL/Vocabulary-v5.0-master/UMLS/YYYYAB\META where YYYY is the year (e.g. 2014). gunzip *-meta.nlm gunzip *.gz --cat MRCONSO.RRF.aa MRCONSO.RRF.ab > MRCONSO.RRF --cat MRHIER.RRF.aa MRHIER.RRF.ab > MRHIER.RRF --cat MRREL.RRF.aa MRREL.RRF.ab MRREL.RRF.ac MRREL.RRF.ad > MRREL.RRF --cat MRSAT.RRF.aa MRSAT.RRF.ab MRSAT.RRF.ac MRSAT.RRF.ad > MRSAT.RRF
B. Alternative commands to run for Windows (run in powershell):
cd C:\VOCABETL\Vocabulary-v5.0-master\UMLS\2014AB\META where YYYY is the year (e.g. 2014). unzip *-meta.nlm gzip -d *.gz MRCONSO.RRF.aa.gz MRCONSO.RRF.ab.gz MRHIER.RRF.aa.gz MRHIER.RRF.ab.gz MRREL.RRF.aa.gz MRREL.RRF.ab.gz MRREL.RRF.ac.gz MRREL.RRF.ad.gz MRSAT.RRF.aa.gz MRSAT.RRF.ab.gz MRSAT.RRF.ac.gz MRSAT.RRF.ad.gz cmd /c copy MRCONSO.RRF.aa + MRCONSO.RRF.ab MRCONSO.RRF cmd /c copy MRHIER.RRF.aa + MRHIER.RRF.ab MRHIER.RRF cmd /c copy MRREL.RRF.aa + MRREL.RRF.ab + MRREL.RRF.ac + MRREL.RRF.ad MRREL.RRF cmd /c copy MRSAT.RRF.aa +MRSAT.RRF.ab + MRSAT.RRF.ac + MRSAT.RRF.ad MRSAT.RRF
Run the following commands in a linux shell or Windows command-line to load each file into the staging table in PRODV5 with the same name.
Note. Each file has a separate control file which is in the vocabETL/vocabulary-v5.0-master/UML sub-directory and the full path to the data sets to be loaded must be specified in the command (replace <password> with the database password of the PRODV5 user in the sqlldr statements below).
Note. You can review and then ignore any single .bad record for each file which just contains the Windows EOF file char added by the above batch copy statements.
sqlldr 'PRODV5/<password>' CONTROL=MRCONSO.ctl LOG=MRCONSO.log BAD=MRCONSO.bad sqlldr 'PRODV5/<password>' CONTROL=MRHIER.ctl LOG=MRHIER.log BAD=MRHIER.bad sqlldr 'PRODV5/<password>' CONTROL=MRMAP.ctl LOG=MRMAP.log BAD=MRMAP.bad sqlldr 'PRODV5/<password>' CONTROL=MRREL.ctl LOG=MRREL.log BAD=MRREL.bad sqlldr 'PRODV5/<password>' CONTROL=MRSAT.ctl LOG=MRSAT.log BAD=MRSAT.bad sqlldr 'PRODV5/<password>' CONTROL=MRSMAP.ctl LOG=MRSMAP.log BAD=MRSMAP.bad
Download, the SNOMED datasets from the website. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
alter table concept_stage modify (concept_code varchar2(50));
The international SNOMED-CT and the UK SNOMED-CT will be loaded into separate staging tables and then unioned together in views ready for processing in the load_stage.sql step below.
Staging table load statements
sqlldr PRODV5/<password> CONTROL=SCT2_CONCEPT_FULL_INT.ctl LOG=SCT2_CONCEPT_FULL_INT.log BAD=SCT2_CONCEPT_FULL_INT.bad sqlldr PRODV5/<password> CONTROL=SCT2_DESC_FULL_EN_INT.ctl LOG=SCT2_DESC_FULL_EN_INT.log BAD=SCT2_DESC_FULL_EN_INT.bad sqlldr PRODV5/<password> CONTROL=SCT2_RELA_FULL_INT.ctl LOG=SCT2_RELA_FULL_INT.log BAD=SCT2_RELA_FULL_INT.bad sqlldr PRODV5/<password> CONTROL=SCT2_CONCEPT_FULL_UK.ctl LOG=SCT2_CONCEPT_FULL_INT.log BAD=SCT2_CONCEPT_FULL_UK.bad sqlldr PRODV5/<password> CONTROL=SCT2_DESC_FULL_UK.ctl LOG=SCT2_DESC_FULL_UK.log BAD=SCT2_DESC_FULL_UK.bad sqlldr PRODV5/<password> CONTROL=SCT2_RELA_FULL_UK.ctl LOG=SCT2_RELA_FULL_UK.log BAD=SCT2_RELA_FULL_UK.bad sqlldr PRODV5/<password> CONTROL=der2_cRefset_AssRefFull_INT.ctl LOG=der2_cRefset_AssRefFull_INT.log BAD=der2_cRefset_AssRefFull_INT.bad sqlldr PRODV5/<password> CONTROL=der2_cRefset_AssRefFull_UK.ctl LOG=der2_cRefset_AssRefFull_UK.log BAD=der2_cRefset_AssRefFull_UK.bad sqlldr PRODV5/<password> CONTROL=f_ampp2.ctl LOG=f_ampp2.log BAD=f_ampp2.bad sqlldr PRODV5/<password> CONTROL=f_vmpp2.ctl LOG=f_vmpp2.log BAD=f_vmpp2.bad sqlldr PRODV5/<password> CONTROL=f_amp2.ctl LOG=f_amp2.log BAD=f_amp2.bad sqlldr PRODV5/<password> CONTROL=f_vmp2.ctl LOG=f_vmp2.log BAD=f_vmp2.bad sqlldr PRODV5/<password> CONTROL=f_vtm2.ctl LOG=f_vtm2.log BAD=f_vtm2.bad sqlldr PRODV5/<password> CONTROL=f_ingredient2.ctl LOG=f_ingredient2.log BAD=f_ingredient2.bad sqlldr PRODV5/<password> CONTROL=f_lookup2.ctl LOG=f_lookup2.log BAD=f_lookup2.bad sqlldr PRODV5/<password> CONTROL=dmdbonus.ctl LOG=dmdbonus.log BAD=dmdbonus.bad
Download, the RxNorm datasets from the website. Decompress the gzipped files. Run the ETL script to create database staging tables schema and load the datasets.
Update the update vocabulary latest_update date statement in create_source_tables.sql to the correct date for the file you are loading. Make this change in load_stage.sql for each data feed.
This ETL step processes RxNorm, ATC, NDFRT, VA Product , VA Class and ATC vocabularies.
At step 15 of create_source_tables.sql you must run the generic_update_sql script (from “working” directory) to load the RxNorm concepts from the concept staging tables. You also need to run that same script after the load_stage.sql script finishes.
Download the HCPCS datasets from the website. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
load_stage.sql Steps 9 and 10 are completely manual – a select statement to generate the set of Medical Coder rows which needs to be exported as a file followed by an instruction “Append resulting file from Medical Coder (in concept_relationship_stage format) to concept_relationship_stage”. In the future this could be converted into an insert append statement. Note. The original HCPCS HCPYYYY_CONTR_ANWEB_V2.txt file is a fixed field format file that will not load with the ANWEB_V2.ctl file which requires a comma separated file so see details below on creating a csv file to use for the load.
Staging table load statements
sqlldr PRODV5/<password> CONTROL=ANWEB_V2.ctl DATA=HCPC2015_CONTR_ANWEB_v2.tsv LOG=ANWEB_V2.log BAD=ANWEB_V2.bad
Download, the ICD9CM datasets. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
Staging table load statements
sqlldr PRODV5/<password> CONTROL=CMS32_DESC_LONG_DX.ctl LOG=CMS32_DESC_LONG_DX.log BAD=CMS32_DESC_LONG_DX.bad sqlldr PRODV5/<password> CONTROL=CMS32_DESC_SHORT_DX.ctl LOG=CMS32_DESC_SHORT_DX.log BAD=CMS32_DESC_SHORT_DX.bad
Download, the ICD9Proc datasets. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
load_stage.sql Steps 8 and 9 are completely manual – a select statement to generate the set of Medical Coder rows which need to be exported as a file called 'concept_relationship_manual9cm'. In the future these two steps could be converted into an insert append sub-select statement.
Staging table load statements
sqlldr PRODV5/<password> CONTROL=CMS32_DESC_LONG_SG.ctl LOG=CMS32_DESC_LONG_SG.log BAD=CMS32_DESC_LONG_SG.bad sqlldr PRODV5/<password> CONTROL=CMS32_DESC_SHORT_SG.ctl LOG=CMS32_DESC_SHORT_SG.log BAD=CMS32_DESC_SHORT_SG.bad
Download, the LOINC datasets. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
Add the missing create table statement for LOINC_HIERARCHY and add missing columns to LOINC_ANSWERS create statement in create_source_tables.sql, The added/update two tables are shown below:
CREATE TABLE LOINC_HIERARCHY ( PATH_TO_ROOT VARCHAR2(4000), SEQUENCE NUMBER(38,0), IMMEDIATE_PARENT VARCHAR2(255), CODE VARCHAR2(255), CODE_TEXT VARCHAR2(255) ); CREATE TABLE LOINC ( LOINC_NUM VARCHAR2(10), COMPONENT VARCHAR2(255), PROPERTY VARCHAR2(30), TIME_ASPCT VARCHAR2(15), SYSTEM VARCHAR2(100), SCALE_TYP VARCHAR2(30), METHOD_TYP VARCHAR2(50), CLASS VARCHAR2(20), SOURCE VARCHAR2(8), DATE_LAST_CHANGED DATE, CHNG_TYPE VARCHAR2(3), COMMENTS CLOB, STATUS VARCHAR2(11), CONSUMER_NAME VARCHAR2(255), MOLAR_MASS VARCHAR2(13), CLASSTYPE VARCHAR2(20), FORMULA VARCHAR2(255), SPECIES VARCHAR2(20), EXMPL_ANSWERS CLOB, ACSSYM CLOB, BASE_NAME VARCHAR2(50), NAACCR_ID VARCHAR2(20), CODE_TABLE VARCHAR2(10), SURVEY_QUEST_TEXT CLOB, SURVEY_QUEST_SRC VARCHAR2(50), UNITSREQUIRED VARCHAR2(1), SUBMITTED_UNITS VARCHAR2(30), RELATEDNAMES2 CLOB, SHORTNAME VARCHAR2(40), ORDER_OBS VARCHAR2(15), CDISC_COMMON_TESTS VARCHAR2(1), HL7_FIELD_SUBFIELD_ID VARCHAR2(50), EXTERNAL_COPYRIGHT_NOTICE CLOB, EXAMPLE_UNITS VARCHAR2(255), LONG_COMMON_NAME VARCHAR2(255), HL7_V2_DATATYPE VARCHAR2(255), HL7_V3_DATATYPE VARCHAR2(255), CURATED_RANGE_AND_UNITS CLOB, DOCUMENT_SECTION VARCHAR2(255), EXAMPLE_UCUM_UNITS VARCHAR2(255), EXAMPLE_SI_UCUM_UNITS VARCHAR2(255), STATUS_REASON VARCHAR2(9), STATUS_TEXT CLOB, CHANGE_REASON_PUBLIC CLOB, COMMON_TEST_RANK VARCHAR2(20), COMMON_ORDER_RANK VARCHAR2(20), COMMON_SI_TEST_RANK VARCHAR2(20), HL7_ATTACHMENT_STRUCTURE VARCHAR2(15) );
Staging table load statements
sqlldr PRODV5<password> CONTROL=LOINC.ctl LOG=LOINC.log BAD=LOINC.bad sqlldr PRODV5/<password> CONTROL=MAP_TO.ctl LOG=MAP_TO.log BAD=MAP_TO.bad sqlldr PRODV5/<password> CONTROL=SOURCE_ORGANIZATION.ctl LOG=SOURCE_ORGANIZATION.log BAD=SOURCE_ORGANIZATION.bad sqlldr PRODV5/<password> CONTROL=LOINC_HIERARCHY.ctl LOG=LOINC_HIERARCHY.log BAD=LOINC_HIERARCHY.bad sqlldr PRODV5/<password> CONTROL=LOINC_CLASS.ctl LOG=LOINC_CLASS.log BAD=LOINC_CLASS.bad sqlldr PRODV5/<password> CONTROL=LOINC_ANSWERS.ctl LOG=LOINC_ANSWERS.log BAD=LOINC_ANSWERS.bad sqlldr PRODV5/<password> CONTROL=xder2_scccRefset_MapCorrelationOriginFull_INT.ctl LOG=xder2_scccRefset_MapCorrelationOriginFull_INT.ctl.log BAD=xder2_scccRefset_MapCorrelationOriginFull_INT.ctl.bad sqlldr PRODV5/<password> CONTROL=CPT_MRSMAP.ctl LOG=CPT_MRSMAP.log BAD=CPT_MRSMAP.bad
Download, the MEDDRA datasets. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
You must have a MedDRA license to download the data set. The processing of this data set follows the same approach as the other data feeds.
Download, the NDC-SPL datasets. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
This data feed loads the NDC vocabulary and the SPL vocabularies.
Staging table load statements
sqlldr PRODV5/<password> CONTROL=PRODUCT.ctl LOG=PRODUCT.log BAD=PRODUCT.bad
Download, the READ code datasets. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
staging table load statements
sqlldr PRODV5/<password> CONTROL=Keyv2.ctl LOG=Keyv2.log BAD=Keyv2.bad sqlldr PRODV5/<password> CONTROL=rcsctmap2_uk.ctl LOG=rcsctmap2_uk.log BAD=rcsctmap2_uk.bad
Download, the DRG dataset. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
staging table load statements
sqlldr PRODV5/<password> CONTROL=FY2011.ctl LOG=FY2011.log BAD=FY2011.bad sqlldr PRODV5/<password> CONTROL=FY2012.ctl LOG=FY2012.log BAD=FY2012.bad sqlldr PRODV5/<password> CONTROL=FY2013.ctl LOG=FY2013.log BAD=FY2013.bad sqlldr PRODV5/<password> CONTROL=FY2014.ctl LOG=FY2014.log BAD=FY2014.bad sqlldr PRODV5/<password> CONTROL=FY2015.ctl LOG=FY2015.log BAD=FY2015.bad
MeSH datasets contains in UMLS.
ICD10 datasets contains in UMLS.
GCN_SEQNO datasets contains in RxNorm.
ETC datasets contains in “ETC sources.zip”.
Indication datasets contains in “Indication sources.zip”.
Download the ICD10CM datasets. Decompress the gzipped files. Run the ETL script to create the staging tables schema and load the datasets.
In the final_assembly directory, run the two SQL scripts to populate the concept_ancestor and drug_strength tables.
In the “working” directory, run the manual change scripts.
These scripts are collections of ad-hoc inserts / updates that have been applied over time. Before running each block of sql statements review them against the current V5 vocabulary table values to avoid potential duplicate inserts or inappropriate updates. Contact Christian Reich and the Athena vocabulary team for more info on these scripts.
In the “working” directory run a script that will update the V4 schema tables with the new data in the V5 schema tables.
The v4 tables and the v5 tables should already exist and be populated with data. The prodv4 user should have been granted read access to the prodv5 schema tables.