의료 데이터 분석/설계를 위한 OHDSI
CDM 기반의 의료 데이터 분석/설계 오픈소스 OHDSI Atlas
의료 데이터 분석/설계를 위한 OHDSI
OHDSI? CDM?
OHDSI는 OMOP CDM 기반의 분산 연구망을 표준 및 관련 소프트웨어 도구를 만들고 유지 관리하는 국제적인 비영리 단체입니다. CDM 기반의 오픈소스를 운영하고 있습니다. OHDSI와 누적된 의료 데이터를 활용하여 여러 분석 설계 및 실행을 진행할 수 있습니다. OHDSI Atlas 사용 환경 구성을 위해 OHDSI에서 제공하는 컨테이너를 활용하여 구성하였고, 이를 공유합니다. DB는 PostgreSQL로 구성하였고, 사용자를 위한 Jupyter와 R 등의 분석 컨테이너를 포함하였습니다.
필요 패키지
●OHDSI WEBAPI
●OHDSI Atlas
●OHDSI Achilles
●R
●PostgreSQL
●Jupyter
●Docker
OS 설치
CentOS 7.9 (최소설치)
방화벽 해제
(local)$ systemctl disable firewalld
(local)$ systemctl stop firewalld
Docker 설치
(local)$ yum -y update
(local)$ yum install yum-utils device-mapper-persistent-data lvm2
(local)$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
(local)$ yum install docker-ce
(local)$ systemctl start docker&&systemctl enable docker
작업 폴더 생성
(local)$ mkdir /sourcedata
(local)$ mkdir /sourcedata/data
(local)$ mkdir /workspace1
(local)$ mkdir /workspace2
(local)$ mkdir /db1
(local)$ mkdir /db2
docker-compose 설치
(local)$ curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
(local)$ chmod +x /usr/local/bin/docker-compose
(local)$ ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
SQL 테이블 데이터 다운로드
(local)$ yum install -y git
(local)$ cd /sourcedata
(local)$ git clone -b v5.3.2 https://github.com/OHDSI/CommonDataModel.git
ATLAS webtool compose 파일 다운로드
(local)$ cd /sourcedata
(local)$ git clone https://github.com/OHDSI/Broadsea.git
PostgreSQL 컨테이너 생성
(local)$ docker run --name postgres1 -d --restart unless-stopped --shm-size=1g \
-p 1040:5432 -e POSTGRES_PASSWORD=Itmaya2009! \
-v /db1:/var/lib/postgresql/data \
-v /sourcedata:/sourcedata \
-v /workspace1:/workspace postgres
**--shm-size-=1g 옵션을 실 서버에 구성할때는 32g로 구성하여 성능 확보 필요함
PostgreSQL DB 구성
(local)$ docker exec -ti postgres1 bash
(postgres1)$ psql -U postgres
(postgres1 #)# CREATE USER atlas PASSWORD 'Itmaya2009!' SUPERUSER;
(postgres1 #)# CREATE DATABASE atlasdb OWNER atlas;
(postgres1 #)# \c atlasdb
(postgres1 #DB)# CREATE SCHEMA cdm;
(postgres1 #DB)# CREATE SCHEMA ohdsi;
(postgres1 #DB)# CREATE SCHEMA results;
(postgres1 #DB)# exit
DB 테이블 생성 및 데이터 복사
(local)$ docker exec -ti postgres1 bash
테이블 쿼리 생성
(postgres1)$ cd /sourcedata/CommonDataModel/inst/ddl/5.3/postgresql/
(postgres1)$ echo 'SET search_path to cdm;' | cat - OMOPCDM_postgresql_5.3_ddl.sql > 1.sql
(postgres1)$ echo 'SET search_path to cdm;' | cat - OMOPCDM_postgresql_5.3_primary_keys.sql > 2.sql
(postgres1)$ echo 'SET search_path to cdm;' | cat - OMOPCDM_postgresql_5.3_constraints.sql > 3.sql
(postgres1)$ echo 'SET search_path to cdm;' | cat - OMOPCDM_postgresql_5.3_indices.sql > 4.sql
(postgres1)$ sed -i 's/\@cdmDatabaseSchema/cdm/g' /sourcedata/CommonDataModel/inst/ddl/5.3/postgresql/1.sql
(postgres1)$ sed -i 's/\@cdmDatabaseSchema/cdm/g' /sourcedata/CommonDataModel/inst/ddl/5.3/postgresql/2.sql
(postgres1)$ sed -i 's/\@cdmDatabaseSchema/cdm/g' /sourcedata/CommonDataModel/inst/ddl/5.3/postgresql/3.sql
(postgres1)$ sed -i 's/\@cdmDatabaseSchema/cdm/g' /sourcedata/CommonDataModel/inst/ddl/5.3/postgresql/4.sql
테이블 생성 (1.sql)
(postgres1)$ psql -U atlas -d atlasdb -a -f 1.sql
권한 변경 (2.sql)
(postgres1)$ psql -U atlas -d atlasdb -a -f 2.sql
권한 변경 (3.sql)
(postgres1)$ psql -U atlas -d atlasdb -a -f 3.sql
테이블 인덱스 생성 (4.sql)
(postgres1)$ psql -U atlas -d atlasdb -a -f 4.sql
(postgres1)$ exit
webtools, atlas, rstudio 컨테이너 생성
docker compose 구성
(local)$ echo "version: '2'
services:
broadsea-methods-library:
image: ohdsi/broadsea-methodslibrary
container_name: achilles1
ports:
- "1020:8787"
- "1050:6311"
- "1060:1444"
volumes:
- /workspace1:/workspace
environment:
-PASSWORD=Itmaya2009!
broadsea-webtools:
image: ohdsi/broadsea-webtools
container_name: atlas1
ports:
- "1010:8080"
volumes:
- .:/tmp/drivers/:ro
- /workspace1:/workspace
- /sourcedata/Broadsea/config-local.js:/usr/local/tomcat/webapps/atlas/js/config-local.js:ro
environment:
-WEBAPI_URL=http://192.168.0.249:1010
- env=webapi-postgresql
- security_enabled=false
- security_origin=*
- datasource_driverClassName=org.postgresql.Driver
- datasource_url=jdbc:postgresql://192.168.0.249:1040/atlasdb
- datasource.cdm.schema=cdm
- datasource.ohdsi.schema=ohdsi
- datasource_username=atlas
- datasource_password=Itmaya2009!
- spring.jpa.properties.hibernate.default_schema=ohdsi
- spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
- spring.batch.repository.tableprefix=ohdsi.BATCH_
- flyway_datasource_driverClassName=org.postgresql.Driver
- flyway_datasource_url=jdbc:postgresql://192.168.0.249:1040/atlasdb
- flyway_schemas=ohdsi
- flyway.placeholders.ohdsiSchema=ohdsi
- flyway_datasource_username=atlas
- flyway_datasource_password=Itmaya2009!
- flyway.locations=classpath:db/migration/postgresql" > /sourcedata/Broadsea/postgresql/docker-compose.yml
(local)$ cd /sourcedata/Broadsea/postgresql/
(local)$ docker-compose up -d
achilles 컨테이너 ssh 구성
(local)$ docker exec -ti achilles1 bash
(achilles1)$ apt update
(achilles1)$ apt install -y openssh-server vim
(achilles1)$ sed -i 's/\#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
(achilles1)$ sed -i 's/\#Port 22/Port 1444/g' /etc/ssh/sshd_config
(achilles1)$ passwd root
(achilles1)> 패스워드 입력 (Itmaya2009!)
(achilles1)$ service ssh start
(achilles1)$ exit
atlas DB 연동
(local)$ echo "ALTER TABLE ohdsi.source ALTER COLUMN is_cache_enabled SET DEFAULT true;
truncate ohdsi.source;
truncate ohdsi.source_daimon;
INSERT INTO ohdsi.source( source_id, source_name, source_key, source_connection, source_dialect)
VALUES (1, 'OHDSI CDM V5 Database', 'OHDSI-CDMV5', 'jdbc:postgresql://192.168.0.249:1040/atlasdb?user=atlas&password=Itmaya2009!', 'postgresql');
INSERT INTO ohdsi.source_daimon( source_daimon_id, source_id, daimon_type, table_qualifier, priority) VALUES (1, 1, 0, 'cdm', 2);
INSERT INTO ohdsi.source_daimon( source_daimon_id, source_id, daimon_type, table_qualifier, priority) VALUES (2, 1, 1, 'cdm', 2);
INSERT INTO ohdsi.source_daimon( source_daimon_id, source_id, daimon_type, table_qualifier, priority) VALUES (3, 1, 2, 'results', 2);
INSERT INTO ohdsi.source_daimon( source_daimon_id, source_id, daimon_type, table_qualifier, priority) VALUES (4, 1, 3, 'cdm', 2);" > /sourcedata/CommonDataModel/inst/ddl/5.3/postgresql/5.sql
(local)$ docker exec -ti postgres1 bash
(postgres1)$ psql -U atlas -d atlasdb -a -f /sourcedata/CommonDataModel/inst/ddl/5.3/postgresql/5.sql
(postgres1)$ exit
Atlas 컨테이너 재시작
(local)$ docker restart atlas1
Achilles 버전 변경
(local)$ docker exec -ti achilles1 bash
(achilles1)$ R
(achilles1)> remotes::install_github('OHDSI/OhdsiRTools@v2.0.2')
(achilles1)>> skip Enter
(achilles1)> remotes::install_github('OHDSI/Achilles@v1.7.0')
(achilles1)>> skip Enter
*** 분석 결과 테이블 생성 (데이터 부재로 오류 발생함. 데이터 없이는 진행하지 말 것)
(achilles1)> library(Achilles)
(achilles1)> connectionDetails achilles(connectionDetails, cdmDatabaseSchema = "cdm", resultsDatabaseSchema="results", cdmVersion = "5.3.2")
(achilles1)> quit()
(achilles1)$ exit
Jupyter Notebook 구성
jupyter 컨테이너 생성
(local)$ docker run -v /sourcedata:/sourcedata -v /workspace1:/workspace --name=jupyter1 -e GRANT_SUDO=yes --user root -p 1030:8888 -d jupyter/datascience-notebook
패스워드 로그인 설정
(local)$ docker exec -ti jupyter1 bash
(jupyter1)$ apt update
(jupyter1)$ apt install -y vim
(jupyter1)$ ipython
(jupyter1)> from notebook.auth import passwd
(jupyter1)> passwd()
(jupyter1)> Itmaya2009!
(jupyter1)> Itmaya2009!
(jupyter1)> exit
(출력되는 password 보안키를 복사)
(jupyter1)$ echo "c.NotebookApp.password_required = True" >> ~/.jupyter/jupyter_notebook_config.py
(jupyter1)$ echo "c.NotebookApp.password = '복사한 보안키'" >> ~/.jupyter/jupyter_notebook_config.py
(보안키 잘 들어갔는지 vi 로 ~/.jupyter/jupyter_notebook_config.py 파일 마지막줄 확인)
(jupyter1)$ exit
(local)$ docker restart jupyter1
서비스 인프라 확인
Port 22 : Server Local (CentOS 7.9 Base) ( user:root / password:Itmaya2009! )
atlas config #1
공용볼륨 : /workspace1:/workspace
Port 1010 : Atlas (atlas1 container)
Port 1020 : R studio (achilles1 container) ( user:rstudio / password:Itmaya2009! )
Port 1030 : Jupyter Notebook (jupyter1 container) ( password:Itmaya2009! )
Port 1040 : PostgreSQL (postgres1 container) ( DB:atlasdb / user:atlas / password:Itmaya2009! ) - schema (cdm, ohdsi, results)
Port 1050 : R Serve (achilles1 container)
Port 1060 : Dev SSH (achilles1 container) ( user:root / password:Itmaya2009! )
atlas config #2
공용볼륨 : /workspace2:/workspace
Port 2010 : Atlas (atlas2 container)
Port 2020 : R studio (achilles2 container) ( user:rstudio / password:Itmaya2009! )
Port 2030 : Jupyter Notebook (jupyter2 container) ( password:Itmaya2009! )
Port 2040 : PostgreSQL (postgres2 container) ( DB:atlasdb / user:atlas / password:Itmaya2009! ) - schema (cdm, ohdsi, results)
Port 2050 : R Serve (achilles1 container)
Port 2060 : Dev SSH (achilles1 container) ( user:root / password:Itmaya2009! )
서비스 동작 확인
WebAPI : http://192.168.0.249:1010/WebAPI/source/sources
atlas : http://192.168.0.249:1010/atlas
rStudio : http://192.168.0.249:1020/ ( user:rstudio / password:Itmaya2009! )
Jupyter : http://192.168.0.249:1030/ ( password:Itmaya2009! )
SSH : ssh root@192.168.0.249 -p 1060 ( user:root / password:Itmaya2009! )
DB : jdbc:postgresql://192.168.0.249:1040/atlasdb ( user:atlas / password:Itmaya2009! ) - schema (cdm, ohdsi, results)
2022.12.20