ミームの死骸を待ちながら

We are built as gene machines and cultured as meme machines, but we have the power to turn against our creators. We, alone on earth, can rebel against the tyranny of the selfish replicators. - Richard Dawkins "Selfish Gene"

We are built as gene machines and cultured as meme machines, but we have the power to turn against our creators.
We, alone on earth, can rebel against the tyranny of the selfish replicators.
- Richard Dawkins "Selfish Gene"

なぜ何もないのではなく何かがあるのか

書きたいことがない.書きたいことはあるが,それをテキスト化のフローに載せていくことが出来ていない.というわけでこれは無理矢理に文章を出力する試みである.軽く 2000 字を目処に.

一つの思想の真の生命は,思想がまさに言葉になろうとする地点に達するまで持続するにすぎない.その地点で思想は石と化し,その後は生命を失う.だが化石化した太古の動植物のようにその思想は荒廃を免れる.我々は思想のつかのまの生命を,まさに結晶せんとする瞬間の結晶体の生命に比することができる.

ショーペンハウアー読書について』 p.38

仕事ではめっきりコードを書く機会が減り,自然言語を書いている.技術職ではあるが,それを道具としながら日本語と英語を読み書きして人間と社会をやっている.英語はもっと喋れるようになりたいな.論理と自然言語を装備して正論と事実で殴ることのできる今の仕事は案外性に合ってるとは思うが,コードを書いてものを作り続けている人はほんとうに尊敬に値する.

仕事が楽しいのでわりと社畜っぽい働き方をしているが,IT 業界の闇みたいな辛い話がない職場で待遇的にもかなり恵まれているとは思う.現世に楽園は存在しないんで嫌なこともあるが総じてな.成果測定の難しいことをやっているので,給料分はチームの役に立っていることを願う.

学生時代から得意とする絨毯爆撃的な学習を日常業務に活用する方法が自分の中でようやく確立できてきた気がする.この方法を人間的やっていきの瞬発的飛び道具と組み合わせ,いくつかそりっどな成果を得ることが出来た.1000 ページあるドキュメントを片っ端から読んでいったりする人間は少なく,知識獲得そのものにモチベーションを感じて継続できるというのは社会全体から見るとレアな方の気質であるらしい (エンジニア職はそういう気質わりと多いような気もするけど).ともあれ,そういう偏執的な姿勢は使いようによっては社会でも役に立つらしい.院を出て就職したばかりの僕に聞かせてやりたい希望のある話である.しかし油断はできない.この世に慈悲はなく僕自体に価値はなく油断をした瞬間に死ぬことは確定的に明らかである.

もちろん偏執的なだけでは社会をやっていくことが出来ないため,人間とのコミュニケーションにおいては基本的な論理を使って丁寧に事実を整理してみる.整理した論理を言葉に落とし込んで理解のポイントをすり合わせようと試みる.そもそも人間の頭脳は基礎的な論理 (とくに因果関係) プラットフォームに乗りやすいようには思う.

つい先日 「異世界からきた」論文を巡って: 望月新一による「ABC予想」の証明と、数学界の戦い « WIRED.jp なんて記事を読んだりもして,"人間の頭脳の程度がだいたい全部同じくらい" とはとても主張できないのだけど.僕もできることなら天才になりたかった.元々ものごとの理解力が格別優れているわけでもなく,むしろとんでもなく基礎的で誰も見向きしないような場所の石ころに躓いていつまでもそこで途方にくれているような頭脳でしかない.

閑話休題

『生命・エネルギー・進化』

突然ですが最近読んでよかった本の紹介です.

ニック・レーンによる『生命・エネルギー・進化』という本で,原題は “THE VITAL QUESTION – Why Is Life the Way It Is?".著者がかつて『ミトコンドリアが進化を決めた』で展開した論をさらに先へ進めたもの,っぽく,より汎用性の高い語り口として "進化には実は,生命のきわめて根本的な特性の一部を第一原理から予測できるようにする強い制約 – エネルギーの制約 – があるということ” を主張する.

とくにこの制約が顕著に感じられるのは我々真核生物という “異端” においてである.細菌も古細菌も,その化学・遺伝的特性の吹っ飛び方からは考えられないほど,見た目にはほとんど同じである. “まるでそこに内在する物理的制約が原核生物を複雑な形態に進化できなくしているかのようで,その制約はなぜか真核生物の進化では解かれたのである” (p.57) … こうした謎を提起しながら論をすすめる本書はある種推理小説的というか,謎解きの楽しさを与えてくれる.まぁ謎解きというか著者に導かれて"謎の解かれていき" を見ることになるわけだが,そこらへんの事情は推理小説でもさほど変わるまい.

生命 (life) とは何か,ではなく,生きている (living) とは何なのか.生化学畑の学生であったこともあり実に楽しい読書体験であったと言える.

ひそむもの

仕事と生活にある程度の安定感が出てくると,この先どうするという思考が仄暗い水の底から浮かび上がってくる.いまググって知ったけど仄暗い水の底からってパチンコになってんのか頭おかしい.人生でやりたいことはいろいろあるが,僕は本当に人生の進捗が遅く遠回りばかりで,ぐるぐると何かの周りを歩き続ける以外にこれといった存在の使い方もしていないように思われる.

そうしてぐるぐると歩いているうちにある程度は身の程を知ってしまい,自身の無能と現実の現実たる現実に打ちひしがれているうちにぐるぐる回っているときは見えていたはずのものがいつのまにかひどくぼんやりとして来て,視界不良と幸福の定義に悩みながら新しい火薬を手札に加えるべく周回ルートを外れてあてどなく生きていく以外に何も

それはぼくの思いすごし 悪いことばかり思いつく いつもの日曜日の午後

スガシカオ「日曜日の午後」

Spark on EMR で 1000 Genomes Project のデータを触る

なんやかんやで年始から記事書いてないですが, 外部要因がないとブログを書かないようになっている. "Distributed computing (Apache Hadoop, Spark, ...) Advent Calendar 2016" の 12/11 担当として何かを書きます.

qiita.com

1000 Genomes Project public data set on S3

AWS S3 には無造作にいろんなびっぐなでーたが置いてあり,

aws.amazon.com

その中に 1000 Genomes Project のデータがあります: 1000 Genomes Project and AWS.

1000 Genomes Project については公式ページ 1000 Genomes | A Deep Catalog of Human Genetic Variation などを参照して頂ければと思いますが, 複数民族をソースとして匿名の 1000 人以上のゲノム配列を決定しよう, というプロジェクトで既に完了しています. なんで 1000 人も要るかって言うとヒトのみならず生物ってのは同じ種でも個体ごとに微妙にゲノム配列に差があってその差がいわゆる "体質" とか "病気のかかりやすさ" 的な差を生み出しているからで, ヒトの標準的なゲノムは何なのか, ということを知る意味でもある程度の N が必要だからです. ともあれ, そのデータは匿名化された上で公開されており, S3 上にも上がっているというわけです.

