2019년 3월 19일 화요일

커서에 한영 상태를 표시하는 작은 도구 IMECursor v0.71

참고한 사이트는 여기이다. 타자를 치기 시작하다가 백스페이스 키를 눌러서 잘못 입력된 글자를 지운 다음 [한/영] 전환키를 누를 필요가 없다.


그런데 실제 작동을 해 보면 알겠지만, '가' 또는 'a'가 작게 표시되는 것은 마우스 포인터이지 커서 자체는 아니다. 텍스트를 입력 가능한 위치에 마우스 포인터를 올리면 현재의 한/영 상태가 표시되는 것이다.

마우스 커서? 다음의 것을 마우스 커서라고도 부르는 것 같다. 마우스 포인터가 제대로 된 명칭이라고 생각했는데 영어권에서도 이런 표현을 사용한다.


아주 간단하지만 유용한 프로그램을 알게 되어 즐겁다. 기왕이면 텍스트가 입력되는 커서를 따라 이동하면서 한/영 표시가 나오면 좋을 것이다.

2019년 3월 13일 수요일

도마 위에 진공관 앰프 꾸미기

식재료를 다듬기 위해 칼질을 할 때 밑에 받치는 물건이 도마다. 순 우리말로서, 체조 경기 종목 중 하나인 도마(跳馬)와는 아무런 상관이 없다.

나무판은 앰프 자작을 할 때 부품들을 늘어놓는 용도로 흔히 쓰인다. 하지만 일부러 나무판을 재단해 오려면 상당히 귀찮은 일이라서, 주변에서 흔히 구할 수 있는 재료로 대체하는 일이 많다. 그때 쓰이는 것이 바로 나무로 만든 도마다. 요즘은 다이소에 가면 매우 저렴한 가격에 도마를 살 수 있다.

아파트의 폐기물 내놓는 곳에서 제법 쓸만한 도마를 구하게 되어 여기에 43 오극관 싱글 앰프를 올리기로 하였다. 목공을 잘 모르기 때문에 어떤 재질의 나무인지는 모른다. 나사못이 술술 들어가는 것으로 보아 굉장히 무른 재질임을 알 수 있다.


R코어 출력 트랜스의 받침대에 각재를 덧댄 다음에 공구통에서 굴러다니던 작은 경첩을 달아서 도마에 고정하였다. 경첩의 움직임을 이용하려는 것은 전혀 아니고, 다만 ㄱ자 꺾쇠를 대신한 것이다. 두 개의 코어에 케이블타이를 가로질러 묶어서 도마를 기울여도 트랜스가 쏟아지지 않게 하였다.


진공관 바로 곁에서 나사못을 박으려고 스크류 드라이버를 쓸 때에는 주의를 해야 되겠다. 자꾸 진공관을 드라이버로 툭툭 건드리게 되니 말이다. 비싼 진공관은 아니지만 깨지면 아깝다. 내가 소유한 모든 물건 중에 가장 오래된 것이니(1940년대 제조)...


소켓 가이드와 러그판 등을 사용해서 도마 위에 멋지게 재배선을 할까 여러날 고민하였지만 일단은 이대로 두기로 하였다. 심지어 출력 트랜스에 케이스를 씌우려던 생각도 접었다. 현 상태로도 소리는 매우 잘 나고, 첫 작품을 원형 그대로 보존하는 것이 의미도 있기 때문이다. 대신 6N1+6P1 싱글 앰프용 출력 트랜스(아마도 EI 코어를 쓴 기성품)은 따로 구입을 하는 것이 좋겠다. 트랜스 하나를 여러 앰프에 바꾸어 가면서 듣는 것도 한계가 있지 않은가. R코어에 다시 한번 에나멜선을 감으려니 엄두가 나질 않는다. 57 코어(싱글 5 와트) 정도를 염두에 두고 있다.

도마를 사용하여 전기기타를 만드는 사람도 있다. 물론 따라서 할 엄두는 나지 않는다.


출처: https://www.instructables.com/id/Cutting-Board-Electric-Guitar/

[Bash, shell] 구분자가 포함된 문자열의 조작 기법

