2015년 4월 25일 토요일

어제 배송된 칩 앰프 보드에 집을 지어주다



고요한 토요일 아침, 쇳가루를 날리며 부산하게 금속제 시계 케이스에 구멍을 뚫었다. 나에게 가장 어려운 일은 나무판 직각으로 똑바로 톱질하기, 구멍 수직으로 예쁘게 뚫기이다. 잘 해보려 했지만 이번에도 예외는 아니라서 바인딩 포스트 4개를 고정하기 위한 구멍을 반듯하게 뚫지 못했다. 그래도 기판 고정용 구멍 4개는 아주 잘 맞추어 뚫었다.

얇은 금속판에 드릴을 대고 뚫다 보면 찌그러지기 쉽다. 세상에 쉬운 노릇이 없다.

갖고 있는 3.5 mm 스테레오 폰잭이 별로 좋은 것이 아니라서 실드선 끝에 female 커넥터가 달린 것(전에 연장선으로 쓰다가 잘라 놓은 것)을 대충 납땜하여 연결하고 수축튜브 처리를 했더니 접촉이 매우 좋지 않다. 보수 공사가 필요하다. RCA 단자냐 3.5 mm 단자냐, 그것이 문제로다!  의욕만 앞섰지 깔끔하게 마무리를 못하니 문제가 아닐 수 없다.

2015년 4월 24일 금요일

지름의 결과 - 야마하 칩을 쓴 class D amplifier 보드

관련 글: 습관적인 지름

이번 배송은 보름이 넘게 걸렸다. 거의 잊어버리고 있던 찰나에 우편함에 얌전히 놓여있는 손바닥만한 국제우편 봉투를 발견하였다. 기념으로 사진을 찍어본다.



입력부에 3.5 mm 스테레오 폰잭을 납땜해야 되겠다. 헤드폰 출력부가 있다는 것이 특징이다. 전원전압은 12볼트. 브리즈 TPA3116과는 어떤 차이가 있을까? 그리고 내가 갖고 있는 다른 칩앰프 2개와는 또 어떻게 다를까? 

이런 물건을 하나둘 모으는 것은 즐겁지만 늘 케이스 가공이 문제로 남는다. 아마도 이것은 집에서 거실용 앰프로 쓰이지 않을까 생각한다. 구멍을 뚫다가 찌꺼기가 많이 생기는 반찬통 말고 다른 재질을 택해야 되겠다.

주말 소일용 장난감이 또 하나 늘었다. 딸아이 중간고사 준비하는 것을 봐줘야 하는데...


[하루에 한 R] 행렬 형태의 데이터 구조

R의 초보자 딱지도 아직 떼지 못했는데 주제넘게 이런 포스팅을 하여 인터넷 공간을 어지럽히는 것은 아닌지... [하루에 한 R]을 쓰게 된 동기는 다른 독자들이 이 글을 보고 조금이나마 도움을 얻기 위함이 아니라, 개인적인 공부를 하기 위함이다. 그러니 실수나 오류가 있을 수 있다.

오늘의 포스팅에서는 IT에서 이야기하는 복잡한 <데이터 구조>의 기술적인 면을 이야기하고자 함이 아니다. 엑셀이든, csv 파일이든, 일반적으로 행렬형태의 데이터를 우리가 어떻게 바라보아야 하는지 개념을 잡는데 도움을 주고자 간단한 그림과 함께 글을 써 나가도록 한다.

여러개의 샘플에 대해서 어떤 측정이나 조사를 하려고 한다. 측정이나 조사에는 여러개의 수치화 가능한 항목이 있을 것이다. 갯수가 얼마 안되면 대충 수첩에 적어도 좋겠지만, 대부분의 경우는 엑셀과 같은 프로그램에서 입력을 하는 것이 수월할 것이다. 예를 들어서 전체 학생의 중간고사 성적표 일람을 생각해 보자. 하나의 행(row)은 개별적인 학생에 해당하고, 각 열(column)에는 국어, 영어, 수학 등의 시험 점수가 적힌다. 이를 90도 돌려서 개별 학생의 성적을 세로(열)로 배열하고 싶은 사람도 있을 것이다. 논리적으로는 문제가 없지만 영 어색하다. 각 학생은 하나의 샘플이라 간주할 수 있고, 수가 많은 샘플은 행 단위로 추가되는 것이 바람직하다. 따라서 아래 그림이 가장 보편적인 2차원 행렬 형태의 데이터 집합 구조라고 보면 된다.

첫 행과 첫 열부터 기록치를 써내려가는 사람은 없을 것이다. 첫 행과 첫 열에는 나머지 셀에 어떤 항목이 들어가는지 제목부터 달아 놓는 것이 자연스럽다. 특히 중요한 것은 각 열의 이름이다. 이를 R에서는 보통 variable이라고 이야기한다.

생명과학 분야에서 흔히 다루는 expression data의 구조는 이와 조금 다르다. 개개의 observation(chip 또는 RNA-seq 실험)이 열로 배치되고, 행은 유전자 ID로 삼는 것이 관례이다. 따라서 hierarchical clustering 등을 하려면 t() 함수를 사용하여 트랜스포즈를 해야 된다.

R에서 행과 열의 이름을 지정할 때에는 dimnames()라는 함수를 쓴다. dimname(data)라고 하면 data 오브젝트에 이미 설정된 행과 열의 이름을 반환한다. 조금 뒤에 살펴볼 row.names() 함수도 마찬가지로 작동한다. 먼저 dimnames() 함수의 사용법을 알아보자.

> countries = c("Austria", "France", "Germany")
> variables = c("GDP", "Population", "Inflation")
> dimnames(country.data) = list(countries, variable)

만약 세번째 컬럼을 쏙 빼서 row name으로 삼고 싶다면?

> row.names(country.data) = country.data[, 3]
> country.data = country.data[, -3]  # 세번째 컬럼 제거

R이 훌륭한 점은 이렇게 행렬 형태로 구성된 데이터를 매우 자유롭게 다룰 수 있다는 점이다. 물론 어떤 사람은 엑셀이 더 편리하다고 말할 것이다. 마우스를 클릭해서 눈에 즉시 보이는 결과를 얻는다는 점에서는 엑셀이 낫다. 그러나 어떤 데이터를 임포트한 뒤 특정 컬럼이나 행을 없애고 계산을 하고 새로운 행과 열을 만들고... 이런 일을 하다보면 최종 결과물만 남을뿐 과정을 기억하기가 어렵다. 이런 점에서 스크립트 형식으로 작업하는 R은 훨씬 유연하고 정확하며 실수가 적다.

R은 다음과 같은 일을 하는데 정말 편리하다. 단, 반드시 유념할 것이 있다. for..와 같은 반복문을 쓰지 않는 것이 R의 기본 정신이다. 나는 최소한 그렇게 생각한다.

  • 어떤 조건을 만족하는 행이나 열 제거하기
  • 어떤 조건을 만족하는 행이나 열만 뽑아내기
  • 행이나 열을 기준으로 계산하거나(예: 평균, 최대값, 최소값...) 조작하기(예: 정렬)
  • 테이블 여러개를 합치기
인터넷을 참조해 보면 이러한 상황에 사용할 수 있는 정말로 아름다운 사례가 많다. 시간이 허락하는대로 포스팅해 보고자 한다. 아, [하루에 한 Perl]도 해야 되는데...