aws cli が使えるなら以下のコマンドですぐアクセスできます.

$ aws s3 ls s3://1000genomes
                           PRE alignment_indices/
                           PRE changelog_details/
                           PRE complete_genomics_indices/
                           PRE data/
                           PRE hgsv_sv_discovery/
                           PRE phase1/
                           PRE phase3/
                           PRE pilot_data/
                           PRE release/
                           PRE sequence_indices/
                           PRE technical/
2015-09-09 06:16:09       1663 20131219.populations.tsv
2015-09-09 06:17:01         97 20131219.superpopulations.tsv
2015-09-09 00:01:44     257098 CHANGELOG
2014-09-03 00:39:53      15977 README.alignment_data
2014-01-30 20:13:29       5289 README.analysis_history
2014-01-31 12:44:08       5967 README.complete_genomics_data
2014-08-29 09:22:38        563 README.crams
2013-08-07 01:11:58        935 README.ebi_aspera_info
2013-08-07 01:11:58       8408 README.ftp_structure
2014-09-03 06:19:43       2082 README.pilot_data
2014-09-03 21:33:15       1938 README.populations
2013-08-07 01:11:58       7857 README.sequence_data
2015-06-19 03:28:31        672 README_missing_files_20150612
2015-06-04 04:43:32        136 README_phase3_alignments_sequence_20150526
2015-06-19 01:34:45        273 README_phase3_data_move_20150612
2014-09-03 21:34:30    3579471 alignment.index
2014-09-03 21:32:59   54743580 analysis.sequence.index
2014-09-03 21:34:57    3549051 exome.alignment.index
2014-09-03 21:35:15   67069489 sequence.index

Adam

今回は s3://1000genomes/release/ 配下の多型データを使いますが, これは Variant Call Format (VCF) という形式で保存されておりこのままでは Spark で扱うことが出来ません. そこでマエショリが必要になってくるのですが, Spark でゲノムデータ解析をする際は Adam というパッケージがデファクトスタンダードっぽくなっているので, 以下それを使って Parquet ファイル (相当) に変換します.

GitHub - bigdatagenomics/adam: ADAM is a genomics analysis platform with specialized file formats built using Apache Avro, Apache Spark and Parquet. Apache 2 licensed.

EMR クラスタ (Release label: emr-5.1.0 *1 ) を立て, Adam をビルドします. maven, sbt は適当に入れているものとします. EMR 5.1.0 は Spark 2.0.1 がバンドルされており Scala のバージョンは 2.11.8 なので, ./scripts/ 配下の適切なスクリプトを流す.

$ git clone https://github.com/bigdatagenomics/adam.git ~/adam
$ cd !$
$ ./scripts/move_to_scala_2.11.sh
$ ./scripts/move_to_spark_2.sh
$ MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=256m" mvn clean package -DskipTests

モノがビルドされると, spark-shell, spark-submit を拡張した adam-shell, adam-submit なるコマンドが使えるようになります.

[hadoop@ip-172-31-12-100 adam]$ ./bin/adam-shell
Using SPARK_SHELL=/usr/bin/spark-shell
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel).
16/12/11 13:57:32 WARN Client: Neither spark.yarn.jars nor spark.yarn.archive is set, falling back to uploading libraries under SPARK_HOME.
16/12/11 13:57:41 WARN SparkContext: Use an existing SparkContext, some configuration may not take effect.
Spark context Web UI available at http://172.31.12.100:4040
Spark context available as 'sc' (master = yarn, app id = application_1479477268424_0036).
Spark session available as 'spark'.
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.0.1
      /_/

Using Scala version 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_111)
Type in expressions to have them evaluated.
Type :help for more information.

scala>

VCF to "Adam Format" (Parquet に毛の生えたフォーマット)

adam-submit のサブコマンドに vcf2adam というものがあり, これを噛ませることで VCF ファイルを ADAM Format に変換します. 変換元に先述の S3 1000genomes バケットを指定し, 出力先として自分の手持ちのバケットを指定する感じです. ゲノムデータは染色体単位で分かれて記録されているので, とりあえずトリソミーになるとダウン症を発症する 21 番染色体を選んで変換してみようと思いますが, まずは手元に落として, 少し VCF ファイルを覗いてみます.

$ aws s3 cp s3://1000genomes/release/20130502/ALL.chr21.phase3_shapeit2_mvncall_integrated_v5a.20130502.genotypes.vcf.gz
 /home/hadoop/

// 冒頭部分
$ zcat ~/ALL.chr21.phase3_shapeit2_mvncall_integrated_v5a.20130502.genotypes.vcf.gz | head -n 6
##fileformat=VCFv4.1
##FILTER=<ID=PASS,Description="All filters passed">
##fileDate=20150218
##reference=ftp://ftp.1000genomes.ebi.ac.uk//vol1/ftp/technical/reference/phase2_reference_assembly_sequence/hs37d5.fa.gz
##source=1000GenomesPhase3Pipeline
##contig=<ID=1,assembly=b37,length=249250621>

