2018년 10월 27일 토요일

43번 오극관(43 power pentode) 싱글 앰프 프로젝트 - [8] 프리앰프 바꾸기

나무판 위에 서툴게 만든 43 오극관 싱글 엔디드 앰프를 매일 흐뭇하게 바라보면서 어떻게 섀시를 만들지 고민을 하던 중 프리앰프가 망가지고 말았다. 재생 중에 갑자가 전원이 들락날락거리기 시작한 것이다. '퍽' 소리와 함께 파일럿 LED도 꺼지고 아무런 소리가 나지 않는다. 잠시 살아나는 것 같다가 또 꺼지고를 반복하였다. 처음에는 전원 커넥터쪽의 접촉 불량이라고 생각했지만 납땜을 새로 해고 아무리 만져 보아도 소용이 없었다. 전원을 넣고 무슨 일이 벌어지는지 기다리는데 갑자기 연기가 나면서 대용량 저항이 타고 말았다. 문제점을 진단하고 고칠 능력이 없으니 이제 이 앰프는 12AU7 진공관 한 알을 남기고 잡동사니 상자에 들어가는 신세가 되었다.

43 오극관은 전력증폭회로를 담당한다. 이 앞에서 신호(오디오 신호이므로 교류)를 적당한 수준으로 흔들어 줄 '드라이버'가 필요한 것이다. 드라이브단은 소스 기기에서 출력되는 전압을 흔들어 주는 것이라서 큰 전력을 소비하지는 않는다. 명색이 진공관 앰프이니 드라이브단도 진공관을 쓰는 것이 자연스럽다. 그러나 43 오극관의 히터(25 V) 및 B+ 전원(95~160 V)은 요즘 보통 사용하는 다른 진공관과 같이 쓰기에는 적합하지가 않다. 그래서 나는 진공관-MOSFET 하이브리드 헤드폰 앰프 겸 프리앰프를 사용했던 것이다.

제이앨범의 매니저께서는 요즘 43번 오극관을 이용한 앰프 회로의 설계를 거의 마쳐가고 있다. 초단에는 오극관인 6KT6을 사용한다. 계산 결과에 의하면 드라이브단에서는 36~40 V 정도의 범위를 흔들어야 한다. 반도체 프리앰프로는 이는 도달하기 어려운 값이다. 왜냐하면 전원전압이 결국 프리앰프의 출력 범위를 결정하기 때문이다(물론 게인도 중요하다).

이에 나는 수년 전에 만들었던 op amp 기반의 CMoy 헤드폰 앰프(위키피디아)를 개량하기로 하였다. 이것은 헤드폰 앰프 스테이션(하스)의 신정섭 님(sijosae)이 상세한 제작법을 소개하여 국내에 널리 알려진 것이다(제작 정보). 놀랍게도 이 글은 2002년 작성된 글이고 2006년 이후 신정섭 님은 하스 커뮤니티의 자작방에 글을 올리지 않고 있다. 근황이 무척 궁금하지만 나는 하스의 회원이 아니니 물어볼 수가 없다. 그의 작품은 외국에서도 많이 알려져 있다. 궁금하다면 Sijosae's DIY Gallery를 방문해 보자.

헤드폰 앰프는 프리앰프로 써도 별 문제가 없는 것으로 안다(그 역은 항상 성립하지는 않는다). 그렇다면 별도의 목적을 갖고 있는 프리앰프가 진공관 싱글 앰프의 초단에 쓰여도 되는가? 진공관 전력증폭회로가 필요오하는 전압의 폭보다 훨씬 낮은 것은 사실이다. 그러나 침실에서 그다지 크지 않은 음량으로 듣는 것이 목적이라서 문제는 없을 것으로 생각한다.

초단, 드라이브단, 위상반전단...

여기에서 잠시 진공관 앰프의 회로 구성에 대해서 잠깐 논하기로 한다. 위상반전단(inverter)은 푸시-풀 앰프에서 필요한 것이니 제외하기로 한다. 

사진 출처: Lenard Audio Institute
위의 그림을 보면 출력관을 구동(drive)할 전압을 만들기 위해 pre-amp와 driver의 두 단계(stage)를 거친다. 이것은 흔히 이야기하는 초단과 드라이브단을 각각 일컫는 것으로 보인다. 그러나 우리나라에서는 pre-amp라고 하면 특정한 목적이 있는 별도의 장비(즉 power amplifier 혹은 integrated amplifier와 구별되는)로 인식되는 것 같다. 소출력 앰프라면 진공관 한 알을 가지고서 프리앰프과 드라이버의 두 stage를 전부 담당하도록 설계하는 것이 보통이다. 초단, 위상반전단, 드라이브단 및 출력단의 의미를 서병익오디오 기술칼럼에서 확인해 볼 수 있다(링크).

헤드폰 앰프의 개조

내가 신정섭 님의 제작 정보를 따라서 만든 헤드폰 앰프는 게인이 약 1.3 정도에 불과하다. 그래서 저항을 각 채널에서 하나씩 바꾸어서 11배(20.8 dB)로 만들었다. 이렇게 하면 43 오극관 전력증폭회로에 잠시 물려서 사용했던 프리앰프의 그것과 거의 비슷하다. 사용된 op amp는 LF353(datasheet)이다. 


원래 op amp는 직류 양전원이 필요하다. CMoy 헤드폰 앰프에서는 9 V 전지 두 개를 직렬로 연결하여 +9/0/-9 V를 얻는 것이 기본이고, 신정섭 님의 버전에서는 9 V 전지 하나에 캐패시터와 저항을 연결하여 이를 반분하여 +4.5/0/-4.5 V를 만든다. 나는 갖고 있는 SMPS 어댑터를 사용하기로 했다. 9 V, 24 V 및 32 V의 것을 전부 연결해 보았다. 부품의 내압에는 문제가 없다. LF353 데이터시트에 의하면 최대 공급 전압 범위는 ±18 V이니 안전하다. 물론 게인을 더 올리지 않으면 출력 전압이 여기에 접근하지 못할 것이다.

TDA7297 '반찬통 앰프'가 희생되었다.
소리를 들어 보았다. 음량 수준은 바로 수일 전까지 사용하던 진공관-MOSFET 하이브리드 프리앰프와 비슷하다. 고급 op amp라고 할 수는 없지만 잡음 수준도 양호하다.

반찬통 안의 남은 공간이 넉넉하다.

여분으로 보유한 op amp (TL072와 NE5532). 회로 기판에 지금은 LF353이 꽂혀 있는 것은 아마도 이들 중에서 잡음이 제일 적어서 선택된 것 같다.
만약 내가 인내심이 충분했더라면 AliExpress 혹은 eBay에서 몇 달러에 판매하는 NE5532 preamplifier board를 구입하여 사용했을지도 모른다. 그러나 가장 최근에 주문한 물건이 한 달이 훨씬 넘도록 배송이 되고 있지를 않아서 당분간은 해외 구매를 자제하려고 한다.

2018년 10월 26일 금요일

awk와 sed를 사용하여 muti-fasta 파일의 서열 ID를 일괄적으로 바꾸기

수십 개의 대장균 유래 MiSeq 데이터를 Unicycler(GitHub 링크)로 조립하였다. 실행 결과물은 전부 샘플별 디렉토리에 나뉘어 저장된 상태이다. 디렉토리 이름은 전부 다르지만, 그 내용물의 파일 이름은 전부 같다. 예를 들자면 최종 조립 결과 파일의 이름은 모두 assembly.fasta이다. 이를 한데 모아서 저장하자면 파일 이름에 샘플의 이름이 들어가도록 바꾸어야만 한다.

이 작업은 파일의 내용을 직접 건드리는 것이 아니라서 비교적 쉽다.

1
2
3
4
5
$ mkdir final
$ find . -name assembly.fasta | while read f
> do
> cp $f `echo $f | awk -F/ '{sub(/assembly/, ""); print "final/"$2"_plasmid"$3}'`
> done

이상의 명령을 실행하면 ./123/assembly.fasta 파일은 ./final/123_plasmid.fasta로 바뀐다. 세 번째 줄을 참고하면 awk의 sub() 함수를 사용하여 assembly라는 문자열을 제거하고, 파일 경로로부터 샘플의 이름(원래는 디렉토리 이름이었음)을 추출하는 것이 핵심이다.

다음으로는 각 fasta 파일로 들어가서 서열 ID를 바꾸는 방법을 알아보자.

1
2
3
4
5
6
7
$ ls *fasta
1039_plasmid.fasta  1536_plasmid.fasta ... 
$ ls *.fasta | while read f
> do 
> h=${f%%_*}
> sed -i "s/>/>s${h}p/" $f
> done