예전에는 늘 Perl을 써서 작업하던 것을 shell 수준에서 구현하기 위해 노력하고 있다. 제목에서 밝힌 문자열은 사실은 파일의 제목을 의미한다. 오늘 글을 쓰는 목적은 NCBI에서 다운로드한 파일을 하나 가득 들어 놓고는 제목을 한꺼번에 변경하기 위한 방법을 정리하기 위함이다. 특정 균주(Paenibacillus polymyxa E681)에 대한 RefSeq assembly 다운로드 사이트(링크)를 방문해 보자.


파일의 이름은 '필드1_필드2_필드3_..' 형태이다. 여기서 구분자는 밑줄 문자(_, under)이다. 위치를 기준으로 하여 원하는 필드만 조합하여 파일명을 단순하게 바꾸는 사례를 알아보자. NCBI에서 유전체 정보를 일괄적으로 다운로드하여 이름을 바꾸는 방법은 나의 위키 페이지(링크)에 상세히 설명하였다. 여기에 나온대로 따라서 하면 다음과 같은 형태의 파일을 얻는다.

Rhodococcus_sp._H-CA8f_GCA_002501585.1.fna

때로는 빨갛게 표시한 부분만을 떼어서 파일명으로 삼고 싶을 때가 있다. iTOL 서버를 쓰는 경우에는 단순하게 표시된 자료로 만든 newick tree file을 업로드한 다음 실제로 표시할 label을 별도로 제공하는 것이 더 합리적이다.

그렇다면 위에서 보인 파일명을 구분자(_)로 나눈 뒤 5, 6번째 필드를 붙인 것으로 바꾸면 된다. 이때 유용한 명령어는 cut이다.

$ ls *fna | while read F
> do
> mv $F $(cut -d'_' -f5,6 <<<$F)
> done

꺾쇠 세 개가 연달아 표시된 줄이 약간 난해한데, 어쨌든 잘 작동은 한다. 그러나 이 방법은 필드의 수가 엄격하게 고정된 경우에 한하여 쓸 수 있다. 파일명의 세번째 필드, 그러니까 strain 명에 해당하는 곳에 또 밑줄이 들어간 경우가 종종 있다. 'ATCC 842'와 같이 원래는 공백이지만 파일명에 공백을 넣는 것이 별로 바람직하지 않기 때문에 밑줄을 추가적으로 넣게 된 것이다. 이러한 상황에서는 '구분자를 떼어낸 다음 몇 번째 필드를 취하라' 하는 식으로는 원하는 결과를 얻기 어렵다. 차라리 '앞에서 처음, 혹은 뒤에서 처음'하는 방법이 더 낫다. 이때 BASH의 문자열 조작 기법이 매우 유용하게 떠오른다.

상세하게 공부를 하려면 Advanced Bash-Scripting Guide의 제10장 Manipulating Variables를 숙독하라. 나는 여기에서 꼭 필요한 부분만을 골라서 설명하겠다. 다음의 예제만 잘 보면 뭐가 어떻게 돌아가는지를 잘 알 수 있다. #와 %는 앞 또는 뒤로부터 시작하는 매치를 삭제하는 것이다. *를 쓰지 않고 ${NAME#_}라고만 쓰면 앞부분부터 시작해서 첫번째 '_'가 나오는 곳까지를 삭제할 것만 강렬한 욕구가 느껴지지만 이건 오해다(사실 이것 때문에 혼동을 많이 했다). 반드시 *_라고 써야 하고, #를 사용하는 경우에는 _*라고 해야 한다. #와 ##, %와 %%의 차이는 shortest(하나) or longest match(둘)를 의미하는 것이다.

