2021년 11월 17일 수요일

43 오극관 싱글 앰프의 개선 작업 마무리

전원 트랜스포머의 교체 및 B+ 전압 조정 작업이 얼추 끝났다고 생각하고 음악을 듣는데, 좌우 채널 전체에서 '버석 버석'하는 소리가 들리기 시작했다. 접촉 불량인가, 새로운 타입의 발진인가? 또다시 좌절감에 휩싸였다. 겨우 쌍삼극관(6N2P) 하나와 핀이 6개 달린 구형 power pentode 두 개를 가지고  점대점 결선(point-to-point wiring, 나는 하드 와이어링이라는 표현이 옳지 않다고 믿음)으로 만든 싱글 앰프 하나를 제대로 못 만들다니! 내가 X손이라니!

앰프를 뒤집어 놓고 이곳 저곳을 건드려 보았다. B+ 전원 공급을 위해 새로 만들어 넣은 기판을 움직일 때 이에 맞추어 잡음도 같이 발생하는 것을 눈치챘다. 만능기판에 납땜한 스크류 터미널의 접촉이 아무래도 문제인 것 같았다. 나사를 풀고 기판의 동박에 납땜으로 직결을 하였더니 잡음이 사라졌다.

차폐용 커버가 없는 일반(오디오용이 아닌) 전원 트랜스포머를 쓰게 되면서 전원부에서 유도되는 잡음이 이전보다는 약간 늘어난 것 같았다. 리플 제거 보드를 사용함에도 불구하고 험이 들린다는 것은 몹시 자존심이 상하는 일이다. 전원을 넣으면 전원 트랜스 자체에서도 미약하나마 울리는 소리가 난다. 아마도 유도 잡음을 유발하는 부품의 배치 문제일 것으로 여겨진다. 실용상으로는 별 문제가 없으므로 당장은 그냥 쓰기로 하였다.

잡음의 원인을 찾는답시고 출력관을 좀더 상태가 좋은 실바니아 것으로 바꾸어 끼웠다.
대단한 것을 이룬 것은 아니지만 진공관 앰프의 기본에 대하여 이해도를 높인 좋은 계기가 되었다고 생각한다. 아직도 앰프를 뒤집어 놓고 보면 손을 대고 싶은 곳이 한두 군데가 아니다. 하루 아침에 해결될 문제는 아니다. 빨리 끝내려고 할 일이 아니라 과정을 즐기는 것, 그것이 진정한 아마추어의 자세이자 특권이 아닌가 싶다. 

아마추어는 과정을 즐기고, 프로는 결과로 말한다.

2021년 11월 16일 화요일

Roary 'query_pan_genome'의 고약한 출력물

Roary: the Pan Genome Pipeline은 내가 밥 먹듯이 즐겨 사용하는 프로그램이다. 최신판은 2019년 11월 6일에 릴리즈되었으니 더 이상 개선의 여지도 없는 프로그램이 아닐까 한다. MUMmer와 같이 거의 수정도 거치지 않으면서 오랜 기간 사랑받는.

Roary의 부속 유틸리티인 query_pan_genome은 두 그룹 간의 교집합, 합집합, 또는 차집합에 해당하는 gene cluster를 추출하는 다재다능한 프로그램이다. 그룹 정보는 GFF 파일로 제공하면 된다. 예를 들어 그룹 one에는 있지만 그룹 two에는 없는 유전자를 찾고 싶다면, 다음과 같이 실행하면 된다.

$ query_pan_genome -a difference --input_set_one 1.gff,2.gff --input_set_two 3.gff,4.gff,5.gff

만약 각 그룹을 구성하는 GFF 파일이 많다면 명령행에 이를 일일이 타이핑하기가 곤란할 것이다. 그런 경우에는 fofn(file of file name)을 만든 뒤 paste 명령을 써서 쉼표를 사이에 두고 이어 붙이면 된다.

$ cat one.fofn
1.gff
2.gff
3.gff
$ one=$(paste -sd, one.fofn)

두 그룹에 대하여 이렇게 변수를 만든 다음, '--input_set_one $one'과 같은 형식으로 옵션을 주면 된다. GFF 파일이 현재 디렉토리에 없다면, fofn을 만들 때 find 명령어를 잘 이용하면 된다.

'query_pan_genome -a difference' 명령을 수행하면 'set_difference_'로 시작하는 11개의 파일이 생긴다. 그룹 one에만 있는 유전자에 대한 정보는 다음의 파일에 수록된다.

  • set_difference_unique_set_one
  • set_difference_unique_set_one_reannotated
  • set_difference_unique_set_one_statistics.csv