현 디렉토리에 존재하는 .fasta 파일의 이름을 변수 f에 넣은 다음 밑줄('_')부터 끝까지를 제거하는 명령(다섯 번째 줄)을 먼저 눈여겨 보자. Shell에서 문자열을 조작하는 매우 유용한 방법이니 잘 기억해 두어야 한다. %%, %, ##, #에 따라서 삭제의 범위와 위치 기준이 달라지고, 치환도 가능하다. 상세한 사항은 Advances Bash-scripting Guide: Manipulating Variables를 참조하자. 다음에는 서열 ID를 sed 명령으로 치환한다. sed의 -i 옵션은 파일을 직접 고치는 것을 뜻한다. 따라서 실수를 하면 곤란하다. 그러나 -i.bak라고 입력하면 원본파일.bak이라는 백업본이 남는다.  흥미롭게도 -i와 SUFFIX 문자열 사이에는 공백이 없어야 한다. Shell variable을 sed의 치환 명령어 내에서 그대로 쓸 수 있다는 것이 매우 편리하다. 단, 명령어를 겹 따옴표로 둘러싸야 한다. 이상을 실행하면 서열의 ID는 다음과 같이 바뀐다.

(변경 전) >1 length=25428 depth=1.01x
(변경 후) >s1039p1 length=25428 depth=1.01x

awk를 사용하면 똑같은 일을 좀 더 복잡하게(?)할 수 있다. Shell variable을 awk 명령어 내에서 쓰려면 -v 옵션을 이용해야 하고, 서열 ID가 있는 라인과 서열만 포함한 라인을 모두 출력하려면 next 명령을 써야 한다. 그러나 printf() 함수를 이용하여 좀 더 세련된 결과를 얻을 수 있다. 다음의 사례에서 세번째 awk 명령어에 주목해 보자. awk의 sub( ) 함수 용법을 먼저 이해해야 하고, next의 의미는 곧 이어서 설명하겠다.


1
2
3
4
$ ls *fasta | while read f
> do
> awk -v s="${f%%_*}" '$1~/^>/{sub (/>/, ""); printf ">s%d-p%d %s %s\n", s, $1, $2, $3; next}{print}' ${f} > ./edit/${f}; done
> done

세 번째 줄의 awk 명령어 구조가 좀 난해하다. 이를 이해하려면 다음의 두 명령어가 무엇이 다른지를 알아야 한다.

  1. awk '조건{명령어A}{명령어B}' 파일
  2. awk '조건{명령어A; next}{명령어B}' 파일
작업 중이 라인이 조건에 맞으면 {명령어A} 블록을 실행하고, 맞지 않으면 {명령어B} 블록을 실행하는 것이 아니다! 첫 번째 명령어는 조건에 맞으면 A를 실행하고, 같은 라인에 대해서 그대로 B를 수행함을 뜻한다. B를 수행함에 있어서는 앞에서 선언한 조건과는 상관이 없다. 따라서 조건에 맞는 줄에 대해서 A를 실행하고, 다음 줄로 넘어가려면 그 블록 안에서 next 명령을 선언해야 한다. 이렇게 해야 조건에 맞지 않는 줄에 한하여 명령어 B 블록이 수행된다. 이렇게 표현하는 것이 마음에 들지 않으면 if ~ else ~ 구문을 써야 한다.

아무 fasta 파일에 대해서 다음의 명령을 실행시켜 보라. NR은 현재 작업 중인 라인의 번호를 의미한다. 그 다음에는 next를 제거한 뒤 다시 똑같은 명령을 실행해 보라. 어떤 차이가 있는지를 쉽게 이해할 수 있을 것이다.

$ awk '$1~/^>/{print NR, ": header"; next}{print NR, ": seq"}' test.fasta

오늘 소개한 방법이 최선이 아닐 수도 있다. 다음 웹페이지에서 소개하는 짤막한 awk 코드에도 공부할 것이 많이 숨어 있다.

one liner to split a multifasta into separate single file


1
2
3
4
print 'hello world!'cat hg18.fa | awk '{
        if (substr($0, 1, 1)==">") {filename=(substr($0,2) ".fa")}
        print $0 > filename
}'


2018년 10월 24일 수요일

블로그 포스트에 코드 조각 삽입하기

코드 조각(code snippet)을 블로그 포스트에 예쁘게 삽입하려면 정성을 기울여야 한다. 한때 Syntax Highlighter를 써 보려고 노력했지만 블로그의 템플릿을 수정하는 것도 까다로웠고 실제 적용한 뒤에 페이지를 로드해 보면 제대로 불러오는데 시간이 많이 걸린다는 느낌이 들었다.

좀 더 간편한 방법은 없을까? Stack Overflow에서 그 해답을 찾았다.

Formatting code snippets for blogging on Blogger

첫번째는 hilite.me 웹사이트를 이용하는 것이다. 웹사이트 주소도 아주 외우기 쉽다. '하이라이트 미' 아니겠는가? 여기를 방문하여 소스코드 창에 원하는 코드 조각을 입력하고 언어의 종류와 스타일을 결정한 뒤 나오는 HTML 코드를 복사하여 블로그 편집창에 넣으면 된다. 이렇게 말이다. 편집모드는 HTML로 놓는 것이 좋다.


#!/usr/bin/perl

while (<>) {
    chomp;
    my @data = split /\t/, $_;
    print "$data[0]: $data[3]\n";
}

이러한 용도의 웹사이트는 몇 군데가 더 있다.
또 다른 사용자는 다음의 css 스크립트를 복사하여 쓰는 것을 제안하였다. 중간의 블록에 코드를 삽입한 다음 이를 그대로 블로그 편집창에 넣으라는 것이다. syntax highlighting 기능은 없지만 소스 코드를 그대로 보이는 데에는 유용하다. 매우 단순한 방법이다.

 <pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; 
                color: #000000; background-color: #eee;
                font-size: 12px; border: 1px dashed #999999;
                line-height: 14px; padding: 5px; 
                overflow: auto; width: 100%">
       <code style="color:#000000;word-wrap:normal;">

            <<<<<<<YOUR CODE HERE>>>>>>>

       </code>
 </pre>

이를 한 번 적용해 보았다.

#!/usr/bin/perl

while (<>) {
    chomp;
    my @data = split /\t/, $_;
    print "$data[0]: $data[3]\n";
}       

블로그 문서 내에서 '<'과 '>'을 제대로 표시되게 하는 것은 여전히 어렵다. 몇 번씩 '미리보기'로 확인을 해야 하니까 말이다. 오늘 찾은 방법은 잘 기억해 두었다가 활용하도록 하자.

2018년 10월 23일 화요일

Protein sequence clustering과 dN/dS 분석

새로운 과제를 시작하면서 단백질 서열 클러스터링이라는 매우 고전적인 일을 하게 되었다. 단백질 패밀리의 분석, pan-genome 계산, ortholog 추출, dN/dS 분석, 데이터셋의 크기 축소 등 단백질 클러스터링은 매우 여러 분야에 쓰인다. 자료를 조사하면서 지난 2월에 작성했던 글인 Usearch 맛보기도 업데이트하였다. 오늘 작성하는 글은 "How to cluster protein sequences: tools, tips and commands"을 많이 참고하였다.

단백질 서열 클러스터링 기법은 크게 다음의 두 가지로 나눌 수 있다.
  • Sequence-based clustering: CD-HIT, UCLUST, USEARCH...
  • Graph-based clustering: LAST, legacy BLAST, BLAST+...
  • Network clustering: MCL
Graph-based clustering에서는 모든 단백질 서열 사이의 1:1 similarity 정보를 얻어내는 것이 필요하다. BLAST 계열의 프로그램을 사용하는 경우 결과물을 파싱하여 Reciprocal Best BLAST hit(RBB, RBH, or biodirectional best hit BBH)을 추출하여 활용하면 되는 것이다. RBB는 두 genome 사이에서 ortholog candidate를 산출하는 데에도 널리 이용된다.

RBH으로부터 ortholog를 정확하기 추출하기 위한 BLAST option을 제안한 논문이 2008년에 발표된바 있다(PMID: 18042555). 이를 기반으로 하여 다음의 BLASTP 옵션이 제안되었다. 논문에서는 첫번째 조건만을 제안하였다. 이렇게 함으로써 ortholog의 수는 가장 많게, 그러나 error는 최소화할 수 있었다고 한다.
  • -F "m S" -s T (combination of soft filtering and Smith-Waterman final alignment)
  • E value: 10-5 또는 10-6 이하
BLAST 프로그램은 database search와 alignment의 두 단계로 이루어지는데, soft filtering이란 첫번째 단계에서만 low-complexity sequence를 마스킹하는 것을 의미한다(-F "m S"). 기본 조건은 -F T -s F이다. -F "m S"라는 옵션이 있다는 것은 blastall의 모든 옵션이 수록된 페이지(링크; 혹은 명령행에서 blastall이라고만 치면 나오는 텍스트)에서 찾아보기 어렵다.

이상의 옵션은 legacy BLAST에 대한 것이다. 그러면 요즘 권장되는 BLAST+에서는 무엇이라고 옵션을 제공해야 하는가? NCBI의 매뉴얼 페이지(링크)를 참조해 보면 -soft_masking T -use_sw_tback (-evalue 10-5)일 것으로 추청된다. 

다음의 북 챕터에서는 BLAST+를 이용하여 상동유전자 정보를 찾고, 이로부터 dN/dS 분석일 실시하는 방법을 친절하게 설명하였다. 사용된 Perl script(BLAST+ 결과물에서 RBB를 추출하는 스크립트 포함)는 제1저자인 Daniel Jeffares의 웹사이트에서 입수 가능하다고 해 놓았다.