// 行き来しながら探したところ 253 行目がヘッダーの模様.
$ zcat ~/ALL.chr21.phase3_shapeit2_mvncall_integrated_v5a.20130502.genotypes.vcf.gz | head -n 253 | tail -n 1
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT  HG00096 HG00097 HG00099 HG00100 HG00101 HG00102 HG00103 HG00105 HG00106 HG00107      HG00108 HG00109 HG00110 HG00111 HG00112 HG00113 HG00114 HG00115 HG00116 HG00117 HG00118 ... (省略

// データの中身.
$ zcat ~/ALL.chr21.phase3_shapeit2_mvncall_integrated_v5a.20130502.genotypes.vcf.gz | head -n 1000 | tail -n 1 | head -c 200
21      9440889 rs574517239     A       C       100     PASS    AC=1;AF=0.000199681;AN=5008;NS=2504;DP=13457;EAS_AF=0;AMR_AF=0;AFR_AF=0.0008;EUR_AF=0;SAS_AF=0;AA=.|||;VT=SNP        GT      0|0     0|0     0|0     0|0     0|0     0|0     0|0     0|0     0|0     0|0     0|0     0|0     0|0 ... (省略

では, adam-submit 叩きます. adam-submit コマンドは spark 用のオプションと adam オプションの間に -- を入れる必要があります. ちょっとハマりました.

$ ./bin/adam-submit \
--deploy-mode cluster \
--master yarn \
--num-executors 10 \
--executor-memory 20G \
-- \
vcf2adam \
s3://1000genomes/release/20130502/ALL.chr21.phase3_shapeit2_mvncall_integrated_v5a.20130502.genotypes.vcf.gz \
s3://hash-genome-work/chr21.v5/

行けましたね. コアノード 2 台でやっていましたが, この辺で処理が遅いことに気が付き金で殴るべく m3.2xlarge x 10 台に増設しています. そのスペックで 21 番染色体の VCF の Adam フォーマット変換処理に要する時間が 1.5hr 程度でした.

結果.

$ aws s3 ls --recursive s3://hash-genome-work/chr21.v5
2016-12-12 02:39:55          0 chr21.v5/_SUCCESS
2016-12-12 02:39:56      11895 chr21.v5/_common_metadata
2016-12-12 02:39:56       5548 chr21.v5/_header
2016-12-12 02:39:56      29687 chr21.v5/_metadata
2016-12-12 02:39:56      28835 chr21.v5/_samples.avro
2016-12-12 02:39:56       3466 chr21.v5/_seqdict.avro
2016-12-12 02:39:47  119661147 chr21.v5/part-r-00000.gz.parquet
2016-12-12 02:39:50  117920329 chr21.v5/part-r-00001.gz.parquet
2016-12-12 02:39:52  117938957 chr21.v5/part-r-00002.gz.parquet
2016-12-12 02:39:54   24165424 chr21.v5/part-r-00003.gz.parquet
2016-12-12 01:08:37          0 chr21.v5_$folder$

Parquet 化された多型データを adam-shell から参照

adam-shell で色々見てみたいのですが, AdamContext だと S3 からは直接ロードが出来ず HDFS に置く必要があるっぽいので先に HDFS に書き出します.

$ aws s3 cp --recursive s3://hash-genome-work/chr21.v5 /home/hadoop/chr21.parquet
$ hadoop fs -mkdir /user/hadoop/ch21
$ hadoop fs -put /home/hadoop/chr21.parquet/*.parquet /user/hadoop/ch21/

$ hadoop fs -ls /user/hadoop/
Found 2 items
drwxr-xr-x   - hadoop hadoop          0 2016-12-11 19:18 /user/hadoop/.sparkStaging
drwxr-xr-x   - hadoop hadoop          0 2016-12-11 19:35 /user/hadoop/ch21

$ hadoop fs -ls /user/hadoop/ch21/
Found 4 items
-rw-r--r--   3 hadoop hadoop  119661147 2016-12-11 19:35 /user/hadoop/ch21/part-r-00000.gz.parquet
-rw-r--r--   3 hadoop hadoop  117920329 2016-12-11 19:35 /user/hadoop/ch21/part-r-00001.gz.parquet
-rw-r--r--   3 hadoop hadoop  117938957 2016-12-11 19:35 /user/hadoop/ch21/part-r-00002.gz.parquet
-rw-r--r--   3 hadoop hadoop   24165424 2016-12-11 19:35 /user/hadoop/ch21/part-r-00003.gz.parquet

さて, ようやく Adam Shell からデータを読めそうです.

$ ./bin/adam-shell

scala> val data = spark.read.parquet("/user/hadoop/ch21/*.parquet")
data: org.apache.spark.sql.DataFrame = [variant: struct<contigName: string, start: bigint ... 8 more fields>, contigName: string ... 20 more fields]

scala> data.count
res13: Long = 2785018912

約 27.8 億レコードと, 21 番染色体の variant だけでけっこうなデータ量. スキーマ見てみます.

scala> data.first
res14: org.apache.spark.sql.Row = [[null,null,null,WrappedArray(rs559462325),G,A,true,true,WrappedArray(),false],21,9411238,9411239,[true,true,WrappedArray(),null,null,null,null,null,null,null,WrappedArray(),WrappedArray(),null,null,Map()],HG00096,null,null,WrappedArray(REF, REF),null,null,null,null,null,null,WrappedArray(),WrappedArray(),WrappedArray(),false,true,null,null]

scala> data.printSchema
root
 |-- variant: struct (nullable = true)
 |    |-- contigName: string (nullable = true)
 |    |-- start: long (nullable = true)
 |    |-- end: long (nullable = true)
 |    |-- names: array (nullable = true)
 |    |    |-- element: string (containsNull = true)
 |    |-- referenceAllele: string (nullable = true)
 |    |-- alternateAllele: string (nullable = true)
 |    |-- filtersApplied: boolean (nullable = true)
 |    |-- filtersPassed: boolean (nullable = true)
 |    |-- filtersFailed: array (nullable = true)
 |    |    |-- element: string (containsNull = true)
 |    |-- somatic: boolean (nullable = true)
 |-- contigName: string (nullable = true)
 |-- start: long (nullable = true)
 |-- end: long (nullable = true)
 |-- variantCallingAnnotations: struct (nullable = true)
 |    |-- filtersApplied: boolean (nullable = true)
 |    |-- filtersPassed: boolean (nullable = true)
 |    |-- filtersFailed: array (nullable = true)
 |    |    |-- element: string (containsNull = true)
 |    |-- downsampled: boolean (nullable = true)
 |    |-- baseQRankSum: float (nullable = true)
 |    |-- fisherStrandBiasPValue: float (nullable = true)
 |    |-- rmsMapQ: float (nullable = true)
 |    |-- mapq0Reads: integer (nullable = true)
 |    |-- mqRankSum: float (nullable = true)
 |    |-- readPositionRankSum: float (nullable = true)
 |    |-- genotypePriors: array (nullable = true)
 |    |    |-- element: float (containsNull = true)
 |    |-- genotypePosteriors: array (nullable = true)
 |    |    |-- element: float (containsNull = true)
 |    |-- vqslod: float (nullable = true)
 |    |-- culprit: string (nullable = true)
 |    |-- attributes: map (nullable = true)
 |    |    |-- key: string
 |    |    |-- value: string (valueContainsNull = true)
 |-- sampleId: string (nullable = true)
 |-- sampleDescription: string (nullable = true)
 |-- processingDescription: string (nullable = true)
 |-- alleles: array (nullable = true)
 |    |-- element: string (containsNull = true)
 |-- expectedAlleleDosage: float (nullable = true)
 |-- referenceReadDepth: integer (nullable = true)
 |-- alternateReadDepth: integer (nullable = true)
 |-- readDepth: integer (nullable = true)
 |-- minReadDepth: integer (nullable = true)
 |-- genotypeQuality: integer (nullable = true)
 |-- genotypeLikelihoods: array (nullable = true)
 |    |-- element: float (containsNull = true)
 |-- nonReferenceLikelihoods: array (nullable = true)
 |    |-- element: float (containsNull = true)
 |-- strandBiasComponents: array (nullable = true)
 |    |-- element: integer (containsNull = true)
 |-- splitFromMultiAllelic: boolean (nullable = true)
 |-- phased: boolean (nullable = true)
 |-- phaseSetId: integer (nullable = true)
 |-- phaseQuality: integer (nullable = true)

わお. いくつか取ってみます.

scala> data.first.get(1) // contigName. このデータでは染色体番号が入ってるので 21
res15: Any = 21

scala> data.first.get(0)
res17: Any = [null,null,null,WrappedArray(rs559462325),G,A,true,true,WrappedArray(),false]
// variant の情報. referenceAllele = G で alternateAllele = A なので,
// リファレンス配列では G のところが A になってる変異のレコード, ということになる

scala> data.first.get(5)
res21: Any = HG00096
// sampleId.

sampleId HG00096 について少し調べてみると, 年齢不詳イギリス人男性の B 細胞からサンプリングされたものであることがわかる.

なにか面白い解析が出来るとよかったのだけどぱっと思いつかなかったので一旦ここまでで公開. 何か思いついたら追記するかも.

とりあえず一発でアクセス可能な場所 (S3) に世界的な科学研究の成果が転がっていて, データを使ってあれこれ弄れる形まで持って行くのは案外簡単ですよ, というあたりが伝われば幸いです.

*1:最新版は EMR 5.2.0 ですが手元に立ってたのが 5.1.0 だったので...

最近は有給を取って大七酒造の見学に行ったりしている

寿司のネタには地域差があり北海道なんかはそこらのチェーン店でクソ美味いネタが流れてくる約束の地であると言うが,

f:id:Hash:20160229022304j:plain

レーンに日本酒銘柄が流れてくる土地.それが福島である.

f:id:Hash:20160229022312p:plain

大七酒造.

f:id:Hash:20160229022345j:plain

"大七" は僕が大学学部生時代の「なんとなく日本酒美味しい」から「日本酒にもいろいろあるんだな」時代を経て「日本酒最高!!!」へ至るターニングポイントとなった銘柄であり,その見学をしてきたというまさにブロガーといった趣きの大変心温まるハートフルエントリであり今日はあんま戯言系ないです.

経緯

時は遡り,なんでド平日に福島まで足を運んで酒造見学してるのか*1という話を.あれは今から 1 年...いや 1 ヶ月前だったか,まぁいい.私にとってはつい昨日の出来事だが君たちにとっては明日の云々

要するにこういうついーとをして無事選ばれたためである.ブログ書いとくもんだ.ちなみにこの企画は

プロが厳選!福島の酒造が選ぶ日本酒×おつまみを、月イチで自宅にお届け! | クラウドファンディング - Makuake(マクアケ)

↑の一環,震災で被害を被った福島の地域活性化的なサムシングでやっているシロモノプロジェクトらしい.

プロジェクトメンバーに古いネットの知り合いがいたりして面白かったりしたが,その方は僕を主にブログでのみトラッキングしており最近まで日本酒飲む勢とは知らなかったらしい.確かにシャカイジンになり「あっ仕事つらい」期に酒浸った経緯などはブログに書いて居なかったなぁ.今は辛くなくなったけど日本酒の美味しさには浸り続けていると.いい話ですね.

大七酒造概観

時は戻り大七酒造の見学.大七酒造は...えーと,福島県の有名酒造さんで,作るお酒の特徴としては"きもと"の代名詞みたいなところがある."きもと" ってのは漢字では "生酛" と書いて,日本酒作りの中で"酵母"を育てるプロセス,その最古の造りを指す.以下ちょっと詳しく説明を試みる.

例えばワインはぶどうの中に糖分があって,ぶどうの皮なんかに住み着いてる酵母がその糖分をアルコールに代謝する...化学式で書くと C6H12O8 -> 2C2H2HO + 2CO2 こんな感じ,なんだけど,日本酒の原材料は米で,米自体はさほど糖分を含まない.なので,前処理が必要になる.米に含まれるデンプンはコウジカビ(糸状菌の一種)によって分解されグルコース(糖分)とアミノ酸を生成する.これを「糖化」と言う.

「糖化」されたらようやく状況はブドウに並ぶ... と言いたいところがそうでもなく,米さんチームは「酵母」を持っていない.酵母は真菌の一種なのでまぁ生物だ.パスツール以降に生きる我々としては,生物さんが戦闘に加わるためにはどこかから降臨してくれないといけないと知っている.酵母は糖分を元にアルコールを創り出す役割なので,なんとかしてどっかから酵母に来て貰わないと「サケ」どころか単なる「甘い米汁」で終わっちゃう(これはこれで美味そうだが).

で,古くからサケを作ってきたお蔵さんには酵母が住み着いている.米をシャコシャコ擦りながら酵母が健全に育つのを待つ(このプロセスを "山卸(やまおろし)"と言う)のが伝統的なお酒の作り方,"生酛造り" である.元々は自然発生的に入りこんだ酵母だったんだろうが,顕微鏡もないまま,見えないものを信じて作業を洗練させ酒を作り続けた先人には本当に頭が下がる.

ともあれ,むかし(昭和以前)はむしろ普通の作り方だったんだが,その生酛造りにえらい時間がかかるってんで,戦前ごろから「酒造りも工業化や!」言うて,精製した酵母粉末をブチ込んで三分クッキング的な酒作りが主流になった.これを "速醸もと(酛)造り" という.ありとあらゆる酒蔵が "速醸酛" 方針へ転換する中,「いやウチは昔ながらの生酛造りで行く」と決断したのが大七酒造の八代目で,当時は多分時代遅れだのなんだの批判されたんだろうけど,結果的に現代まで生き残り良い酒を作り続け,今の地位を確立した大御所中の大御所... という認識でいる.いま Wikipedia みたらなんか山廃,生酛,速醸酛の分類で議論が怖い感じっぽいのであまり触れないことにする.後は専門家に任せた.

生酛系の酒母造りは、長い歳月のあいだに日本人が自然界の法則を巧みに利用して完成させてきた、以下のような酵母の純粋培養技術である。

生酛系の酒母の中では、じつに多様な菌が次々に活動して生存競争を繰り広げる。どのようなライバルの菌がタンクの中に同居しているか、また生育環境のpHはどれほどか、などによってそれぞれの菌の最適な生存環境が異なるため、菌たちの勢力の序列は刻々と推移するのである。

初めは硝酸還元菌、野生酵母、産膜酵母が隆盛を極めるが、酒母造りの5日目ごろを境にそれらは乳酸菌によって駆逐され急減していく。

一口に乳酸菌といっても多様な種類があり、大きく球型と稈型に分けられるが、12日目ごろは球型乳酸菌が、15日目ごろには稈型乳酸菌が隆盛のピークを迎える。しかしそれぞれのピーク後は、それらもやがて自らの生成した酸によって死滅していく。

このころに酒母は乳酸をたっぷり含んだヨーグルトのような状態となっており、もはや雑菌や野生酵母が入り込める余地はない。それを見極めると杜氏は、乳酸に強い清酒酵母(本来は蔵に棲みついている「蔵つき酵母」「家つき酵母」)を投入し、じわじわと増殖・培養させていくのである。

このように投入された清酒酵母の中でも、生命力の弱いものは途中で淘汰されていく。生存競争を生き抜いた強健な酵母だけをじっくりと育て、またその年の気候や酒米の状態などを考慮し、最適と思われる系統だけ選抜育成して醪の醗酵に用いることになる。

生もと - Wikipedia

f:id:Hash:20160203164408j:plain f:id:Hash:20160229022453j:plain f:id:Hash:20160229022559j:plain

杉玉とサケタンク・瓶の一軍.なんかいい匂いする.

杉玉(すぎたま、すぎだま)とは、スギの葉(穂先)を集めてボール状にした造形物。酒林(さかばやし)とも呼ばれる。日本酒の造り酒屋などの軒先に緑の杉玉を吊すことで、新酒が出来たことを知らせる役割を果たす。「搾りを始めました」という意味である。

杉玉 - Wikipedia

f:id:Hash:20160203155903j:plain

酒造り人たちはこのステンドグラスを見て酒造りという神聖な儀式に挑む心を整えるとのこと.アイテー企業の受付にも作ると良いと思う.ステンドグラスのみならず,"生酛造り" イメージから連想される古さとは打って変わり立派な洋館風のオフィス.

f:id:Hash:20160203164435j:plain

客人を迎えるエントランスホールには大七銘柄の数々が見事にディスプレイされている.

f:id:Hash:20160203154805j:plain f:id:Hash:20160203155230j:plain

酒造の見学

先に「"生酛造り" イメージから連想される古さ」と言ったが一枚ひっぺがすと全くそうではなく,伝統を守りつつも,精米歩合パーセントの数値にとらわれず本当に効率的に米の芯だけを残す削り方"扁平精米"の開発,また酒は可能な限り空気に触れさせない方が良い,という信念に基づく"真空充填"の確立など最新技術の開拓にも余念がなく,これが王者かといったところ.

ちょうど新酒を絞る時期でつい最近まで忙しかったのだと思うが,酒蔵の中まで見せていただいた.唎酒師試験に受かるも年会費の高さに心折れた勢としては実際のプロセスをナマで見て「ああこれがあの」と感心することしきりである.

f:id:Hash:20160229023544j:plain

ほらこれですよ奥さん,真ん中のステンレスの桶が"山卸し"やって酵母を育てるやつ.壁には移転前の蔵から"酵母が付着してると思われる"木板が立てかけられており,工業と生物育種のマリアージュが面白い.

f:id:Hash:20160229023557j:plain

ふなしぼりの"槽(ふね)"です.エヴァっぽい.

「ふなしぼり」とは「槽(ふね)」という昔ながらの道具で、圧力をかけずにもろみを自然な重みで絞ったもの。雑味が入りにくいため、本当の酒の美味しさが味わえます。

「しぼり」編 - 南部美人のこだわり - 南部美人

f:id:Hash:20160229023549j:plain

震災の時に設置したという,入る前に塵を吹き飛ばすエアーシャッター的なもの.

f:id:Hash:20160203162833j:plain

f:id:Hash:20160203162328j:plain

あと関係ないけど印象的だったのが,取引先ですらないイチ見学者の我々がオフィスの隣を通り過ぎる時,事務職と思われる社員さん方がビシッと起立して深々と頭を下げて見送られたこと.

試飲

世の中には体験しないとわからないものがいっぱいある.たとえば酒の味である.というわけで試飲ターーーイム!!!

f:id:Hash:20160229022750p:plain

紹介が遅れましたが奥の気品あふれる紳士が大七酒造十代目現当主,代表取締役社長の太田氏である.東大法学部卒からの大七酒造入社,20年弱前に社長に就任したとのこと.見た目通り物腰柔らかいものの,熱い語りから酒造りへの信念を感じる社長さんです.お忙しい中時間を割いていただき直々に酒造の説明を受けたり一緒に試飲させて頂いたりなど.手前の味方ポケモンっぽいのが僕です.

f:id:Hash:20160229022818p:plain

ポケモン酒を呑む. 先にネタっぽいついーとを掲載したが,奥に映ってる"大七 純米生もと" は個人的に「あっ日本酒って銘柄によってこんな違うんだ」「つーかなんだこれ美味い ...大七?」と目覚めるきっかけになった思い入れのある酒で,社長が「やっぱり日々の晩酌で飲むなら "純米生もと" ですね」と仰っていたのは大変うれしいものでした.

f:id:Hash:20160229022849j:plain f:id:Hash:20160203170054j:plain

リーデルグラス の日本酒専用機.

f:id:Hash:20160203165318j:plain

結局こんなラインナップで試飲させていただきました.先述の "純米生もと" はもちろん僕の大好きなやつなんだが,他にも大七梅酒は完全に日本酒飲まない勢を引き込む裾野の広さを持ってるし,"箕輪門" はけっこうな高級酒のはずなんだけどしれっと出てきてたまらない.

いじょ

近況は以上です.日本酒好きでほぼ毎日飲んでるんだけど,大して知識がないために詳しく熱く語らないタイプなのでみなさん気軽に僕と飲んで行きましょう.渋谷-目黒近辺で良い店巡る仲間を募集しております.

*1:なおヘーシャはカジュアルに有給取れるし待遇もよいのでそこそこ腕に覚えはあるんだけど激務ツライな方はご連絡ください

カレーはハウスの箱裏レシピが至高

カレーを作った.

f:id:Hash:20151213204747j:plain

玉ねぎを炒めます

f:id:Hash:20151213204833j:plain

かぼちゃも切って一緒に

f:id:Hash:20151213204907j:plain

親の仇のように飴色になるまで炒めます.いい具合になったら野菜たちを取り出してざっと鍋を洗ったらおもむろに

f:id:Hash:20151213204918j:plain

肉を

f:id:Hash:20151213204933j:plain

強火で焼き

f:id:Hash:20151213204947j:plain

野菜たちを戻してアスパラとかと一緒に 1L の水で煮込みます.沸騰してから 15 分,

言葉と物―人文科学の考古学

言葉と物―人文科学の考古学

フーコー『言葉と物』を読みながら灰汁を掬い,待ちます.

f:id:Hash:20151213205136j:plain

具材がちょっととろっとして来たらルーを投入.個人的なベストはハウスの「こくまろ 中辛」と「ジャワカレー 辛口」の組み合わせです.

弱火で10分コトコトしたら,炊きたてご飯にかけます

f:id:Hash:20151213205217j:plain

以上,ブログらしいブログを書いてみたかった.オチはない.

取り寄せた本が届いたら DynamoDB Stream を元に Lambda 経由で Twitter に通知させる

人間は図書館を活用することで住民税の元を取ることが出来る.取り寄せ依頼した本が届いたり借りてる本の返却期限が近付いたりすると Twitter bot が通知してくれるようにしている.が,単純に cron で回していたので人間側の対応が遅れると何度も同じことを言われてしまう.

f:id:Hash:20151205132900p:plain

今回「今年もやるよ!AWS Lambda縛り Advent Calendar 2015 - Qiita」の 12/05 分担当として,上記の仕組みをDynamoDB の更新 Stream をイベントソースとして Lambda で一回だけ通知してくれるように改良する話を書く.

前提

図書館の web をスクレイピングして DynamoDB に格納する... ところは Lambda Advent Calendar としては本題ではないので省略*1

f:id:Hash:20151205220309p:plain

うちの地区はこんな感じのページ.とりあえず人間が

  • 本の取り寄せ依頼(予約)をしたとき
  • 取り寄せた本が届いた時
  • 本を借りた時
  • 本を返した時

といった行動をした際に,日付,書籍 ISBN,行動タイプが以下の様な形式で DynamoDB に格納される機能が実装済とお考えください.

{
  "date": "2015-12-02",
  "hashed_title": "7f550dd47d40ea31eb84c092dbcdd2f66ff960db",
  "isbn": "9784000236218",
  "type": "borrow",
  "uuid": "b946c18b-0aa9-45fc-938e-be5b52d1fc33"
}

なお書籍データ本体は別の場所に ISBN をハッシュキーとして格納している. ...で,該当テーブルに対して DynamoDB Stream を有効化する.DynamoDB Stream はリリース当初 Preview 版で利用申請が必要だったが今は誰でも使える.

DynamoDB ストリームは、Amazon DynamoDB テーブル内の項目に加えられた変更に関する情報の順序付けされた情報です。テーブルでストリームを有効にすると、DynamoDB はテーブル内のデータ項目に加えられた各変更に関する情報をキャプチャします。 ...

DynamoDB ストリーム は、ストリームレコードをほぼリアルタイムで書き込むため、これらのストリームを使用し、内容に基づいてアクションを実行するアプリケーションを構築できます。

引用元: DynamoDB ストリーム を使用したテーブルアクティビティのキャプチャ - Amazon DynamoDB

DynamoDB マネジメントコンソールからテーブルを選択してぽちぽちやると有効化される.

f:id:Hash:20151205134428p:plain

すると,こんな感じの Stream ARN が得られる.

arn:aws:dynamodb:ap-northeast-1:<MY_AWS_ID>:table/<MY_TABLE_NAME>/stream/<Stream を有効化した時刻>

ARN = Amazon Resource Names は AWS サービスにおいて何らかのリソース (EC2 インスタンス, IAM ユーザ,DynamoDB のテーブル etc) を URI よろしく一意に識別する ID のようなもので,AWS サービス間で何か連携しようとするとよく出てくる.

Lambda で DynamoDB Stream を受け取る

ようやく Lambda.先の操作で得られた Stream ARN をイベントソースとして受け取り発火させる設定を行う. ゼロから書き始めてもいいんだけど,マネジメントコンソールで "Create a Lambda Function" を選択,"dynamodb-process-stream" という blueprint を元にすると話が早い.

f:id:Hash:20151205220407p:plain

console.log('Loading function');

exports.handler = function(event, context) {
    //console.log('Received event:', JSON.stringify(event, null, 2));
    event.Records.forEach(function(record) {
        console.log(record.eventID);
        console.log(record.eventName);
        console.log('DynamoDB Record: %j', record.dynamodb);
    });
    context.succeed("Successfully processed " + event.Records.length + " records.");
};

event.Records の中に Stream の更新情報がどばっと入ってきている.たとえば以下の様な形.

{
  "Records": [
    {
      "eventID": "1",
      "eventVersion": "1.0",
      "dynamodb": { // 更新レコード情報
        "Keys": { "uuid": { "S": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } },
        "NewImage": {
          "date": "2015-12-03",
          "hashed_title": "7f550dd47d40ea31eb84c092dbcdd2f66ff960db",
          "isbn": "9784000236218",
          "type": "return",
          "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES",
        "SequenceNumber": "111",
        "SizeBytes": 26
      },
      "awsRegion": "ap-northeast-1",
      "eventName": "INSERT", // レコードの新規作成
      "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:<MY_AWS_ID>:table/<MY_TABLE_NAME>/stream/<Stream を有効化した時刻>",
      "eventSource": "aws:dynamodb"
    }
  ]
}

f:id:Hash:20151205220433p:plain

先の Stream 有効化時に "New and old Images" を選択していると,更新前/更新後のレコードがフルフルで入ってくる.単に「なんか更新合ったよ」という事実を知りたいだけなら "Keys Only" でいいと思う. Stream から取得できる "Records > dynamodb > NewImage ..." あたりの内容を使えば Twitter 通知に必要な情報は取れそう.

Twitter API

今回やりたいことのためには Twitter API を Lambda から叩く必要があるが,その名も twittter という npm package で簡単に実現できる.

var client = new Twitter({
  consumer_key: <consumer_key>,
  consumer_secret: <consumer_secret>,
  access_token_key: <access_token_key>,
  access_token_secret: <access_token_secret>
});

var msg = "予約していた『" + event.Records[0].dynamodb.NewImage.title + "』が図書館で確保済です. (" + event.Records[0].dynamodb.NewImage.date + "迄)";
client.post('/statuses/update.json', {status: msg}, function(err, ...) {
 // ...
});

こんなイメージのコードを書けば,Lambda から bot を喋らせることが出来る.

f:id:Hash:20151205213615p:plain

ところでちょっと余談気味だけど,consumer_key とか access_token_secret とかを zip に含めて Lambda にアップロード,ってのはちょっとせきゅりてぃ的な意味でやりたくない.そこで AWS Key Management Service (KMS) を使うようにした.KMS のコンセプトについてはクラメソさんの 10分でわかる!Key Management Serviceの仕組み #cmdevio | Developers.IO などを参照にするとわかりやすい気がする.

流れとしては,あらかじめ KMS の Master Key を作っておいた後,その key-id を指定して Twitter API の各種 API credentials 情報をカンマで接続したテキストを暗号化.

$ aws kms encrypt --profile my-profile --key-id 9xxxxxx-9999-aaaa-a996-ffffffffffff --plaintext "consumer_key:<my_consumer_key>,consumer_secret:<my_consumer_secret>,access_token:<my_access_token>,access_token_secret:<my_access_token_secret>" --query CiphertextBlob --output text | base64 -D > ./encrypted-credentials

この encrypted-credentials を zip に含め,ソースコードと一緒に Lambda にあげてやる.

Lambda 上では毎回実行時に KMS へのリクエストを行い,credentials を複合する.Lambda Function に紐付けた Role からのみ復号可能となるように IAM 的に制限することができる,という仕組み.Lambda 上で動作する KMS decrypt 部分のコードは以下.

var encrypted = fs.readFileSync('./encrypted-credentials'); // コードと一緒に上げた暗号化済 credentials 情報
kms.decrypt({CiphertextBlob: encrypted}, function(err, data) {
  if (err) {
    console.log(err, err.stack);
    context.fail('failed');
  } else {
    var decrypted = data['Plaintext'].toString();
    // console.log(decrypted);
    obj = {};
    decrypted.split(',').forEach(function(item) {
      var pair = item.split(':');
      obj[pair[0]] = pair[1];
    });

    // Lambda 上で復号した credentials 情報を使って Twitter API を叩く
    var client = new Twitter({
      consumer_key: obj.consumer_key,
      consumer_secret: obj.consumer_secret,
      access_token_key: obj.access_token_key,
      access_token_secret: obj.access_token_secret
    });
    // ...

いじょ

もう少し DynamoDB Stream + Lambda の汎用的な話にするつもりだったんだけど,ざっくり用例を一つ紹介する記事になってしまった.がんばります.

*1:余談だが図書館の web はなかなか酷いものの銀行系のそれに比べればかなり精神負荷低くスクレイピング可能なレベル

人生のコントロールを取り戻す(五七五)

生きれば案外死なないもので,僕も今年で29になる.

労働を始めてからというもの一方的に社会に殴られ続け(体感には個人差があります)特に2013年は公私ともに乱れる酷い年で師走ともなればやれやれ死ぬかという心持ちであったが,憑き物が落ちたかのように2014年から人生のコントロール権をめきめき取り戻している,社会に出て初めて自分の足で立っているような気がしており,三十而立とは孔子もよく言ったもんだと思う.

うまくいってることもいかないこともあるけど, 記憶はただの記録であり語らなければミームは死ぬ.というわけでこのへんで久しぶりに人生の進捗報告風戯言を書いておく."人生コントロール権獲得感覚"は,今回書くようないくつかの行動が精神に反映されたものだと僕は考えている.

こんてんつ

  • 会社を設立する
  • ±100年に想いを馳せる
  • 肉体を管理する
  • 美味いものを食う
  • 知識を積み上げる

会社を設立する

2014年に会社を作った.とはいえ別にこれで食ってるわけではなく,主収入は相も変わらずサラリマンである.

サラリマンってのは税金コストが高すぎて資産形成に向かないという話は聞いていたが,いざ収入が増えてくるとほんとに馬鹿馬鹿しいくらい取られる.20代前半からずっと収入源を複数持ちたいという思いはあったし,そのへんの武器として設立した次第.

働き始めてからはずっと中小・ベンチャー企業を見てきたので会社を作るというとどうしても「事業を興す = 起業」が第一の発想に来てしまうが,僕の目的は橘玲氏の著作なんかで取り上げられる所謂 「マイクロ法人」 である.個人的にはジョジョのスタンド的なイメージで,ひとりでやるつもりだったけど乗ってくれた友達がいたので何人かで楽しくやってる(やってない).

最初の会社で既に「あっ社会ってこんな適当に回るんだ」とびっくりしたものだが*1,会社設立というトモすれば身構えてしまいそうな現実も地続きの日常であるらしい.そうこうあって,"会社"を特別な何かであると見る意識は完全に雲散霧消している.

会社作り自体はCookPadにレシピ乗せれそうなくらい簡単なもの*2で,2005年の会社法改正で資本金の最低額もなくなったので最悪作るだけなら1円と印紙代金あればいいし,司法書士やら行政書士に無駄な金払うような話でもない.RPGのクエスト感覚で面白いので自分でやるのオススメ.

f:id:Hash:20150505035740j:plain

会社を作ることによって,個人とは異なるもう一つの人格(法人格)が手に入る.そうすると,不思議なことが次々と起きるようになる.

貧乏はお金持ち──「雇われない生き方」で格差社会を逆転する橘玲

僕が11年前に株投資を始め,簿記の勉強をして ,金融を扱う会社に飛び込んだ頃から続く一連の経済的自由を求めるプロジェクトであり,法人格を使ってちょんちょん社会を突っついて税務署に怒られながら経験値を溜めている.

彼女は有限責任というダメコン*3を装備して産み出された法人格とはいえ,それなりに語ろうと思えば語れる(いまは語る気がない)熱い心がないでもなく,俺のミームの器となるべく社名に"研究所"を冠する.形式的には「いつかは研究所を作りたい」という僕の目標が叶ったことになるが,今はただのペーパーカンパニーに過ぎない.もっと力と金を貯め,機会を掴んでこの子にちゃんとした魂を込めてやりたい.

自分の仕事をもう少し考慮して選ぶなら、人間はみな本質的には研究者か観察者になるはずだ。というのも、人間の性質や運命は、明らかに誰にとっても同じように興味深いものだからだ。自分自身や子孫のために財産を溜め込もうが、一家や国家を築き上げようが、さらには名声を得ようが、人間は必ず死ぬのだ。しかし真実を相手にするとき、僕たちは不滅であり、変化や不慮の出来事を恐れる必要はなくなる。

孤独の愉しみ方―森の生活者ソローの叡智 (智恵の贈り物)』ヘンリー・ディヴィッド・ソロー

±100年に想いを馳せる

人間は必ず死ぬ.先日祖父母の家に泊まり久しぶり(もしかすると僕が物心ついて初めて)にたっぷり話す機会を作ったのも,仮にも僕の遺伝子プロバイダーなのだし,三十手前にして社会と真正面から殴り合う覚悟が出来てきた今,生きているうちに人間として向き合っておきたかったからかもしれない.まー向き合い直さないといけないものは色々あるんだけど.

祖父にも何か思うところはあったのか,到着すると古いアルバムを見せながら戦時中は戦闘機*4作ってたとか,ご先祖様は,みたいな橋本家系譜の話を聞かせてくれる.祖母からは係る人間の背景心理や数値の話などを.「お前裏の土地に家建てたらええが」と笑って言われたが,確かに土地に根を張り系譜に乗っかる道もあり得たのだろう.

f:id:Hash:20150505035706j:plain

僕が東京に出てきた背景にある考えは6年前(6年前!!)のブログ記事(田舎は好きだが、それでも東京を選択する。 - ミームの死骸を待ちながら )に詳しいが,当時の思考記録にはまだ僕に至るまでの血の歴史という視点が含まれていない.

人間の見ることが出来る時間範囲は極めて狭い.自身の生物としてのルーツに触れることで,僕は狭い視野を超えて思考をすこし遠い時代に飛ばすことができる.

僕は僕という意志主体であると同時にひとつの肉であり,肉の上で生きていくしかない(中でというべきか).肉を支える生命システムはとても興味深く神秘的ですらあるが,運用側としては不便かつ苛立たしい.百年経てば僕もみんなも等しく死骸である.そう考えるととても心が安らかになるが,同時に己の有限性というものを切実な痛みとして感じる*5

人間は肉の上に有限であるが,有限性を乗り越える武器がミームや遺伝子などに代表される自己複製子である.自己複製子は矮小な生命を乗り継ぐ神であると同時に我々の武器でもある.肉上の生を意識すればするほど,遺伝子を残したいという気持ちも強くなってくる.

肉体を管理する

肉といえば,ここ1年で10kgくらい痩せた.とりあえずこの痛快なグラフを見てほしい.

f:id:Hash:20150607041108p:plain

体脂肪率は10-13%くらいか.残念ながらもともと骨格太くて丸顔なのであまり見た目に分からないが,社会に出てから溜め込んだカルマを浄化した感覚が心地よく,体調もすこぶる良い.マウス実験では摂取カロリーを低く保てば寿命が伸びるらしいが,ヒトだとどうなんだろうね.

小細工を弄さずとも結局のところ摂取エネルギーひくことの消費エネルギーで身体の変化は予測可能で,予測できれば計画が立てられ,計画があれば行動の制御も可能である.肉体を意志の管理下におくことで,明確に言語化されるわけではないが何となく「意志で身体を制御できるのだから延長で周りの環境も制御してやろう」という自信が湧いてくる.

あと1,2kg落とせば目標(グラフ中点線)達成なので,そこまでたどり着いたら方法論をブログに書く予定.大したことしてねーけど.まぁ確実に成果が上がる方法ってのはいつもつまらんものなのかもしれない

美味いものを食う

言葉は要らない.

f:id:Hash:20150607051636j:plain f:id:Hash:20150607051642j:plain f:id:Hash:20150607051723j:plain f:id:Hash:20150607051712j:plain f:id:Hash:20150607051717j:plain f:id:Hash:20150607051735j:plain f:id:Hash:20150607051747j:plain

美食とダイエットは完全に両立可能である.

知識を積み上げる

元々学習の快楽で命を繋いでるような人間であったが,労働を始めてからは日々生き延びることに精一杯でそんな余裕もなく.

f:id:Hash:20150607042812p:plain

ようやく「まずは自分を幸福にしなければならない」と気が付き昨年からちょいちょい目標を決めて数ヶ月スパンで勉強することを再開している.試験という明確な合否が出るもので言うと

また,継続的な勉強としては

などがあり,どれも楽しい.あとは読書か.最近の読書メモブログ => ミームの死骸のmemex(拡張記憶)

いじょ

人間は死と税金だけは避ける事が出来ないと言ったのは誰だったか*6,肩の力を抜いてよくよく世界を見てみると,確かにくっきりと浮かび上がってくる高い壁であるのは確かだ.強大ではあるが,尽力すればそれなりに太刀打ち出来ない相手ではないと思っている.殴り合おう.俺はここで足止めする.別に倒してしまっても構わんのだろう?

知識を深め,現実の新たな姿を知るのは実に楽しい.思い通りにならないこともあるが,ものごとが"成る"こと,意志に反応してくれる世界それ自体に愛しさがある.

いっさいの目標がないということ、いっさいの限界がないということは、意志そのものの本質に属している。意志は終わるところを知らぬ努力である。

意志と表象としての世界〈1〉 (中公クラシックス)ショーペンハウアー p.366

抱く理想も遠い歴史も溺死するほど深くない.きっとすべて現実に落とし込んでいくと「ああこんなものか」と感じるのだろう.理想は理想そのままに,真実は真実ありのままに具現化されることは決してない.

そうした現実にまみれたものごとに美しさを感じられるようになったのは,精神が成熟してきたのかそれとも弾力を失っているのか.僕としてはあまりネガティブな変化と思っておらず,自他ともに認める理想主義者でとにかく生きる現実がつらい,な状態よりはマシかなと楽観的に捉えている.

もしくは単純にこれが老いってやつなのかもしれない.いずれにせよ,現実という場に現れた手持ちのカードで最善手を打ち続けていくしか術はない.

老いゆくぼくの次回作にご期待ください.知らんけど.

*1:参考: ちいさな会社の殺し方 : ミームの死骸を越えてゆけ

*2:難しくはないが複雑

*3:日本の合同会社に米国式LLCのパススルー課税が付かなかったのは残念

*4:「これ紫電改じゃん」とわかったのはつまみ食い艦これ知識のおかげ

*5:僕が死ぬまでに意識が電脳世界に飛び立つ技術が確立される可能性もあるが,それはそれ

*6:いまググったらベンジャミン・フランクリンらしい

バイオインフォ(略)技術者試験に不本意な成績で合格

したっぽい.

Japanese Society for Bioinformatics - JSBi :: バイオインフォマティクス技術者認定試験

昨年11月に試験で12月には合格わかってたんだけど, 成績がようやく今月に入って届く.

f:id:Hash:20150114063509j:plain

誕生日記載する必要なくね?

答え合わせして900(1000点満点)は超えてるだろと思ってたら, フタを開けると800点しか取れておらず愕然とする.

f:id:Hash:20150114063500j:plain

特に点数の低いバイオインフォマティクス分野(後半)は, タンパク質立体構造系の問題が多くてよっしゃと思ってたのに何があったのか... 悲しい. 解答の公開が待たれる.

平成26年度試験問題&解答

平成27年1月中の公開を予定しています。

Japanese Society for Bioinformatics - JSBi :: 平成26年度試験情報

はよはよ

試験について

試験は4パートに分かれており

  1. Bio
  2. Info
  3. BioInfo(1)
  4. BioInfo(2)

がそれぞれ250点ずつというイメージ. 過去問が公式Webサイトから落とせるのでそれを解いて, わからない問題については教科書などを調べるという勉強法で出社前とか昼休みとかに1.5ヶ月ほど.

バイオインフォな実務で使う知識がどれくらい含まれてるのかわからんのが正直なところだけど, 久しぶりに専門分野の記憶を引っ張りだして来れてわくわくしたのと, やはり自分は学習が大好きなことを再確認し, それなのに就労以降明らかに低下し続けている知性を顧み, さらに正月に弟と4,5年ぶりに顔を合わせたらヤツは理系修士からの技術職就職してて, 大学で学んだ知識ばりばり使ってとても楽しそうでいいなぁ, 人生とは... みたいな気分に. 話が逸れた. 人生よ.

使った教科書的なものをアフィリエイト

f:id:Hash:20150114083821j:plain

バイオインフォマティクス ゲノム配列から機能解析へ 第2版

何はともあれこれ. 今まで買おう買おうと思いつつ値段から踏ん切りがつかなかったけど試験挑戦がきっかけとなり購入. 良い本です

f:id:Hash:20150114084231j:plain

ヴォート 生化学〈上〉

ヴォートはまぁ, たまたま僕が学生時代に使ってた生化学の教科書がコレというだけなんだけど, 生体分子の働きを化学レベルから考察するレイヤーがとても心地よい. バイオ分野の学習に.

f:id:Hash:20150114084837j:plain

Molecular Biology of the Cell

おなじみザ・セルこと細胞の分子生物学. わりとマクロなバイオ分野知識が抜けてたりしたのでこいつで補う. 実際僕が持ってるのは銀色表紙の第4版なんだけど, 昨年末に青表紙の第6板が出たので記念してそっちを貼っとく. 買いたいが金欠で辛い... Kindle版だと1万円台で買えるっぽくて揺れてる.

で, インフォ分野の問題は

  • 実務で馴染んでて「はいはい」で回答できる問題
  • ググれば十分な情報が得られる問題

が多くてそんな教科書の出番を感じず特に紹介するものなし. 数学(統計・確率)がらみの問題がやや手こずったけど, 前回の記事でも触れた↓の本が概念をつかむ助けになった.

f:id:Hash:20141204010417j:plain

いじょ

人生よ