여기서 한 가지 주의할 것이 있다.  그룹 one에만 있는('unique') 유전자란, 그룹 one의 모든 멤버에 다 있는 것만을 포함하는 것이 아니다. 예를 들어 그룹 one이 10개의 균주(A, B, C ... J)로 이루어졌다고 하자. 그러면 set_difference_unique_set_one에는 A에만 있는 것, A와 B에 있는 것 등 별의별 녀석들이 다 섞여 있다. 만약 그룹 특이적인 유전자를 찾는 것이 목적이라면, A부터 J까지 모든 멤버에 다 있는 것을 파악해야 한다. 그러려면 위에서 나열한 세 개의 결과 파일 중 set_difference_unique_set_one_statistics.csv를 참조해야 한다.

여기에서 문제가 발생한다. 바로 gene ID가 바뀐다는 것이다. set_difference_unique_set_one의 첫 번째 컬럼은 Roary 실행 결과 파일에서 보편적으로 쓰이는 unique cluster ID를 유지하지만(cluster는 accessory gene도 포함, 즉 pan genome을 전부 아우름), set_difference_unique_set_one_reannotated에서는 GFF 파일을 참조하여 일부가 gene name으로 바뀌고, 이것이 set_difference_unique_set_one_statistics.csv로 그대로 전달된다.

실제 사례를 들어 보자. 오늘 아침에 query_pan_genome 스크립트로 Strepcococcus genus에 속하는 두 종(N=301, set one은 232개, set two는 69개)의 roary 결과를 투입하여 13683개의 set one-specific gene을 얻었다. 그런데 gene ID를 sort하여 uniq 명령어를 통과시키면 13553개만 남는다. reannotated gene ID에서 중복이 발생했다는 뜻이다.

set_difference_unique_set_one과 set_difference_unique_set_one_reannotated 파일의 나머지 컬럼에는 실제 이를 구성하는 유전자들의 ID가 있으니 그룹 자체를 건드리지는 않는다. 그러나 pan_genome_reference.fa 파일에서 set one에 특이적인 유전자(대표 서열로서)를 찾으려면 여간 번거로운 일이 아니다.

query_pan_genome 스크립트를 전혀 쓰지 않고 roary의 기본 결과 파일인 gene_presence_absence.csv를 R에서 조작하여 각 그룹 특이적인 유전자를 찾을 수는 있는데 여간 성가신 일이 아니다. 왜 query_pan_genome 스크립트는 다시 annotation을 하여 식별자를 유일하지 않은 것으로 만들어 버리는지 알 수가 없다. QueryRoary.pm를 내가 고칠 수 있는 수준의 일도 아니고...


2021년 11월 11일 목요일

43 싱글 앰프 튜닝 - 전원부 개선

전원 트랜스포머를 220V 50W 절연트랜스로 교체하고, 초단관을 12DT8에서 원래 구성이었던 6N2P로 바꾸었다. 그리고 각 진공관은 최적 B+ 전원 조건에서 구동하고자 실험을 시작하였다. 일반적인 진공관 앰프에서는 전원장치에서 출력트랜스포머를 우선적으로 연결하고, 저항으로 전압 강하를 하여 초단관의 플레이트로 보내게 된다. 그런데 구식 라디오에 쓰이던 43이라는 오극관은 요구하는 플레이트 전압이 매우 낮다. 최대 160V, 찌그러짐이 가장 적은 조건(2와트 출력)에서는 135V이다. 콘트롤 그리드에 걸리는 바이어스 전압 -15V를 감안허면 155V가 가장 적당한 수준의 전압이 된다. 그러나 드라이브단의 6N2P의 플레이트 전압은 ~250V 정도가 되어야 한다.

인터넷에 43 오극관의 데이터시트가 있다는 것이 얼마나 고마운 일인지 모르겠다. 작성일은 무려 1936년 6월 26일다.

지금까지는 43에 공급한 전압을 약간 낮추어서 6N2P에 공급하는 방식이었다. 이렇게 낮은 플레이트 전압에서 6N2P가 작동을 하지 않는 것은 아니지만, 아무리 들어 봐도 소리가 작은 것은 초단관의 동작 상태가 최적이 아닌 것에 그 원인이 있는 것 같아서 개선 작업에 착수하였다. 별 것 있겠는가? 전압을 거는 순서를 바꾸면 되지 않는가. 특히 이번 개선 작업에서는 리플 제거 보드에서 각 진공관으로 연결되는 전압 강하 회로를 채널별로 따로 만들어 보았다. 비교적 값이 비싼 국산 전해 캐패시터가 많이 들어가서 아깝다는 생각이 들었다. 테스트가 끝난 다음에 기판에서 떼어내어 재활용하기도 어려운데...