A Beginners Guide to Estimating the Non-synonymous to Synonymous Rate Ratio of all Protein-Coding Genes in a Genome. Methods Mol Biol. 2015;1201:65-90. doi: 10.1007/978-1-4939-1438-8_4. PMID.

그러나 지금 이 사이트를 방문해보면 figshare에 Perl 스크립트 일부만이 남아있다. 그러나 Daniel은 이를 기반으로 하여 VESPA라는 파이프라인을 개발하여 2017년 PeerJ Comput. Sci.에 발표하였다(VESPA: Very large-scale Evolutionary and Selective Pressure Analyses. 저널 GitHub 매뉴얼). VESPA를 공부하려면 단순히 RBB를 찾으려는 목적이 아니라 더 큰 안목을 가지고 착수해야 할 것이다.

InParanoid를 사용해서 두 단백질 세트 사이에서 ortholog를 찾을 수도 있다. 그런데 Why InParanoid sucks라는 글(2014년도)을 보니 이제는 이 프로그램을 떠나야 하는 것이 아닐까하는 생각도 들기 시작하였다. 알고리즘적으로 특별히 문제가 되는 것은 아니지만 말이다. 어쩌면 blast_rbh.py 스크립트가 바로 내가 찾던 것이 아닌지 모르겠다. 이를 다운로드하여 실행해 보았다. duplicate가 있다는 경고는 나오지만 결과 파일에서 이들이 어느 것인지를 보여주지는 않는다. 상동유전자를 찾는 프로그램으로서 GET_HOMOLOGUES도 유용한 프로그램으로 여겨진다.


$ ls
A.faa  B.faa
$ python ~/script/blast_rbh.py -o example.tab -t blastp -a prot A.faa B.faa 

Done, 10 RBH found
Warning: Sequences with tied best hits found, you may have duplicates/clusters
$ ls
A.faa  B.faa  example.tab
$ head -n 1 example.tab 
#A_id B_id A_length B_length A_qcovhsp B_qcovhsp length pident bitscore

BLAST+ 분석 결과물에서 best hit(RBB는 아님)을 추출한 뒤 mcl로 클러스터링하는 명령행을 정리하여 보았다. 이는 서두에서 언급한 참고문헌에서 발췌한 것이다.

$ makeblastdb -in DB.fasta -dbtype prot -out DB
$ blastp -query example.fasta -db DB -outfmt '6 std qlen slen' -out output_tmp.list -evalue 1.03e-05
$ awk '{if($1!~/^#/ && $3>=50) print $1"\t"$2"\t"($3/100)}' output_tmp.list > hits.list
$ sort -nrk 3 hits.list | sort -k 1,2 -u > best_hit.list
$ mcl hits.list -I 1.8 --abc -o clusters.txt
$ awk '{if(NF>=2) print}' clusters.txt > clusters_after_threshold.txt

맨 아래의 awk 명령어는 singleton을 제거하기 위함이다.

마지막으로 대용량의 pan-genome 분석을 위한 새로운 프로그램을 하나 소개해 본다. 늘 Roary만 편식을 심하게 했었는데 이제는 다른 것에도 눈을 돌려볼 때이다.



2018년 10월 21일 일요일

독서 기록 - [디스럽션] 외 세 권

대출 기간이 임박하여 책 표지 사진을 찍은 뒤 곧바로 반납을 해 버려서 간단한 서지정보만 남긴다.


디스럽션

  • "사물인터넷 비즈니스의 모든 것"
  • 저자: 강시철
커넥슈머, 프라이버시 스왑...

모든 교육은 세뇌다

  • "4차 산업혁명 시대의 경쟁력, 몰입의 힘"
  • 호리에 다카후미 저|박흥규 감수|하진수 역
도서관에는 아직도 '4차 산업혁명 관련 도서' 서가가 따로 마련되어 있다. 과연 이 유행어가 내년까지 갈지 두고 보아야 되겠다.

다시 읽는 한국 현대사

  • "정치의 새로운 실천을 기대하며"
  • 양우진 저
근대사의 전 과정을 부정의 역사로 보는 진보 진영의 시각에 대한 보수주의자의 비판. 시각을 넓혀보자는 차원에서 고른 책이다.

열한 계단

  • "나를 흔들어 깨운 불편한 지식들"
  • 채사장 저(책 소개)
이 책을 읽기 전까지는 채사장(팟캐스트 지대넓얕 진행자, 블로그)을 전혀 몰랐다. 지대넓얕이란 '지적 대화를 위한 넓고 얕은 지식'을 뜻한다. 알쓸신잡보다 먼저 만들어진 낱말인가? 인문학 = 교양이 아니다. 인문학은 그 자체로서 의미가 있는 것이지 치장을 위하여 '소비'되는 것이 아닌데.. 물론 저자의 노력을 폄훼하고자 함은 아니다. 

한자 丁에는 '고무래'라는 뜻이 전혀 없다

丁 넷째 천간 정, 장정 정

단 두 획으로 이루어진 매우 간단한 모양의 한자이다. 장정이란 한 사람의 일꾼 몫을 하는 어른 남자를 뜻한다. 군대에 갈 연령, 즉 징집 연령에 달한 남자를 뜻하는 것이기도 하다.
이 한자는 한국 또는 중국인의 성씨에도 쓰인다. 우리 집안의 성이 바로 이 한자를 쓴다. 인구 비율로 훨씬 많은 鄭(나라 정, 나라 이름 정)과 구별하기 위해 흔히 丁자를 '고무래 정'이라고 부르기도 한다. 고무래는 곡식 낱알 등을 긁어모으는 농기구의 일종으로 이 글자와 모양이 똑같다.

출처: 국립중앙과학관

그러나 이 글자 자체에 고무래라는 뜻(훈, 訓)은 전혀 없다는 것이 나의 상식이었다. 과거에 분명히 한자사전에서 이러한 설명을 분명히 보았었다. 심지어 어떤 사람이 丁자를 '갈고리 정'이라고 부르는 바람에 아연실색을 한 적이 있었다. 남의 성씨를 마치 공포영화에 나옴직할 흉칙한 물건으로 칭하다니...

며칠 전에 컴퓨터를 만지작거리면서 그냥 호기심에 丁자의 의미를 검색해 보았다. 그런데 놀랍게도 '고무래'라는 뜻이 있는 것으로 나타나지 않는가?

먼저 네이버 한자사전. '고무래'라는 뜻이 맨 위에 있다.


다음 사전. 여기는 정확하게 풀이하였다. 매우 친절하게도 '※ 흔히 「고무래 정」이라 칭하는 것은 글자 모양에 따른 속칭임.'이라는 추가 설명을 달았다.


나무위키. 고무래를 맨 위에 올렸다.


이외에도 한자 학습을 위해 만들어진 많은 사이트에서 이 한자가 '고무래'를 뜻한다고 기록해 놓았다. 이는 잘못되어도 한참 잘못되었다. 마치 '입 구(口)'자의 모양이 네모를 닮았다고 하여 이를 '네모 구'라고 부르다가 인터넷 한자사전에 '네모'라는 뜻이 있다고 등재하는 것이나 다를 것이 없다. 실제로 口자를 네모라는 뜻으로 쓴 사례가 없으면 아무런 소용이 없는 것이다. 丁자 역시 마찬가지이다. 과거 혹은 현재의 문헌에서 이를 고무래라는 뜻으로 쓰지 않았다면 이런 훈이 있다고 붙여서는 안된다.

정말 내가 알고 있는 丁의 뜻이 맞는지 한자 사전을 찾아보고 싶었다. 그러나 요즘은 종이책으로 된 사전이 거의 나오지를 않고 집에도 국어사전과 영한사전 뿐이라서 직접 도서관에 가서 민중서림의 한자대사전(전면개정·증보판)을 찾아 보았다.


그 어디에도 고무래라는 뜻은 없다. 글자의 본래 모양은 '못'이지 '고무래'가 아니다. 그리고 여기에도 '고무래정으로 훈함은 잘못'이라고 하였다. 홍윤표 연세대 교수도 이 한자에 고무래라는 해석을 달았던 시대는 없었음을 분명히 하였다('사나이'의 어원).

사실에 기반한 것도 아니고 검증도 되지 않은 엉터리 지식이 인터넷을 떠돌면서 진짜 지식으로 이렇게 둔갑하는 것이다. '인터넷에서 보았다'라는 것은 그 지식 자체가 정확함을 입증하는 근거가 전혀 되지 못한다.

2018년 10월 18일 목요일

구글플러스 검색법

블로그로 작성한 글은 별도의 검색창이 있으니 찾는데 그렇게 큰 수고가 들지 않는다. 하지만 구글플러스에 내가 쓴 글을 찾는 방법을 아직도 잘 모르고 있었다. 연주회가 끝나고 기타연주자 박규희 씨와 찍은 사진을 구글플러스에서 찾느라 애를 먹은 적이 있었다.

