글쓴이 보관물: plusha

책: 실용주의 프로그래머 – 앤드류 헌트, 데이비드 토머스

‘실용주의 프로그래머’는 전문 프로그래머들을 위한 조언들이 담긴 책입니다. 제가 대학원생 때 읽고 책의 조언들 중 몇 가지를 직접 실천해보면서 많은 도움을 얻었습니다. 총 70가지의 조언들이 담겨 있는데 여기에서 내용을 확인할 수 있습니다. 제가 실천했던 조언들 중 몇 가지만 살펴보겠습니다.

  • 11. DRY (Don’t Repeat Yourself) – 반복하지 마라.
  • 12. 재사용하기 쉽게 만들라.
  • 21. 명령어 셸의 힘을 사용하라.

연구하면서 반복적으로 하는 작업들이 있습니다. 대학원생 때 반복적으로 하던 작업들 중 이진 파일로 된 탄성파 자료나 속도모델 등에서 trace나 profile을 추출하는 작업, 지하 영상에 미분이나 라플라시안 필터를 적용하는 작업, 깊이에 따라 속도가 선형으로 증가하는 속도모델을 만드는 작업 등이 있었습니다. 그때 그때 코드를 새로 작성하거나 예전에 사용했던 코드를 수정해서 작업했었는데 이러한 반복 작업을 없애기 위해 명령어 셸에서 옵션만 바꿔가며 쉽게 재사용할 수 있는 프로그램들을 작성했었습니다. 그리고 그런 프로그램들을 모아 gpl 라이브러리라고 이름을 붙였죠. 주로 당시 사용하던 포트란 프로그래밍 언어로 프로그램들을 작성했는데, 명령어 셸에서 사용할 수 있도록 option parser도 만들고 파일 입출력도 많이 다루면서 프로그래밍 연습을 할 수 있었습니다.

  • 22. 하나의 에디터를 잘 사용하라.

리눅스 Command line 상에서 프로그래밍을 했기 때문에 당시 사용할 수 있는 에디터로 VimEmacs가 있었습니다. 둘 중 어느 것을 사용할까 비교해보다가 결국 어디에나 설치되어 있는 Vi(Vim)를 사용하기로 했고, 각종 명령어와 plugin들을 이용해 Vim 고급 사용법을 익혔습니다.

  • 23. 언제나 소스코드 관리 시스템을 사용하라.

당시에는 Mercurial을 선택해서 사용하다가 몇 년 전부터는 Git만 사용하고 있습니다.

  • 28. 텍스트 처리 언어를 하나 익혀라.

당시 포트란과 C 언어만 사용하고 있었는데, 이 책을 읽은 후 Ruby, Perl, Python 중 프로그래머를 행복하게 하자는 철학을 내세웠던 Ruby를 선택해서 공부하고 사용했었습니다. Ruby를 배워놓았던 것이 도움이 돼서 나중에 Ruby와 Seismic Unix를 이용해 Muting/Interpolation 스크립트도 작성할 수 있었습니다. 참고로 지금은 Ruby는 사용하지 않고, 과학/공학 라이브러리가 많은 Python을 주로 사용합니다.

위의 조언들 외에도

  • 20. 지식을 일반 텍스트로 저장하라.
  • 29. 코드를 작성하는 코드를 작성하라.
  • 36. 모듈간의 결합도를 최소화하라.
  • 49. 소프트웨어를 테스트하라.
  • 61. 수작업 절차를 사용하지 말라.
  • 68. 문서가 애초부터 전체의 일부가 되게 하고, 나중에 집어넣으려고 하지 말라.

등 다양한 조언들을 실천해보면서 프로그래밍 실력을 향상시킬 수 있었습니다. 우리가 전문 프로그래머는 아니지만 주로 프로그래밍을 이용해 연구를 수행하고 있으니 프로그래밍에 대해 공부하는 것도 많은 도움이 됩니다. 단, 이것 자체가 연구는 아니니 연구하는 중에 틈틈이 연습해보는 것이 좋겠죠.

책: 소유냐 존재냐 – 에리히 프롬