보유한 저항의 값이 다양하지 않아서 다소 이상한 모습의 회로가 되었다. 리플 제거 회로의 출력은 260V 정도이다. 2.2K옴 저항을 거치면 6N2P 부하저항에 200V 정도가 걸리게 된다. 여기까지는 아주 마음에 드는데, 43 오극관에 맞게 전압을 더 낮추는 것이 문제이다. 6.8K옴 시멘트 저항 3개를 병렬로 연결하여 2.267K옴을 만드니 드디어 120V 정도가 된다. 이보다는 약간 높은 값을 얻어야 하지만 더 이상 병렬로 이어붙일 저항이 없다.

저항의 발열을 생각하면 말이 안되는 테스트 회로이다. 2.2K옴은 겨우 2와트급이다. 3개를 병렬로 연결한 6.8K옴 시멘트 저항(각 5와트)도 매우 뜨거운데, 2와트 금속피막저항 하나가 펄펄 끓는 것은 당연하다. 대략 계산하면 2.2K옴 저항에서 약 2.2W, 시멘트 저항 3개를 병렬로 연결한 합성저항에서는 1.95W가 걸린다.  저항이 뜨거워지면, 여기에 연결된 전해 캐패시터도 덩달아 뜨거워진다. 이래서는 곤란하다. 

2.2K옴 + 1K옴 정도로 2단 구성을 하면 최종적으로 150V 가량을 뽑을 수는 있을 것이다. 문제는 적당한 저항이 없다는 것. 소리는 과거보다 더 커진 것이 확실하다.

처음부터 2차에 150V 정도 출력되는 전원 트랜스포머를 썼더라면 높은 전압을 내리기 위해서 덜 고생을 했을 것이다. 되도록 기성품으로 팔리는 일반 용도의 트랜스포머를 쓰려는 것이 취지였으니, 이런 고생을 해도 감내해야 한다.

이번 개선 작업을 통해 떼어낸 전원트랜스포머(2차 230V 120mA, 6.3V 1.6A)는 정말 무용지물이다. 진공관 앰프를 자작하면서 처음으로 주문 제작을 한 것이었는데, 전기만 통하면 정격을 넘는 것도 아닌데 요란하게 울어대니 도대체 오디오 앰프로 쓸 수가 없는 것이었다. 그래서 전단에 110V 강압트랜스(단권 트랜스라서 용량에 비해 크기는 작음)를 달아서 출력 전압을 낮게 만들어 43 앰프에 사용하였던 것이다. 겉으로 보면 알 수가 없지만, 앰프를 뒤집어 놓으면 아주 가관이다. 
전기만 흘리면 우는 전원 트랜스포머. 그림 출처는 내 블로그의 글이다(링크).
새 앰프를 만들어 보려고 알리익스프레스를 며칠 동안 뒤지다가 기존의 앰프를 개선하는 것부터 먼저 해결하기로 마음을 바꾸어 먹기를 참 잘 한 일이라고 생각한다. 이렇게 단순하고도 아름다운(!) 앰프의 기본적인 문제도 해결하지 못한 상태로 또 다른 앰프를 만든다는 것은 올바른 배움의 자세가 아니다.


2021년 11월 10일 수요일

Bactopia test - 방황의 끝(3): 공식 매뉴얼이나 도움말에서 쉽게 파악하기 힘들었던 기본 개념과 사용법 정리

Bactopia test - 방황의 끝(2) - 2021년 5월 23일 작성

이 주제와 관련하여 '방황의 끝' 혹은 '방황의 끝(1)'이란 제목을 붙인 글은 보이지 않는다. 끝나기 전까지는 끝이 난 것이 아니다! 여전히 bactopia의 공식 문서를 찾아 읽으면서 내가 뭘 잘못 이해하고 있었는지를 깨닫고 있다. 몇몇 데이터셋은 self-signed SSL certificate의 문제로 집에서 다운로드한 뒤 직장으로 가지고 나와서 복사를 하는 번거로운 과정을 거쳐야 하지만, 활용 빈도가 늘어나면서 점차 익숙해지는 중이다.

Bactopia를 설치한 뒤 가장 먼저 할 일은 데이터셋을 빌드하는 일이다. 쓰이는 명령어는 'bactopia datasets'이다. 우선 다음의 것은 species를 확정하지 않은 상태('--species STR' 파라미터를 제공하지 않음)에서 설치되는 데이터셋이다. 설치 가능한 모든 데이터셋이 궁금하면 'bactopia datasets --available_datasets' 명령어를 실행하면 된다.

  • ariba: 기본 세트는 vfdb_core와 card
  • minmer
  • amr: NCBI의 AMRFinder+ database
