2022년 6월 30일 목요일

GNU parallel을 readstats.py에 적용하기, 그리고 우연히 알게된 AWS의 RONIN

내가 즐겨사용하는 readstats.py는 FASTA/FASTQ 파일을 읽어들여서 총 sequence 수와 bp를 출력하는 스크립트로서 khmer package에 포함되어 있다. 염기서열 파일을 다루는 많은 유틸리티가 있지만 관성이란 참으로 무서운 것이라서 초기에 접하여 손에 익은 프로그램은 계속 사용하게 된다. 기본적인 사용법은 다음과 같다.

$ readstats.py -o readstats.txt --csv *fastq

|| This is the script readstats.py in khmer.
|| You are running khmer version 2.1.1
|| You are also using screed version 1.0
||
|| If you use this script in a publication, please cite EACH of the following:
||
||   * MR Crusoe et al., 2015. http://dx.doi.org/10.12688/f1000research.6924.1
||
|| Please see http://khmer.readthedocs.io/en/latest/citations.html for details.

... SRR13060952.fastq 0
... found 37750 bps / 250 seqs; 151.0 average length -- SRR13060952.fastq
... SRR13060953.fastq 0
... found 37750 bps / 250 seqs; 151.0 average length -- SRR13060953.fastq
... SRR13060954.fastq 0
...중간 생략...
$ head -n 5 readstats.txt 
bp,seqs,avg_len,filename
37750,250,151.0,SRR13060952.fastq
37750,250,151.0,SRR13060953.fastq
37750,250,151.0,SRR13060954.fastq
37750,250,151.0,SRR13060955.fastq

이틀 전에 소개한 HRGM(Human Reference Gut Microbiome, 블로그 링크)을 공부하기 위하여 NCBI Sequence Read Archive study SRP292575로 등록된 raw sequencing read를 다운로드하였다. 논문에서는 90개의 분변 시료라 하였는데 SRR accession으로는 106개였다.  

SRA에서 파일을 다운로드할 때에도 parallel을 이용할 수 있다. 106개의 모든 SRR accession에 대하여 fasta-dump 명령어를 만들어서 다음과 같은 run.sh이라는 텍스트 파일을 만든다.

fastq-dump --split-files SRR13060942
fastq-dump --split-files SRR13060943
fastq-dump --split-files SRR13060944

이를 parallel에 공급하면 된다. Parallel을 사용하는 아주 기본적인 기법에 들어간다.

$ parallel --jobs 16 < run.sh &
[1] 17592

모든 파일을 압축하고 싶다면 'parallel gzip ::: *fastq'를 실행하면 된다. 

FASTQ 파일을 다운로드하였으니 각 파일이 몇 bp나 되는지를 헤아려 볼 순간이 되었다. 여러 파일의 다운로드 또는 압축 작업은 parallel을 쓰기에 아주 좋다. 왜냐하면 각 파일에 대해서 이루어진 작업에 대하여 출력되는 메시지 따위에 신경을 쓸 필요가 전혀 없기 때문이다. 그러나 readstats.py는 약간 다르다. 인수로 주어지는 FASTA/FASTQ 파일에 대한 집계 수치를 표준 출력/표준에러/'-o filename'으로 지정된 파일에 기록하게 되므로, parallel로 작업을 하려면 세심하게 명령어를 날려야 한다. 예를 들자면 Parallel tutorial 문서를 참조하여 다음과 같이 실행할 수 있다.

$ parallel --results outdir readstats.py ::: *fastq

그러면 새로 만들어진 outdir 디렉토리 아래에 각 fastq 파일에 대한 별도의 디렉토리가 생기고, 그 아래에 seq stderr stdout이라는 파일이 생긴다. 솔직히 말하자면 이것을 정리하는 일이 더욱 귀찮다. 따라서 입력 파일 하나에 대해서 '-o filename'으로 출력 파일을 하나씩 만든 후(이때 parallel을 사용), 가장 마지막 단계에서 모든 출력파일을 집계하여 최종 결과를 만드는 것이 더욱 바람직하다. Parallel 명령어는 다음과 같이 만들어서 실행하라.

$ parallel -j 16 'readstats.py {} > {.}.stat' ::: *fastq

{}는 input line을, {.}는 input line에서 파일 확장자를 제거했음을 의미한다. 매뉴얼을 잘 읽어보면 의미를 알 수 있지만 사용법을 빨리 익히려면 실제 사례를 보는 것이 낫다. 오늘 익힌 이 사례는 Parallelising jobs with GNU Parallel이라는 글에서 참고하였다. 이 글을 쓴 사람은 유전체학 분야에서 일을 하는 것으로 여겨진다. 이 글이 실린 RONIN - our guide to cloud computing's tricky bits이라는 곳이 무슨 목적으로 만들어졌는지도 관심을 가져 보아야 되겠다. RONIN이란, AWS(아마존웹서비스) 위에서 돌아가는 연구용 클라우드 컴퓨팅 서비스 정도로 이해하면 될 것 같다.

AWS를 1년 정도 써 본 경험에 의하면, 생각보다 요금이 많이 들었다는 기억만 남는다. BioStarts에 소개되었던 보다 차원 높은 parallel 사용법을 소개하는 것으로 끝을 맺는다.


2022년 6월 29일 수요일

ZGA pipeline에 두 쌍의 paired end read FASTQ 파일을 투입한 결과가 좀 이상하다

서로 다른 종에 속하는 미생물 균주로부터 유래한 일루미나 sequencing read를 한꺼번에 조립하면 결과는 엉망이 된다. 특별히 metagenomic assembler를 쓰지 않은 상황이라면 이런 불량한 결과가 나오는 것은 너무나 당연하다. 가끔은 일부러 테스트를 위해 이런 조립을 해 보기도 한다. 

매우 유사하지만 ANI 기준으로 분명히 서로 다른 종에 속하는 두 균주에서 생산한 일루미나 sequencing read가 있다. 전부 오래전에 NCBI SRA에 등록해 놓았는데 그 분량이 너무나 많은 관계로 다운로드 후 각각 150x 분량으로 서브샘플링을 하였다. 

  • 균주 A: A_1.fastq, A_2.fastq
  • 균주 B: B_1.fastq, B_2.fastq

SPAdes로 조립을 하려면 다음과 같이 입력해야 한다.

spades.py --threads 16 -o outdir \
--pe-1 1 A_1.fastq --pe-2 1 A_2.fastq \
--pe-1 2 B_1.fastq --pe-2 2 B_2.fastq

혼동하기 쉽게 생겼다. 예전 방식(deprecated syntax)으로는 '--pe1-1 A_1.fastq --pe1-2 A_2.fastq --pe2-1 B_1.fastq --pe2-2 B_2.fastq'의 형태로 입력하란다. Library ID number에 해당하는 숫자(빨간색)의 위치가 미묘하게 다르다. 

이렇게 조립을 하면 당연히 결과는 엉망이 된다. Contig의 수는 많고, 길이는 매우 짧으며, total length도 크게 늘어난다. 그러면 ZGA pipeline을 쓸 때에는 어떻게 명령어를 조합해야 하는가? Assembly engine으로는 SPAdes를 사용한다. 

ZGA 웹사이트의 설명을 보자.

zga -1 Lib1.R1.fq.gz Lib2.R1.fq -2 Lib1.R2.fq Lib2.R2.fq combination of reads from two sequencing libraries

SPAdes보다는 명령어 라인 구성이 간결해서 좋다. 라이브러리의 순서를 지켜서 forward read file은 -1 뒤에, reverse read file은 -2 뒤에 나열하면 된다. 그런데 결과가 너무나 좋다! A 유래 샘플만 사용한 것과 거의 다르지 않은 것이다! 이건 말이 되지 않는다. 그래서 다음과 같이 두 파일을 합쳐서 하나로 만든 뒤 이를 이용하여 ZGA를 실행하였다.

cat A_1.fastq B_1.fastq > C_1.fastq
cat A_2.fastq B_2.fastq > C_2.fastq
zga -o output -1 C_1.fastq -2 C_2.fastq

심하게 조각난 assembly가 산출되었다. 이렇게 나오는 것이 정상이다. ZGA 소스 코드에 약간의 버그가 있는 것 같다. 그것이 아니라면 나의 착각 또는 실수?

SPAdes version 3.14.0부터 도입된 '--isolate' 옵션을 쓰는 이유나 철저하게 이해하도록 하자. metaSPAdes를 돌리는 것이 아닌데도 '--isolate' 옵션을 따로 준다는 것이 잘 받아들여지지는 않지만 말이다.

Special --isolate option for assembly of standard datasets with good coverage (>100x). If you have high-coverage data for bacterial/viral isolate or multi-cell organism, we highly recommend to use --isolate option.