2015년 4월 23일 목요일

[하루에 한 R] 특정 조건에 맞는 row만 출력하기

어제의 포스팅에서 다루었던 파일(data3.txt)을 이용하여 R의 또 다른 활용 방법을 살펴보자. 특정 조건을 만족하는 row만을 출력해 보는 것이다.
$ cat data3.txt
Nation,Pop.density, Area, Population
UK,255.6,243610,62262000
France,111,547030,63601002
Germany,233,357021,81799600
Korea,513,100210,51098531
N.Korea,200,120538,25051706
Japan,337,377873,127387000

 첫 줄의 요소 수는 나머지 라인의 요소 수와 같다. 이를 감안하여 R에서 데이터 파일을 읽어들이자. 이렇게 읽어들인 data 오브젝트는 list이다. mode(list)라고 실행하면 금방 알 수 있다.
> data = read.table("data3.txt",sep=",",header=TRUE,row.name=1)
> data
        Pop.density   Area Population
UK            255.6 243610   62262000
France        111.0 547030   63601002
Germany       233.0 357021   81799600
Korea         513.0 100210   51098531
N.Korea       200.0 120538   25051706
Japan         337.0 377873  127387000
오늘의 과제는 인구밀도(Pop.density)가 300보다 작은 널널한 나라를 찾아보자는 것이다.

방법 1. 슬라이싱을 절묘하게 이용하기

마치 암호같지만 잘 살펴보면 그 작동 원리를 이해할 수 있다. 두 가지 방법을 나열해 보겠다.
> data[, "Pop.density"] < 300
[1]  TRUE  TRUE  TRUE FALSE  TRUE FALSE
> data[data[, "Pop.density"] < 300, ]
        Pop.density   Area Population
UK            255.6 243610   62262000
France        111.0 547030   63601002
Germany       233.0 357021   81799600
N.Korea       200.0 120538   25051706

> data$Pop.density < 300
[1]  TRUE  TRUE  TRUE FALSE  TRUE FALSE
> data[data$Pop.density < 300, ]
        Pop.density   Area Population
UK            255.6 243610   62262000
France        111.0 547030   63601002
Germany       233.0 357021   81799600
N.Korea       200.0 120538   25051706
여기에서 R 코드의 가장 아름다운 면이 드러난다. 바로 [, -1]과 같이 데이터를 '쳐 내는' 것이다. 그러면 위 코드에 대한 설명을 해 보겠다. 첫번째 사례에서는 data[, something] < 300이라는 조작을 했다. [ ] 안의 두번째 위치이니 something에 해당하는 컬럼에 대해서 조건을 만족하는지를 모든 row에 대해서 시험하는 것이다. 따라서 반환되는 값은 TRUE FALSE... 와 같다. 이를 전체 데이터에 대해서 다시 첫번째 인자로 넣었으니 이 조건을 만족하는 row를 내놓으라는 뜻이 된다.

조건을 하나 더 붙여보자. 인구밀도는 300보다 작은데다가 면적은 350000을 넘는 덩치가 크고도 널널한 나라를 찾아보자. & 혹은 |를 쓰면 된다. Perl에서 && 및 || 연산자를 떠올리면 된다. 정확히 같은 것과 같지 않은 것도 뽑을 수 있다. 그건 각자 알아보라.

> data$Pop.density < 300 & data$Area > 350000
[1] FALSE  TRUE  TRUE FALSE FALSE FALSE
> data[data$Pop.density < 300 & data$Area > 350000, ]
        Pop.density   Area Population
France          111 547030   63601002
Germany         233 357021   81799600

방법 2. 데이터프레임으로 전환한 뒤 subset() 함수 적용하기
> data.frame = as.data.frame(data)
> subset(data.frame, Pop.density < 300)
        Pop.density   Area Population
UK            255.6 243610   62262000
France        111.0 547030   63601002
Germany       233.0 357021   81799600
N.Korea       200.0 120538   25051706
조건을 여러개 다는 것도 위에서 살펴본 것과 마찬가지 방법으로 가능하다. 
> subset(data.frame, Pop.density < 300 & Area > 350000)
        Pop.density   Area Population
France          111 547030   63601002
Germany         233 357021   81799600
팁 하나: 출력물을 파일로 보내고 싶다.... sink() 함수 활용하기

출력물이 한 화면을 넘어가면 이를 일일이 긁어서 페이스트를 할 수는 없다. 다음과 같이 해 보라. result라는 파일에 화면 출력물이 고스란히 저장된다. 다시 출력을 화면으로 되돌리는 것은 인수 없이 sink()를 실행한 이후이다. 공백은 탭 형태로 저장된다. 
> sink("result")
> subset(data.frame, Pop.density < 300 & Area > 350000)
> sink()
정말 멋지지 않은가? 다음에는 heatmap을 그리는 방법에 대해서 포스팅하고자 한다.

[업데이트] 2019년 2월 8일에 추가한 글

슬라이싱(slicing)의 정확한 의미는 무엇인가? 칼로 얇게 썰어내듯이 데이터 프레임의 어떤 부분(주로 row)를 잘라서 취하는 것을 일반적으로 의미하는가, 혹은 dplyr 패키지의 slice() 함수를 사용하는 것만을 의미하는가? Subsetting에 대해서도 똑같이 이야기할 수 있다. slice() 함수의 기능은 'select rows by position'이라고 하였다. 그렇다면 row를 논리적 조건에 의해 골라내는 것은 슬라이싱이라고 불러서는 안될 것이다. subset() 함수는 R의 기본 패키지에 포함되어 있다.


[하루에 한 R] 매트릭스 형태의 텍스트 파일 입력과 헤더의 처리

최근 세균 유래의 RNA-seq 데이터 분석 처리를 의뢰받으면서 1년 넘게 손을 놓고 있었던 R 관련 자료를 뒤적이게 되었다. 세균 RNA-seq 데이터 처리에 특화된 Rockhopper라는 도구가 있어서 비교적 편하게 expression 수치와 fold change 값은 뽑아내었다. 그러나 의뢰자에게 제공할 QC 등과 관련한 시각화 자료를 제공하기에는 R만큼 좋은 것이 없다. 다시 기초 자료를 뒤적이면서 R에서 행렬(matrix) 형태의 자료를 입력하여 다루는 기본적인 사항을 블로그에 정리해 보기로 하였다.

우선 다음과 같이 간단한 자료 파일(data1.txt)이 있다고 가정하자. 설명은 전혀 없고 숫자와 이들을 구분하는 콤마로만 구성된 텍스트 파일이다.
$ cat data1.txt
255.6,243610,62262000
111,547030,63601002
233,357021,81799600
513,100210,51098531
200,120538,25051706
337,377873,127387000
R에서는 아무런 옵션 없이 다음과 같이 단순하게 읽어들여 보자.
> data = read.table("data1.txt",sep=",")
> data 
     V1     V2        V3
1 255.6 243610  62262000
2 111.0 547030  63601002
3 233.0 357021  81799600
4 513.0 100210  51098531
5 200.0 120538  25051706
6 337.0 377873 127387000
데이터의 row가 매우 길다면 head() 함수를 써서 데이터의 앞부분 일부를 볼 수 있다. 더욱 바람직하게는 View() 함수를 쓰면 별도의 창이 뜨면서 데이터가 표시된다. view()가 아니고 View()임에 유의하라. 아무튼 데이터를 표시해 보면 원본 파일에는 없었던 V1, V2, V3가 맨 위에 나온다. R에서는 이를 variable이라고 한다. 반면 맨 왼쪽에는 1, 2, 3...라는 일련번호가 붙어서 각 레코드(row)를 구분해주고 있다. View(data)를 실행해 보자.