우리는 자본주의 사회에 살고 있습니다. 자본주의 사회는 빚과 소비가 있어야 돌아가는 사회로, 생산자들은 곳곳에서 광고와 뉴스 등을 통해 사람들에게 필요한 또는 불필요한 재화와 서비스의 소비를 부추기고 있습니다. 자본주의 사회에서는 많이 벌어서 많이 소유하고 많이 소비하는 것이 행복한 삶이라는 것을 전제로 하고 있고, 각종 미디어의 영향에서 자유로울 수 없는 우리들은 별다른 생각 없이 위의 전제를 받아들이며 살아가는 경우가 많습니다. 하지만 이 전제는 잘못되었고 그에 따라 많은 사람들이 인간 소외로 고통을 겪고 있습니다. 인류 역사에 자본주의가 등장한 것은 얼마 되지 않았지만 우리는 자본주의에 너무 익숙해진 나머지 자본주의 생활 양식이 아닌 다른 생활 양식이 있다는 사실을 생각하지 못하고 살아갈 때가 많습니다. 책을 읽을 때의 장점 중 하나가 이렇게 평소 삶 속에서 생각하지 못하던 것들을 새롭게 깨달을 수 있다는 점입니다.

에리히 프롬은 이 책에서 많이 소유하는 것을 추구하는 삶 뿐 아니라 풍요롭게 존재하는 것을 추구하는 삶도 있다는 것을, 그러한 삶이 더 가치 있는 삶임을 일깨워줍니다. 자본주의의 소유하는 삶은 탐욕적으로 자신의 소유(재산, 명예, 권력 등)를 늘리고, 남들과 비교하여 자신이 우월하다는 데에서 행복을 발견하는 삶입니다. 반면에 존재하는 삶은 소유물에 집착하지 않는 삶, 기쁨에 차서 자신의 능력을 생산적, 능동적으로 사용하고, 사랑하고 나누며 베푸는 삶입니다. 소유하는 삶은 자신의 소유물로 자신의 가치를 매기고 소유물의 노예가 되는 삶이지만 존재하는 삶은 존재의 절대적 가치를 아는 삶입니다. 존재하는 삶이라고 해서 소유가 전혀 없는 것은 아니지만 존재하는 삶을 사는 사람은 자신의 소유물에 대해 집착하지 않고 소유로부터 자유롭습니다.

두 가지 생활 양식이 학생들의 실생활에서는 어떻게 나타날까요? 소유하는 삶에 길들여진 학생은 강의를 들을 때 잘 암기하여 좋은 성적을 거두는데 중점을 두지만, 존재하는 삶을 사는 학생은 강의 내용을 통해 새로운 생각을 하며 성장하는데 중점을 둡니다. 소유하는 삶의 학생은 책을 읽을 때 소설의 줄거리를 파악하고 철학 서적의 주요 사항을 뒤따라 암기하는데 중점을 두지만, 존재하는 삶을 사는 학생은 소설을 통해 인간의 본성을 통찰하고 철학 서적의 사상을 비판적으로 읽습니다. 소유하는 삶에서는 보다 많이 아는 것이 중요하지만, 존재하는 삶에서는 보다 깊이 아는 것이 중요합니다. 소유하는 삶에서 사랑이란 사랑의 대상을 구속하고 지배하여 소유하는 것이지만, 존재하는 삶에서의 사랑은 사랑의 대상을 배려하고 알고자 하며 소생시키고 생동감을 증대시키는 과정입니다.

우리 물리탐사 연구실이 존재하는 삶을 실천할 수 있는 공동체가 되길 바랍니다. 책 뒷부분에 가면 인간 성격 변화에 관한 거시적인 이야기가 나오지만 우리는 우선 작게 연구실에서 실천할 수 있는 부분을 생각해봅시다. 수업을 들을 때 시험 잘 보고 좋은 성적을 얻는 것도 중요하지만 수업을 통해 스스로가 성장하는데 중점을 둡시다. 연구하고 논문을 쓸 때 실적을 늘리는데 중점을 둘 것이 아니라 연구를 통해 새로운 것을 발견/발명하는 기쁨을 누리고 논문을 통해 사회에 기여한다는 생각으로 논문을 씁시다. 다른 사람과 경쟁해서 이기기 위해서가 아니라 어제의 나와 경쟁해서 더 성장하기 위해 노력합시다. 교수님 말이라고 절대적으로 받아들이지 말고 교수님도 틀릴 수 있으니 자신의 생각과 의견을 이야기합시다. 서로를 가족같이 여기고 자신이 좀 더 아는 것을 나누며 서로의 성장을 도웁시다. 연구실에서 보내는 시간을 학위를 위해 희생하는 시간이 아닌, 그 자체로 보람되고 행복한 시간으로 만들어갑시다. 연구실 생활을 통해 우리 모두의 존재가 좀 더 풍성해지길 바랍니다.