구글을 로그아웃한 뒤 구글 검색창에 숫자로 된 내 아이디를 넣으면 내가 쓴 공개글이 다 보인다고 한다. 이외에도 몇가지 유용한 팁이 다음에 소개되어 있다.

https://plus.google.com/+googlekorea/posts/XND1ENoA3Mc

Whizz Xanadu 님이 쓴 글이다.

그런데 구글플러스 숫자 계정을 어떻게 확인해야 할까? 구글플러스 -> 프로필을 클릭하면 주소창 맨 끝에 숫자 계정이 잠깐 나왔다가 순식간에 '+영문이름'으로 바뀐다. 너무나 당연하고 간단하지만, 평소에는 일부러 찾아보지를 않으니 알 수가 없다.

또 검색을...

이렇게 짧은 글을 구글플러스가 아니라 블로그에 남기는 것은 나중에 쉽게 검색을 하기 위함이다. 아, 부끄럽다.

Plasmid Profiler 삽질기

100 건이 넘는 다제내성 Acinetobacter baumannii의 MiSeq read에 대해서는 잘 돌던 Plasmid Profiler가 40 건의 대장균 시퀀싱 결과물에 대해서는 에러를 토해내었다. 벌써 며칠째 제자리 걸음인지를 모르겠다. Plasmid Profiler를 제외하면 Galaxy를 쓰지 않으니 익숙하지 않은 시스템에서 출력하는 에러 메시지를 접해도 해결하기는 곤란할 것이라고만 짐작하였다.

파이프라인의 맨 끝까지 가서 png/html/csv 파일을 만들어내는 R 스크립트가 제대로 결과를 내지 못하는 것이 직접적인 이유였다. 이 스크립트는 사용자가 워크플로우를 실행하면서 입력하는 4 가지 파라미터 이외에 두 종류의 중간 결과 파일(BLAST TSV, SRST2 TSV)을 이용하게 된다. 에러 메시지를 직접 확인해 보았다. BLAST TSV 파일을 파싱하는데 서열 중간에 하이픈이 있다는 것이다. Plasmid Profiler가 기본적으로 제공하는 DB 파일은 플라스미드 서열 및 replicon + AMR(antimicrobial resistance) 서열 파일의 두 가지이다. 그런데 두번째 파일에서는 기본 제공된 AMR gene이 얼마 되지 않는다. 그래서 내가 ResFinder에서 항생제 내성 유전자 서열을 가져다가 기존 DB 파일 뒤에다가 추가를 한 뒤 사용을 했었다. 에러가 발생한 FASTA file의 라인 번호를 찾아가 보았다.


어라? '>'가 나오는 위치에서 줄바꿈을 하지 않은 것이었다. 이 라인은 줄을 바꾼 뒤 다음과 같이 시작하도록 고쳐야 한다.

>(AMR)mcr-1_1_KP347127

Acinetobacter baumannii의 시퀀싱 결과물을 분석할 때에는 이 AMR gene에 대한 hit가 없어서 에러가 발생하지 않았던 모양이다. 이 라인을 수정한 뒤 다시 프로그램을 실행하였다. 그런데 또 비슷한 종류의 에러가 발생하였다. 여기 말고도 줄바꿈 실수가 있었던 곳에 다섯 군데나 더 있었던 것이다. 분명히 Perl 스크립트를 짜서 DB 파일을 수정한 것으로 아는데 왜 중간의 몇 줄에서만 오류가 발생했는지 그 이유를 모르겠다.

DB 파일 전체를 대상으로 줄바꿈 오류를 전부 수정한 뒤 테스트 데이터셋을 투입하여 Plasmid Profiler를 돌려 보았다. 이제 제대로 된 heat map이 나오기 시작한다. 이 문제로 말미암아 약 삼일을 낭비하였다. 서열 분석에서 다루는 데이터 파일에 오류가 없는지를 가끔은 점검해 볼 필요가 있다는 단순하고도 심오한 진리를 깨달았다.

글을 끝마치기에 앞서서 Enterobacteriaceae family의 플라스미드 서열 데이터셋을 하나 소개한다. 구조화된 데이터가 아니므로 database가 아니라 dataset이라 하였다.

A curated dataset of complete Enterobacteriaceae plasmids compiled from the NCBI nucleotide database. Data in Brief 2017 PMC

학술용 data를 figshare에서 공유한다는 것이 특이해서 지난주에 내 블로그에도 글을 올렸었다(링크).

2018년 10월 16일 화요일

정류용 브리지 다이오드 주변에 0.01 uF 바이패스 캐패시터를 연결하는 이유

인터넷에서 프리앰프 회로를 뒤적거리다가 정류회로의 브리지 다이오드 주변에 4개의 0.01 uF 캐패시터를 연결한 것을 보게 되었다. 다음의 그림은 4S Universal Preamplifier for 12A?7 Valves에서 인용한 것이다. 이 전원회로는 Mark Houston이 작성한 것으로서 원래 Matt Renaud가 제안 간단한 프리앰프에 기초한 것이다(원본). Matt의 원본 회로에서는 정류관을 쓰고 있다.

그림 출처: diyaudioprojects.com

정류용 다이오드 주변에 소용량 캐패시터를 병렬로 배치한 것을 가끔 본 일이 있어서 그 이유가 궁금하였다. 해답은 Designing a Power Supply(Augustica Technologies)에서 찾았다.

그림 출처: Augustica Technologies.
정류용 실리콘 다이오드는 입력된 전압이 0.7 V를 넘어야 출력을 내기 시작한다. 따라서 교류가 입력되는 경우 0 V 근처에서 전혀 전류가 흐르지 않는 dead zone이 대칭적으로 생기게 된다. 유도성 소자인 트랜스포머는 이렇게 회로가 끊어진 것과 동등한 상태에서 유도 기전력을 발생한다. 트랜스포머 내부의 부유 용량(stray capacitance) 덕분에 유도 기전력이 너무 높아지지는 않지만, 이것이 발진을 일으킬 수도 있다. 0.01 uF 필름 캐패시터는 이를 바이패스시켜 제거하는 역할을 한다.

코일의 유도기전력은 전원이 차단될 때 더 심하다. 인덕터의 기초지식 가장 처음에 나오는 그림을 참고하라.

2018년 10월 12일 금요일

figshare에 데이터 파일을 올리고 공유하기

Elsevier의 학술지 Data in Brief에 소개된 어떤 유전체 서열 데이터셋의 파일을 받기 위해 URL을 확인하니 figshare였다. figshare는 (파워포인트) 문서 파일 정도를 올려서 공유하는 사이트가 아니었던가? 아, 그건 slideshare였던가? 그런지도 모르겠다.

웹사이트를 방문하니 Store, share, discover research라는 문구가 보였다. Elsevier와 협정을 맺고서 이 저널에 출판되는 논문에 부속되는 대용량 데이터에 한해서 업로드 및 공유가 가능한 것인지, 혹은 이 저널과 관계없이 누구나 회원 등록을 하면 데이터를 올릴 수 있는 것인지는 잘 모르겠다. 데이터 등록 요령 사이트를 방문해 보았다.

How to upload and publish my data

개인 공간에는 20 GB를, 공개하는 경우에는 용량에 제한이 없다고 한다. 한번에 올릴 수 있는 파일의 크기는 5 GB이다. 그러면 어떻게 수익을 창출하는지 매우 궁금하다. 혹시 이것 역시 공공 기관에서의 접속이 막혀있는 것은 아닌지 모르겠다. 구글 드라이브나 드롭박스가 그랬듯이 말이다. 백문이 불여일견이다. 회원 등록을 하고 웹 인터페이스에 논문 PDF 파일을 하나 드래그하여 넣었다. 나에게 저작권이 있는 것이 이나니 'Publish' 버튼을 클릭하지는 않았다.

잘 들어간다. 채워야 하는 메타데이터는 다음과 같다.


남들도 다 아는 것을 뒤늦게 발견한 것은 아닌지 모르겠다. 공공 목적이 큰 데이터라면 여기에 올리는 것도 좋을 것 같다는 생각이 들었다. 학술 목적이 아닌 것이면 또 어떠랴.

Publish or perish가 아니고 이제는 Share or perish의 시대가 되었는지도 모르겠다. 약간 냉소적으로 말한다면 공개는 곧 미덕이므로 '사생활도 없다'.

Awk를 이용한 간단한 텍스트 파일 조작(join)

Awk는 개발자 세 사람 - Alfred Aho, Peter Weinberger 및 Brian Kerninghan - 이름의 머리글자를 따서 명명된 프로그래밍 언어이다. 이들은 전부 1940년대 초반에 출생하신 원로이다. 아마추어 무선을 하는 사람을 일컫는 ham (ham radio)역시 무선통신의 역사를 세운 세 사람의 이름인 Hertz, Armstrong, Marconi에서 왔다는 설도 있으나 이는 근거가 없다고 한다(Etymology of ham radio). 여담이지만 우리나라에서는 radio라 하면 공중파 방송을 듣는 라디오 수신기만을 생각하지만, 미국에서는 무선을 이용한 모든 활동을 뜻하는 것 같다. 무전기(휴대용 및 거치형 전부)를 two-way radio라고도 부른다고 하니 말이다.