이제 데이터 파일을 살짝 바꾸어서 맨 윗줄이 헤더역할을 하게 만들어 보자. 즉 첫줄은 각 컬럼이 수록한 값을 설명하는 표지가 되는 것이다. 다시 말하자면 각 컬럼은 이름을 갖게 되는 것이다.
$ cat data2.txt
Pop.density,Area,Population
UK,255.6,243610,62262000
France,111,547030,63601002
Germany,233,357021,81799600
Korea,513,100210,51098531
N.Korea,200,120538,25051706
Japan,337,377873,127387000
여기서 유의할 점은, 첫 줄(variable name 수록)의 요소는 3개이지만 두번째 줄부터는 4개의 요소가 담겨있다는 점이다. 즉 헤더 줄을 제외한 나머지 줄의 첫번째 요소는 row name이라는 암묵적인 선언인 것이다. 이를 R에서 읽어보자. 다음과 같이 variable(=column name)과 row name이 자동적으로 인식이 되었다. 이제 데이터 파일이 수록한 수치가 무엇인지를 알게 되었을 것이다. 우리나라를 포함한 5개 국가의 인구밀도, 면적, 그리고 총 인구수를 나태낸 것이다.
> data = read.table("data2.txt",sep=",")
> data
        Pop.density   Area Population
UK            255.6 243610   62262000
France        111.0 547030   63601002
Germany       233.0 357021   81799600
Korea         513.0 100210   51098531
N.Korea       200.0 120538   25051706
Japan         337.0 377873  127387000

위에서 빨강색 상자로 둘러친 부분(row.names)은 data[,1]를 입력하여 반환할 수 있는 일반적인 컬럼이 아니다.

만약 헤더라인의 첫번째 요소에 'Nation'이 들어가는 것이 좀 더 완벽하다고 생각한다면?

$ cat data3.txt
Nation,Pop.density,Area,Polulation
UK,255.6,243610,62262000
France,111,547030,63601002
Germany,233,357021,81799600
Korea,513,100210,51098531
N.Korea,200,120538,25051706
Japan,337,377873,127387000

이 파일을 R에서 읽어보자.

> data = read.table("data3.txt",sep=",")
> data
       V1          V2     V3          V4
1  Nation Pop.density   Area  Population
2      UK       255.6 243610    62262000
3  France         111 547030    63601002
4 Germany         233 357021    81799600
5   Korea         513 100210    51098531
6 N.Korea         200 120538    25051706
7   Japan         337 377873   127387000

그렇다. 데이터 파일의 모든 줄이 같은 수의 요소를 갖고 있다면, R은 모든 줄을 다 데이터 자체로 생각하는 것이다! 첫 줄의 요소 수가 나머지 줄보다 하나 적다면, 자동적으로 첫 줄을 헤더라인, 즉 variable 명을 담고 있는 것으로 인식한다. 그리고 더욱 중요한 것은, 두번째 줄부터 나타나는 첫번째 요소는 row name으로 인식한다는 것.

따라서 data3.txt파일처럼 모든 라인이 같은 수의 요소로 이루어졌다 하더라도 첫 줄이 헤더임을 명시하려면 다음과 같이 하면 된다.

> data = read.table("data3.txt",sep=",",header=TRUE)
> data
   Nation Pop.density   Area Population
1      UK       255.6 243610   62262000
2  France       111.0 547030   63601002
3 Germany       233.0 357021   81799600
4   Korea       513.0 100210   51098531
5 N.Korea       200.0 120538   25051706
6   Japan       337.0 377873  127387000

그러나 아직 완벽하지 않다. 나라 이름이 아직 row name으로 인식되지 않고 있기 때문이다. 첫번째 컬럼이 row name에 해당한다는 것을 알려주려면 다음과 같이 해야 한다.

> data = read.table("data3.txt",sep=",",header=TRUE, row.names=1)
> data
        Pop.density   Area Population
UK            255.6 243610   62262000
France        111.0 547030   63601002
Germany       233.0 357021   81799600
Korea         513.0 100210   51098531
N.Korea       200.0 120538   25051706
Japan         337.0 377873  127387000

row.name=2라고 쓰면 데이터 파일의 두번째 줄을  row name으로 인식한다. 당연한 이야기지만 row name으로 선언된 컬럼 내의 값은 각자 유일해야 한다. 그렇지 않으면 에러가 발생한다.

헤더라인의 첫번째 요소를 'Nation'이라고 명시적으로 나타내는 것이 옳은가? 즉 Nation도 하나의 variable로 봐야 할 것인가? 이건 철학적인 문제라서 무엇이 정답이라고 할 수는 없다. 단, 첫 줄의 요소 수가 나머지 줄과 동일한가 혹은 그렇지 않은가(하나 적은가)에 따라서 R의 read.table() 기본 작동이 달라진다는 것, header=TRUE라고 선언하는 것은 오직 variable의 인식에만 관여할 뿐 row name과는 상관이 없다는 것을 기억하는 것이 중요하다.

row.names라는 파라미터를 모른다면 다음과 같이 추가적인 단계를 거치면 된다. 첫번째 컬럼을 row.names(data)에 할당하고, 그 컬럼을 없애면 된다.

> data = read.table("data3.txt",sep=",",header=TRUE)
> row.names(data) = data[,1]
> data = data[,-1]
> data
        Pop.density   Area Population
UK            255.6 243610   62262000
France        111.0 547030   63601002
Germany       233.0 357021   81799600
Korea         513.0 100210   51098531
N.Korea       200.0 120538   25051706
Japan         337.0 377873  127387000

이상의 사례에서 보았듯이 새로운 데이터(여러개의 variable로 구성)는 하나의 줄(row)로 추가되는 것이 자연스럽다. 그러나 생명과학에서 흔히 다루는 발현수치, 즉 microarray나 RNA-seq 자료는 어떠한가? 여기에서는 기본적으로 한번의 실험에서 얻어진 모든 유전자의 발현 수치가 하나의 컬럼으로 구성된다. 대신 row는 각 유전자에 해당한다. 따라서 매트릭스 형태의 발현 수치 데이터를 읽어들인 후 계층적 클러스터링을 하려면 t() 함수를 써서 트랜스포즈를 해야 하는 것이다. 즉 행과 열을 바뀌치기 하는 것이 필요하다.

매우 기본적인 사항이지만 평소에 눈여겨보지 않았던 것을 이렇게 정리하고 나니 머리속이 좀 맑아지는 기분이다...

2017년 12월 15일에 추가한 글: R 매뉴얼을 통해서 header 관련한 동작을 비로소 이해하였다. read.table() 함수에서는 기본적으로 header=F이지만 첫 줄의 데이터 필드가 나머지 줄보다 하나 적을 때 자동으로 T가 된다. 반면에 read.csv(), read.delim() 등 다른 계열의 함수에서는 기본적으로 header=T이다.