Species를 확정하면 prokkamlst dataset를 더 가져온다.  Prokka dataset은 유전체 주석화를 위해 미리 준비하는 단백질 서열 자료이다. RefSeq에서 complete genome('--assembly_level' 파라미터를 써서 다른 것으로 조정 가능)에 대한 GenBank 파일(max 1000; '--limit' 파라미터로 조정 가능)을 받아서 단백질 서열을 추출한 뒤 cd-hit로 클러스터링하여 이를 마련한다. '--include_genus' 파라미터를 주면 지정한 species외에도 이것이 속하는 genus의 유전체 정보를 더 가져와서 단백질 자료를 만든다. RefSeq에서 다운로드한 원본 파일을 나중에 재사용하려면 '--keep_files' 파라미터를 주어라. 아마 한번에 내려받은 GenBank flat file은 나중에 재사용을 할 일이 무척 많을 것이다. 내가 요즘 bactopia를 즐겨 사용하는 것도 바로 이 기능 때문이다. 이를 위해 뒷단에서 수고를 하는 스크립트는 바로 ncbi-genome-download이다.

이때 다운로드한 GenBank 파일은 prokka 데이터셋을 만들고 끝나는 것이 아니다. 다음의 위치에 Mash sketch DB를 만들어서 실제 유전체 해독 데이터를 이용한 후속 분석 때에 가장 가까운 reference genome을 자동으로 찾는 용도로 쓰인다. 이 reference 서열은 SNP 분석을 위해 필요하다. Reference genome을 자동으로 찾는 것이 싫다면 명령행에서 별도로 지정해도 된다.

datasets/species-specific/SPECIES/minmer/refseq-genomes.msh

datasets 디렉토리에 이미 파일이 있다면, 'bactopia datasets'은 데이터셋 다운로드를 다시 시도하지 않는다. 단, amr 데이터셋은 항상 새로 다운로드하여 설치를 하는 것이 기본 동작이다. 따라서 이것이 성가시다면 '--skip_amr' 파라미터를 주면 된다. 이미 데이터셋이 설치되어 있음에도 불구하고 새로 다운로드하여 설치하려면 '--force' 파라미터를 이용한다.

위에서 굵은 글씨로 표시한 다섯 가지의 데이터셋(ariba, minmer, amr, prokka 및 mlst) 각각에 대하여 설치 생략 혹은 강제 설치를 하려면 각각 --skip_STR 또는 --force_STR 파라미터를 지정하면 된다. STR에는 데이터셋을 나타내는 문자열을 넣어라.

다음은 노트북 컴퓨터에서 Streptococcus pneumoniae의 데이터셋을 빌드하는 과정을 보인 것이다. general dataset이 이미 설치된 상태에서 종을 지정하여 species-specific dataset을 추가로 설치하였다. 

$ bactopia datasets --species "Streptococcus pneumoniae" --include_genus --cpus 4 --keep_files
2021-11-09 21:06:11:root:INFO - Streptococcus pneumoniae verified in ENA Taxonomy database
2021-11-09 21:06:11:root:INFO - Setting up Ariba datasets
2021-11-09 21:06:11:root:INFO - vfdb_core (./datasets/ariba/vfdb_core) exists, skipping
2021-11-09 21:06:11:root:INFO - card (./datasets/ariba/card) exists, skipping
2021-11-09 21:06:11:root:INFO - Setting up pre-computed Genbank/Refseq minmer datasets
2021-11-09 21:06:11:root:INFO - ./datasets/minmer/genbank-k21.json.gz exists, skipping
2021-11-09 21:06:11:root:INFO - ./datasets/minmer/genbank-k31.json.gz exists, skipping
2021-11-09 21:06:11:root:INFO - ./datasets/minmer/genbank-k51.json.gz exists, skipping
2021-11-09 21:06:11:root:INFO - ./datasets/minmer/refseq-k21-s1000.msh exists, skipping
2021-11-09 21:06:11:root:INFO - Setting up antimicrobial resistance datasets
2021-11-09 21:06:11:root:INFO - Setting up latest AMRFinder+ database
2021-11-09 21:06:55:root:INFO - AMRFinder+ database saved to ./datasets/antimicrobial-resistance/amrfinderdb.tar.gz
2021-11-09 21:06:55:root:INFO - Setting up MLST datasets
2021-11-09 21:06:55:root:INFO - Setting up default MLST schema for Streptococcus pneumoniae
2021-11-09 21:06:55:root:INFO - Creating Ariba MLST dataset
2021-11-09 21:07:59:root:INFO - Creating BLAST MLST dataset
2021-11-09 21:08:09:root:INFO - Setting up custom Prokka proteins
2021-11-09 21:08:09:root:INFO - Setting up custom Prokka proteins for Streptococcus pneumoniae
2021-11-09 21:08:09:root:INFO - Downloading genomes (assembly level: complete)
2021-11-09 21:08:10:root:INFO - There are less available genomes than the given limit (1000), downloading all.
2021-11-09 23:15:53:root:INFO - Processing 827 Genbank files
2021-11-09 23:20:11:root:INFO - Median genome size: 2111425 (n=88)
2021-11-09 23:20:11:root:INFO - Running CD-HIT on 1516278 proteins
2021-11-09 23:29:50:root:INFO - Writing summary of available datasets