ART sequencing read simulator의 '-m' 파라미터는 정확히 무엇을 가리키는가?

ART sequencing simulator의 여러 파라미터 중 라이브러리의 크기와 직접 관련이 있는 것은 '-m'(the mean size of DNA/RNA fragments for paired-end simulations)이다. 길이 분포는 표정규분포를 가정하되 표준편차는 '-s' 파라미터로 설정한다. 일루미나 시퀀싱 라이브러리의 insert size와 fragment size는 보통 다음 그림과 같이 서로 다르게 정의된다.

출처: BioStars

정리하면 다음과 같다(참조: BioStars).

  • insert size = the sequence between adapters
  • fragment size = insert size + adapters

Fragment length는 양 끝의 어댑터를 포함하는 길이에 해당한다. CLC Genomics Workbench의 mapping 또는 de novo assembly report에서 만들어지는 paired reads distance 분포는 위 그림에서 inner distance에 해당할 것으로 생각하기 쉬운데, CLC Genomics Workbench 매뉴얼에 의하면 'The paired read distance includes the full read sequences"라고 명시되어 있다. 따라서 위에서 보인 그림의 insert size에 해당한다. 만약 이렇게 하지 않으면 forward와 reverse read가 서로 겹치는 경우 inner distance는 음수의 값을 갖게 될 것이다.

art_illumina의 '-m' 파라미터는 fragment size라고 하였으니 양 끝 어댑터의 길이를 합친 값을 제공해야 할 것처럼 보인다. 그런데 read simulator의 입장에서 어댑터의 크기를 고려할 일이 있을까? 몇 번의 시행착오를 거친 끝에 '-m' 뒤에는 insert size(CLC Genomics Workbench의 paired read distance 대푯값)에 해당하는 숫자를 넣으면 된다는 것을 알았다. 오랫동안 art_illumina를 사용해 왔지만 simulation으로 만들어진 read의 실제 분포를 측정해 본 일은 없었다. 대충 '-m 400' 정도로 놓고 read를 만들어서 사용하기만 했었다. 

다음은 실제 데이터인 SRR1144835의 자료를 샘플링하여 CLC Genomics Workbench에서 de novo assembly를 한 결과 리포트에서 딴 것이다. 분포가 예쁘지는 않지만 대략 470 bp 정도를 목표로 하였다.


다음은 '-p -l 101 -m 470 -s 30 -f 150' 파라미터로 시뮬레이션한 read의 조립 후 분포이다. 너무나도 정직한 정규분포의 모습을 따른다. Fragment(length)와 관계된 것이니 '-f' 파라미터라고 착각하면 안 된다. '-f'는 fold of read coverage를 지정하는 파라미터이다. 나도 처음에는 여러 차례 혼동했었다. 




Torsten Seemann의 블로그 "The Genome Factory"에 paired-end read의 길이에 대한 명쾌한 설명이 나온다. 이미 내 블로그에서 이 링크를 과거에 한 번 소개했었던 것 같다. 오늘 발견한 문제는 ART나 CLC에서 다루는 길이 관련 정의가 일반적으로 받아들여지는 것과는 조금 다르다는 것이다.

2022년 6월 28일 화요일

한국인 유래 샘플을 포함하는 장내 마이크로바이옴 카탈로그, HRGM(Human Reference Gut Microbiome)

메디톡스에서 파견 근무를 하던 2020년 4월에 생화학분자생물학회에서 발간하는 웹진의 TiBMB 섹션에 인체 장내 마이크로바이옴 참조 유전체 데이터베이스의 개발 현황이라는 글을 실은 적이 있다. TiBMB는 아마도 'Trends in Biochemistry and Molecular Biology'의 약자가 아닌가 싶은데, 정작 학회 웹사이트에서는 이것이 정확히 무엇을 의미하는지 찾기가 어렵다. 처음에는 TiBMB 자체가 학회에서 발간하는 여러 온라인 간행물의 하나라고 생각했었다.

TiBMB 화면 갈무리(링크)


이때 소개했던 Unified Human Gastrointestinal Genome(UHGG) 및 Unified Human Gastrointestinal Protein(UHGP) 관련 논문은 프리프린트 서버인 bioRxiv에만 올라온 상태였었다. 공개된 날짜는 2019년 9월 19일이었다. Nature Biotechnology에 정식으로 출판된 것은 2020년 7월 20일이다.

A unified catalog of 204,938 reference genomes from the human gut microbiome (open access)  

공개된 유전체 자료에서 인체 장에서 유래한 것을 어떻게 모으고 조립하였는지, 일정 identity 기준 이내에 들어오는 것을 어떻게 합쳤는지 등 방대한 자료 처리 과정에 대해서는 정말 공부할 것이 많다. UHGG를 만드는 데에는 isolate genome뿐만 아니라 MAG(metagenome-assembled genome)도 포함되어 있다.

논문 소개 자료를 인쇄해서 늘 책상 위에 놓고 있었는데 이제 비로소 쓸모를 발견하게 되었다.

장내 마이크로바이옴 관련 데이터베이스는 이것이 전부가 아니다. 예를 들어 같은 해에 Microbiome 저널에 실린 HumGut라는 것도 있다.

HumGut: a comprehensive human gut prokaryotic genomes collection filtered by metagenome data (open access)

초록을 조금만 인용해 보자. UHGG과 어떤 점이 다른지를 어렵지 않게 파악할 수 있을 것이다.

In this work, we aimed to create a collection of the most prevalent healthy human gut prokaryotic genomes, to be used as a reference database, including both MAGs from the human gut and ordinary RefSeq genomes. 

We screened > 5,700 healthy human gut metagenomes for the containment of > 490,000 publicly available prokaryotic genomes sourced from RefSeq and the recently announced UHGG collection.

이상의 데이터베이스에서는 한국인 유래 마이크로바이옴 자료는 찾아볼 수 없다. UHGG에는 동아시아인 유래 자료로서 중국인의 것이 꽤 많이 포함되었을 뿐이다. 국내에서도 장내 마이크로바이옴 연구가 점차 활발해지고 있는데, 한국인 분변에서 추출하여 만든 MAG 관련 연구 성과는 과연 무엇이 있을까? 검색을 해 보니 연세대학교 이인석 교수 연구팀에서 2021년에 Genome Medicine에 발표한 HRGM(Human Reference Gut Microbiome) 논문이 나왔다. 

Human reference gut microbiome catalog including newly assembled genomes from under-represented Asian metagenomes (open access)

이미 BRIC에도 소개된 중요 연구 성과였는데(링크) 모르고 지나쳤던 것 같다. 개인적으로는 별로 좋아하지 않는 '유전체 지도 구축'이라는 제목이 쓰였다. KOBIC의 대용량 컴퓨팅 설비가 쓰였다는 점도 매우 반갑다. 실제로 KOBIC에서 어느 부분을 담당했는지는 실무자를 수소문하여 물어 봐야 되겠다. Human genome에 대한 스크리닝인지, 조립 과정인지, 주석화 과정인지?

한국인(90 샘플), 일본인(645 샘플), 그리고 인도인(110 샘플)의 분변 유래 whole-metagenomic shotgun sequencing(WMS) 자료를 모아서 29,082개의 genome을 얻은 뒤, 이를 반복적으로 클러스터링하여 2199개의 species cluster를 얻었다. ㅇ32,098개의 non-redundant genome을 구성하고, 이를 UHGG의 5414 species cluster와 합쳐서 다시 후처리를 계속하여 최종적으로 5414개의 species cluster로 구성된 HRGM을 확보하게 된 것이다. 특히 한국인 샘플로부터는 ultra-deep WMS(>30 Gbp or > 100 million reads pairs)를 생산하여 low-abundance species를 찾는데 만전을 기하였다. 모든 결과물은 https://www.mbiomenet.org/HRGM/에 공개된 상태이다.

HRGM 웹사이트의 화면 갈무리.

요즘 나는 한국인 분변에서 분리한 미생물(메타게놈이 아님)의 특성을 분석하는 일을 하고 있다. 이 균주가 속하는 종이 실제 한국인 분변에 얼마나 존재하는지를 점검하는데 이인석 교수 연구팀에서 생산한 SRA 자료(NCBI Sequence Read Archive SRP292575)가 매우 유용하게 쓰일 것 같다. 각 샘플에 존재하는 특정 taxon의 relative abundance는 KRAKEN 2를 이용하여 판별한 것으로 보인다. 내가 쓰는 컴퓨터에서는 전체 시퀀싱 raw data를 내려받는 것만으로도 벅찰 것만 같다.

2022년 6월 27일 월요일

소리전자는 웹사이트 관리를 하지 않는 것인가? 네이버 계정 정보 탈취 문제