$  NAME=abc_def_123_456.txt
$ echo ${NAME#*_}
def_123_456.txt
$ echo ${NAME##*_}
456.txt
$ echo ${NAME%_*}
abc_def_123
$ echo ${NAME%%_*}
abc
$ echo ${NAME/_/XYZ}
abcXYZdef_123_456.txt
$ echo ${NAME/_*/}
abc
$ echo ${NAME/*_/}
456.txt

그러면 파일명을 구성하는 필드의 수가 일정하지 않다 하더라도 맨 뒷부분을 이용하여 assembly accession만을 떼어내는 것이 가능하다.

$ ls *fna | while read F
> do
> mv $F GCA_${F##*_}
> done

변수 F의 앞에서부터 시작하여 *_를 longest match로 삭제하면 ...GCA_의 나머지 부분이 남는다. 이렇게 얻은 값의 앞에 다시 GCA_를 붙이면 된다. 혹은 while-do 블록 내의 명령어를 mv $F GCA_${F#*_GCA_}으로 써도 결과는 같다. _GCA_는 변수 F의 값에서 단 한번만 존재하므로(철저한 사람이라면 균주명에 앞뒤에 공백을 포함하는 GCA라는 이름이 들어있지는 않은지 확인을 해 보겠지만) #를 한 번만 써도 된다.

대충 써 왔던 기법이 이제 좀 정히가 되었다.

2019년 3월 8일 금요일

밀린 윈도우즈 업데이트 - 업데이트가 되지 않을 때 해결 방법

3월 8일이 되어서야 3월의 첫 포스팅을 하게 되었다. 무엇인가 무척 바쁘거나, 심경의 변화가 있거나(개인적인 글을 인터넷에 올리는 것에 대해서 회의가 들기 시작했다거나) 등등의 핑계를 댈 수 있겠다.

언제부턴가 Windows Update가 되지 않기 시작하였다. 업데이트의 의미는 새롭고 신기한 기능을 제공하는 것도 있지만 그보다는 보안을 향상시키는 것에 있다.

도대체 문제가 무엇일까? 구글링을 하여 이런 메시지가 나올 때 대처하는 방법을 찾아보았다. 마이크로소프트 커뮤니티에서 제공하는 공식적인 해결책을 하나 찾았다.

Windows Update 확인을 할 수 없습니다

이대로 하나씩 따라서 하면 몇 달 동안 밀린 업데이트를 할 수 있으리라 생각을 했다. 그런데 세번째 단계에서 C: - WINDOWS - SoftwareDistribution 폴더의 이름을 변경할 수가 없는 것이었다. 이건 또 왜 이런가?

새로 발견한 문제를 해결하기 위해 영문으로 검색을 해 보았다.

cannot Rename SoftwareDistribution folder error "the action can't be completed because the folder or a file in it is open in another program"

될까? 여기에 나온대로 따라서 했더니 SoftwareDistribution과 softwaredostribution.old의 두 가지 폴더가 보인다. 무슨 원리인지는 모르겠으나 SoftwareDistribution 폴더는 계속 새로 만들어진다는 생각이 들었다. 여기까지 한 다음 다시 첫번째 사이트의 지시대로 나머지 과정을 진행한 뒤 윈도우즈 업데이트를 실행하였다.

20개의 업데이트가 나를 기다리고 있다! 다행이다. 밀린 숙제를 하러 공책을 펼친 기분이다. 이것이 다 끝나면 퇴근을 해야 되겠다.

2019년 2월 26일 화요일

Fast and flexible bacterial genomic epidemiology with PopPUNK

Genomic epidemology에 관한 최신 논문을 찾아보다가 올해 1월 24일 Genome Research에 발표된 새로운 소프트웨어 도구인  PopPUNK(Population Partitioning Using Nucleotide K-mers)를 발견하였다.
Lees JA, Harris SR, Tonkin-Hill G, Gladstone RA, Lo SW, Weiser JN, Corander J, Bentley SD, Croucher NJ. Fast and flexible bacterial genomic epidemiology with PopPUNK. Genome Research 29:1-13 (2019). doi:10.1101/gr.241455.118
출처: https://poppunk.readthedocs.io/en/latest/index.html

병원체 감시(pathogen surveillance)를 위한 유전 데이터를 분석하는 방법으로는 MLST(multilocus sequence typing)가 전통적으로 널리 쓰인다. 유사한 MLST sequence type(ST)을 갖는 균주끼리 minimum-spanning tree를 만들어서 eBURST로 시각화하는 방법이 매우 보편적인데, 몇 개의 housekeeping gene만을 대상으로 하기 때문에 해상도에는 한계가 있다. 이제는 유전체 시퀀싱을 매우 염가에 할 수 있으므로, cgMLST(core genome MLST) 또는 wgMLST(while-genome MLST)를 활용하는 방법도 바람직하다. 그러나 결국 sequence alignment라는 시간이 오래 걸리는 계산을 피할 수 없고, 유전자에 대한 정보가 필요하며, 새로운 샘플이 약간만 추가되더라도 분석을 처음부터 다시 해야 하므로 스케일업이 매우 어렵다.

PopPUNK는 이러한 단점을 극복한 typing & clustering 도구로서 여러 시각화 도구에서 사용 가능한 결과 파일을 만들어 낸다. 두 유전체 사이의 관계(pmatch,k)를 가변 k-mer sketch로 계산하여 core distance(π, SNP density)와 accessory distance(a)를 축으로 하는 2차원 평면에 점으로 표시하고, 이들의 분포를 가장 잘 설명할 수 있는 모델의 피팅 및 최적화를 거쳐서 네트워크 구조를 만들어 낸다.


위의 수식에서 보였듯이 한 쌍의 서열 사이에 k-mer가 매치할 확률은 비교 대상 중 어느 하나에만 존재하는 accessory locus에 존재하지 않을 확률(paccessory) 곱하기 mismatch가 없는 공통 core genome 서열에 존재할 확률(pcore)로 표현된다. 나도 아직은 이 수식을 완벽하게 이해한 것은 아니다. PopPUNK의 전체 과정을 설명하는 그림을 원문 사이트에서 인용해 본다.

Fig. 1. Summary of the PopPUNK algorithm. 출처 링크.

99 균주의 유전체 서열을 가지고서 PopPUNK를 돌려 가면서 감을 잡기 위해 노력하는 중이다. 아직은 모델의 최적화를 이루지 못하였다. 논문에서 예시로 든 다른 species에 비해서는 다양성이 매우 적다고 느껴진다.

microreact로 시각화한 결과.

PopPUNK 결과물을 제대로 보려면


PopPUNK가 만들어내는 다양한 interactive output은 다음의 환경에서 보면 된다.
  • Microreact: Open data visualization and sharing for genomic epidemiology
  • phandango: Interactive visualization of genome phylogenies
  • GrapeTree: A fully interactive, tree visualization program, which supports facile manipulation of both tree layout and metadata
  • Cytoscape: Network data integration, analysis and visualization in a box (네트워크 구조를 상세하게 조사하려면 cytoscape를 권장한다)

2019년 2월 21일 목요일

[하루에 한 R] POCP 매트릭스를 이용하여 미생물 균주를 genus 별로 군집화하기

POCP(percentage of conserved proteins)에 대한 간략한 소개는 여기를 참조하라. 결론만 이야기한다면 POCP 50%를 기준으로 하여 세균이 같은 속(genus)에 속하는지를 판별하는 것을 제안한 것이다. 50%라는 기준은 평균값을 통해서 제안된 것이라 실제의 분포는 꽤 넓다.

POCP 매트릭스를 만들면 R에서 계층적 군집화(hierarchical clustering) 분석을 통해서 같은 genus에 속하는 균주를 구분하는데 도움이 될 것으로 기대를 하였다. heatmap을 그리면 균주들 사이의 대략적인 관계를 파악할 수 있지만, 실제로 군집이 어떻게 이루어지고 그 멤버는 누구인지를 결정해 주지는 않기 때문이다.

군집 분석에 대하여 알기 쉽게 설명한 글이 있어서 먼저 소개해 본다. 거리를 계산하는 방법과 군집 알고리즘의 차이에 대해서 특히 유념하여 읽도록 한다.

군집분석(Cluster Analysis) - Amazon AWS
[R 군집분석 (Cluster Analysis)] 군집분석의 개념 및 유형

그러면 34개의 유전체 서열을 이용하여 만든 POCP 매트릭스로 작업을 해 보자. 이 매트릭스는 d3이라는 데이터 프레임에 들어 있는데, 아직 완성되지 않은 일이라서 genus 정보만 남기고 균주 정보를 살짝 가리기 위해 약간의 트릭을 썼다. 수정된 데이터 프레임은 d4로 저장하였다. paste(vector1, vector2, sep=" ")을 실행하면 vector1의 모든 원소는 같은 위치에 해당하는 vector2의 원소와 공백을 경계로 하여 연결된 상태로 반환된다. POCP 매트릭스를 dist() 함수로 처리하여 euclidean distance를 구하여 이를 기반으로 계층적 군집화를 실시한다. hclust() 함수에 넘겨주는 method를 average로 지정하면 바로 우리에게 친숙한 UPGMA(Unweighted Pair Group Method with Arithmetic mean)이 된다.

출처: R Friend

실제 코드와 실행 결과는 다음과 같다. 요즘 몰두하고 있는 미생물은 Agathobaculumn, Butyricicoccus, 그리고 Eubacterium의 일부이다.

d4 = d3
k = row.names(d3)
km = gsub(" .*$", " sp. ", k)
n = 1:34
row.names(d4) = paste(km, n, sep="")
x = hclust(dist(as.matrix(d4)),method="average")
plot(x)


그런데 이렇게 그린 그림에서 세로축의 height는 우리에게 별다른 느낌을 주지 않는다. POCP 값(퍼센트)을 100에서 뺀 수치를 나만의 거리로 사용하면 안 되는 것일까? ANI도 마찬가지 성격의 지표가 된다. 이렇게 자체적으로 만든 매트릭스를 그대로 디스턴스로 삼으려면 as.distance() 함수를 쓰면 된다.

mydist = 100 - d4
x = hclust(as.dist(as.matrix(mydist)),method="average")
plot(x)
rect.hclust(x, border="red",h=50)


덴드로그램의 구조는 약간 달라진다. 그러나 여기에서는 (100 - POCP)가 height로 나타나므로, 일정 기준을 만족시키는 클러스터 주변에 사각형 경계를 씌울 수 있다. 동일 클러스터를 이루는 균주들은 POCP가 50을 넘는 것들이니 같은 genus에 속하는 것으로 볼 수 있다.

각 클러스터를 이루는 멤버들의 이름을 확인하고 싶다면? 트리 형태의 데이터를 데이터 그룹으로 잘라내려면 cutree() 함수를 쓰면 된다. cuttree가 아님에 유의하라. height = 50을 기준으로 잘라내는 코드와 결과를 같이 살펴보도록 하자. 클러스터의 수를 지정하여 잘라낼 수도 있다(k = 원하는 수).


> groups = cutree(x2,h=50)
> table(groups)
groups
 1  2  3  4 
31  1  1  1 
> names(groups[groups==1])
 [1] "Butyricicoccus sp. 1"     "Agathobaculum sp. 2"     
 [3] "Clostridia sp. 5"         "Butyricicoccus sp. 7"    
 [5] "Butyricicoccus sp. 8"     "Agathobaculum sp. 9"     
 [7] "Butyricicoccus sp. 10"    "Agathobaculum sp. 11" 
 ....(후략)

벡터의 원소를 가리키는 이름(names)이 groups 벡터를 다루는데 얼마나 요긴한지를 알 수 있다.

2019년 2월 18일 월요일

[2019 오디오 자작] 6N2P + 43 싱글 엔디드 앰프의 전원부 수정

전원트랜스에서 인출한 110V 교류를 다이오드 브리지로 정류하여 평활회로를 거친 뒤 초단과 출력관에 전부 연결하면 출력관의 캐소드-애노드 사이에 85V 이상을 걸기가 어렵다. 전원회로쪽의 저항을 약간 작은 것으로 하면 몇 볼트를 올릴 수 있지만 험이 커진다.

원래대로 DC-DC boost converter를 쓰면 어떨까? 6N2P 초단 회로의 B전원도 여기에서 한꺼번에 공급한 이후로는 스피커에서 간헐적으로 잡음이 들리기 시작했다. '웅`' 혹은 '윙-'의 중간쯤 되는 소리인데, 입력을 끊고 잠시 기다리면 사라진다. 이래서야 음악 감상을 하기가 곤란하다. 잠시 트랜스를 사용한 전원회로로 외도를 했던 것도 이러한 잡음 때문이었다. 6N2P 한 알이 들어가는 프리앰프만을 전원트랜스로 구동할 때에는 문제가 없었다. 물론 여기에는 많은 편법이 동원되었다. 출력이 6.3V(히터) 및 230V라서 정류를 한 뒤에는 도저히 43 오극관의 애노드에 맞출 수가 없었기 때문이다. 갖고 있는 캐피시터의 내압도 250V가 최고이고, 저항을 연결하여 낮추자니 적당한 수치의 것이 없다. 발열도 심할 것이 자명하다.

컨버터 출력에 RC 필터를 달면 어떨까? 아내의 푸념을 뒤로 하고 주말 작업에 돌입하였다. 아래 회로도에서 파랑색 곡선으로 둘러친 것이 어제 새로 추가한 필터에 해당한다. 컷오프 주파수는 15.39Hz로 계산된다. 만약 220R과 100uF 조합이라면 7.32Hz가 되어 더욱 양호한 직류 전원이 얻어질 것이다. 그러나 부품통에는 47uF 250V 캐패시터가 전부이다. 아주 초기에는 컨버터 출력에 47uF 전해 캐패시터 하나를 병렬로 연결하여 사용했던 적이 있었다.

확정된 6N2P + 43 싱글 엔디드 앰프의 회로도. 파랑색으로 표시한 RC 필터를 전원부에 추가함으로써 잡음을 해결하였다.
컨터버 모듈의 가변저항을 살며서 돌려서 출력관의 캐소드-애노드 사이에 130V 이상이 걸리게 하였다. 소리는 어떠한가? 매우 양호하고 음량도 높아졌다. 무신호 상태에서 스피커에 귀를 바싹 대고 볼륨 놉을 최대로 올리면 약간의 잡음이 들릴 수준이다. 실용적으로 문제가 없다.

만약 다음 기회에 다시 전원 트랜스를 쓰게 된다면 2차 110V 출력을 배전압 정류한 다음 저항으로 적절히 강압하여 사용하면 될 것이다.

어제 작업을 하는 동안 작은 사고가 하나 일어났다. 2016년 5월 구입한 목인두가 앰프 샤시(케익 틀)를 살짝 스치면서 불꽃이 일어나는가 싶더니 차단기가 내려가고 집안의 모든 전기가 끊겼다. 테스터로 찍어보니 인두의 히터는 단선이 되었다. 도대체 왜? 누전 때문이 아닌가 싶다. 접지되지 않은 멀티탭을 쓰다가 최근에 접지가 있는 것으로 바꾸었는데, 같은 멀티탭에는 43 앰프가 연결된 상태이다. 여기에 꽂힌 12V SMPS 어댑터는 출력의 마이너스 극과 220V 전원의 접지가 내부적으로 또한 연결이 된 상태이다. 아마도 납땜인두의 팁 부분에 누전이 일어나서 앰프의 새시 -> SMPS 어댑터의 접지를 통해 전기가 흘렀고, 차단기가 이를 감지하여 자동으로 끊긴 것으로 생각된다. 누설전류는 앰프쪽 SMPS가 아니라 인두 파워 케이블의 접지를 통해서 흘러나갔는지도 모른다. 분명히 눈 앞에서 '딱' 소리와 함께 불꽃이 튀었는데 너무나 순식간이라서 정확히 어디인지를 기억하지 못하겠다.

만약 접지가 없는 멀티탭을 계속 사용했더라면 이러한 '사고'는 일어나지 않았을지도 모른다. 그러나 이런 인두를 계속 쓰다간 부품이 망가지거나, 더욱 운이 없었더라면 내가 감전으로 다쳤을지도 모른다. 세대용 분전반에 설치된 차단기는 과전류가 흐를 때 차단을 시키는 목적도 있지만, 더욱 중요한 것은 누전을 감지하여 차단하는 것이다. 사실 이것을 이해한 것도 비교적 최근의 일이다.

남아있는 소용량 납땜인두로는 단자 등 큰 부위의 납땜이 어렵다. 안전을 위해서 다음에는 세라믹 인두팁이 장착된 것을 구입하도록 하자.

작업을 마친 상태. B전원용 컨버터는 섀시 위로 올렸다. 볼트 구멍의 흔적이 어지럽다.
LED 파일럿 램프를 달았다.

만약 이 앰프에 다시 손을 대게 된다면, 그것은 새로운 섀시에 완전히 새로 제작하기로 결심을 한 이후가 될 것이다.