2018년 2월 25일에 추가한 글: 간혹 매트릭스 형태의 데이터 파일 중에서는 첫번째 줄의 요소 수가 나머지 줄과 동일하면서도 첫번째 셀(1,1)을 비워 둔 것을 보게 된다. 분리자가 탭("\n")인 경우의 사례를 보자. 첫번째 줄의 최초 분리자 바로 앞에는 아무것도 없다.
\tPop.density\nArea\nPopulation
UK\n255.6\n243610\n62262000
France\n111\n547030\n63601002
Germany\n233\n357021\n81799600
Korea\n513\n100210\n51098531
N.Korea\n200\n120538\n25051706
Japan\n337\n377873\n127387000
이러한 파일은 엑셀에서 즉시 읽어들이기에는 좋다. 하지만 R 입장에서는 빨강색 "\t"이 없다면 read.table() 함수로 그냥 읽으면 될 것을 header=T,row.names=1 파라미터를 추가로 공급해야 함을 잊지 말자.


2015년 4월 22일 수요일

오디오 생활 중에 발생한 궁금증들

내가 본격적으로 오디오 생활을 한 시점을 언제부터로 보아야 할까? 김기덕씨가 진행하던 <2시의 데이트>를 들으며 좋아하는 곡이 나오면 달려가서 테이프에 녹음을 하기 시작하던 시기는 감히 오디오 생활이라 말하기 어렵다. 오디오 수리를 위해 인켈 서비스 센터를 다니고, 포터 안테나를 구하여 좀 더 나은 FM 수신을 위해 노력하던 수년 전? 그것도 아니다. 만약 그때부터 오디오 생활이 시작되었다면, 엣지를 수리한 인켈 스피커를 그렇게 쉽게 내다 버리지는 않았을 것이다. 모델명이 아마 ISP-3000이었나? 아이들 친구 집에서 얻은 홈시어터 시스템의 스피커를 단지 잡음이 좀 난다는 이유로 내다 버리기도 하였으니 지금 스피커에 대해 갖고 있는 관심 수준을 생각한다면 정말 그때 나는 눈뜬 장님이 아니었나 싶다. 조금이라도 더 뜯어보고 궁리해 볼 것을... 그래도 인켈 스피커 SH-950을 끝까지 내치지 않고 지금까지 주력기로 사용하고 있는 것이 다행이다.

진공관 앰프 1호기를 장만하게 된 2014년 구정 무렵부터가 본격적인 오디오 생활의 시작이라고 보는 것이 가장 적합할 것이다. 그렇다면 이제 1년이 겨우 지났을 뿐이다.

어쨌든 느슨한 기준으로서 오디오 생활을 시작한 이후 생긴 의문점을 나열해 보고자 한다. 일부는 해답을 얻었지만 일부는 그렇지 못하다.

1. 왜 인켈 RV-7050R 리시버 앰프는 그렇게 험이 심하였나?
  <- 서비스 센터에서도 그 제품이 원래 그렇다는 대답만을 들었다. 동일 모델의 다른 제품을 들어 본 일이 없으니 제품에 따른 편차에 의한 것인지, 원래 설계에 문제가 있는지는 모른다.  Daum에서 쥬크박스라는 카페(주로 튜너 수리)를 운영하는 기술자에게 문의한 바에 따르면, 근본적으로 완벽하지 않은 기기라 하니 받아들일 수밖에는.

2. 왜 인켈 시디 플레이어는 그렇게 자주 픽업을 갈아야 했나? 컴퓨터의 ODD나 DVD 플레이어는 그렇게 교체 주기가 짧다고 느껴지지 않는데 말이다.

3. 시디 플레이어의 픽업을 교체하면 반드시 조정을 해야 하나? 다시 말하자면, 계측기가 없는 일반 소비자가 할 수 있는 일이 아닌가?

4. 왜 KBS 대전 FM은 수신 상태가 그토록 불량한가? 
  <- 안테나 방향을 바꾸어서 많이 양호해졌으나, 자동차를 타고 이동하면서 KBS 청주 FM과 비교하면 분명 차이가 있다. 음량은 더 높으나 펄럭거리는 잡음이 위치에 따라 심하다. 반면 MBC FM은 항상 고르고 안정적인 수신이 된다.

5. 왜 튜너는 몇 년이 지나면 FM 스테레오 수신이 불량해지는가? 그렇게 쉽게 망가지는 부품이 들어있단 말인가?

6. 앞으로 기기를 하나 둘씩 더 사모으는 것이 과연 옳을까? 언젠가는 큰 집을 갖게 되어서 큰 음량으로 음악을 마음껏 들을 날이 올까?

롯데 CD 플레이어 LCD-7500의 픽업(부품명: KSS-210A) 자가 교체 성공기

서울의 원영전자에 주문을 넣은지 하루만에 택배로 픽업이 배달되었다. 소니에서 만들어진 정품인가, 혹은 중국에서 만들어진 호환품인가? 그건 나도 잘 모른다. 아마도 후자가 아닐까? 정품과 호환품을 구별하는 방법을 인터넷에서 본 기억이 있다.


아래 사진에서 노랑색 원으로 표시된 부분의 납땜을 제거해야 한다. 정전기(?)로 인한 파손에서 부품을 보호하기 위하여 저렇게 연결해 놓은 것이라 한다. 납땜인두와 흡입기로 이를 제거하였다.


원래는 재조립 과정에서 실수를 줄이기 위해 CD 플레이어를 분해하는 과정을 매 단계마다 사진을 찍어 남겨 놓으려 했으나 그다지 복잡하지 않았기에 촬영은 생략하였다. 단, 마지막 단계의 분해에서는 인터넷에서 찾은 인켈 CDG-5400 수리(1): 소니 KSS-210A 픽업 교환을 많이 참고하였다. 이 글에는 설명이 되어 있지 않지만, 픽업을 움직이는 흰식 톱니바퀴를 빼는 것이 좋다. 축 부분의 갈라진 모습을 보면 어떻게 톱니바퀴를 뽑아야 하는지를 쉽게 깨달을 수 있다.

만약 이번 부품 교체에 실패를 한다면 더 이상 소질이 없음을 솔직하게 시인하고 앞으로는 모든 오디오 DIY 활동을 중단하겠다는 비장한 각오를 갖고 작업에 임했다. 결과는? 그런 비장한 결심을 할 필요는 없었다. 그리고 실패할 경우 이제는 CD를 쓰지 말고(몇 장 되지 않음) 컴퓨터에 음원을 정리하는 방식으로 전환할 생각을 갖고 있었다. 그래서 지난 주말 몇 장의 CD를 윈도우 미디어 플레이어에서 리핑하여 라이브러리에 저장해 보았다. 그러나 정리 방식을 결정하는 것이 쉽지 않았다. 특히 Go!Classic에서 음원을 내려받아 구운 시디는 앨범 정보가 들어있지 않아서 매우 불편하였다. 아직까지 나는 CD 더미에서 적당한 것을 골라 자켓에서 CD를 꺼내는 손맛을 좀 더 즐기고 싶다. 어떤 글을 보니 모아 놓은 음원 - 요즘 하드디스크로 몇 개 되지 않는 분량이지만 - 을 한번씩만 들으려 해도 시간을 계산해 보면 평생이 더 걸린다고 하였다. 하드디스크나 클라우드 저 너머 알 수 없는 곳에 막연하게 존재하는 음원보다는 비록 용량 대비 부피는 많이 차지하더라도 내 손에 잡히는 매체가 아직은 친숙하다.