연구실 홈페이지 블로그

부경대학교 에너지자원공학과 물리탐사연구실 가족 여러분! 앞으로 연구실 홈페이지의 블로그를 방문객이 아니라 우리를 위해 사용하려고 합니다. 서로에게 도움이 될만한 글, 소식, 하고싶은 말, 추천해주고 싶은 내용 등을 올려주세요. 글을 올릴 때에는 글쓰기 연습이라는 목적도 있으니 다른 글을 복사해서 붙여넣기보다는 직접 써서 올릴 것을 권장합니다. 방문객에게도 열려 있으니 개인정보 공개에 주의하세요~

소개: 하완수

Professor

성명: 하완수

고등학생 때 막연히 수학과 컴퓨터가 좋아서 공대에 진학했습니다. 대학생 때 수학과 컴퓨터가 좋아서 수학과 컴퓨터를 많이 사용하는 대학원 연구실에 진학하였습니다. 지금도 수학과 컴퓨터를 이용해 탄성파 자료 처리 연구를 진행하고 있습니다.

학력
2000.3. ~ 2006.2. 서울대학교 지구환경시스템공학부 공학사
2006.3. ~ 2008.2. 서울대학교 에너지시스템공학부 공학석사
2008.3. ~ 2011.2. 서울대학교 에너지시스템공학부 공학박사

경력
2011.3. ~ 2013.8. 서울대학교 에너지자원신기술연구소 선임연구원
2011.9. ~ 2013.8. 서울대학교 에너지자원공학과 시간강사
2009.6. ~ 2013.8. (주)신스지오피직스 자문위원
2013.9. ~ 2017.8. 부경대학교 에너지자원공학과 조교수
2017.9. ~               부경대학교 에너지자원공학과 부교수

Fortran config parser

포트란 언어에서 사용할 수 있는 configuration file parser 모듈을 github에 공개했습니다.

다음과 같은 configuration 파일에서 변수들을 읽어들일 수 있는 모듈입니다. 사용법은 github에 올렸습니다.

[DEFAULTS]
path = ../include
use_abs = True

[Section 1]
nmax = 30
# comment 1
vmin = 1.0
freqs = 5.0, 10.0, 30.0, 50.0
amps = 0.0, 1.0, 1.0, 0.0
path = ../text

[Section 2]
use_abs = no
; comment 2
my file = $(Section 1:path)/file.txt

거꾸로 수업 4학기

거꾸로 수업과의 만남

2015년 2월 말, 개강을 한 주 앞두고 마음이 무거웠다. 강의에서 보게 될 일부 학생들의 멍한 눈빛과 조는 모습이 눈 앞에 아른거렸다. 그동안 조는 학생들보다는 열심히 듣는 학생들이 더 많았고 강의 평가도 나쁘지 않았지만 내 무미건조한 말투 때문에 잠과 사투를 벌일 학생들을 생각하니 마음이 아팠다. 그 때 하나님의 은혜로 ‘플립러닝’이란 단어가 생각났다. 그게 무엇인지는 몰랐다. 이전 학기에 대학교육개발원에서 플립러닝 교수법 강의가 있어서 가보고 싶었지만 강의 시간과 겹쳐서 못 갔었는데 그 때 생각이 난 것이다. 그래서 인터넷을 찾아보고 2014년 봄에 방송했던 KBS의 21세기 교육혁명 미래교실을 찾아서 프로그램도 봤다. 거꾸로 교실 관련 책도 두 권 주문해서 읽으며 당장 모든 학부 강의에 거꾸로 수업을 도입하기로 했다.

거꾸로 수업