827개의 유전체 파일을 다운로드하였지만 이는 '--include_genus' 옵션에 의해 다른 종의 것까지 포함하고 있다. 실제로 이 종의 유전체 크기를 추정하는데 쓰인 것은 88개이다. 

2021년 11월 9일 화요일

진공관 앰프 자작용 SMPS가 점점 많이 팔리고 있다

'세계의 공장' 중국이 글로벌 경제에 미치는 영향은 실로 엄청나다. 당장은 싼 값에 공산품을 살 수가 있으니 나처럼 취미로 전자 공작을 하는 사람은 알리익스프레스를 뒤져서 맘에 드는 물건을 싸고 편하게 구입하게 된다. 창의력을 발휘한 물건도 꽤 많아서 때로는 감탄을 하기도 한다. 요즘 어떤 물건이 널리 팔리는지를 보면서 시장이 바뀌어 나가는 모습을 관찰하는 것도 흥미로운 일이다. 

무역의 중국 의존도가 높아지면 다른 문제도 생겨난다. 요즘 겪고 있는 요소수 대란처럼 말이다. 중국의 내부 사정에 의하여 산업과 생활에 꼭 필요한 물건을 갑자기 공급받지 못하면 이렇게 패닉에 가까운 상황이 발생한다. 중국과 지리적으로 너무나 가까와서 본토에서 날아드는 공해 물질에 의한 피해도 무시하기 곤란하다.  

이처럼 세상이 너무나 많이 얽혀 있어서 미처 예상하지 못했던 남의 나라 문제가 우리의 생계에 직접적으로 영향을 주게 된다. 본래 네트워크가 고도화되면 약간의 변동에도 흔들림이 없이 'robust'한 상태가 되어야 하는 것이 아니던가? 오히려 변동이 더 자주 생기고 이를 예측하기 어려워지는 것만 같다.

어찌되었든 연말을 앞둔 소일거리를 찾기 위하여 알리익스프레스를 뒤지고 있는데, 몇년 전에 비하여 진공관 앰프의 전원부로 쓸 수 있는 완제품 SMPS(switched-mode power supply)가 훨씬 다양해졌다. 아래에 보인 것은 빙산의 일각이다. 빨갛게 테두리를 친 것이 250~300V의 직류 고전압 및 히터용 6.3V를 제공하는 것이다. 출력 전압을 자유로이 조절할 수는 없지만, 이 정도라면 6V6 싱글을 물론 푸시풀 앰프 정도까지는 가뿐하게 구동할 수준이 된다.


2018년에 제이앨범 '고야' 회원께서 완성 상태의 자작 SMPS와 부품을 거저 보내주셔서 직접 SMPS를 만든 일이 있다. 이것으로 6N1 + 6P1 싱글 앰프의 B전원과 히터를 성공적으로 작동하였었다. 당시의 글은 제이앨범에 고스란히 남아있다(링크).

SMPS를 직접 만드는 것은 매우 흥미로운 일이지만, 이를 실용 수준으로 만들려면 조심할 점이 많다. 일단 상용 220V를 직접 정류하는 회로를 잘 꾸며야 한다. 무엇보다도 안전하게! 내가 쓴 회로는 무엇이 문제인지 - 아마도 대용량 캐패시터에 의한 돌입전류? - 퓨즈가 자꾸 끊어졌었다. 그리고 출력부가 단락되든지 했을 때 이를 안전하게 대처할 수 있는 방안이 전혀 마련되어 있지 않다. 부하에 의해서 전압이 과도하게 떨어지면 보상을 하는 회로도 필요할 것이다. 그런데 이런 요구사항을 자꾸 충족시키면 자작이 힘들어진다. 

무엇보다도 자작 SMPS는 소형화하기가 어렵다고 생각한다. 무게는 트랜스포머를 쓰는 고전적인 전원회로에 비해서 훨씬 적게 나가지만, 부품이 비교적 많이 들어가서 작게 꾸미는 것이 쉽지 않다. 무엇보다도 어려웠던 것은, 몇 가지 반도체 부품이 정상 상태인지를 확인하는 것이었다. 