재조립을 마치고 구운 시디를 넣어 보았다. 훌륭하게 잘 작동이 된다! 인식 불량, 잡음, 일체 발생하지 않는다.


이 시디 플레이어는 1991년도에 제조되었다. 나는 이를 1년 전에 중고로 구입하였다. 픽업은 아마도 몇 번의 교체를 거쳤을지 모르겠지만, 구동 모터는 24년째 돌고 있는 것이 아닐까? 가끔은 윤활유를 칠 필요도 있을텐데? 



2015년 4월 21일 화요일

CLC Genomics Workbench의 contig join(v8.0 기준)

요즘은 미생물 유전체의 NGS data를 가지고 de novo assembly를 하는데 A5-miseq(PDF)를 애용하고 있다. Read의 오류 교정부터 scaffolding 및 assembly의 교정까지를 최적화된 파이프라인으로 실행해 주기 때문이다. 몇 가지 샘플에 대해서 CLC Genomics Workbench와 비교해 본 결과 조립 성적이 더 좋다. 대신 실행 시간은 좀 더 오래 걸린다. 그렇다고 해서 CLC Genomics Workbench와 결별을 하겠다는 것은 아니다. 시각적인 결과가 필요할 때에는 이것이 월등하니까.

효모의 데이터를 다루면서 미토콘드리아 게놈에 해당할 것으로 추정되는 콘티그를 뒤적이다가 분홍색 annotation 화살표를 발견하였다. 지금까지는 본 적이 없던 표시이다.



"Contigs joined"라니? 마우스 포인터를 가져가 보았다. 다음과 같은 노트가 표시된다. 약 46 kb에 이르는 contig 하나에 이런 표지가 총 3개 존재한다.

A repeat or another ambiguous structure was solved using paired reads and two contigs could be joined into one.

친절하기도 하다. 그러나 read depth 측면에서는 그렇게 아름답지는 않다...

2015년 4월 20일 월요일

CD 플레이어 자가 수리(픽업 교체)를 준비하며

소리전자 중고장터에서 1년전에 구입한 롯데 LDP-7500의 시디 인식률이 급격히 나빠졌다. 특히 구운 시디를 잘 읽지 못하고, 틱틱틱~하는 잡음이 들린다. 93년에 구입한 오디오 세트는 전부 폐기하고 91년에 만들어진 중고 CDP를 구입하다니. 하부를 열어보면 기판에 녹이 꽤 슬어있다. 플럭스를 제대로 세척해 내지 않아서 그런 것이었을까?


원영전자라는 곳에서 CD 플레이어의 픽업을 주문하였다. 내 시디 플레이어에는 소니의 KSS-210A라는 제품이 들어간다. '마이너스의 손'이 아니라면 픽업 교체는 그다지 어려운 일이 아니라고 한다. 나는 작년에 중고 튜너를 잘못 건드렸다가 낭패를 본 일이 있어서 걱정이 좀 되기는 한다.

어떤 글을 보면 픽업의 자가 교체를 한 뒤 반드시 조정을 해야 하므로 소비자가 직접 할 일이 아니라고 한다. 그런데 또 다른 글을 보면 공장 출하시 이미 본체에서 조정이 되어 있어서 픽업 교체 후에 따로 조정을 할 일이 없다는 제조사측 엔지니어의 주장도 있다. 무엇이 옳은지는 잘 모르겠다. 인켈의 CDP와 LDP를 써 본 경험에 의하면 의외로 교체 주기가 매우 짧았었다. 이번에 교체를 하면 과연 얼마나 쓸 수 있을까? 아니, 교체 후 제대로 작동을 할까? 만약 긁어 부스럼이 된다면, 그 이후에는 어떻게 할 것인가?

메카니즘을 분해할 때에는 절대 무리한 힘을 가하지 말고, 매 단계마다 사진을 찍어서 조립시에 실수가 없게 해야 할 것이다. 만일 실패한다면, 어차피 갖고 있는 시디가 그렇게 많은 것도 아니니 이제는 전자파일 형태의 음원으로 관리하면서 들을까? 성공적인 교체를 마치고 'Err' 표시가 없는 액정 화면을 만나고 싶다. 이번 교체 시도는 내가 앞으로 오디오 DIY를 할 자격이 있는지를 결정하는 중요한 기점이 될 것이다.



[2015년 4월 21일 추가 작성] 주문한 픽업을 방금 받았다. 웹 검색을 해 보니 더 싸게 파는 곳을 발견하였다(Neocost). 이미 구입한 것을 어쩌겠는가.


2015년 4월 16일 목요일

10인치 우퍼와 트위터를 조합한 2-way 스피커의 구상 - 부품의 선정

가장 중요한 것은 적절한 우퍼를 고르는 것이라 생각한다. 사실상의 풀레인지에 트위터를 덧붙이는 것을 제안한 사람도 있었지만, 일반적인 용도의 10인치 우퍼를 골라도 실용적인 면에서 큰 문제가 있을 것으로는 생각하지 않는다. 비싼 외산 유닛을 사용할 생각은 전혀 없다. 국산 10인치 8옴 유닛 중에서 가격이 6만원대를 넘지 않는 것 중에서 골라보기로 한다. 출력은 정격/최대를 의미한다.

마샬음향의 제품은 끝에 F가 붙은 것이 가정용 오디오 용도이다. P는 업무용이다.

마샬 10S-1250F "최고급 홈 오디오용 유니트"
75/150 W, 93 dB, 50-2500 Hz, 48,000원

마샬 10S-1250FL "홈 오디오용 스피커 유니트"
75/150 W, 90 dB, 45-3500 Hz, 43,000원

마샬 10S-1450F "홈 오디오용 최고급형 유니트"
100/200 W, 95 dB, 40-3000 Hz, 58,000원

마샬 10A-1450F "홈 오디오용 최고급형 유니트, 주물 프레임"
100/200 W, 95 dB, 40-3000 Hz, 62,000원

스피커매니아 Concert 1029
250 W, 94 dB, 30-3500 Hz, 49,500원

스피커매니아 모델명 없는 10인치 우퍼
200 W, 92 dB, 40-5000 Hz, 33,000원

삼미전자의 제품 중 ME로 시작하는 것은 악기용, MO로 시작하는 것은 모니터용이다. CWR 시리즈는 잘 모르겠다. 노래방용?

삼미 ME-250B50
50/100 W, 94 dB, 66.3-10000 Hz, 33,000원

삼미 ME-250B100
100/200 W, 94 dB, 70.3-9000 Hz, 36,000원

삼미 CWR-250B50K
50/100 W, 92 dB, Fo-3000 Hz, 35,000원

크로스오버 필터는 국외에서 무척 많은 종류의 것들이 팔린다. 그런데 컷오프 주파수가 명시되지 않은 것들이 많다. 전형적인 2-way 스피커의 크로스오버 컷오프 지점은 1 kHz와 2.5 kHz 사이에 있다는데...

(ebay) 컷오프 주파수가 조절되는 2 way crossover filter
(AliExpress) 180 W, 3.2 kHz cufoff
(스피커매니아 2-way) CT203(2.5 kHz, 12" 우퍼 추천), CT241(1.5 kHz, 6.5~10" 우퍼 추천),  CT243(4 kHz), CT245(4 kHz)
(사운드하우스) 고가품 위주로 판매