소리전자(https://www.soriaudio.com/)는 진공관 오디오 앰프의 자작과 중고 거래에 관심이 있는 사람이라면 누구다 다 알 만한 웹사이트이다. 여기에서 판매하는 진공관 앰프 키트는 국내의 관련 취미 활동 저변 확대에 크게 기여를 하였다. 언젠가 한 번은 여기에서 파는 싱글 엔디드 앰프 키트를 구입해서 만들어 보고 싶은 욕망이 있다. 그러나 쓰레기나 다를 것이 없는 물건을 중고품으로 올리는 판매자들의 글이 일절 관리가 되지 않는 것을 보면 안타까울 때가 많다.

이 사이트의 가장 큰 문제는 회원 관리뿐만 아니라 보안 측면에서도 실소를 금치 못할 일이 종종 벌어진다는 것이다. 예를 들어 웹브라우저를 통해 접속을 해 보면 다음과 같이 네이버 ID와 암호를 넣으라는 창이 버젓이 뜰 때가 있다. 항상 그런 것은 아니다.



나도 작년 가을 무렵 이 창을 처음 보았을 때에는 네이버와 소리전자가 계정 연동이 된 것으로 착각을 했었다. 다행스럽게도 여기에 내 정보를 넣지는 않았다. 아마도 누군가가 네이버 계정 정보를 탈취하기 위하여 악성 코드를 심어 놓은 모양인데, 시간이 오래 흘러도 전혀 개선이 되지 않는다. 나는 소리전자 회원이 아니라서 관리자에게 알리거나 하는 등의 적극적인 요청을 하지 않았다.

와싸다 사이트에도 이에 대한 경고성 글이 올라온 상태이다. 다음의 글은 2022년 2월 1일에 올라온 것인데, 이것 말고도 주의를 요구하는 글이 많이 있다.

[주의요망] 인터넷 검색 후 소리전자 게시글 조회시 절대 네이버 계정 정보 넣지 마세요.

다음은 실제 피해자의 글이다.

꼭 읽어 주십시요(네이버 계정 도용)

구글을 검색해 보니 이미 2014년부터 이러한 문제에 대한 보고가 있었다(링크). 그 때에는 소리전자 웹사이트 내에 숨겨 놓은 네이버 계정 탈취용 html 문서를 띄우는 정도였는데, 이제는 아예 그럴싸하게 팝업 창을 만들어 낸다. 다소 과격한 발상이지만 인터넷보호나라 같은 곳에서 이런 웹사이트를 강제로 차단하면 어떨까 하는 생각을 잠깐 해 보았다. 

Mendeley Desktop은 더 이상 다운로드할 수 없다 - Mendeley Reference Manager로 변화하는 과정

다운로드한 논문 PDF 파일 정리를 위해 Mendeley Desktop을 열었더니 다음과 같인 메시지가 나타났다. 9월 1일부터 Medeley Desktop 다운로드가 불가능해진다고 한다.

Mendeley Desktop will no longer be available for download from 1st September 2022. As you have Mendeley Desktop installed you will still be able to sign in and use it as normal after this date. For more information sett https://blog.mendeley.com

멘델레이 블로그를 방문해 보니 다음과 같은 글이 최신 글로 올라온 상태였다. 2월 22일에 게시된 글이다. 거의 4개월 동안 이 블로그에는 새 글이 없었다는 뜻이다.

Introducing Medeley Reference Manager - designed for today's researcher workflow

드디어 Medeley가 EndNote를 넘볼 준비를 하려는 모양이다. 많은 학술지가 EndNote 형태의 레퍼런스 스타일 파일을 제공하고 있으며, Microsoft Word 안에서 'add-in' 기능을 사용하여 아주 쉽게 포매팅을 할 수 있다. 이제 Mendeley에서도 Meneley Cite라는 add-in을 제공한다고 한다.

PDF 파일을 관리할 때에는 Mendeley가 훨씬 편했었고, 논문 작성을 하면서 PubMed에 온라인으로 접속하여 참고문헌을 뽑아 삽입할 때는 EndNote가 유리하였다. 그렇다면 Medeley Cite에서는 EndNote의 'Cite While You Write(CWYW)'와 같은 기능을 제공하게 될 것인지? 혹은 내가 보유한 PDF 파일 - 즉 나의 Mendeley library에 존재하는 파일 - 에 대해서만 참고문헌으로서 정리를 해 주는 것인지? 

Getting started with Mendeley Cite에 의하면 아직 CWYW 기능에 상응하는 것은 구현되지 않은 것 같다. CWYW가 비록 논문을 쓸 때 대단히 편리한 기능인 것은 맞지만, 참고문헌 전문을 읽어보지 않고 단지 PubMed에서 초록 정도만 확인하고 인용하는 게으른 버릇을 고칠 필요는 있다. 단지 그 자료가 유명한 저널에 실렸기 때문에, 또는 그 자료를 내가 참고한 다른 논문에서 참고문헌으로 인용했기 때문에 단지 타성에 의해서 나도 인용한다는 것은 약간 부끄러운 노릇임을 솔직하게 고백한다.

서울대 AI 연구팀의 표절 논문 사건으로 학계가 시끌벅적하다.

"결국 터질게 터졌다"...서울대 AI 연구팀의 민낯

다른 기사에 의하면 제1저자가 camera-ready(최종본)를 대폭 바꾼 것이라고 윤 교수가 말했다고 한다. 그의 말에 따르면 학술대회 발표 승인이 난 뒤에 이런 일을 했다고 하니 이해가 잘 되지 않는 행위이다. 곧 열릴 연구진실성위원회에서 잘잘못을 가릴 것으로 믿는다.

논문 한 편을 만들어내는 작업은 참으로 고단한 과정이다. 실수가 있어서도 안 되고, 올바르지 않은 방법을 동원해서도 안 된다. 대충 편하게 마무리하려는 유혹과도 싸워야 한다. 더욱 어려운 것은 논문을 혼자 쓰는 일은 별로 없다는 것. 나 혼자 모든 것을 컨트롤하기가 곤란하다.

2022년 6월 24일 금요일

KMB 2022 학회 마지막 날 받은 뜻밖의 포스터 발표 장려상

한국미생물·생명공학회 국제학술대회 삼 일째 접어드는 날 아침, 발표를 듣고 있는데 갑자기 모르는 번호로부터 전화가 왔다. 포스터 발표 수상자로 선정되었으니 혹시 폐막식 때 상을 받을 수 있느냐는 것이었다. 학회 마지막 날이라서 수상자가 벌써 자리를 뜬 것은 아닌지 미리 확인하기 위함이었다.

고등학교를 졸업한 후로는 상을 받을 일이 거의 없었다. 대부분 대학원생이 포스터 발표자로서 상을 받게 되는데 머리에 허옇게 서리가 내린 중견 연구자가 포스터 발표자로 상을 받다니... 한국연구재단의 안내에 의하면 중견 연구자는 박사 학위 취득 후 10년이 경과한 사람이다. 이러한 기준을 따른다면 나는 박사 학위를 받은 뒤 무려 25년이 지났다. 정부출연연구소 소속 기준으로 정년 퇴직이 10년 미만으로 남았다.


시상식 사회를 보던 연세대 반용선 교수로부터 '수상자 중에 나이가 많은 분도 계시네요'라는 농담 섞인 말을 들으며 학생들 틈에서 쑥스럽지만 상장을 받았다. 수십 명의 수상자가 한꺼번에 단상에서 사진을 찍을 때에는 학회장 이정기 교수님의 배려로 바로 곁에 설 수 있었다. 쑥스럽고도 유쾌한 추억을 하나 남기게 되었다. 혹시 나를 잘 아는 포스터 심사위원의 '장난(?)'은 아니었을까 하는 생각도 하면서.

첫날 개회사를 하시던 학회장 이정기 교수님.

보통 학술대회 포스터라면 대학원생이나 연구원이 실험한 결과를 정리하여 직접 포스터를 작성하여 저자 이름 중에서 맨 앞에 위치하게 되고, 현장에서 발표를 진행한다. 그리고 전 과정을 지도 감독한 지도 교수가 맨 뒤에서 교신 저자로 자리잡게 된다. 이번에 상을 받은 내 포스터는 다른 연구원이 만든 실험 결과를 넘겨받아 생명정보학적 분석을 실시하여 내가 직접 포스터를 만들었다. 기본 가설을 세우기 위하여 NCBI에서 천 개 이상의 미생물 유전체 서열을 다운로드하여 분석 결과를 만들기도 하였다. 포스터를 만들자고 제안한 것도 나였고, 저자 목록의 중간을 차지하던 연구원과 UST 학생은 나의 동료일 뿐이다. 나는 그 동료들을 지도한다고 생각해 본 적이 한 번도 없고, 그 UST 학생의 지도 교수도 아니다. 보통의 대학에서 연구 활동이 벌어지는 구조와는 사뭇 다르다. 물론 내가 일하는 곳은 UST 캠퍼스의 하나인 것은 맞지만, 내가 2018년부터 2년 동안 기업 파견을 다녀오면서 UST 겸임교원을 그만 둔 이후 재임용 신청을 하지 않았다.

아직까지는 내가 제1저자로서 논문이나 포스터를 쓸 수 있다는 것에 대해 자부심을 느끼고 있다. 그러나 후학을 양성하여 그들로 하여금 좋은 연구를 하게 만들고 연구 과제 등을 통해 아낌없는 서포트를 하는 것이 현 시대가 필요로 하는 진정한 '중견 연구자'의 모습이라는 생각이 많이 든다. 물론 후배 연구자를 키워나가는 방법은 대학과 정부출연연구소가 매우 다르다. 이전부터 존재하던 학연 제도, 그리고 UST라는 비교적 최근에 만들어진 제도를 통해서 정부출연연구소는 대학의 형식을 따라가려고 애를 쓰지만 결코 같아질 수도 없고, 같아져서도 안 된다. 나는 이렇게 '잘 만들어진' 제도를 제대로 이용하지도 못했으며, 나를 돋보이게 애를 쓰지도 않았고, 그저 자유로운 영혼으로 연구를 즐기며 살아왔던 것 같다. 사람들을 규합하고 큰 일을 꾸미는 능력, 추진력, 그리고 내가 아무리 독학으로 따라잡으려 애를 써도 잘 되지 않는 (bio)informatics 분야의 분석 결과를 수월하게 쏟아내는 연구자들의 발표를 2박 3일 동안 들으며 과연 나는 어떤 경쟁력을 갖추고 이 분야의 발전에 기여를 할 수 있을지 많은 반성을 하였다. 아니, 단 한 점이라도 의미 있는 흔적을 남길 수 있었으면 좋겠다.

1,800명 정도가 사전 등록을 한 대규모의 학술행사를 성공적으로 마치기 위해서 애를 쓴 학회 관계자와 봉사자, 그리고 후원 업체들에게 이렇게 개인 블로그로나마 고마운 마음을 전한다.

태평양 건너편의 해외 석학이 온라인으로 실시간 기조 연설(plenary lecture)을 하고 있다. 오디오 상태도 매우 완벽하였다. 참으로 놀라운 세상이다. 


굿바이, HICO!


2022년 6월 22일 수요일

경주에서 완성한 Roary 매뉴얼

제49회 한국미생물·생명공학회 국제학술대회 및 정기학술대회에 참석하기 위해 경주화백컨벤션센터(HICO)를 찾았다. 본격적인 장마를 하루 앞두고 무척이나 덥고 습한 날씨가 기승을 부리고 있었다.

HICO 앞마당에서.

EMBL Peer Bork 박사의 발표 "Analyzing Microbiomes for Human and Plenatary Health" 이렇게 좋은 아이디어를 갖고서 대규모 연구를 하니 우리는 뭘 하지?

이번에 받은 가방은 마음에 든다. HICO에서 실시하는 설문조사에 응하고 휴대폰 거치대를 얻었다.

일정을 조금 일찍 마치고 숙소로 돌아와서 쉬면서 위키 사이트에 수일 동안 써 오던 Roary 설명서를 완성하였다. Pan genome analysis pipeline인 roary는 2015년에 논문으로 공개된 뒤 지금은 거의 업데이트가 이루어지지 않는다. 그도 그럴 것이 더 이상 개선할 여지도 없다고 생각한다. Roary는 내가 가장 즐겨 사용하는 생명정보학 프로그램 중 하나이지만, 그 기능을 완벽하게 이해하는 것도 아니었다. 별도로 Word 파일로 만들어서 계속 수정해 나가고 있는 나의 유전체 분석 매뉴얼에서 roary는 매우 큰 비중을 차지하고 있으나 늘 부족함을 느끼고 있었다. 위키 사이트에 작성한 매뉴얼은 아예 이 Word 파일을 참조하지 않고 거의 새로 쓰다시피 하였다. 정확하게 말하자면 방문자를 위한 친절한 입문서는 전혀 아니다.

Roray는 GFF3 파일을 대상으로 pan genome(core + accessory)를 계산하여 매우 다양한 형태의 결과 파일을 만든다. 부속 스크립트를 이용하여 각종 수치를 시각화해 주기도 하고, 유전체(구체적으로는 GFF3 파일) 단위의 operation을 할 수도 있다. 기본적으로 gene cluster ID를 반환하지만, 아미노산 서열을 뽑아내는 것도 가능하다. 내가 만든 매뉴얼의 후반부에서는 roary 결과물을 이용하여 GFF3 파일로부터 지정된 cluster ID에 해당하는 유전자의 염기서열을 추출하는 방법을 설명하였다. 이는 roary 자체 및 부속 스크립트의 기능으로 해결되지 않는다.

매뉴얼을 작성하면서 CSV(comma-separated values) 파일을 다루는 유틸리티 중 하나인 csvkit를 알게 되었고, 'seqkit grep' 명령어를 사용하여 ID의 정규 표현식에 의한 서열 추출 방법도 익히게 되었다. Lorance Stinson의 AWK CVS parser는 상당히 도전적인 과제가 될 것이다. AWK를 복잡한 스크립트로 쓰는 것도 모자라서 함수까지 만들어 사용하다니! xsv는 csvkit보다 더 나아 보이는데, 내가 아는 리눅스 시스템에서 설치하기가 조금 까다롭다. Nix/NixOS? Rust? Cargo? 이것이 다 무엇인가? 우분투 22.04 LTS에서 xsv를 설치해 보니 희한한 곳에 binary를 만들어 놓는다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ sudo apt install cargo
$ cargo install xsv
...
  Installing /home/hyjeong/.cargo/bin/xsv
   Installed package `xsv v0.13.0` (executable `xsv`)
warning: be sure to add `/home/hyjeong/.cargo/bin` to your PATH to be able to run the installed binaries
$ ~/.cargo/bin/xsv
xsv is a suite of CSV command line utilities.

Please choose one of the following commands:
    cat         Concatenate by row or column
    count       Count records
    fixlengths  Makes all records have same length
    flatten     Show one field per line
    fmt         Format CSV output (change field delimiter)
    frequency   Show frequency tables
    headers     Show header names
    help        Show this usage message.
    index       Create CSV index for faster access
    input       Read CSV data with special quoting rules
    join        Join CSV files
    sample      Randomly sample CSV data
    search      Search CSV data with regexes
    select      Select columns from CSV
    slice       Slice records from CSV
    sort        Sort CSV data
    split       Split CSV data into many files
    stats       Compute basic statistics
    table       Align CSV data into columns

Roary 말고도 몇 가지 주제에 대한 매뉴얼 작성 거리를 머릿속에 쌓아두고 있다. 너무 늦어지지 전에 해결해야 되는데...



2022년 6월 17일 금요일

학술논문 출판에서 scooping을 어떻게 막을 것인가? - ASM Journal의 새로운 정책

구글에서 영단어 'scoop'의 정확한 의미를 찾아 보았다. 국어에는 이것과 정확히 일치하는 낱말은 없다.

팝콘이 담긴 스쿠프 사진은 Pixabay에서 내려받은 것(Pixabay license - free for commercial use)


공들여 연구한 내용을 학술논문으로 정리하여 이제 막 투고를 하고 심사 중인데, 별안간 같은 주제의 논문이 다른 학술지에서 먼저 발표된다면 이처럼 맥이 빠지는 일은 없을 것이다. 대부분의 경우는 우연의 일치일 것이다. 생명과학 분야에서 한창 떠오르는 주제라면 이를 연구하는 사람이 전 세계에 어디 나 혼자뿐이겠는가? 어떠한 아이디어를 확인하기 위해 A라는 모델 생명체에서 연구를 진행하여 논문을 투고하고 심사 과정에 있는데, 다른 연구팀에서 동일 또는 유사한 주제를 B라는 모델 생명체에서 연구하여 오늘 갑자기 논문을 출판했다고 치자. 이러한 사실을 리뷰어가 알게 되면 내 논문이 무사히 출판될 가능성이 적어질 것이 자명하다. 

어디서 주워 들은 이야기를 하나 소개해 본다. 리뷰어가 투고자 A의 논문을 유난히 오랫동안 심사를 하면서 시간을 끌고, 그 사이에 그 논문의 아이디어를 이용하여 리뷰어 자신(혹은 잘 알고 지내는 다른 연구자?)이 별도로 실험을 진행하여 재빨리 논문을 먼저 낸 다음, 비슷한 연구 결과가 이미 발표되었으니 A의 논문을 출판에 적합하지 않다고 거절하는 것이다. 이는 사실 범죄에 가까운 행위이다. 실제로 이러한 일이 얼마나 존재하는지는 모르겠으나, scoop의 아주 나쁜 사례이다. 대부분의  scooping은 경쟁적인 연구 분야에서 우연의 일치로 벌어지는 것으로 보아야 할 것이다.  

ASM(American Society for Microbiology)에서 New Scooping Protection Policy라는 제목의 이메일을 보냈다. 이 정책과 관련된 웹사이트는 이곳이다. ASM 학술지에 투고를 한 경우, 그보다 앞서 6개월까지 유사한 논문이 발표되거나 preprint로 공개되었는지를 점검해 준다는 것이다. 어찌보면 이는 논문 투고를 준비하는 저자가 사전에 꼼꼼히 점검해야 할 일인지도 모른다. 이 정책을 음미해 보자면 투고자를 위해 scooping을 방지해 주는 것이 아니라, 아주 최근에 이미 다른 연구자에 의해서 논문으로 공개된 것과 유사하거나 일치하는 연구 결과를 ASM에 또 투고하는 헛짓거리를 하지 말라는 것 아닌가?

이는 저자를 scoop에서 보호하는 것이 아니라 저널을 보호하기 위한 정책에 더 가까워 보인다. '누가 가장 먼저 했는가?'는 학문 분야뿐만 아니라 모든 분야에서 누구나 다 중요하게 여기고 기억하는 기준이 된다. A라는 저널에 어떤 연구 결과가 먼저 발표되고, 뒤이어서 B라는 저널에서 이와 유사한 것이 발표된다면(B에 논문을 투고한 저자나 리뷰어 모두 A 저널에 유사한 연구 결과가 앞서서 발표된 것을 미처 모르는 상태에서), A 저널에 실린 논문의 인용 가능성이 더 커진다. 임팩트 팩터 또는 여러 가지 지표료 매겨지는 학술지의 순위에서 A << B가 아니라면 말이다.

누구나 쉽게 정보를 찾아볼 수 있는 시대가 되었으므로 '미처 모르고 있었다'라는 변명을 하기는 점점 더 어려워진다. 나의 독창성을 검증하기 위해 미리 검토해 봐야 할 정보의 범위가 너무나 넓어지고 있으니 삶의 피로도 역시 높아진다.

2022년 6월 16일 목요일

로드 자전거의 튜브 상태가 예사롭지 않다

모름지기 기계나 도구는 쓰지 않으면 망가진다. 사람이 살지 않는 집이 금방 망가지는 것처럼. 자전거도 예외가 될 수 없다. 저녁에 집 근처 1 km 정도 떨어진 식당에서 모임이 있어서 차는 집에 세워두고 오랜만에 자전거를 타고 1 km 정도를 이동해 보려고 계획하였다. 펌프를 집어들고 바람을 채우는데 공기가 새는 소리가 들린다. 앞바퀴는 타이어 옆면에서, 뒷바퀴는 밸브 근처에서...

아마 튜브가 팽창하지 않은 상태로 몇년을 방치하다 보니 튜브가 눌리고 접힌 곳에 손상이 발생한 것 같다. 대부분은 수선 가능하지만, 밸브 근처에서 튜브가 뚫리면 손을 쓸 수가 없다. 어쩌면 앞뒤 튜브를 전부 교체하는 것이 현명할 것이다. 

브레이크 선의 당김을 해제하고, 휠을 분리하고(QR이라서 어렵지는 않음), 타이어를 힘겹게 분리하고, 튜브를 교체하고... 손에 시커멓게 기름때를 묻혀가며 작업할 생각을 하니 벌써부터 한숨이 난다. 어휴...

일단 교체용 튜브를 몇개 구입해 놓는 것에서 출발하자. 

2022년 6월 10일 금요일

펄(Perl) 뻘짓 - pod를 이용한 펄 스크립트의 매뉴얼 작성

Pod(plain old documentation format, 링크)를 이용하여 펄 스크립트의 도움말을 만들어 보았다. Pod는 펄 프로그램이나 모듈의 documentation에 쓰이는 간단한 마크업 언어이다. 코드 내부에 문서를 직접 작성한다는 것이 특징인데, 코드가 아닌 텍스트 정보만을 저장한 .pod 파일을 만들어 활용할 수도 있다. 순수한 pod 문서의 사례는  리눅스 배포본이라면 다 갖고 있을 /usr/share/perl5/pod/perlpod.pod 파일(펄 안내서)을 참조하면 된다. 이 파일을 확인하려면 리눅스 명령행에서 'perldoc perlpod'를 입력하자. 이 문서(perlko)의 한글판은 여기에 있다.

코드 내부에 작성해 넣는 문서는 어떤 용도인가? 당연히 그 코드의 설명을 위한 것이다. 가령 펄에서 '#'로 시작하는 줄(주석)은 인터프리터가 해석하지 않고 지나가므로, 코드의 특정 부분을 설명하는 용도로 쓰인다. 그러나 이러한 방식의 정보는 코드를 텍스트 편집기로 열어야만 보인다. Pod는 코드 안에 작성되지만 실행을 통해서 화면에 일정한 형식을 갖추어 보기 좋은 형태로 뿌려진다. 따라서 코드의 설명서를 별도로 작성하는 수고를 덜어준다. 한글 Perl Maven 웹사이트의 Pod 소개문을 읽어 보면 개념을 잡는데 도움이 될 것이다.

요즘 가장 인기 있는 마크업 언어는 아마도 간단하고 문법이 쉬운 경량의 Markdown이 아닐까 한다. LaTeX도 마크업 언어의 일종으로 간주된다. 생명과학 전공자로서 LaTeX으로 학위논문을 썼던 나도 상당한 수준의 '뻘짓러'가 아니었을까? 도대체 왜 그랬었지?

엇, perlko 문서의 저자에 '신정식'이란 이름이 보인다. 현재 구글의 소프트웨어 엔지니어로 일하는, 내가 아는 그 Jungshik Shin이 맞을 것이다. 그는 인터넷의 한글화에 큰 공헌을 했던 것으로 알고 있다. Nerd와 Geek가 득실거렸던 대학교 1학년 때의 기숙사가 생각난다. 신정식과는 몇 개의 수업을 같이 들었었던 것 같다. 

펄 스크립트 또는 모듈 내에 심은 pod 문서를 보려면 'perldoc <script명>'을 입력하는 것이 일반적이다. 그러나 도움말을 보기 위하여 다른 명령어를 또 불러야 한다는 것이 성가시다. 그래서 명령행에 인수가 없거나 혹은 '-h' 또는 '--help'라는 단일 인수가 주어졌을 때 내부적으로 'perldoc <스크립트>'를 실행하여 스크립트 내에 심어놓은 도움말이 출력되게 하였다. 명령어 바로 뒤에 연달아 입력하는 문자열을 option, switch, flag, argument 등으로 세분해야 한다고 믿는 사람도 있겠지만, 그건 별로 중요하지 않다.


Pod 공식 설명 문서만으로는 그 문법을 이해하기가 어려워서 Bio::Seq.pm을 편집기로 열어서 실제 사례를 참조하였다. Bio::Seq 파일의 위치를 알고 싶다면 다음과 같이 입력한다. Bio와 Seq 사이의 연속된 콜론 두 개는 디렉토리('/')를 의미한다. 따라서 Bio::Seq.pm 모듈 파일의 실제 이름은 Seq.pm이다. 'perldoc -l Bio::Seq.pm'이라 입력해도 결과는 같다.

$ perldoc -l Bio::SeqIO
/usr/local/share/perl5/Bio/SeqIO.pm

기술 문서를 마크다운으로 배포하는 것은 이상할 것이 없지만, 요즘 분위기에서는 pod 파일로 배포하기는 적합하지 않다. 그저 펄 스크립트 내에 심어서 설명 용도로 쓰는 것이 최선일 것이다.


2022년 6월 16일 업데이트

Bash 스크립트 내에 POD-like documentation을 삽입하는 방법도 있다. 매우 유용한 팁이 아닐 수 없다. 다음에 소개할 문서는 2007년에 작성된 매우 오래된 것이다.


그런데 O'Reilly에서 발간한 Bash Cookbook에도 이미 Embedding Documentation in Shell Script라는 문서가 있다. 여기에서는 스크립트 내에서 =pod라는 태그를 쓰지 않는다. 두 문서 모두 연구해 볼 만한 가치가 있다.

2022년 6월 9일 목요일

뻘짓의 지평을 넓혀야 인생이 풍부해진다 - 자전거 이야기

'뻘짓'은 허튼짓을 뜻하는 전라남도 사투리라고 한다. 결코 비속어가 아니다. 비슷한 의미의 낱말로 '삽질'을 떠올리게 되는데, 근원이 불확실하여 별로 쓰고 싶지 않다.

젊어서 철이 없을 때 되도록 많은 뻘짓을 해 봐야 한다. 그러면 나중에 나이가 들어서 '뻘짓'을 재발견하면서 새로운 재미를 느끼게 될 것이다. 뻘짓은 창조적 정신의 원천이다! 내가 경험했던 다양한 뻘짓 중에 자전거 관련 취미가 있다. 2000년대 초반에 출퇴근 길에 열심히 달렸던 자전거가 복도 계단에 자물쇠로 묶인 상태로 벌써 몇년이 흘렀는지 기억이 나지 않는다. 자전거에 관한 이야기는 구글 블로그를 쓰기 전, 네이버에서 운영했던 블로그(2005-2015)에 대부분 존재한다. 네이버 블로그는 중간에 한번 탈퇴를 거치는 바람에 PDF 백업본 파일로만 남았다.

자전거 감옥. 약 10년 째 수감 중? 바람이 빠진 타이어는 옆면에 균열이 보이기 시작했고 계단에 눌린 상태라서 아마 내부의 튜브도 유착이 발생했을 것이다.

휘발유 가격도 크게 올랐고, 평소에 운동을 거의 하지 않는 나의 생활 습관을 그대로 두고 볼 수는 없어서 다시금 자전거 출퇴근에 관심을 가질까 생각한다. 매일은 어렵더라도 일주일에 두 번 정도라는 목표를 세우고 다시 습관을 들이고자 한다. 출근길은 편도로 약 9 km. 자전거를 한창 타던 시절에는 일부러 KAIST쪽으로 돌아가는 편도 11 km의 코스를 비가오나 눈이오나 매일 달렸었다.

나의 자전거는 생활형 로드 자전거(삼천리 랠리)이다. 한때 유명했던 입문 수준의 로드 자전거 랠리가 아니란 뜻이다. 일명 '도싸' 그리고 '발바리'로 알려진 커뮤니티에서 무료·중고 부품을 구입하여 순전히 재미로 조금씩 업그레이드를 하여 지금에 이르렀다. 브레이크 레버는 Cane Creek(신품), 뒷디레일러는 알리비오, 크랭크셋과 BB는 캄파뇰로... 겨우 2 x 6(카세트 스프라켓이 아니고 프리휠!)단 구식 기어에 퀼 스템에 고정하는 변속레버를 쓰는 주제에 온갖 기괴한 조합의 부품을 갖다가 붙였다. 리어 액슬은 거저 얻은 부품을 이용하여 QR용으로 바꾸었다.



내 자전거의 가장 아름다운 모습은 바로 크랭크셋에 있다. 휠셋은 로드 자전거의 표준인 700C가 아니고 '구식 사이클'에 널리 쓰이던 27인치이다. 내기억이 맞다면 ISO 630 규격이다. 

이탈리아에서 온 캄파뇰로!

 

개인이 할 수 있는 자전거 정비와 부품교체도 해 보지 않은 것이 없을 정도로 경험을 쌓았었지만 10년 가까이 이 '뻘짓'을 잊고 살았더니 이제는 기억이 잘 나지 않는다.

이것이 전부가 아니다. 나에게는 700C 통타이어(tubular tire)용 휠세트도 한 조 있다. 7단 카세트를 달고 있는 뒷쪽 휠의 허브를 살펴보면 현 울테그라의 전신인 Shimano 600'이라는 마킹이 보인다. 이 휠셋을 쓰기 위하여 트랙 경기 후 벗겨낸 튜블러 타이어를 싸게 팔던 것을 커뮤니티 회원과 한번에 구입하여 나눈 일도 있었으니... 겨우 하루에 20 km 남짓한 거리를 달리면서(주말 장거리 주행은 해 본 일이 없음) 부품 교체 장난질은 왜 이렇게 많이 하였는지, 지금 생각하면 정말 뻘짓이 맞다. 

하루에 20 km를 달리면서 출퇴근을 했다면 매주 100 km요, 세 달이면 1,000 km가 넘는다. 몇 년 동안 이 짓을 했으니 따지고 보면 적은 주행 거리는 아니다.

다시 자전거 출퇴근을 개시하려면 고칠 것이 많다. 이것 말고도 미니벨로가 하나 더 있는데, 타이어의 현 상태는 더욱 열악하다.

나에게 인터넷을 통해 자전거에 대한 엄청난 지식을 선사했던 전설적인 자전거 미캐닉 고 Sheldon Brown(1944-2008)에게 경의를 표하는 바이다. 구글 검색창에서 Sheldon Brown 또는 '셸던 브라운'을 입력하면 영문 위키피디어에서 자동으로 번역된 정보 말고는 한글로 된 정보가 전혀 나오지 않는다. 

뻘짓의 재발견은 계속된다. 다음 순서는 아마도 천체 망원경이 아닐런지...

[Perl] 텍스트 파일을 'chunk' 단위로 읽어들이기

chunk는 '큰 덩어리'라는 뜻이다. Perl을 이용하여 텍스트 파일을 읽어들일 때, 보통은 while 루프를 이용하여 줄 단위로 하나씩 읽어서 순차적으로 처리하게 된다. 그러나 어떤 분리자를 경계로 하여 구분된 여러 라인의 덩어리를 단위로 삼아서 변수로 읽어들이고 싶을 때도 있을 것이다. 예를 들어서 EMBOSS primersearch 프로그램의 결과 파일을 살펴보도록 하자. 다음에 보인 그림은 9개 프라이머쌍의 정보를 담고 있는 파일을 이용하여 하나의 FASTA file을 뒤져 amplimer를 탐색한 결과이다. 인간이 읽고 이해하기에는 쉽지만, 컴퓨터로 하여금 결과를 집계하도록 만들려면 매우 불편하다. 특히 수백 혹은 그 이상의 FASTA file에 대하여 primersearch를 돌렸다고 가정해 보자. 


언제 어떻게 활용될지 몰라서 프라이머 염기서열은 일단 가렸다. FASTA 파일 하나에 대해서 하나의 결과 파일을 쓰게 할 수도 있고, 여러 FASTA 파일에 대한 탐색 결과를 하나의 결과 파일에 몰아서 기록할 수도 있다. 후자의 방법을 이용하려면, 결과 파일 내에 입력 FASTA 파일에 따른 구분자를 넣을 수도 있다. 여러 FASTA 파일에 대한 탐색 결과를 처리하는 더 미련하고 복잡한 방법도 얼마든지 고안할 수 있다.
  

한 쌍의 프라이머에 대한 amplimer 탐색 결과는 빈 줄("\n\n")을 경계로 다른 결과와 구분된다. 바로 이것이 하나의 chunk이다. 이를 구현하기 위한 힌트는 StackOverflow의 Grabbing Chunks of Data from File in Perl에서 얻었다.

local $/ = "\n\n";

open LOG, $ARGV[1];
while ( $chunk = <LOG> ) {
   # do something on $chunk
}

결국은 "\n"을 경계로 하여 $chunk 변수를 분할하여 세부적인 작업을 해야 된다. 그러나 이렇게 하는 것이 편한 이유는, chunk 단위가 하나의 프라이머 쌍에 대한 '모든' amplimer 예측 결과에 해당하기 때문이다. 

Multi-record GenBank 파일은 '//'로 개별 단위가 분리된다. 오늘 알아본 방법을 통해서 GenBank 파일을 chunk 단위로 처리할 생각은 '1'도 없다. chunk 내의 구조가 워낙 복잡하기 때문이다. 꼭 필요하다면 csplit 유틸리티를 써서 각 레코드를 물리적인 파일로 나누어 버리는 것이 더욱 현명하다. 다음은 실제 응용 사례이다. 코드가 약간 난해하다! 아니, 난해할 것은 없다. 파일 분리자로 사용할 '//'를 정규표현식으로 나타낸 것에 불과하다. 맨 뒤의 '{*}'가 어떤 의미인지 알기가 좀 어렵다. csplit의 매뉴얼에 의하면 'repeat the previous pattern as many times as possible'이다. 'find ... -exec' 명령어에서 맨 뒤의 '\;'도 이해하기 쉽지는 않다. Bash 환경에서 {}, (), \, ; 등이 나오면 본능적으로 긴장을 하게 된다.

csplit --prefix=test ../genome.gbk '/^\/\/$/' '{*}'

리눅스 bash 환경에서 출현하는 특수한 문자 중 나를 가장 긴장하게 만드는 것은 바로 GNU parallel 유틸리티의 고급 용법이다...

BLAST parser 따위는 제발 짜지 말라는 글(Mad Scientist)이 기억났다. 과거에 BioPerl을 이용하여 human readable 형태의 BLAST 결과 파일을 파싱하는 코드를 짰던 적은 있다. 그 이후에 Zerg를 한동안 사용했었다. 잠시 추억에 젖어서 찾아보니 Zerg는 2003년에 나온 프로그램이다(논문 링크). 지금은 tabular output을 지정하면 되니 되므로 특별히 parser를 쓸 필요가 없다. Alignment를 반드시 눈으로 봐야 한다고 고집하지 않는다면 말이다. 2000년대 초반의 blastall 프로그램이 tabular output을 제공하지 않았었던가? 기억이 나지 않는다.

이러한 명령행 환경의 자료 조작 업무를 이제는 전부 Python으로 대체해 나가야 할까? 장기적으로는 그것이 정답일 수 있는데, 자꾸 손은 Perl Cookbook을 향하고 있으니...

2022년 6월 8일 수요일

세상은 넓고 공부할 것은 많으며 들을 음악도 많다

넷플릭스를 뒤적거리다 <영광의 깃발(원제: Glory)>이라는 1989년도 미국 영화를 보게 되었다. 남북전쟁에서 흑인들로만 구성된 부대(제54매사추세츠 의용보병연대)와 그 지휘관인 실제 인물 로버트 굴드 쇼(Robert Gould Shaw, 1837-1863)의 이야기이다. 노예 신분을 갓 벗어난 흑인들이 - 노예 제도를 허용하지 않던 북부에 살아서 그랬을 수도 있고, 남부에서 노예 생활을 하다가 탈출한 상태였을 수도 있음 - 군대에 자원해서 실제 전투에 가담한다는 것은 당시로는 매우 획기적인 일이었을 것이다. 영화의 마지막을 장식하는 와그너 요새 공격에서 비록 대패하였지만, 이들의 용맹은 더 많은 흑인이 남북전쟁에 참전하게 만드는 계기가 되었다고 한다. 전 부대원이 가로로 길게 늘어서서 전혀 엄폐도 하지 않은 채 적진을 향해 일제히 총을 쏘는, 매우 위험하고 비능률적인 전투 대형을 보고 의아하게 생각하다가 이 전쟁이 미국인들에게 어떤 의미를 갖는지 찾아보게 되었다. 1·2차 세계대전과 6·25 전쟁에 참전했던 미군보다 더 많은 사람이 남북전쟁 때 희생되었다고 한다. 그럼에도 불구하고 이 전쟁은 하나의 미국을 만들어 나가는 값진 전쟁으로 미국인들 가슴 속에 남아 있는 것 같다.

로버트 굴드 쇼와 매사추세츠 54연대 기념 부조. 출처: 미국 National Park Service.

남북전쟁에서 큰 전환점이 되었던 게티즈버그 전투(1863년)을 재연하는 행사는 지금도 인기가 있는 것 같다. 행사 참가자는 북군이든 남군이든 원하는 역할을 맡을 수가 있다. 그런데 만약 우리가 6·25 전쟁의 특정 전투를 재현하는 행사를 갖는다면? 결국 이 전쟁을 통해 어느 쪽으로든 통일이 이루어지지 않았기 때문에, 북한군의 역할을 맡고 싶은 '한국인'은 아무도 없을 것이다. 미국의 남북전쟁 재연 행사가 백인 중심의 시각으로 재구성된 역사를 미화하는 일이라는 비판도 있다고 한다.

미 남북전쟁 재연행사 "역사 보존" vs "백인중심 추종" 논란(2019년 6월 25일 한경 기사 링크)

앞으로 보름 남짓이면 6·25 전쟁 발발 72주년을 맞지만, 아직도 이 전쟁의 원인과 성격에 대해서 완벽한 정의를 내리기가 어렵다. 심지어 모스크바 3상회의에서 한반도의 신탁통치에 관한 결론이 당시 국내에 잘못 보도되었다는 것도 최근에야 알게 되었다. 소련이 신탁통치를, 미국은 즉시 독립을 주장했다는 국내 신문사의 보도는 완전한 오보였다고 한다. 이것이 단순한 오보인지, 혹은 어떤 정치적인 의도를 가지고 일부러 사실과 다르게 보도했는지는 알 수가 없다. 이 잘못된 보도로 말미암아 국내에는 맹렬한 반탁운동이 일어나게 되었고, 결과적으로는 분단의 고착과 나아가서는 동족 상잔의 비극인 6·25 전쟁까지도 이르게 된 것이다.

동족 상잔이라는 면에서 미국의 남북전쟁이나 한반도의 6·25 전쟁은 다를 것이 없다. 그런데 왜 전자는 하나의 국가를 만들어 나가는 성장통이었고, 후자는 있어서는 안될 비극이자 그로 인한 서로간의 적대감을 아직까지 해소하지 못한 상태로 갖고 있어야 하는가? 전쟁이 끝난 뒤 흐른 시간이 달라서? 통일이 이루어지지 않았기 때문에?

6·25 전쟁을 제대로 아는 것이 아직도 쉽지 않다. 내전인가? 강대국 사이의 대리전인가? 일제에 나라를 빼앗기고 급변하는 세계 정세에 자주적으로 준비하지 못한 우리의 책임은 없는가? 2014년 프레시안에 실렸던 기사 '6·25 전쟁'도, '한국전쟁'도 틀렸다를 매우 흥미롭게 읽었으나 링크 접속이 현재 원활하지 않아서 유감이다.

국가 사이의 갈등이 가장 폭력적으로 표출되는 것이 바로 전쟁이다. 역설적으로 전쟁은 새 질서를 만들기도 하고 기술의 극적인 발전을 유발하기도 한다. 또 어떤 사람들에게 전쟁은 둘도 없는 비즈니스 기회가 된다. 그렇다고 하여 전쟁을 장려할 수는 없는 노릇이다. 폭력이라는 인간의 내재적인 속성을 잘 다스려서 이를 전쟁이 아닌 다른 방식으로 승화해야 한다.

두 번째 주제인 음악 이야기로 넘어가자.

음악을 꽤 좋아하면서도 '이러한 거물 음악가를 아직 모르고 있었단 말인가?'하는 생각이 들 때가 많다. 유튜브를 통해 미처 몰랐던 곡을 들으며 감동에 빠지다가도, 내가 참으로 체계 없이 음악을 듣고 있었다는 자괴감 비슷한 것을 느낄 때가 많다. 칼라 블레이(Carla Bley)라는 1936년생 재즈 뮤지션을 알게 된 것은 불과 이틀 전. 그녀는 2018년 자라섬 재즈 페스티발에 참여하기도 하였다.

Carla Bley(사진 출처 링크)

"니 칼라 블레이 들어봤나"...90년대 음악애호가들의 단골멘트(매일경제 2021년 1월 9일 기사 링크)

(1987년 앨범 'Sextet'에 담긴 'Lawns'라는 곡은) 이후 이 곡은 음악 좀 듣는다는 뮤지션들이 라디오 음악 방송에 나와서 '이 곡 잘 모르셨죠'하는 느낌으로 소개하는 대표곡이 됐다.

다음 유튜브 동영상은 Carla Bley와 Steve Swallow의 <Lawns> 연주이다. 그렇다! 난 이틀 전까지 이 곡을 들어 본 일이 없었다. 존 콜트레인은 알면서 칼라 블레이를 모르면 무식한 건가? 아직도 찾아 들을 새로운 음악이 많다는 것을 오히려 다행으로 여기자.

 


2022년 6월 5일 일요일

계룡산 오르기(삼불봉)

지나친 운동부족 상태로 나이만 먹어가는 것은 옳지 않다는 생각이 들어서 아내와 함께 계룡산을 조금씩 올라가 보기로 했다. 늘 계룡산 사찰(동학사, 갑사, 신원사)과 근처 물가만 맴돌다가 지난주 은선 폭포를 시작으로 이번 주는 삼불봉에 도전하였다. 변변한 등산복이나 모자도 없는 상태에서 갖고 있는 것이라고는 경등산화 한 켤레가 전부였다. 혹시나 싶어서 쿠팡에서 최저가 등산스틱을 구입하였는데 정말 큰 도움을 받았다.

싸구려 등산스틱은 무겁고, 크고, 길이 조절이 불편하다. 손잡이 부분을 이루는 플라스틱에서는 왜 이렇게 유기용매 냄새가 나는지... 환경 호르몬이 풀풀 배어 나오고 있을 것이다. 그래도 이번 삼불봉 등산에서는 큰 몫을 했다.

우리는 등산스틱이라고 부르지만 영어권에서는 trekking pole이라고 부른다. '등산'은 하이킹(hiking), 트레킹(trekking), 그리고 마운티니어링(또는 마운틴 클라이밍 mountaineering or mountain climbing)으로 구분된다. 트레킹이라 해도 보통 이틀 이상의 코스는 되어야 그렇게 부른다고 한다. 저마다 알록달록한 등산복(반대편의 극단에는 레깅스가 있겠다)을 입고 배낭에 음료와 도시락 한끼 분량을 싸서 아침에 출발하여 저녁에 집에 돌아오는 것은 하이킹이다!

6월 4일 등산, 아니 하이킹 코스는 계룡산 동학사쪽 입구의 주차장에서 천정탐방지원센터를 시작으로 남매탑까지 2.8 km를 간 후 삼불봉에 오르는 것을 목표로 하였다. 돌아올 때에는 남매탑에서 세진정으로 곧바로 내려오는 코스를 택했다. 천정탐방지원센터를 기점으로 하면 입장료를 낼 필요가 없어서 매우 유리하다. 계룡산 국립공원 웹사이트(링크)에서 천정코스라고 부르는 이 코스는 남매탑에서 삼불봉으로 가는 편도 0.5km의 샛길을 제외하면 5.8km(3시간), 난이도 '중'에 해당한다.

지난주 은선폭포를 갈 때에는 뙤약볕이 내리쬐는 코스였지만, 이번에는 대부분 숲길이어서 매우 쾌적하게 오를 수 있었다. 여름을 위한 최적의 경로라고 해도 무방할 것이다.

등산은 기다림이다! 걷기 힘들어하는 아내를 조금 앞서 천천히 가면서 기다려 주기. 지난주에 은선폭포를 다녀와서는 장딴지가 아파서 삼사일 고생을 했지만, 이내 회복 후 단련이 되었는지 이번에는 괜찮았다.

큰 바위 앞에서. 전해져 내려오는 이름이 있지 않을까?

삼불봉을 다녀온 직후 남매탑 앞에서. 남매탑의 전설은 역사적 사실일까?

정중앙 바로 오른편의 뭉툭한 봉우리가 관음봉(766m)이다. 우리가 위치한 삼불봉보다 9미터 낮다.

엉덩이 붙일 곳을 찾기 어려울 정도로 비좁은 삼불봉에서.



발끝만 보면서 힘겹게 걷다가 탁 트인 하늘을 바라보는 기분. 이것이 산에 오르는 재미가 아닐까? 단 나이가 나이니만큼 무릎이 망가지지 않게 조심해야 한다.

언젠가는 삼불봉에서 관음봉까지 이르는 자연성릉을 따라 가리라.

남매탑에서 세진정으로 내려오는 길은 생각보다 힘들었다. 특히 남매탑에서 시작하여 첫 쉼터까지 내려오는 약 0.6km의 길은 공식 등산 안내도에도 난이도 4급(총 5급)으로 나와 있을 정도라서 등산 초보에게 쉽지 않았다. 오죽하면 그 길을 올라오는 사람에게 얼마나 더 내려가야 되느냐고 묻고 싶을 지경이었으니까. 사실 이것은 예의가 아니다. 결혼 전에 아내와 함께 이 길을 통해서 남매탑까지 올라갔던 적이 있었다. 그때는 비교적 쉽게 올랐던 것 같은데 생각해보면 돌도 씹어먹을 20대였으니 당연하지 않을까?

어느 경로를 거치든 관음봉까지 가 보는 것이 올해의 목표이다. 나 혼자라면 언제든 가겠지만, 체력이 좋지 못한 아내와 함께 오르려면 연습이 필요하다. 아내를 위해 좀 더 가벼운 등산스틱을 사야 되겠다.

긴 가뭄 끝에 오늘 꽤 많은 비가 내려서 당분간 은선 폭포에는 물이 꽤 많이 흐를 것이다.

바위 한가운데 갈라진 틈에 뿌리를 박고 사는 나무의 생명력이 대단하다.



2022년 6월 3일 금요일

논문을 출판하려면 돈이 많이 든다

논문을 내려면 생각보다 돈이 많이 든다. 연구비(인건비를 포함해야 함)가 기본적으로 들어가고, 논문 원고를 영어로 작성하여 교정을 하는 데에도 적지 않은 돈이 든다. 학술지를 선택하여 투고하면 지난한 검토 과정(review process)을 거쳐서 게재 승인이 떨어진다 해도, 최종적으로 게재료를 납부해야 정식으로 출판이 된다. 게재료는 논문 출판 기관에 따라서 천차만별이다.

논문의 저자 입장에서는 출판을 끝으로 돈이 더 이상 들지 않겠지만, 이를 읽으려는 독자는 돈이 들 수도 있고 들지 않을 수도 있다. 요즘 OA(open access)가 추세라고 한다. 이는 이용자들에게 학술정보, 논문 등을 무료로 개방하는 것이다. 그러나 출판사는 자선사업을 하는 것이 아니므로, OA로 논문을 공개하려면 저자에게 더 비싼 게재료를 내게 한다.

OA가 아닌 경우, 보통은 논문 PDF 파일 하나에 일정 비용을 지불하고 다운로드를 받게 된다. 일반 논문에 비하여 인용 횟수가 높을 것임은 자명하므로, 이에 굴복하여 큰 돈을 지불하도록 결정을 내릴 수도 있을 것이다. 만약 이용자가 소속된 기관이 해당 출판사에 꽤 큰 금액을 연 단위로 지불한 회원이라면, 이용자는 논문 이용료를 개별적으로 내지 않아도 된다. 

최근 국내 학회에서 발간하는 어느 학술지에 논문을 투고하여 심사를 거친 후 게재 승인을 받았다. 공개일자는 바로 어제. 실제 발간은 Springer Nature라는 회사에서 진행한다. 국내 학회에는 50만원의 게재료를 납부한 상태였다. 그런데 Springer Nature에서 온 안내 메일을 보니, OA로 출판하려면 무려 2,900달러를 내라는 것이었다. 납부 증명을 가져오면 국내 학회에서는 이미 냈던 돈 50만원을 돌려준다고 하였다.

2,900달러라니... 임팩트 팩터가 5를 넘는 '고급' 학술지도 아닌데 이렇게까지 할 필요가 있을까 싶어서 OA를 선택하는 것은 포기하였다. 따라서 내 논문의 PDF를 다운로드하려는 이용자는 소속 기관이 이 학술지를 구독하지 않는 경우 34.95유로, 즉 오늘 환율로 약 46,645원을 지불해야 한다. 어제 저널 웹사이트의 latest articles에서 가장 위에 자리잡은 내 논문은 전문이 공개되어 있지만, 아마 조금 뒤면 초록만 공개되는 상태로 바뀔 것이다. 한 저널에 실린 논문이 추가 비용을 냈는지에 따라서 어떤 것은 OA, 어떤 것은 돈을 주고 사서 보는 것으로 운명이 갈린다. 물론 논문을 읽으려는 사람의 소속 기관이 이 저널을 구독하고 있다면 차이가 없겠지만.

게재료가 치솟는 것이 요즘의 추세이다. 예를 들어 한국미생물생명공학회에서 발간하는 Journal of Microbiology and Biotechnology는 올해 3월 1일부터 게재료(article processing charge, 줄여서 APC 또는 출판비)를 무려 120만원으로 인상하였다. 학회 회원에게는 할인이 적용되어 70만원을 받는다. 외국인 투고자는 600달러를 내야 한다. 

논문 게재 실적이 연구자들의 승진이나 연구비 신청 경쟁에서 매우 중요한 근거로 쓰이게 되니 이를 이용하는 비즈니스가 성장하는 것을 막을 길이 없다. 다만 이를 악용하는 약탈적 학술지(predatory journal)가 자꾸 생겨나서 검증하기가 어렵다는 것이 문제이다. 이러한 현실을 비꼰 글 몇개를 인용해 본다.

MPDI나 Frontiers가 약탈적 학술지인가? BRIC 커뮤니티를 보면 이를 묻는 글이 심심찮게 올라온다. 참 판단하기 어려운 문제이다. 해당 출판사에서 만드는 저널이 분야에 따라 수십 개로 나뉘므로 여기에 모두 일률적인 잣대를 들이대기도 어렵고(IF가 있는 것도 있고 없는 것도 있고...), 단지 APC가 비싸다고 해서 모두 주의를 요하는 저널이라고 하기도 어렵다. 내가 몇번 논문을 낸 적이 있는 Frontiers in Microbiology의 현재 APC(링크)는 얼마인가? 여기도 지금은 2,950달러나 하는구나! 참고로 Frontiers 저널 전체에 대해서 나는 지금까지 총 6편의 논문을 실었었다(링크).

오죽하면 국가과학기술연구회 소속 출연연구소에서 Elsevier나 Wiley서 저널에 논문을 출판할 때 APC를 지원하겠는가. 두 회사의 평균 APC가 각각 약 3천달러와 3400달러나 된다. APC가 높은 학술지라고 해서 고급 학술지(소위 IF가 높은..)인 것도 아니니 판단은 논문 저자가 알아서 해야 될 것이다.