결론적으로 말하자면 자작 SMPS는 실험용 전원으로는 적당하다고 생각한다. 원하는 전압을 만들려면 페라이트 코어에 감은 에나멜선의 권선수를 조절하면 되니까 말이다. 그리고 동작 상태의 확인을 위해 오실로스코프도 있으면 좋을 것이다. 이런, 배보다 배꼽이 더 커진다! 내 오실로스코프는 너무 낡아서 화면이 제대로 보이지 않는다...

만약 앞으로 진공관 앰프를 더 만들게 되면, 거의 틀림없이 시판되는 SMPS를 쓰게 될 것 같다. 내가 SMPS 실험을 처음 시작하던 무렵에는 이렇게 많은 물건이 올라와 있지 않았다. 지금 이렇게 다양한 제품이 있는 것으로 미루어 짐작하건대 수요가 충분한 규모로 성장한 것으로 보인다. SMPS는 진공관 앰프에 써서는 안될 물건이라는 예전의 믿음도 이제는 많이 사라진 것이 아니겠는가? 이것도 혁신이라면 혁신이라 불러도 되겠다.

2021년 11월 8일 월요일

독특한 진공관 앰프를 찾아서

가을이 깊어지면서 진공관 앰프의 따뜻한 불빛을 즐기게 된다. 이미 침실에서 두 대의 앰프(43 및 PCL86 싱글 앰프)가 번갈아 가동 중이고, 약 반년 가량 드라마 촬영용 소품으로 외부에 대여해 준 6LQ8 앰프 두 대도 조만간 집으로 돌아올 것이다. 거실에는 올해 장만한 인터M 레퍼런스 앰프 R150PLUS가 자리를 잡아서 좋은 동반자 역할을 한다. 

자작 진공관 싱글 앰프(single-ended amplifier)의 빈약한 출력과 잡음에 실망하여 부품을 전부 해체하여 거두어 들였다가 또 다시 만들기를 반복하는 이유는 무엇일까? 그것은 바로 만드는 과정이 주는 마약과 같은 즐거움이 있기 때문이 아닐까? 한번씩은 다 거쳐 가는 대중적인 오디오 전용관을 나도 반드시 경험해야 한다는 생각은 별로 없다. 원래 오디오 앰플리파이어용으로 제조되지 않은 진공관을 이용하여 소리를 내 보는 것도 즐거운 일이다. 

적극적으로 이러한 일을 개척해 나가는 사람은 따로 있다. 나는 그들이 남긴 '유산'을 쉽게 이용할 뿐이다. 요즘 알리익스프레스에 들어가 보니 진공관 앰프를 위한 스위칭 파워 서플라이가 예전보다 종류가 많아졌음을 알 수 있다. 이것도 전통과는 거리가 있는, 새로운 시도라고 여겨진다.

갖고 있는 트랜스포머류를 활용할 수 있는 독특한 진공관 앰프 반제품은 뭐가 있을까? 뿔난 항아리, 또는 부항을 닮은 FU-32(Valve Museum의 소개)라는 진공관이 눈에 뜨인다. 1950년대에 초단파(VHF) 송신용으로 쓰이던 832A를 중국에서 오디오용으로 재해석하며 만든 것이라 한다. 빔 테트로드 한 쌍이 하나의 유리관 안에 들어 있어서 저출력의 앰프를 만들기에 매우 적당하고 소리도 나쁘지 않다고 한다. 우선은 이 앰프 보드에 관심을 두고 있다. 아래에 보인 제품에서는 6J1이 드라이브단에 쓰이지만 쌍삼극관인 12AX7이나 6N2를 사용하는 것도 있다.

출처: 알리익스프레스 GHXAMP Worldwide Store
마침 220V 50VA 급의 절연 트랜스포머를 갖고 있어서 전원부를 구성하기에 충분하다. 출력트랜스포머로는 R코어에 직접 감은 것(5K:8)이 한 조 있다. 이전의 6N1 + 6P1 싱글 앰프에서 해체하면서 리드선 부분이 훼손되어 이를 쓰려면 손을 좀 보아야 한다. 소출력 앰프에 쓰기에는 코어 크기가 좀 아깝다.

관심을 두는 두번째의 대상은 6N9P(6SL7GT와 유사)와 6N8P(6SN7GT와 유사)를 사용한 푸시풀 앰프이다. 쌍삼극관을 한 채널의 푸시풀 출력 회로에 이용한다는 것이 독특하다. 내가 잠시 사용하였던 이영건 선생님 제작 6J6도 비슷한 개념의 앰프로 볼 수 있다. 원래 출력관으로 만들어진 것이 아니라서 이 제품운 2.5 W + 2.5 W 정도가 나온다고 한다.