2015년 4월 14일 화요일

10인치 우퍼와 트위터를 조합한 2-way 스피커의 구상

사무실 책상 위에서 제 몫을 다하고 있는 5인치 풀레인지 1호기(정확히 말하자면 트위터가 하나 얹혀 있음)의 진가를 아직도 다 파악하지 못한 상태에서 마음은 벌써 2호기를 향해 달리고 있다.

어제 불현듯이 "10인치 우퍼 + 트위터의 2-way는 어떨까?"하는 생각이 들었다. 요즘 흔히 보이는 스타일은 전혀 아니다. 열심히 웹을 검색해 보았지만 노래방 스피커나 무대용 모니터 스피커 말고는 Hi-Fi용으로 이런 구성을 만들어 쓴다는 정보가 잘 보이지 않았다.

네이버 스피커 공작 카페에 이런 스피커가 음악 감상용으로 쓸만한 것인지를 물었더니 몇 개의 답글이 달렸다. 그 중에 Dynaco라는 스피커를 소개한 것이 있어서 원본 링크를 여기 소개해 본다.

Dynaco Speakers
Seas A26
Aperiodic Loudspeaker Systems

원래 라디오 스피커 제작소였던 Seas Norway라는 회사에서 1969년 최초의 Dynaco A 25 스피커를 출시하였다고 한다. 더이상 방구석에 숨겨진 스피커가 아니라 당당히 스탠드 위에 올려서 귀뿐만 아니라 눈도 즐겁게 하기 위한 콘셉트로 태어났다고 한다. 이 제품은 상당히 인기가 있어서 70년대에 수십만 세트가 팔렸다고 한다.

빈티지 유닛을 수배하여 갖고 있는 것은 아니나, 재현의 의미가 충분히 있다고 생각된다.


[추가 작성] 좀 더 세밀하게 검색을 해 보았다. Instructables 사이트에 10인치 드라이버를 이용한 2-way 스피커 제작 가이드가 실려 있다. 그렇게 유별나거나 고급스런 우퍼를 사용한 것도 아니다. 컷오프 주파수는 2.5 kHz로 하였다. 인클로저 재질은 3/4 인치 파티클 보드로서 외형 치수는 10"(W) x 16"(H) x 10"(D), 즉 밀리미터로 환산하면 254 x 406.4 x 254 (mm)가 된다. 우퍼 가장자리가 전면의 가로 폭을 꽉 채우는 컴팩트한 스타일이다.


2015년 4월 13일 월요일

차이콥스키 교향곡 6번 <비창>을 들으며

실제 러시아 사람들은 차이콥스키가 아니라 치콥스키에 가깝게 발음한다고 한다.

차이콥스키의 교향곡 6번 <비창>은 내가 고등학교때 방학 숙제로 들으면서 클래식 음악에 가까와지게 된 계기가 된 곡으로, 가장 좋아하는 음악이기도 하다. 특별히 좋아하는 악장이 어느 것이라 할 수 없을 정도로 전체를 다 좋아하고, 수도 없이 많이 들었다.

어제 저녁 KBS 클래식 FM에서 대구 교향악단의 최근 공연 실황 녹화를 들었다. 3악장이 끝날 때, 박수가 터져나오고 말았다. 워낙 흥겹고 박력이 넘치는 악장이라서 관객들이 전곡이 완전히 끝나는 것으로 착각을 할 수도 있었을 것이다. 발레나 오페라에서는 극적인 장면 혹은 아리아 직후 박수가 터져나오는 것이 일반적인데, 교향곡이나 모음곡 연주에서는 그런 것을 기대하기 어렵다.

지금은 <명연주 명음반>을 틀어놓고 일을 하는 중이다. 어느 악단의 연주인지는 모르겠으나 또 <비창>이 흘러나오고 있다. 이어져 나오는 곡은 브람스의 바이올린 협주곡 D장조이다. 아이작 스턴의 꽤 오래된 실황 앨범이라 한다.

많은 사람들이 가정용 Hi-Fi 오디오가 추구해야 할 것은 실제 공연장과 같은 소리를 내 주는 것으로 말한다. 나는 그렇게 생각하지 않는다. 음악적으로만 본다면 스튜디오에서 녹음한 것의 음질을 따를 방법이 없다. 내가 생각하는 공연장의 의미는 음악적(음질?)으로 완벽한 것이 아니라 눈으로 보는 즐거움을 포함한 '현장의 분위기'이다. 약간의 방해요소와 기술적 불완전성을 감수하고서라도. 최근에 다녀온 2회의 클래식 음악 공연에서는 끊임없는 관객들의 기침소리로 집중을 하기 어려웠다. 그렇다 해도 공연은 공연으로서의 즐거움이 있다. 공연 시작하기 직전, 객석은 아직 소음으로 부산하고 자리를 잡은 오케스트라의 주자들은 저마다 무대에 앉아서 막바지 개인 연습으로 불협화음을 내다가 드디어 악장 혹은 수석 연주자의 몸짓을 시작으로 조율을 한다. 그리고는 불이 꺼지고 무대 중앙으로 나오는 지휘자에게 열렬한 박수를 보낸다. 바로 이런 분위기를 느끼러 공연장에 가는 것이지, 완벽한 <소리>를 듣기 위해 가는 것은 아니다. 최소한 나에게는.

관객과 연주자의 입장에서는 관객과 상호작용하는 공연과 스튜디오 녹음, 어느 것이 더 완벽한 연주를 할 수 있을까? 대중성이 강한 음악이라면 공연의 의미가 매우 크겠지만, 클래식 음악은 그렇지 않을 수도 있을 것이다. 기회가 있다면 전문 연주자에게 한번 이렇게 물어보고 싶다.

"공연을 좋아하세요, 녹음을 좋아하세요?"
"음악적으로 더욱 완벽한 연주는 공연인가요, 혹은 녹음시 스튜디오에서인가요?"

손수 만든 스피커 시스템이 무미건조한 사무실 근무환경에 색다른 즐거움을 선사하고 있다. 솔직하게 말하자면 진공관 앰프에 대한 관심이 스피커쪽으로 많이 옮겨갔다. 국내에서도 대규모는 아니지만 자체적으로 스피커를 만드는 업체가 생각보다는 많다는 것을 알게 되었다. 이러한 업체가 전부 소출력 진공관 싱글앰프에 적합한 풀레인지 스피커를 만드는 것은 아니다.  그러나 주파수 특성이 비교적 평탄한 4인치급 유닛을 고르게 되면 고음 스피커를 쓰지 않고도 그런대로 음악 감상에 지장이 없을 수준으로 즐길 수 있다는 것도. 그리고 스피커 드라이버(유닛)을 제조하는 일과, 드라이버를 인클로우저에 넣고 크로스오버 튜닝을 하는 일은 또 별개의 기술력을 요하는 일이라는 것도. 그리고 더욱 심각하게는... 자작에는 분명한 한계점이 있다는 것까지.

새로 알게 된 것이 또 있다. 가정용 오디오에 들어가는 스피커보다 PA용 스피커 세계 시장이 더 크다는 것도.

2015년 4월 10일 금요일

Scaffolding tool SSPACE