우선 첫번째 AWK 사례를 설명해 보자. 왼쪽과 같이 의 조합으로 이루어진 단순한 텍스트 파일이 있다고 가정한다. 이를 오른쪽처럼 변환하려면 어떻게 하면 좋을까?


이때 awk의 associative array(예제 링크)가 쓰이게 된다. Associative array는 숫자가 아닌 것도 인덱스로 사용할 수 있는 배열을 의미한다. Perl에서 흔히 사용하는 hash와 매우 유사하다. 위에서 기술한 매우 간단한 과업을 수행하려면 다음의 명령어 한 줄이면 된다.
$ awk -F, '{a[$1] = a[$1] FS $2} END{for (i in a) print i a[i]}' file
-F,는 입력 파일의 field separator를 쉼표로 지정한다는 뜻이다. {}으로 둘러싼 AWK 명령어 내부에서는 FS가 같은 의미로 쓰였다.

다음으로는 두 텍스트 파일을 공통된 컬럼 값으로 묶는 약간 복잡한 응용 사례이다. Using Awk to join two files based on several columns를 참조하였다. 여러 컬럼으로 이루어진 두 개의 텍스트 파일 file_a.bed와 file_b.bed가 있다고 가정하자. 첫번째 파일의 컬럼 1-2와 두번째 파일의 컬럼 3-4가 동등한 종류의 내용을 담고 있다. 빨갛게 표시한 것은 값 자체가 같은 것이다. 컬럼을 구분하는 것은 공백이 아니고 탭문자이다.

$ cat file_a.bed
chr1 123 aa b c d
chr1 234 a b c d
chr1 345 aa b c d
chr1 456 a b c d
$ cat file_b.bed 
xxxx abcd chr1 123 aa c d e
yyyy defg chr1 345 aa e f g

이때 다음과 같이 두번째 파일에서 동일한 라인에 해당되는 결과를 끌어다가 첫번째 파일의 해당되는 라인에 출력하는 것이 목적이라고 하자. 아래 그림에서는 파랑색으로 표시하였다.

chr1 123 aa b c xxxx abcd
chr1 234 a b c
chr1 345 aa b c yyyy defg
chr1 456 a b c

다음과 같이 awk 명령어를 작성하면 된다(명령어 1).

$ awk 'NR==FNR{a[$3,$4,$5]=$1OFS$2;next}{$6=a[$1,$2,$3];print}' OFS='\t' file_b.bed file_a.bed

읽어 들인 라인에 대해서 associative array가 어떻게 작동하는지는 이 글의 뒷부분에 [Awk associative array의 활용 예제]를 통해서 설명하였다. 먼저 awk의 내장 변수에 대해서 이해를 넓힐 필요가 있다. NR는 현재 처리 중인 라인 번호를 의미한다. Awk가 여러 파일을 처리하는 경우 NR은 전체 파일에 대한 라인 번호를, FNR은 각 입력 파일에 대한 라인 번호를 의미한다. 다음을 실행해보면 감이 잡힐 것이다. 인수로 주어진 파일은 두 개이지만, awk는 라인 단위로 순차적인 처리를 하게 되므로 첫 번째 파일(file_a.bed)에 대해서 작업을 먼저 한 뒤, 이어서 두 번째 파일(file_b.bed)를 가지고서 일을 하게 된다.

$ awk '{print FILENAME, NR, FNR}' file_a.bed file_b.bed
file_a.bed 1 1
file_a.bed 2 2
file_a.bed 3 3
file_a.bed 4 4
file_b.bed 5 1
file_b.bed 6 2

명령어 1을 실행할 때 언제 NR==FNR{}의 조건을 충족하게 되는가? 첫 번째 파일에 대한 작업을 할 때이다. 즉, 첫번째 인수로 주어진 파일(file_a.bed)에 대해서 {} 내의 명령을 실행하라는 뜻이다. next는 그 다음에 따라오는 {} 명령어 블록을 실행하지 말라는 뜻이다. 이것은 대단히 중요하지만 약간 어려운 개념이다. 그림으로 설명을 해 보겠다. 부디 내가 이해한 것이 옳기를 바란다. 별도로 작성한 글 awk와 sed를 사용하여 multi-fasta 파일의 서열 ID를 일괄적으로 바꾸기에서도 next문의 중요성을 설명하였다.

numbers라는 파일은 각 라인에 1..10까지의 숫자를 수록하고 있다. 각 라인의 수와 홀수 또는 짝수줄 여부를 화면으로 프린트하려면 어떻게 하는지를 다음의 그림에 설명하였다. next가 왜 중요한지를 잘 보여준다.


그러면 다시 원래의 awk 문으로 돌아가자. 두번째 인수로 주어진 file_a.bed에 대해서는 NR==FNR이 FALSE가 된다. 따라서 두번째 {} 내부의 명령어를 수행하게 된다. 즉 file_a.bed를 읽어서 마지막 필드($6)를 associative array의 값으로 바꾸어서 프린트하게 된다.

어쩌면 if..else를 쓰는 것이 좀 더 명확할지도 모르겠다.

$ awk '{if(NR==FNR){a[$3,$4,$5]=$1OFS$2}else{$6=a[$1,$2,$3];print}}' OFS='\t' file_b.bed file_a.bed

첫번째 주어진 답을 다르게 표현하면 이렇게 된다. 오히려 이것도 이해하기 쉬운 해결책이다.

$ awk 'NR==FNR{a[$3,$4,$5]=$1OFS$2}NR!=FNR{$6=a[$1,$2,$3];print}' OFS='\t' file_b.bed file_a.bed

awk에서 다음을 잘 구별하는 노력이 필요하다.
  • 조건{...} {...} <= 조심해서 써야 한다!
  • 조건{...;next}{...} <= 이 사례는 의외로 유용하다. 어떤 조건을 만족하는 라인은 조작을 가해서 출력하고, 조건을 충족시키지 않는 것을 그대로 출력하는데 좋다. FASTA file의 서열 ID만 바꾸는 경우가 이에 해당한다. sed로도 이렇게 할 수 있을까>?
  • 조건1{...} 조건2{...}
  • if문을 사용하는 것

[업데이트] Awk associative array의 활용 예제

이 글을 추가로 써 넣으면서 걱정이 앞서기 시작하였다. awk는 그렇게 고수준의 언어가 아니라서 복잡한 일을 시키기는 곤란하다. 아래에서 든 예제 및 결과를 나중에 다시 찾아보았을때 어떻게 동작하는지를 이해하지 못하게 될까봐 고민이다. 자주 읽어보고 실습을 해 보는 것이 해결책이다.

두 개의 파일(file_a, file_b)를 갖고 있다고 가정하자. 첫번째 파일 file_a는 자료를 담고 있고, 이 중에서 첫번째 컬럼에 특정 값이 있는 경우 그 라인만을 뽑아내고 싶다. 해당되는 값은 두번째 파일 file_b의 첫번째 컬럼(key)에 담겨 있다. 만약 file_b가 하나의 컬럼만으로 구성되어 있다면 shell 환경에서 grep -f file_b file_a라고 입력하면 된다. 그러나 파일이 길어지면 속도가 느려질 것이 뻔하고(file_b에 수록된 패턴 한 줄에 대해서 file_a 전체를 훑는 일을 계속 반복해야 하므로), file_a의 해당되는 라인을 출력하는 것 이외의 일은 하지 못할 것이다.

$ cat file_a
1 A
2 B
3 C
4 D
5 E
6 F
7 G
8 H
9 I
10 J
$ cat file_b
7 seven
3 three
6 six
2 two

첫번째 파일을 그대로 출력하되 두번째 파일에서 정의된 라인 뒤에 특별한 표시를 하는 것이 작업 목표이다. 표시할 값은 두번째 파일의 두번째 컬럼(value)에서 나열한 값이다. 실생활에서 쉽게 접할 수 있는 사례를 들자면 한 파일에는 학번과 과목별 점수가, 다른 파일에는 학번과 이름이 적혀 있는 상황에서 학번, 이름, 점수를 표시하는 일과 같은 것을 생각하면 된다. 두 파일에서 동일한 성격의 값이 수록된 필드, 즉 첫번째 컬럼이 동일한지를 살피는 것이 핵심이다. 만약 두번째 파일에 엉뚱하게 '0 zero'가 있다면 어떻게 할 것인가? 이것까지는 해결하지 못한다.

$ awk -F '\t' 'NR==FNR{a[$1]=$2;next}{$3=a[$1];print}' OFS='\t' file_b file_a
1 A 
2 B two
3 C three
4 D 
5 E 
6 F six
7 G seven
8 H 
9 I 
10 J 

아니면 지정된 라인만 출력하고 싶다. 이건 조금 더 까다롭다. 왜냐하면 if(..){..} 구문이 들어가야 하기 때문이다.


$ awk -F '\t' 'NR==FNR{a[$1]=$1;next}{if($1==a[$1]){print}}' OFS='\t' file_b file_a
2 B
3 C
6 F
7 G