기존의 수업은 학교에서 강의를 듣고 집에 가서 숙제를 하는 방식이었다. 강의는 보통 선생님이 앞에서 설명하고 학생들은 조용히 듣는 방식이다. 학생들이 질문을 할 수도 있지만 질문하는 학생은 많지 않다. 집에서 숙제를 할 때에는 강의 자료나 책 등을 참고하는데 이 때 선생님의 도움을 받기는 어렵다.

거꾸로 수업에서는 집에서 강의를 듣거나 읽는다. 수업 시간에는 숙제, 토의와 같은 활동을 하면서 수시로 친구들과 대화하고 선생님께 질문하여 도움을 받을 수 있다.

‘서울대에서는 누가 A+를 받는가’라는 책에서 인용한 연구를 보면 학생은 강의를 들으며 머리를 별로 쓰지 않는다. 따라서 질문할 것도 별로 없다. 반면에 스스로 공부를 하거나 숙제를 할 때에는 머리를 많이 사용하게 되고 질문할 것도 많아진다. 거꾸로 수업에서는 학생들에게 질문이 생겼을 때 선생님이 옆에서 도와줄 수 있다.

수업 준비

거꾸로 수업을 위해서는 학생들이 집에서 예습을 해올 수 있도록 미리 동영상을 만들어 인터넷에 올려야 했다. 적당한 교재가 있다면 동영상이 필수는 아니지만 학생들이 빠르게 예습해올 수 있도록 매 시간 강의의 핵심 내용만 담아 짧게는 10분에서 길게는 30분 정도 길이의 동영상을 만들어 올렸다. 짧은 동영상이지만 제작에는 몇 시간씩 걸린다. 동영상도 중요하지만 더 중요한 것은 수업 시간을 어떻게 채울 것인가이다. 강의 없이 두 시간을 채워야 한다. 수업을 위해 학생들이 토의할 수 있는 질문들과 풀 문제들, 동영상에서 생략된 내용을 채워줄 토의를 준비해야 했는데, 수업 준비하느라 흰머리가 많이 늘어난 듯 하다. 그렇게 2015년 두 학기는 수업 준비와 과제 채점만 하다가 다 보냈다. 올해 1학기에는 작년에 만들었던 동영상을 그대로 사용할 수 있어서 비교적 수월했지만 2학기에는 강의 과목 변경으로 인해 또 두 과목의 동영상을 새로 제작중이다.

고맙게도 대부분의 학생들이 수업 전에 동영상을 보고 왔다. 학생들 중에는 동영상을 보며 몇 장씩 필기를 해오는 학생들도 있었다. 나중에 설문조사를 해보니 동영상이 길지 않아 아무 때나 스마트폰으로 간편히 볼 수 있고, 동영상을 미리 보지 않으면 수업 시간에 조원들에게 피해를 끼치게 되기 때문에 열심히 보고 왔다고 했다.

수업 진행

수업 진행 방식은 강의에 따라 약간씩 달라지지만 크게 내가 제시하는 질문에 대한 학생들의 조별 토의와 문제 풀이로 나뉜다. 조별 토의는 강의실 구조상 한 책상에 앉은 두세 명이 한 조가 되어 진행한다. 조는 보통 내가 지정해주지는 않고 학생들이 알아서 앉도록 한다. 제시하는 질문들은 동영상 내용을 이해했는지 기본 개념을 묻는 질문과 응용이 필요한 질문들이다. 이 때 학생들은 짝을 지어 대화, 토론, 논쟁하는 하브루타 방식으로 공부하게 된다. 학생들은 주요 개념들을 직접 설명하면서 더 잘 이해하고 기억하게 된다. 나는 학생들이 서로 설명하고 토의할 때 학생들 사이를 지나다니며 질문을 받고 대답해준다. 예전 강의식 수업에 비하면 학생들의 질문이 크게 늘었다. 조에 따라 활발히 토론하는 조도 있고 말이 별로 없는 조도 있지만, 현재 학생들의 토의를 평가에 넣지는 않고 있다. 대부분의 학생들이 토의에 열정적으로 참여한다. 토의 후에는 몇몇 학생들에게 토의 내용을 발표하도록 시켜서 바로 이해했는지 확인 후 다음 질문으로 넘어간다. 중요한 개념과 관련된 질문의 경우 발표하는 학생에게 소크라테스식 문답법으로 꼬리에 꼬리를 물고 질문을 던지고 설명해주기도 한다. 학생들 한 명 한 명 이름을 불러 질문하다 보니 내 수업을 처음 듣는 학생들 이름도 금방 기억할 수 있어서 좋다. 평소에 학생들이 토론하는 모습을 관찰하게 되니 학생들이 추천서를 써달라고 왔을 때 쓸 말이 있어서 좋았다.