SSPACE는 네덜란드에 소재한 Baseclear라는 회사에서 제공하는 scaffolding tool이다. 정확히 말하자면 SSPACE의 개발자인 Walter Pirovano가 2011년도에 논문 "Scaffolding pre-assembled contigs using SSPACE"을 발표한 즈음에 Baseclear의 생명정보 및 유전체 분석팀에 합류했다고 보는 것이 맞을 것이다. Baseclear 웹사이트 내에 있는 Pirovino의 정보 페이지를 읽어보니 정말 그러하다.

2014년에는 long read를 사용할 수 있는 SSPACE-LongRead가 발표되었다. 어차피 나는 PacBio SMRT Analysis에서 제공하는 HGAP을 사용하고 있으므로 SSPACE-LongRead를 깊숙하게 활용할 생각은 많지 않으나, 테스트는 해 볼 생각이다.

내가 사용하는 SSPACE는 유료 버전인 프리미엄 v2.3이다. Ion Torrent PGM에서 생산한 mate-pair library read를 pre-existing cotig에 엮어서 스캐폴드를 만들기에는 안성마춤인 도구이다. 유전체 해독을 하면서 mate-pair library가 얼마나 활용성이 좋은지는 두말할 나위도 없다. 단, 일루미나에서 mate-pair library를 만들게 되면 mate-pair가 아닌 read가 상당히 많이 발생한다는 것이 문제이다. 그리고 multiplexed sequencing도 아직 안되는 것 같다. 대신 SOLiD의 mate-pair library 키트를 이용하여 Ion Torrent에서 시퀀싱을 하면 분량은 적지만 꽤 괜찮은 결과가 나온다. 단, 인서트의 양 끝에서 각각 시퀀싱을 하는 것이 아니라 한 방향에서 길게 시퀀싱을 한 뒤 사이에 들어있는 어댑터를 제거하여 두 개의 서열 단편을 만들어야 한다. 이러한 ditag 분리과정은 CLC Genomics Workbench에서 매우 간단하게 할 수 있다.

단, 조심할 것이 있다. 일반적인 short insert library의 paired end sequencing이라면 forward-reverse 방향이 되고, mate-pair library의 paired end sequencing은 revers-forward가 된다. 그러나 SOLiD mate-pair library sequencing 결과에서 나온 mate-pair는 revers-reverse이다. 그러니 이것을 bowtie2와 같은 도구로 매핑을 하려면 방향을 아주 잘 맞추어야 한다.

SSPACE의 설정 파일에는 RR로 방향을 지정할 수 있지만, bowtie(2)에서는 --fr(default), --rf, --ff가 전부이다. --rr은 없다. 조금만 생각해 보면 --rr은 --ff와 일맥상통한다. 다만 파일의 순서에 대한 고민이 필요하다. 결론만 말하자면, reverse reverse로 분리된 paired file을 bowtie에서 매핑하려면 다음과 같이 해야 한다. 물론 -I 와 -X 옵션의 값도 실제 라이브러리의 인서트 크기를 반영하도록 잘 맞추어 주어야 한다.


  1. 첫번째 파일을 reverse complementary로 바꾸어서 --fr(default)로 매핑
  2. 또는 첫번째와 두번째 파일의 순서를 바꾸어서 --ff로 매핑

SSPACE의 기본 동작은 다음과 같다. 두번째 커맨드 라인은 extension을 하는 경우이다(-x 1).


perl (path_to_SSPACE)/SSPACE_Premium_v2.0.pl -l libraries.txt -s contigs_abyss.fa -k 5 -a 0.7 -x 0 -b ecoli_scaffolds_no_extension

perl (path_to_SSPACE)/SSPACE_Premium_v2.0.pl -l libraries.txt -s contigs_abyss.fa -k 5 -a 0.7 -x 1 -m 30 -o 20 -b ecoli_scaffolds_extension

확장을 원한다면 -m 과 -o 의 두 가지 옵션을 추가로 지정해 주어야 한다. -m 30은 contig와 read의 최소 overlap이 30 bp란 의미이고, -o 20은 최소 20개의 read가 있어야 overlap을 해 주겠다는 뜻이다.

2015년 4월 9일 목요일

NCBI ftp에서 genome list만 가져오기

NCBI의 ftp site에 점점 많은 유전체 정보가 등록되면서 웹 브라우저로 ftp를 접속하여 전체 목록을 뽑아보는 일이 점점 어려워지고 있다. 아마 파이썬으로 어떻게든 스크립트를 짜면 ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria에 있는 폴더 목록을 빼 오는 것이 가능할 것이다.

파이썬 찾아보기는 귀찮으니 웹 검색을 해 보자.

텍스트 파일을 하나 만들어서 다음의 내용을 저장하고 ncbi_genomes.lftp라고 저장한다.

open ftp.ncbi.nlm.nih.gov
user anonymous my_email@aaa.com
cd genomes/Bacteria
#cd genomes/Bacteria_DRAFT
ls
#find
exit