출처: 알리익스프레스(판매자 링크)
보드 안에 정류 및 초크 코일을 이용한 평활회로가 들어 있어서 외부에서 전원트랜스만 연결하면 된다. 이 앰프 보드가 흥미로운 것은 LM7906 레귤레이터를 이용한 히터 점화와 일반 교류 점화를 전부 지원한다는 것이다. 회로도를 보면 출력관에 해당하는 6N8P에 대해서 두 가장 방식 중 하나를 골라 쓰라는 것처럼 보인다. 그러면 앞부분의 6N9P는 어떻게 점화를 한다는 것인가? 설명을 아무리 보아도 잘 이해가 가지 않는다. 혹은 초단(6N9P)에는 레귤레이터를 통한 DC를, 출력단(6N8P)는 AC를 가하여 점화를 한다는 것을 다소 혼동스럽게 기술한 것인지... 내가 보기에는 이것이 더 자연스럽다. 회로도는 아래에 소개하였다.


이 보드에 사용할 수 있는 여분의 푸시풀용 출력 트랜스포머도 갖고 있다. 다 예전에 쓰던 것을 해체하여 마련해 둔 것이다. 

두 제품 전부 가격은 거의 비슷하다. 세일이 시작되는 11월 11일이 되면 적당한 것을 골라서 연말 공작용으로 구입할 생각이다. 둘 다 개성이 넘치는 앰프이니 선택을 하려면 상당히 고심을 해야 될 것 같다.

도커(Docker) 컨테이너를 다른 컴퓨터로 옮겨서 실행하기

직장 전상망 내에서 Bactopia를 사용하면서 가장 불편한 것은 일부 general dataset이 SSL 인증서 문제로 다운로드가 불가하다는 것이다. 소위 SSL 가시성 확보를 위해 설치한 웹프록시 장비에서 발급한 인증서를 인정하지 못하는 상황이 벌어지기 때문이다. 장비 제조업체에서 제공하는 인증서를 웹 브라우저 등 일부 애플리케이션에 설치하여 대부분의 업무는 해결이 가능하지만, 프로그램에 따라서는 매우 까다로운 설정을 요구하는 것이 있다. 우분투나 CentOS 각각에 맞추어 system-wide하게 인증서를 설치하는 방법을 따라서 진행을 해도, 파이썬 코드 안에서 직접 파일을 다운로드하도록 짜 놓은 애플리케이션에서는 한계에 부딪히고 만다. 함수를 직접 건드려서 이 문제를 해결하는 방안이 인터넷에 종종 보이지만, 나는 파이썬을 잘 하지도 못하고 더군다나 고칠 곳이 여러 군데라면 여간 성가신 일이 아니다!

그래서 집에 리눅스 서버를 하나 더 설치해 둔 뒤 여기에서 필요한 파일을 받은 다음 이를 다시 직장에 가져와서 덮어 씌우는 번거로운 노력을 들여야만 했다. 이런 편법을 이용하여 Bactopia를 사용해 왔었다. 

만일 도커(Docker)를 이용하여 Bactopia를 사용한다면, 집 서버에서 이를 어떤 형태로든 export하여 직장 컴퓨터로 가져온 뒤 실행하면 되지 않을까? 생각이 여기까지 미쳐서 이를 실제로 테스트해 보기로 하였다. 

도커를 사용한다면 집에 있는 서버가 실제 직장 서버와 같은 리눅스 배포판을 쓸 이유도 없다. 노트북 컴퓨터를 들고 다니면서 도커 환경을 구축한 뒤 파일 형태로 가져올 수만 있으면 된다. 자, 그러면 시작해 보자. 우분투에 최신 도커 엔진을 설치하는 방법은 공식 문서에 잘 나오니 라를 따라하면 된다.


노트북 컴퓨터(집)에서

$ sudo docker pull bactopia/bactopia 
$ mkdir bactopia
$ cd bactopi
$ sudo docker run --rm -it --workdir /bactopia --volume $(pwd):/bactopia:rw bactopia/bactopia:latest bactopia datasets

도커 컨테이너가 생성·실행되면서 general dataset이 현재 디렉토리에 설치되고, 도커는 곧 종료된다. 현 디렉토리(bactopia) 하위에 만들어진 datasets(2021년 11월 7일 기준으로 1.1 GB)를 그대로 가져다가 직장 컴퓨터에 만들어진 Bactiopia 환경에 그대로 복사를 해도 된다. 실제로 지금까지 해 온 방식과 같다. 단지 도커를 사용하지 않았을 뿐이다.