지정된 라인만 출력하되 약간의 장식을 하려면 두번째의 array가 필요해진다. b[$1]=1이라 선언하고 뒤의 if문에서 b[$1]==1로 하는 것이 좀 더 간단하다. Perl이라면 hash를 이용하면 되고, if exists $seen{$key} 구문을 이용하여 주어진 key를 갖는 hash가 존재하는지를 점검할 수 있다. 그러나 awk에서는 그렇게까지 하지 못하기 때문에 두번째의 associative array인 b[]를 도입하게 된 것이다.

$ awk -F '\t' 'NR==FNR{a[$1]=$2;b[$1]=$1;next}{if(b[$1]==$1){$3="FOUND!";print}}' OFS='\t' file_b file_a
2 B FOUND!
3 C FOUND!
6 F FOUND!
7 G FOUND!

$ awk -F '\t' 'NR==FNR{a[$1]=$2;b[$1]=$1;next}{if(b[$1]==$1){$3=a[$1];print}}' OFS='\t' file_b file_a
2 B two
3 C three
6 F six
7 G seven

위의 사례에서는 file_a에서 원하는 라인을 그대로 출력해 놓고 라인의 끝에 추가적인 컬럼을 덧붙이는 형식이었다. 군더더기 없이 file_a를 그대로 출력하되 숫자 자리(첫번째 컬럼)를 아예 치환하고 싶다면?

$ awk -F '\t' 'NR==FNR{a[$1]=$2;b[$1]=$1;next}{if(b[$1]==$1){$1=a[$1];print}}' OFS='\t' file_b file_a
two B
three C
six F
seven G

위 예문을 기초로 하여 여러 가지 응용과 변형을 가해 보는 것이 좋을 것이다.

2018년 10월 9일 화요일

43번 오극관(43 power pentode) 싱글 앰프 프로젝트 - [7] 최종 마무리

얼핏 보아서는 어제 찍어서 올린 사진과 별로 다르지 않다.


전원 트랜스와 정류회로 사이를 배선을 납땜으로 처리하였다. 오늘 아침까지는 악어클립 케이블이었다. 그리고 스피커 연결을 위한 바인딩 포스트를 아예 출력 트랜스 받침대에 고정해 버렸다. 출력 트랜스를 다른 앰프에도 연결하여 사용하기 쉽게 만들기 위한 사전 포석이다. 어수선한 배선들도 케이블 타이로 조여서 정리하였다. 전선을 깔끔하게 잘라내지 못하고 길게 유지하는 좋지 못한 버릇이 있다. 그러나 이렇게 프로토타입 형태로 만든 상황에서는 나무판에 고정한 부품을 잠시 떼어서 손을 볼 때 배선이 너무 짧으면 불편하다.


https://www.vivatubes.com/ 에서는 Super Silvertone을 포함한 브랜드의 43번 중고 5극관을 판매한다. 이베이 등에서도 이따금 눈에 뜨인다. 43번 오극관은 40번대 두자릿수 출력관 중에서 그렇게 고급 취급을 받지는 못하는 것 같다.

2018년 10월 8일 월요일

43번 오극관(43 power pentode) 싱글 앰프 프로젝트 - [6] 전원 스위치 장착

43번 오극관 싱글 앰프는 계속 변화의 길을 걷고 있다. 이번에는 전원 스위치를 달았다. 각재로 만든 R-core 출력 트랜스 받침대도 미처 설명을 하지 않았지만 개조를 하여 바닥 면적을 좁혔다. 이 시리즈물의 다섯번째 글(링크)의 사진을 보면 트랜스 받침대에 하얀 신발끈을 묶어 놓은 것이 보일 것이다. 톱질을 하여 길이를 줄인 뒤 목공용 접착제를 발라서 고정해 놓은 것이다.

아래의 사진은 어제까지의 작업 결과물이다. 약간 다른 각도에서 두 장의 사진을 촬영하였다.



왼쪽 끝의 전원 스위치 고정대는 'ㄱ'자형 알루미늄 판에 1t 포맥스판을 순간접착제로 붙인 것이다. 알루미늄판에 실톱으로 가공을 하다가 구멍을 너무 크게 뚫어버리는 바람에 이렇게 된 것이다. 포맥스는 가공성이 매우 좋으며 그 위에 글씨를 쓰거나 도색을 하기에 아주 좋지만 아무 처리를 하지 않으면 때가 잘 탄다.

램프형 파워 스위치(정식 명칭은 SPST illuminated rocker switch; SPST = single-pole, single-throw = 단극단투 스위치)를 달다가 실수를 하였다. 전원이 들어올 때 불이 켜지게 하려는 것이 원래 의도였으나 배선을 잘못하여 항상 불이 켜지는 것이 아닌가. 이에 대해서는 예전에 글을 작성해 둔 적이 있다(램프형 스위치의 올바른 결선법).


그런데 제품에 따라서는 핀 번호가 다르다. 다음을 보라. 위의 그림과 달리 가운데의 공통핀이 1번이다.

출처: https://www.fasett.info/spst-illuminated-rocker-switch-wiring-diagram/unusual-lastest-collection-lighted-rocker-switch-wiring-diagram/
따라서 배선을 하기 전에 꼭 확인을 하는 것이 현명하다.

아직 납땜을 하지 않고 악어클립으로 물어 놓은 곳이 있다. 두 개의 전원 트랜스 사이, 그리고 두번째 전원트랜스와 정류회로 사이이다. 첫번째 트랜스에서 나오는 13 V를 두번째 트랜스의 12 - 15 - 18 V에 취향껏 연결함으로써 B+ 전압을 선택하는 효과를 누릴 수 있기에 아직 어느 하나의 탭에 붙이지를 않은 것이다.

저전압(그래도 100 볼트를 넘는다)에서 작동하는 진공관 앰프가 매력이 있다!


FM 수신용 안테나 보수하기

발코니 난간에 현 상태로 FM 수신용 안테나가 설치된 것은 지금으로부터 꼭 3년 전이었다.

옥외용 FM 안테나 재설치(2015.9.6.)
FM 안테나 설치 상태 변경(2015.9.20.)

붐대(커튼용 봉을 자른 것)와 안테나를 고정하는데 케이블 타이를 몇 군데 사용하였었다. 이것이 햇볕에 장기간 노출되면서 하나씩 끊어지기 시작하였고, 급기야 안테나가 한쪽으로 기울었다. 다른 곳을 노끈으로 묶어 놓았기에 안테나가 추락할 염려는 없지만 보수 작업이 필요한 상태이다. 무엇보다도 케이블 타이를 대체할 다른 고정 장치가 필요하다. 그래서 택한 것은 바로 다음의 물건이다.


붐대와 안테나 암(arm; 도파기와 방사기 엘리먼트를 고정하는 중앙의 짧고 두꺼운 봉)이 이 부속에 의해서 전기적으로 접촉 상태에 있다는 것이 안테나의 성능에 영향을 미치게 될지는 잘 모르겠다. 안테나 엘리먼트가 발코니 난간 등 다른 금속성 물체에 닿지 않게 하나는 것은 안테나 설치의 상식이다. 이번 경우는 엘리먼트 자체가 아니므로 상관이 없지 않을까? 다른 기성품 안테나의 사진을 찾아보면 내가 사용한 부품에 해당하는 것에서 절연처리를 한 것은 보이지 않는다. 원래 이 물건은 대형 모니터 고정용 부속인데 엉뚱한 곳에서 최종 용처를 찾았다.

10월 초순의 햇살은 여전히 강렬하여 땀을 뻘뻘 흘리면서 설치 작업을 하였다. 아래 사진에서 붐대와 화분 설치대를 묶은 것은 운동화 끈이다. 합성수지로 만들어진 끈(케이블타이 포함)은 이러한 조건에서 사용하기에 적당하지 않다는 것을 알았기 때문이다. 물론 힘을 많이 받지 않는 곳에는 사용해도 괜찮다.

이 안테나는 우리집 기준으로 서쪽에 위치한 계룡산 송신소를 향하고 있다. 남쪽으로는 식장산 송신소가 위치한다. KBS Classic FM 청주(식장산)과 대전(계룡산) 방송을 전부 들을 수는 있는데 MBC FM(식장산)에 비하면 방송 수신의 질이 나쁘다.

새로 만든 진공관 앰프와 보수를 마친 안테나가 FM 방송 청취의 즐거움을 더한다.

2018년 10월 7일 일요일

43번 오극관(43 power pentode) 싱글 앰프 프로젝트 - [5] 발열과 험 문제 개선

나무판 위에 부품을 얼기설기 늘어놓아 만든 앰프는 계속 손길을 필요로한다. 케이스 안에 넣어버리면 귀찮다는 이유로 사소한 문제를 방치하고 싶을 것이다. 사실은 결코 사소한 문제가 아닐 수도 있다.