문제 풀이는 조별 또는 개인 과제로 제출하도록 해서 평가에 반영한다. 개인 과제 제출시에도 베끼지는 말되, 옆 친구들과 적극적으로 토의하며 풀도록 한다. 과제는 되도록이면 수업 시간이 끝나기 전에 마쳐서 제출하도록 하지만 수업 시간중에 다 못해서 나중에 제출하더라도 감점은 없다. 학과에 컴퓨터실이 있어서 과목에 따라 컴퓨터실에서 수업을 진행하며 컴퓨터로 풀어야 하는 과제들을 내주기도 한다.

거꾸로 수업을 하게 되면서 학생들은 서로 말을 많이 하게 되었다. 그에 따라 조는 학생이 없어졌다. 드물게 몇 주에 한 번 조는 학생을 발견하는 경우도 있지만 예전에 거의 매시간 몇 명씩 봤던 것에 비하면 없는 것이나 마찬가지다. 그래서 수업 시간도 이전에 학생들이 많이 졸던 9시, 1시로 잡고 있다. 조별 토의를 통해 편입학한 학생들이 기존 학생들과 쉽게 친해지는 장점도 있었다.

‘어떻게 공부할 것인가’라는 책의 ‘인출 연습’ 개념을 도입하여 토의 내용에 이전 수업 내용과 관련된 질문을 넣기도 한다. 퀴즈와 시험 범위는 처음부터 누적이다. 과목에 따라 학기중 두 세번 정도 학생들이 마인드맵을 이용해 배운 내용을 정리하고 직접 시험 문제를 출제해보도록 해준다. 학생들이 작성해서 제출한 내용은 스캔해서 모든 학생들에게 공개하며 좋은 문제가 있으면 중간 또는 기말 시험에 그대로 출제하기도 한다.

수업 결과

앞에 거꾸로 수업으로 얻게된 장점들을 몇 가지 적었는데, 가장 큰 단점은 수업 준비에 많은 시간과 노력이 필요하다는 점이다. ‘조벽 교수의 명강의 노하우&노와이’에서 준비에 시간이 많이 걸리는 교수법은 좋지 않다고 했다. 새로 동영상을 제작하는데는 시간이 오래 걸리지만 앞으로 동일한 수업을 반복하게 되면 수업 준비 시간이 짧아지게 될 것이다.

현재 네 학기째 학부 수업을 거꾸로 수업으로 진행중이다(대학원 수업은 강의식 수업과 거꾸로 수업의 활동이 혼합된 형태). 강의 경력이 짧아서 학생들의 학업 성취도가 향상되었는지는 알 수 없다. 하지만 학생들의 강의 만족도는 높아졌다. 수업을 열심히 들었던 한 학생은 대학교육개발원의 명강의 에세이 공모전에 내 강의에 관한 글을 써서 상을 받았다. 고맙게도 학생들이 작년 두 학기 강의 평가를 잘 해줘서 단과대학 우수강의교수상을 받았다. 앞으로도 개선해야 할 점들이 많지만 이전의 강의식 수업으로 돌아갈 수는 없을 듯 하다.

속도 프로파일과 탄성파 트레이스 추출하여 그리기

속도모델에서 프로파일을 추출하여 깊이에 따라 속도 그림을 그려보겠습니다. 이진 형식의 속도파일에서 텍스트 파일로 프로파일을 추출한 후 그리는 방법과 이진 속도파일을 직접 읽어서 그리는 방법을 살펴보겠습니다. 참고로, 탄성파 공통송신원모음 등에서 트레이스를 추출하여 그리는 과정 또한 동일합니다.