그러나 이렇게 다운로드한 데이터셋을 한 덩어리의 파일로 전환한다면 다른 곳에 이전하기도 쉽고 교육 등의 목적에 활용하기에도 편리할 것이다. 그러기 위해서는 일단은 도커 컨테이너 형태로 실행 중이어야 하고 파일의 위치도 살짝 바꾸어야 한다. /bactopia 안에 설치된 datasets 디렉토리와 하위 구조들이 컨테이너의 export 결과물에 포함될 것 같지만 내가 테스트해 본 바로는 그렇지 않았다. 현재 상태에서 컨테이너를 다시 기동한 뒤 /bactopia 하위의 자료를 컨테이너 내부의 다른 곳으로 복사해 두어야만 했다. 혹시 내가 잘못 알고 있는 것은 아닌지 모르겠다.

다음과 같이 현재의 작업 위치에서 다시 도커 컨테이너를 생성하되, 편의상 test라는 이름을 붙인다('--name test'). 그리고 /bactopia/datasets을 /datasets으로 복사한다.

$ sudo docker run --rm -it -w /bactopia -v $(pwd):/bactopia:rw --name test bactopia/bactopia:latest
(base) root@6016f6628419:/bactopia# cd ..
(base) root@6016f6628419:/# cp -r bactopia/datasets/ .

이 상태에서 터미널 창을 하나 더 열고 'docker export' 명령을 이용하여 실행 중인 컨테이너를 파일로 저장한다. 

$ sudo docker export test > save.tar

한 덩어리의 파일로 전환하였으므로 어디로든 복사하여 가져갈 수 있다.


실제 작업을 할 서버 컴퓨터(직장)에서

save.tar 파일 다른 컴퓨터로 복사했다 하여도 이를 직접 로드할 수는 없다. 이를 도커 이미지 저장 창고에 밀어 넣은 뒤에 실제로 사용이 가능하다. 이때 사용하는 명령어는 'docker import'이다. 

$ sudo docker import save.tar test
sha256:54f65ae7f5b380804d5b5ffa220774fd5a6c4da90eba1ee47e8554cc498b71e9
$ sudo docker image ls
REPOSITORY                       TAG                    IMAGE ID            CREATED              SIZE
test                             latest                 54f65ae7f5b3        About a minute ago   2.97 GB
hyjeong/ununtu                   v3                     731d875559ed        2 days ago           72.8 MB
hyjeong/ubuntu                   revised                cf60cacf2511        2 days ago           72.8 MB
docker.io/ubuntu                 latest                 ba6acccedd29        3 weeks ago          72.8 MB
docker.io/hello-world            latest                 feb5d9fea6a5        6 weeks ago          13.3 kB
docker.io/centos                 latest                 5d0da3dc9764        7 weeks ago          231 MB
docker.io/ncbi/pgap              2021-07-01.build5508   d84e714fc606        4 months ago         8.43 GB
docker.io/bactopia/bactopia      latest                 20dfd67122b5        5 months ago         1.82 GB
docker.io/antismash/standalone   latest                 c535168192d3        5 months ago         10 GB

특별히 tag를 지정하지 않았다면 'latest'가 붙을 것이다. 이제 컨테이너를 기동해 보자. 간단히 확인만 하기 위하여 복잡한 옵션은 하나도 붙이지 않았다. 단, 이번에는 맨 마지막에 엔트리포인트('bash')를 지정해 주어야 한다.

$ sudo docker run --rm -it test:latest
/usr/bin/docker-current: Error response from daemon: No command specified.
See '/usr/bin/docker-current run --help'.
$ sudo docker run --rm -it test:latest bash
(base) root@451b3e3692f2:/# ls datasets/
antimicrobial-resistance  ariba  minmer  species-specific  summary.json
(base) root@451b3e3692f2:/# ls -l datasets/
total 4
drwxr-xr-x 2 root root   63 Nov  7 23:59 antimicrobial-resistance
drwxr-xr-x 2 root root  102 Nov  7 23:59 ariba
drwxr-xr-x 2 root root  141 Nov  7 23:59 minmer
drwxr-xr-x 3 root root   29 Nov  7 23:59 species-specific
-rw-r--r-- 1 root root 2021 Nov  7 23:59 summary.json
(base) root@451b3e3692f2:/# du -sh datasets/
1.1G	datasets/서

서버 컴퓨터에서 실제로 Bactopia 분석 작업을 하려면 디렉토리 구성을 어떻게 하는 것이 바람직한지는 약간 머리를 써야 되겠다.

이 과정을 익히기 위하여 다음 웹문서를 주로 참조하였다.

[~/xo.dev] 실행 중인 Docker 컨테이너를 파일로 저장하고 다시 불러오기


삽질 후기

도커 콘테이너 안에서 외부 자료를 가져오려다가 또 SSL 인증서 문제로 막혔다. 어휴... 도커 이미지를 고치느니 적당히 쓰고 말겠다. 물론 도커 잘못은 아니지만.