이번에 만든 43번 5극관은 꽤 좋은 소리를 내고 있다. 하지만 아직 완성의 단계는 아니다. 첫번째 문제는 히터 공급용 배전압 정류장치의 전류제한 저항에서 너무 열이 많이 난다는 것이다(아래에 보인 회로도에서 빨강 타원으로 둘러친 것). 5와트의 정격을 넘는 수준은 결코 아니나, 저항과 닿은 코팅 합판의 표면이 까맣게 탈 정도라면 방열 대책을 세워야 한다. 이 저항에 다이오드를 연결하는 리드선 역시 매우 뜨겁다. 저항에서 나는 열이 리드선을 타고 다이오드까지 가는 것 같았다.


재활용 부품을 이용하여 저항에 방열판을 달아주기로 하였다. PC용 파워서플라이에서 뜯어낸 방열판과 못쓰는 그래픽 카드의 마더보드 고정용 부속을 이용하였다. 직접 연결된 저항과 다이오드 사이를 끊은 다음 두꺼운 선재를 사이에 넣어서 연결하였다. 저항에서 발생한 열이 리드선을 타고 가지 말라는 의도였다. 시멘트 저항과 방열판 사이에 방열 시트를 삽입하여 잘 밀착하게 만든 다음 사무용 악어클립으로 고정하였다.



살다보니 저항에 방열판을 다는 일이 다 생긴다. 작동을 시키면서 발열 정도를 체크해 보았다. 방열판이 손을 댈 수는 있을 정도로 뜨거워진다. 방열 처리를 하기 전에는 거의 100도에 육박했을 것이다. 그런데 이렇게 한 이후에도 다이오드는 여전히 전과 같은 정도로 뜨겁다. 그렇다! 다이오드가 뜨거워진 것은 저항과 연결한 리드선을 타고 열이 전달되는 것이 아니라 다이오드 자체의 발열이었던 것이다. 1N400x 다이오드의 최대 작동 온도는 150도 가량이다. 이를 위협할 정도로 열이 나지는 않겠지만 신경을 늘 쓰는 것이 좋을 것이다.

다음은 험(hum)을 잡는 문제이다. 트랜스를 차폐하고, 회로를 금속제 섀시에 꽁꽁 가두고, 접지를 하고... 이런 대책들이 보통 요구된다. 나무판 위에 부품을 그대로 노출시켜서 만들면 온갖 잡음이 유입된다는 의견을 모르는바 아니지만, 합리적으로 잘 만들어진 앰프라면 충분히 극복 가능하다고 생각한다.

현재의 상태에서는 분명히 험이 들린다. 이는 볼륨 폿(프리앰프에서 조절)의 위치와는 무관하고, B 전압을 낮추면 줄어든다. 이를 어떻게 잡아야 하나? 해결책은 전원부에 RC 필터를 하나 더 추가하는 것이었다. 다음 회로도에서 빨강 점선 박스로 둘러싼 부분을 삽입하여 험을 사실상 제거하였다. 처음 설계할 때에는 이 필터를 사용하지 않았었다.

데이터시트에 의하면 플레이트와 스크린 그리드에는 같은 전압을 걸어도 된다고 하였다(95 V 혹은 135 V). 현재의 작동 전압은 110 V 수준(바이어스 전압 포함)이다. 따라서 100R과 470R 사이에서 OPT 및 스크린 그리드로 직접 연결하거나, 혹은 470R-47uF 필터를 제거해도 문제가 없어야 한다. 하지만 이렇게 회로를 바꾸면 스피커에서 험이 들린다. 왜 그런지는 알 수 없다(2018년 10월 16일 추가).

위의 그림에서 'Rectifier & filter'라고 표현된 파랑 상자는 PC의 파워서플라이 기판에서 잘래낸 것을 활용함을 의미한다. 이 회로의 출력부에 대용량의 전해 캐패시터가 이미 존재하므로 추가적인 캐패시터는 없어도 될 것이라고 생각했었다. 하지만 PC 파워서플라이에서는 입력 전압을 정류하여 반분한다. 다음 그림을 보면 빨강 원으로 표시한 곳에서 전선을 뽑아내어 진공관 B 전압용으로 쓰는 셈이다. 대용량의 캐패시터가 두 개 있지만 이들 각각은 출력 전압을 반분하는 곳에 걸쳐있다. 빨강색에 해당하는 곳을 직접 가로지르는 캐패시터는 없는 셈이다. 내가 삽입한 47 uF 캐패시터(100R 저항과 함께)가 정류후 남은 리플을 제거하는 효과가 있다고 생각하기로 했다. 대부분의 진공관 앰프용 전원회로가 이러한 형식을 따르고 있음을 물론이다.

그림 출처: https://www.pocketmagic.net/wp-content/uploads/2012/05/simple_smps_5.png

내가 만드는 진공관 앰프는 모두 이렇게 초크 코일이 없는 구조를 하고 있다. 그러나 음질에 특별한 문제가 느껴지지 않는다.

여기에 보인 RC 필터가 잡음 제거에 결정적인 역할을 하였다.



어제까지 끝낸 작업의 결과물이다. 오른쪽에 보이는 프리앰프도 나무판 위에 고정하였고, 남는 외가닥 인터케이블(노랑색 RCA 커넥터를 보라)을 잘라서 프리앰프를 연결하였다. 스피커를 연결하는 바인딩 포스트의 고정 방법도 바꾸었다.

하루 종일 소스를 연결하여 음질과 발열 상태 등을 점검하고 있다. 내 막귀로는 충분히 듣기 좋은 소리가 난다. 솔직히 말해서 다른 앰프와 무엇이 다른지를 잘 모르겠다. 6N1+6P1 싱글 앰프에 비하면 조금 더 부드러운 것 같기도 하다.

남은 일은 전원 스위치를 다는 일 정도이다. 이 앰프는 앞으로도 계속 실험의 대상이 될 것이므로 당분간은 섀시에 넣지는 않을 것이다. 순전히 호기심으로 시작된 프로젝트였지만 지금 생각해보니 뛰어들지 않았더라면 정말 후회했을 것이다.

2018년 10월 4일 목요일

43번 오극관(43 power pentode) 싱글 앰프 프로젝트 - [4] 조립 및 테스트

글 제목을 결정하기에 앞서서 약간의 고민을 하였다. '완성'이라고 할까, 아니면 '가조립'이라고 할까? 매우 간단한 5극관 전력증폭회로의 이해와 실습을 겸한 이번 프로젝트는 애초에 멋진 섀시를 꾸미는 것을 목표로 하지 않았었다. 따라서 현재의 상태로도 충분히 '완성'이라고 말해도 틀린 것은 아니다.

그러나 나무판 위에 대충 올려진 부품들을 보면 - 완벽한 소리를 들려주고 있다 하여도 - 언젠가는 싫증이 날지도 모르는 일이다. 그래서 앞으로 후속 작업이 있을 수도 있다는 여운을 남기기 위해 '조립'이라고만 하였다. 먼저 회로도를 소개한다. 오른쪽 위에 보인 5극관 전력증폭회로의 기본 모양은 Harry Lythall의 웹사이트("Valve basics")에서 빌려온 것이다.


전력증폭회로 앞에는 소위 초단 혹은 드라이브단에 해당하는 회로가 있어야 한다. 이번 프로젝트에서는 이미 내가 갖고있던 프리앰프를 쓰기로 했기에 이렇게 간단하게 앰프를 꾸미는 것으로 충분했다. 실제로 이 회로에 튜너를 직접 연결했더니 스피커(89 dB SPL/W/m)에서 미약하게 소리는 남을 확인하였다.

전원부를 미리 만들어 두었었기에 개천절 휴일 오전을 투자하여 조립을 마쳤다. 너무나 간단한 회로라서 오배선을 할 여지가 없었고 소리가 나오는 것을 확인하였다. 43번 5극관 두 개의 특성이 똑같지는 않아서 같은 고전압을 걸었지만 그리드와 플레이트에 배분되는 정도가 다르다. 그리드 전압은 대충 -13 ~ -15 V 수준이 나왔다. 플레이트 전압은 105 V 정도였다. 아마 출력은 1 와트 내외가 될 것이다.

저녁때에는 튜닝(이라는 표현을 쓰기에도 부끄럽지만...)을 하여 만족할만한 소리를 내게 만들었다. 오전 작업 때에는 스크린 그리드와 접지 사이에 아무런 캐패시터를 연결하지 않았더니 '웅~'하는 소리가 매우 심하게 나는 것이었다. 험(hum)인가? 아니면 발진인가? 고전압부의 정류 및 평활회로를 다른 것으로 바꾸어도 소용이 없었다. 초크 코일을 쓰지 않아서 그렇다고 생각하기는 싫었다. 제이앨범을 비롯한 다른 웹사이트를 방문한 기억을 되살려 스크린 그리드와 접지 사이에 47 uF 캐패시터를 삽입하였더니 이 잡음은 상당한 수준으로 줄어들어서 실제 음악감상에는 별 문제가 없을 수준으로 되었다. 아주 잘 만든 진공관 앰프의 배경 잡음과는 비교할 수 없겠지만, 취미 수준으로 만드는 앰프에서는 참을 수 있는 정도라고나 할까?



차마 보이기 부끄러운 배선 모습.