텍스트 파일로 추출하여 그리기

바이너리 파일에서 프로파일 또는 트레이스를 추출하기 위해 gpl 라이브러리의 gplTracePick 프로그램을 사용하겠습니다. 이차원 단면(속도모델, 공통송신원모음 등)에서 세로 방향 트레이스를 추출할 때 사용하는 프로그램입니다. (가로방향 트레이스는 gplHTracePick 프로그램을 이용하면 됩니다.) 이 프로그램을 그냥 실행하면 아래와 같은 도움말이 나옵니다.


%%sh # 이 글을 쓰고 있는 jupyter notebook에서 shell 명령을 실행하기 위한 magic command입니다.
gplTracePick # 실제 터미널상에서 실행하는 명령어

 Gpl trace picker
 Required parameters:
     [i] n1=            : # of grids in fast dimension
     [s] fin=           : input binary file
     [s] fout=          : output binary file
     [i] pick=          : (=first), first pick (1~n2)
 Optional parameters:
     [i] last=first     : last pick (pick~n2)
     [i] step=1         : pick step
     [f] d1=1.0         : grid size
     [i] n2=calc        : # of grids in slow dimension
     [s] type=f         : data type [ifdcz]
     [s] otype=a        : output type [ab] (ascii/binary)

위에서 n1finfoutpick은 프로그램 실행시 필수적으로 넣어줘야 하는 값입니다.

  • n1은 세로 방향(fast dimension) 격자수
  • fin은 입력 파일 이름
  • fout은 출력 파일 이름
  • pick은 추출하고자하는 가로 방향(slow dimension) 격자 번호입니다. 격자 번호는 1번부터 시작합니다.

Marmousi 속도모델(nx=576, ny=188, h=0.016 km)에 대해 1.6 km 지점(격자번호 101)에서 시작하여 3.2 km 간격(200개 격자 간격)으로 3개의 속도 프로파일을 추출한다면 아래와 같이 실행할 수 있습니다.


%%sh
gplTracePick n1=188 d1=0.016 fin=marm16km.bin fout=vel_profile.txt pick=101 step=200 last=501

 n2=         576


     n1=188
     d1=0.016
     fin=marm16km.bin
     fout=vel_profile.txt
     pick=101
     step=200
     last=501

그 때 결과물은 아래와 같습니다. 첫 번째 열은 깊이 정보, 두 번째부터 네 번째 열까지는 추출한 속도 프로파일 정보입니다(1.6 km, 4.8 km, 8.0 km).

%%sh
head vel_profile.txt
   0.00000000       1.50000012       1.50000012       1.50000012    
   1.60000008E-02   1.50000012       1.50000012       1.50000012    
   3.20000015E-02   1.50000012       1.65800011       1.59800005    
   4.80000004E-02   1.66200006       1.66200006       1.60200012    
   6.40000030E-02   1.66600013       1.66600013       1.60600019    
   8.00000057E-02   1.67000008       1.73999715       1.69000006    
   9.60000008E-02   1.67400002       1.74399781       1.69400012    
  0.112000003       1.67800009       1.61800003       1.69800007    
  0.128000006       1.78200006       1.70200002       1.63200009    
  0.144000009       1.78600013       1.70600009       1.63600004    

텍스트 파일로 추출한 결과는 gnuplot과 같은 프로그램을 이용해 빠르게 확인해볼 수 있습니다. 여기서는 파이썬의 Matplotlib을 이용하여 위의 속도 프로파일을 그려보겠습니다.


%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np

trc=np.loadtxt("vel_profile.txt")

h=0.016
fs='large'

plt.figure(figsize=[15,5])
for i,ix in enumerate([100,300,500]):
    plt.plot(trc[:,0],trc[:,i+1],label="{0} km".format(ix*h))

plt.legend(loc="upper left",fontsize=fs)
plt.xlabel("Depth (km)",fontsize=fs)
plt.ylabel("Velocity (km/s)",fontsize=fs)

<matplotlib.text.Text at 0x10cc66c88>

png

이진 파일을 직접 읽어서 그리기

이번에는 파이썬에서 이진 형식의 속도모델 파일을 직접 읽어서 그려보겠습니다.