(#로 시작하는 행은 필요에 맞게 적절히 해제하라는 뜻이다. 예를 들어 find 명령을 쓰면 하부 내용까지 전부 recursive하게 나온다.)

그러면 다음과 같이 실행하면 된다.

$ lftp -f ncbi_genomes.lftp | tee todays_list.txt

tee 명령을 사용했으므로 파일로 기록됨과 동시에 표준출력(화면)으로 뿌려진다. 방금 받아서 라인 수만 세어 보았다. 2809개이다.

이렇게 하여 각 균주에 대한 정확한 폴더를 알아낸 다음, 다음과 같이 웹브라우저 주소창에 구체적인 URL을 적기만 해도 훨씬 수월한 파일 접근이 가능하다. 

ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria/_path_to_genome_

2015년 4월 7일 화요일

습관적인 지름

다음번 오디오 DIY 프로젝트는 LM1875 등의 칩을 이용한 일종의 Gainclone 혹은 유사품 앰프를 만드는 것이었다. 그러나 도무지 값싼 호기심은 또 몇천원짜리 칩앰프를 그냥 무시하고 지나가지 못하게 만든다. 케이스가 포함되지 않은 제품은 손대지 않기로 해놓고...


구내식당 점심 두번 건너뛰었으니(도시락으로 대체) 무료 배송으로 5.84달러짜리 칩앰프에 투자하는 것이 대수이겠는가. 야마하의 칩 YDA138-E를 사용한다는 것이 호기심을 자극한 포인트였다. 볼륨이 달려있으니 금상첨화. 헤드폰 앰프 기능이 칩에 포함되어 있다는 것도 흥미롭다. 데이터시트를 찾아보니 날짜가 2005년이다. TPA, TDA, TA, LM으로 시작하는 오디어 앰플리파이어 칩만 보다가 야마하의 것을 발견하니 왜 이렇게 반가운지... 아마 (전자)악기 회사라는 점이 나를 자극한 모양이다.

구입의 핑계는 현재 거실에서 쓰고 있는 케이벨 KB20W 앰프의 소리가 다소 소프트하게 느껴졌기 때문이다. 보름 정도가 지나면 또 두툼한 우편 봉투에 담긴 중국제 기판이 하나 날아올 것이다.

2015년 4월 6일 월요일

생각만 하고 있는 후속 오디오 DIY 프로젝트 2건

진공관 앰프 2호기를 만들려는 계획은 무한정 보류하고, 대신하여 5인치급 풀레인지 스피커를 구하여 인클로우저에 수납하는 일로 2015년 1/4 분기 오디오 DIY는 대략 마무리가 되었다. 집에서 듣는 진공관 앰프의 초단관 12DT8 대신 러시아 군용관인 6N2P를 장착하는 개조도 성공적으로 마쳤고, FM 수신용 안테나도 새롭게 고정하여 KBS 대전 FM(98.5 MHz)을 만족할만한 음질로 수신하게 되었다.

사무실 책상 위에는 TPA3116 브리즈 앰프와 이번에 제작한 풀레인지 스피커가 놓여 있다. 매우 만족스러운 수준의 음악을 들려주고 있다.

다시는 섀시가 없는 앰프 보드만을 구하지 않겠다고 수도 없이 다짐을 하였다. 당장 구입하기에 가격은 저렴하지만, 어설프게 만든 섀시는 앰프에 손이 가지 않게 만드는 가장 중요한 요인이 되기 마련이다.

그럼에도 불구하고 눈과 손은 계속 이베이 또는 알리익스프레스의 '앰플리파이어 보드' 카테고리를 만지작거리고 있다...

만약 앰프를 하나 더 만들게 된다면, 이번에는 class D 앰프가 아니라 20W audio amplifier 칩 LM1875를 이용한 보드를 활용해 보고 싶다. 스피커 보호회로까지 추가된 보드 형태의 완제품을 그다지 비싸지 않은 가격에 살 수 있다. 대신 전원 트랜스포머는 트로이달 형으로 주문 제작하면 만족스럽지 않을까?

섀시에 대해서는 아직 아이디어가 없다. 인터넷을 보면 앰프 기판에 서포트를 달고, 여기에 투명 아크릴판을 같은 크기로 잘라서 덮은 간이형 케이스 제작 사례가 많다.

http://www.aliexpress.com/item-img/New-TDA2030A-LM1875-2-1-amplifier-board-chassis-transparent-acrylic-chassis-2030/1884633167.html

기본적으로 이러한 구성을 응용하되, 알루미늄 4각 파이프를 'ㄷ'자 모양으로 잘라서 앞뒤 패널 대용으로 사용하는 방법을 구상해 본다.

다음으로는 6.5인치 수준의 스피커를 이용한 시스템을 만들어보고 싶다. 국산품인 마샬음향의 유닛에 관심이 많이 간다. 멋진 홈페이지나 객관적인 데이터 시트 공개와는 거리가 있지만(흔하게 보이는 주파수 특성표가 보이지 않음), 이상하게 한번 써 보고 싶다는 생각이 든다. 마샬이라고 하면 흔히 전기기타 앰프의 브랜드가 떠오르지만, 이것과는 직접적인 연관은 없는 것으로 보인다. 국산 스피커 제조사인 삼미와 마샬에 대한 간략한 역사는 오디오평론가 김종룡님의 글 [한국 사운드, 삼미와 마샬/스피커 이야기 10]에서 접할 수 있다.

물론 언제 이러한 후속 프로젝트가 실현될지는 알지 못한다.

2015년 4월 4일 토요일

FM 안테나 보수 공사

며칠 전 밤에 심하게 비바람이 불더니 창틀에 설치한 FM 수신용 안테나가 기울어지고 말았다. 획기적인 방안이 필요하겠다 싶어서 창틀용 화분 받침을 이동하여 그 위에 고정하였다. 더 이상 중력으로 인해 스스로 기울어지지 않는 구조가 되었다.
다음에는 케이블 타이 건을 하나 구입할 생각이다. 케이블 타이는 매우 쓰임새가 많은 물건이짐만 전용 공구가 없으면 세게 조이기가 어렵다. 사진에 보이는 나뭇조각을 고정한 케리블 타이는 용산에서 한 묶음을 구입했던 것이다.

2015년 4월 3일 금요일

실험 균주의 resequencing은 앞으로 보편적인 과정이 되어야 할 것임

지난번 대장균 HB101 (re)sequencing에 이어, 이번에도 대장균 실험 균주의 resequencing을 하게 되었다. Plasmid transformant이긴 하지만 결과적으로는 K-12 W3110을 resequencing한 셈이 되었다. 역시 예상했던 바와 같이 NCBI에서 받은 reference sequence와 차이가 있음을 발견할 수 있었는데, 의외로 large scale 변이가 두 곳에서 관찰되었다.

보통 돌연변이라 하면 염기 서열이 시간이 지남에 따라 하나씩 치환되어 단백질의 변이까지 이어지는 점진적인 변이가 많을 것으로 생각한다. 내가 2009년 대장균 B strain의 참조 유전체 서열 작성과 Richard E. Renski의 그 유명한 실험진화균주 프로젝트에 잠시 관여하기 직전까지도 그런 생각을 갖고 있었다. 그러나 실제 뚜껑을 열어보니 그렇지 않았다. mobile genetic element나 다른 균주로부터 수평적 전달로 도입된 영역에 의한 '급진적'인 변이가 더욱 중요하게 느껴졌기 때문이다. 실험자에게 귀찮은 존재라고만 여겨지는 Insertion Sequence(IS)의 무게감을 느낀 것도 이때이다. 어쩌면 IS야말로 진화의 숨겨진 원동력인지도 모른다.

원시 유전체 프로젝트의 시절에는 각 모델 생명체의 참조 유전체를 확보하면 목표를 달성하는 것으로 보았다. 그러나 이제는 그렇지 않다. 개인별 유전체의 차이로부터 질환 감수성이나 약물 반응성 등을 예측하려는 유전체 의학의 시대가 되어 이제 시퀀싱은 모든 개체로 확대해야 하는 사업이 되었다.

대장균이나 고초균과 같은 세균으로 실험을 하는 경우도 예외는 아니다. 참조 서열이 NCBI에 등록되어 있고, 신뢰도 높은 균주 스톡 센터에서 분양을 받았다 해도 안심하지 말라. 어차피 5 Mb 정도 박테리아 유전체를 일루미나로 읽어서 참조 서열 존재 하에 완벽하게 재구성하는 것은 그렇게 어렵지 않은 시대가 되었다(실제로는 손이 꽤 많이 간다. 재수가 없으면 손에 물을 묻히는 실험을 피하지 못한다...). 모름지기 실험 균주라면 한번씩은 완벽하게 유전체 서열을 읽어서 미처 모르는 부분에서 기대하지 못한 실패가 나타나지 않도록 대비하는 것이 좋을 것이다.

그래서 나는 오늘도 CLC Genomics Workbench와 Consed에게 감사하는 마음을 가지고 있다.

2015년 4월 1일 수요일

리눅스에서 GID와 UID 바꾸기

새로 구입하여 세팅을 완료한 리눅스 서버에 기존의 NAS를 마운트하였더니 파일의 소유자가 전부 다르게 되어있다. 웹 검색을 잠시 해 보니 NFS에서는 실제 계정이 아니라 숫자로 된 UID와 GID를 따른다고 한다. 기존의 리눅스 서버에서는 내 계정이 UID와 GID로서 501번을 소유했었다. 그런데 새 서버에 세팅을 하면서 user라는 계정이 최초로 등록되는 과정에서 501번을 가져갔고 내 계정(hyjeong)은 502번이 된 것이었다.

hyjeong 계정의 GID와 UID를 501로 변경하면 된다.

GID와 UDI를 바꾸는 명령어가 있다.

usermod
groupmod

이제야 비로소 NAS의 파일들이 제대로 내 것이 되었다!