광활한(?) 합판을 이렇게 비능률적으로 사용하다니, 배선 모습을 보이기에는 너무나 부끄럽다. 데스크탑 앰프로 쓰기에는 너무나 크다. 물론 처음부터 그럴 생각은 별로 갖고 있지 않았다.

앞으로 어떤 일이 남았는가? 우선 전원 계통의 배선은 아직 악어 클립으로만 연결한 상태이므로 확실하게 납땜을 해야 한다. 필요하다면 전원 스위치(스파크 킬러를 넣으면 더욱 좋을 것이다)도 설치해야 한다. 그리고 프리앰프부를 이렇게 두지 않고 다른 실험을 할 수도 있다.

라디오에 널리 쓰이던 골동품 수준의 진공관을 사용하느라 히터 전압을 만들기 위해 전원부가 예상보다 복잡해졌다. 그러나 HV 자체가 ~120 V 수준으로 별로 높지 않아서 비교적 안전하게 사용 및 개조를 할 수 있다.

매우 즐거운 경험이었다. 기획부터 실행 완료까지 걸린 시간이 생각보다 길지 않았다. 연말까지는 더 이상 일을 벌이지 말아야 되겠다.

2018년 10월 2일 화요일

만약 인공지능 변호사가 일반화된다면

중앙일보에 실린 2018년 4월 5일자 기사이다.

로펌 간 한국 첫 AI 변호사··· 검사도 놓친 분석 '단 20초'

반면에 지난 8월에는 이런 기사도 실렸다.

AI 의사 가르칠 '데이터'가 없다. 수조원 쏟은 왓슨도 '위기'
(요즘 기사 제목에는 왜 이렇게 따옴표를 많이 쓰는지 모르겠다. 별로 마음에 들지 않는다.)
AI의 미래를 내다볼 때 데이터 부족 문제는 그렇게 심각하게 생각하지 않는 것 같다. 나 역시 그러한 다소는 안이한 생각을 갖고 있다. 어쨌든 방대한 자료에 의거해서 판단을 내려야 하는 업무는 점차 인공지능이 대체하게 될 것은 자명하다. 그러면 이득을 보는 자는 누구인가? 그것이 과연 바람직한가? 이러한 질문은 나중에 생각하기로 하자.

인공지능이 변호사 업무를 일상적으로 맡는 시대가 왔다고 가정하자. 법률 사무소를 찾는 고객의 주머니 사정이 전부 똑같지는 않을 터이니, 아마도 서비스 수준에 따른 차등 가격을 제시할 것이다.

  • 500만원: 10만 건의 판례를 분석한 서비스 제공
  • 1천만원: 30만 건의 판례를 분석한 서비스 제공
두 사람 사이에 민사 소송이 진행 중이라고 가정하자. 의뢰인 갑은 500만원짜리 AI 변호사를, 의뢰인 을은 1천만원짜리 AI 변호사에에세 사건을 맡겼다. 누가 재판에서 이기겠는가? 더 많은 판례로 무장한 비싼 변호사가 더 유리하지 않을까? 이건 좀 불공정하지 않다는 생각이 들지 않는가? 하지만 이는 AI 변호사라서 그런 것이 아니라 사람 변호사를 쓰는 지금도 마찬가지의 일이 이미 벌어지고 있다고 말할 수 있다. 그러면 다른 사례를 들어 보자.

만약 AI 변호사를 사용하는 법률 사무소가 통폐합을 거쳐서 하나의 회사가 되어버렸다고 하자. 그러면 서로 법률적으로 다투는 두 사람은 하나의 법률 사무소에 변론을 의뢰해야 한다. 이건 좀 이상한 사례이다. A와 B라는 자연인이 서로 다투고 있는데, 둘 다 C라는 법률 회사에 소송을 의뢰한다? 그러면 C는 어떤 태도를 취해야 하는가? 서로 다른 AI 변호사를 배정하여 일체 상호작용을 하지 못하게 만들 것인가? 아니면 무조건 높은 수임료를 내기로 내기로 한 고객 위주로 일을 한다?

만약 A와 B가 주장하는 바를 C가 다 전해 듣는다면, 누가 옳고 그른지(정확히 말하자면 누가 이길 가능성이 높은지)를 미리 명확하게 알 수 있을 것이다. 그러나 이러한 판단은 누가 더 많은 돈을 지불할 의사가 있는지에 따라서 얼마든지 달라질 수가 있다.

모든 법률 회사가 하나로 통합되어버릴 가능성이 얼마나 높은지는 나도 모르겠다. 그러나 우리나라처럼 규모나 간판 크기에 사람들이 쉽게 압도되어 버리는 사회에서는 충분히 있음직한 일이다. AI 변호사를 채용한 회사에 자연인 변호사가 밀려서 도태되고, 격심한 경쟁 속에 독점 혹은 과점 체제가 될 수도 있을 것이다.

그러면 정의로운 대한민국에서는 AI 변호사로만 이루어지는 소송에 대하여 어떤 규정을 만들지도 모른다.
  1. (가능하다면) 다툼의 당사자들이 같은 법률회사에 사건을 의뢰해서는 안된다.
  2. 각 AI 변호사의 수임료 차이는 4배를 넘어서는 안된다(잘 지켜질 것 같지는 않다. 자본주의 사회에서 시장 법칙에 따라서 월등히 높은 비용을 부담하고 더 높은 질의 법률 서비스를 받을 자유를 왜 제한하느냐고 항의한다면 할 말이 없으므로).
  3. 부득이하게 (1)의 규정을 지킬 수 없을 때에는(예를 들어 다른 법률 회사가 슈퍼 갑 회사 하나뿐이라면) 의뢰를 받은 각 AI 변호사는 절대로 서로 정보를 주고받지 않는다(수임료를 포함하여). 단, 사내 공용 데이터베이스에 있는 법률집이나 판례는 같이 활용하되, 고객이 지불하기로 약정한 비용에 따라서 활용 범위가 달라지는 것은 법률 회사의 자유이다.
그러나 (3)번 조항이 과연 잘 지켜질까? 법률 회사의 경영주가 수익을 올리는 데에만 너무 골몰한다면, 여러가지의 치시한 전략을 쓸 가능성이 있다. 가장 쉬운 시나리오는 돈을 더 많이 낸 고객이 일단 이기게 만들어 주는 것. 그렇게 해서 다음에도 또 찾아오게 만드는 것이다. 물론 독점 체제가 되면 그럴 필요조차 없을 것이다.

다른 한편으로 뒤집어 생각하면, 두 의뢰인 사이의 쟁점 사항을 면밀하게 판단하여 더 많은 돈을 지불하도록 '조작'을 해 나갈지도 모른다. 재판에서 누가 이기는지는 별로 중요하지 않다. 나는 이 세계가 어떻게 돌아가는지 잘 모른다. 따라서 고객이 법률 사무소를 찾아와서 사건을 맡기고 일단 계약을 하게 되면 약정한 금액 이상의 돈이 들어가는 일이 절대로 없는지, 혹은 간혹 있는지는 알지 못한다. 그러나 불가피한 경우 특약 조항이 있을지도 모른다. 어쩌면 나중에 재판이 잘 풀리지 않을 경우 수임료를 추가로 내야 하는 특약 조항을 눈에 잘 뜨이지 않게 하여 계약서에 인쇄해 놓았을 수도 있다. 그리고 법정에서 어떤 식으로 변론을 하면 재판이 질질 늘어지면서 결국 법률회사가 최대의 수익을 가져갈 수 있는지에 대한 전략을 세울 수도 있다. 이 전략 역시 AI가 알아서 할 것이다. 

흠. 단편 소설 하나를 쓸 수 있을 것 같다. 잘 되면 영화 시나리오라도..  아니다. 그럴 생각이었으면 블로그에 쓰지 말았어야 한다. 어쨌든 AI가 만드는 이런 미래는 별로 생각하고 싶지 않다.

2018년 10월 1일 월요일

LS-BSR의 에러 해결: "File is supposed to contain nucleotides, but doesn't look correct..exiting"

Marker gene 염기서열을 읽어들이는 과정에서 이러한 오류가 발생하였다. 사용한 gene database는 Virulence Factors of Pathogenic Bacteria(다운로드 링크)의 것이다.
File is supposed to contain nucleotides, but doesn't look correct..exiting
어느 유전자 서열에 문제가 있는지 해당하는 것의 ID라도 밝혀주면 좋으련만, 위에서 보인 에러 메시지 한 줄이 전부이다. 도대체 뭐가 문제일까? 마커 유전자 파일의 일부만을 이용하면 문제가 발생하지 않는다.

혹시 FASTA 파일에 non-ATGC character가 있어서 그런 것일까? Artemis에서 확인을 해 보았다.


이게 뭐란 말인가! 비정상적인 염기 문자를 갖는 서열을 FASTA file에서 아예 삭제를 해 버릴까? 아니다. 그렇게 되면 소중한 정보를 잃는 것이 아니겠는가? 이것을 펩티드 서열로 전환하여 실행하면 어떨까? 

EMBOSS:transeq을 사용하여 염기서열 파일을 펩티드 서열로 전환한 뒤 다시 LS-BSR을 실행해 보았다. 이번에는 잘 진행이 되었다.