nx=576
ny=188
vel=np.fromfile("marm16km.bin",dtype=np.float32)
vel.shape=(nx,ny)

h=0.016
fs='large'
depth=np.arange(ny)*h

plt.figure(figsize=[15,5])
for ix in [100,300,500]:
    plt.plot(depth,vel[ix,:],label="{0} km".format(ix*h))

plt.legend(loc="upper left",fontsize=fs)
plt.xlabel("Depth (km)",fontsize=fs)
plt.ylabel("Velocity (km/s)",fontsize=fs)

<matplotlib.text.Text at 0x10d13dd30>

png

참고로, 파이썬은 배열 인덱스가 0번부터 시작하기 때문에 가로방향 100, 300, 500번 속도 프로파일을 가져다가 그렸습니다(gplTracePick을 이용하는 앞의 예제에서는 101, 301, 501번 격자 위치에서 추출했죠).

탄성파 트레이스 그리기

공통송신원모음에서 탄성파 트레이스를 추출하여 그리는 과정은 속도모델에서 프로파일을 추출하여 그리는 경우와 동일합니다. 아래는 샘플 개수가 723개, 샘플링 간격 4 ms, 트레이스가 96개인 공통송신원모음 파일(marm3000.bin)에서 31번째와 61번째 트레이스를 그리는 예제입니다.


ntr=96
ns=723
dt=0.004
trc=np.fromfile("marm3000.bin",dtype=np.float32)
trc.shape=(ntr,ns)

fs='large'
time=np.arange(ns)*dt

plt.figure(figsize=[15,5])
for itr in [30,60]:
    plt.plot(time,trc[itr,:],label="trace {0}".format(itr+1))
plt.legend(loc="upper left",fontsize=fs)
plt.xlabel("Time (s)",fontsize=fs)
plt.ylabel("Amplitude",fontsize=fs)
plt.xlim([0,ns*dt])

(0, 2.892)

png

속도모델 그림 그리기

두 가지 방법으로 2차원 속도모델을 그려보겠습니다. 첫 번째 방법은 SU의 psimage를 이용하는 방법, 두 번째는 python의 matplotlib을 이용하는 방법입니다.

psimage로 그리기

첫 번째 방법부터 보겠습니다. psimage는 쉘에서 사용하는 명령어이지만, gpl 라이브러리의 psplot 모듈을 이용하면 python 명령을 통해 간편하게 속도모델을 그릴 수 있습니다. Marmousi 속도모델을 그림으로 그려보겠습니다.


from gpl.psplot import plot

nx=576
ny=188
h=0.016
fin="marm16km.drt"

opt = "n1={0} d1={1} d2={1} d1num=1 lbeg=1.5 lend=5.5".format(ny,h,h)
plot.velocity("marm16km.png", fin, opt)

psimage label1="Depth (km)" legend=1 d2s=0.5 lheight=1.0 lstyle="vertright" label2="Distance (km)" height=1.0 labelsize=8 lwidth=0.1 d1s=0.5 width=2.65  n1=188 d1=0.016 d2=0.016 d1num=1 lbeg=1.5 lend=5.5 < marm16km.drt > marm16km.eps

// adding velocity unit (km/s)

// fixing bounding box

// converting .eps to .png ..

vel(marm16km.png)

velocity_color를 이용해 컬러로 그릴 수도 있습니다.


plot.velocity_color("marm16km_color.png",fin,opt)

psimage label1="Depth (km)" ghls="0.33,0.5,1" bps=24 bhls="0.67,0.5,1" d1s=0.5 lwidth=0.1 whls="0,0.5,1" legend=1 d2s=0.5 lheight=1.0 lstyle="vertright" label2="Distance (km)" height=1.0 labelsize=8 width=2.65  n1=188 d1=0.016 d2=0.016 d1num=1 lbeg=1.5 lend=5.5 < marm16km.drt > marm16km_color.eps

// adding velocity unit (km/s)

// fixing bounding box

// converting .eps to .png ..

vel(marm16km_color.png)

Matplotlib으로 그리기

두 번째 방법은 python의 matplotlib 라이브러리를 이용하는 방법입니다. 이를 위해서는 코드에서 numpy를 이용해 속도모델을 읽어들인 후에 matplotlib으로 그립니다. 속도모델을 그리는 부분은 함수로 작성하였는데, 필요에 따라 수정해서 사용하면 되겠습니다.


%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np

def plot_vel(vel, h, figsize=[15,4], unit='km/s', xticks=None, yticks=None, cticks=None, cmap='gray_r', fontsize=20):
    xmax=(vel.shape[0]-1)*h
    ymax=(vel.shape[1]-1)*h

    plt.figure(figsize=figsize)
    plt.imshow(vel.transpose(),extent=(0,xmax,ymax,0),cmap=cmap)

    # x,y labels
    plt.xlabel('Distance (km)',fontsize=fontsize)
    plt.ylabel('Depth (km)',fontsize=fontsize)

    # x,y ticks, tick labels
    plt.tick_params(labelsize=fontsize)
    plt.gca().xaxis.tick_top()
    plt.gca().xaxis.set_label_position("top")
    xticks and plt.xticks(xticks)
    yticks and plt.yticks(yticks)

    # colorbar
    cb=plt.colorbar(shrink=1.0,pad=0.01,aspect=10,ticks=cticks)
    plt.clim([vel.min(),vel.max()])
    cb.set_label(unit,fontsize=fontsize)
    ct=plt.getp(cb.ax,'ymajorticklabels')
    plt.setp(ct,fontsize=fontsize)

# 속도모델 읽기
vel=np.fromfile(fin,dtype=np.float32)
vel.shape=(nx,ny)

yticks=[0,1,2] # y축 ticks
cticks=[2,3,4,5] # colorbar ticks
plot_vel(vel,h,yticks=yticks,cticks=cticks)

png

# 컬러로 그리고(cmap='jet') 파일로 저장하기
plot_vel(vel,h,xticks=[0,3,6,9],cmap='jet')
plt.savefig("vel.png",bbox_inches='tight')

png

결과물로 저장한 vel.png 파일은 다음과 같습니다.

vel(vel.png)

Matplotlib을 이용한 탄성파 자료처리 그림 그리기

이전 글에서는 SU 명령어들을 이용해 탄성파 자료처리 결과 확인용 그림을 그리는 방법을 살펴보았습니다. 이번에는 Python의 Matplotlib을 이용하여 그린 그림 예제들을 보겠습니다. 그림은 IPython Processing 모듈을 이용해 그렸으며, 그릴 때 사용한 코드는 github에서 볼 수 있습니다.

속도모델, 구조보정 영상

우선, 다음과 같이 이진파일로부터 2차원 속도모델과 구조보정 결과를 그릴 수 있습니다. 기본적으로 속도모델은 컬러, 구조보정 영상은 흑백으로 그리도록 했지만, 필요에 따라 코드를 수정해서 색상을 바꿀 수 있습니다. 색상을 바꾸고 싶을 경우 imshow 함수의 cmap 인자를 이용하면 됩니다.

%matplotlib inline
from pkprocess import *
import numpy as np

vel = np.fromfile("marm16km.drt", dtype=np.float32)

nx = 576
nz = 188
h = 0.016
vel.shape = (nx, nz)

plot_vel(vel, h)

png


plot_mig(vel,h)

png

공통송신원 모음, 스펙트럼

그리고 SU 파일로부터 공통송신원 모음이나 F-X, F-K 스펙트럼을 그릴 수 있습니다. 공통송신원 모음은 Wiggle trace 또는 이미지로 그릴 수 있고, 이미지 색상은 cmap으로 조절 가능합니다.


su = read_su("marm3000.su")

plot_wiggle(su, perc=97)

min=-616.05078125 max=613.4453125

png


plot_image(su, perc=97)

min=-616.05078125 max=613.4453125

png


plot_image(su, perc=97, cmap='bwr')

min=-616.05078125 max=613.4453125

png


specfx(su)

dt=0.004, fmax=125.0

png


specfk(su)

dt=0.004, fmax=125.0

dx=0.025, kmax=20.0

png

위의 그림들 모두 Matplotlib으로 그렸으므로, 수정이 필요할 경우 Matplotlib 문서를 참고하여 수정해서 사용하시면 되겠습니다.