読者です 読者をやめる 読者になる 読者になる

なまもの備忘録

気になったことをつらつらと書いていきます

大腸菌の脂質二重膜組成

なまもの

大腸菌の脂質二重膜の成分は割と知りたくなる機会が多いのだが、わかりやすくまとめてくれている論文を今まで知らなかった。
今日ちょうど良い具合の論文を見つけたので貼っておく。

Atefeh Shokri and Gen Larsson:Characterisation of theEscherichia colimembrane structure andfunction during fedbatch cultivation,2004

Table1の図よれば、培養の仕方によって多少の差はあれど、概ねホスファチジルエタノールアミン(PE)7割程度、それについで1割半ほどのホスファチジルグリセロール(PG)で膜の大部分が構成されていることが分かる。
メモ程度に。

typedefで配列型に名前をつける

C++

typedefは基本的に以下のように使う。

typedef int size;//以降size型をint型として使うことができるようになる

ただ、配列をtypedefしたい場合は表記法が直感に反したものになる
例えばint型の配列をsizesと定義したい時は以下のように表記する。

typedef int size[];//typedef int[] sizeではない

これは例えばgccのarrayの定義などで使われている。/usr/include/c++/5/にあるarrayファイルには以下のようなコードがある(多分gccはここを見に行っている)。

template<typename _Tp, std::size_t _Nm>
    struct __array_traits
    {
      typedef _Tp _Type[_Nm];//<-ここ
    
…………    

    };

ここでは_Tp型の配列を_Typeとして使うために上記の構文を使用している。
わからないなあ、という話でした。

matplotlibでのオブジェクト指向的な描画

python

matplotlibには主にpyplotの関数を用いてオブジェクトを明示的に操作せず簡単に描画する方法と、オブジェクトを明示的に操作する方法がある。以下後者の方法について。

matplotlibではグラフは一度FigureCanvasに描画され、それがバックエンドのmatplotlib.backend_bases.FigureCanvasBaseを継承した出力フォーマット依存のクラスによって出力されるという仕組みをとっている(はず、要出典)。
FigureCanvasに描画されるFigureは部品ごとに管理されており、すべての部品はmatplotlib.artist.Artistという抽象基底クラスを継承している。Figure自身もArtistの派生クラス。部品というのは例えば、軸(Axisというクラスで管理される)や目盛り、グリッド線(Tickというクラスに管理される)などのことを指す。また、これらはこちらもまたArtistの派生クラスであるmatplotlin.axes.Axesによってまとめられ、管理されている。

オブジェクト指向でのプロットは以下のようになる(例として2つの行列から2つのカラーマップを描く場合を取り上げる)。

import matplotlib.pyplot as pet
import matplotlib.cm as cm

#データを用意する
arr1 = [[1,0,0],[0,1,0],[0,0,1]]
arr2 = [[0,0,1],[0,1,0],[1,0,0]]
data = [arr1,arr2]

#Figure全体を管理するオブジェクトfigを生成する
fig = plt.figure()

#Figureの構成要素である2つの図それぞれを管理するAxesオブジェクトax1とax2を生成する
ax1 = fig.add_subplot(1,2,1)#1行2列のグラフの1つめを描く
ax2 = fig.add_subplot(1,2,2)#1行2列のグラフの2つめを描く

ax1.imshow(data[0], cmap = cm.Greys, interpolation = 'nearest')#オブジェクトにカラーマップの情報をもたせるAxesのimshowメソッドを呼び出す
ax1.set_axis_off()#軸を表示しない設定にするset_axis_off()メソッドを呼び出す
ax2.imshow(data[1], cmap = cm.Greys_r, interpolation = 'nearest')
ax2.set_axis_off()

#描画する
plt.show()

f:id:purple-apple:20170206221130p:plain

上記コードのうちcm.binaryは色を指定している。指定できる色は(http://matplotlib.org/examples/color/colormaps_reference.html)にある。”Greys_r”の”_r”は、グラデーションを反転させている。ここにない色も指定できたりする(例えば”binary”)。また、interpolationの’nearest’は描画をタイル状にしており、無指定だとグラフはグラデーションになる。
図の詳細な設定をいじる場合は図を管理しているAxesオブジェクトのメソッドを使う、というような事になる。Axes.get_xaxisなどのメソッドを使ってX軸の情報のみを管理するXAxisオブジェクトを生成し、更に細かく設定を行うことも(多分)できる。このようなAxesクラスのメソッドは(http://matplotlib.org/api/axes_api.html#axis-limits)に書いてある。

matplotlib version2.0.0をインストールした作業記録[Ubuntu16.04]

Ubuntu python

Ubunt16.04に何も考えずaptでmatplotlibを入れたらversionが1.5.1だった。バージョンの確認は

$ python
>>> import matplotlib
>>> matplotlib.__version__

でできる。
最新版は2.0.0なのでこちらに更新したい。また、今まではpythonで使っていたが折角なのでpython3で使いたい。以下作業ログ。

$ apt search python3-matplotlib

の結果aptで入れられるのは1.5.1までらしい。apt-get updateしても変わらなかった。
少し調べてみるとどうもpythonのパッケージ管理システムpipで入れることができるらしい。そういうわけで、まずはpipを入れる(aptとpipが後々衝突したりしないかとても不安だけれど取り敢えず気にせず入れてみる)。

$ apt search python3-matplotlib

の結果python3-pipがヒットしたのでインストールする。

$ sudo apt-get install python3-pip

pipが入ったので以下でmatplotlibを探そうとしたらpipがまだ入っていないと怒られた。

$ pip search matplotlib

pipという名前では入っていないようなので名前を特定する。/usr/bin内を探したところ、pipというファイルはなかったが代わりにpip3というファイルがあった。おそらくこれだと思われるのでpip3で呼べば良い。
さてmatplotlibのインストールといきたいところだが、念の為以前入れていたmatplotlibを削除しておく必要がある。

$ sudo apt-get purge python-matplotlib

で以前のmatplotlibを削除した。purgeだと設定ファイルごと削除してくれるらしい。
pip3でmatplotlibを検索する。

$ pip3 search matplotlib

matplotlib (2.0.0)がヒットしてくれたのでこれをインストールする。

$ pip3 install matplotlib  

ちゃんとpython3のmatplotlib(2.0.0)が入っているかどうか確認する。

$ python3
>>> import matplotlib as mpl
>>> mpl.__version__

と打ったら

'2.0.0'
<||

と帰ってきたので無事完了したか?と思ったのだけど、その後

>||
$ python3 (実行ファイル名).py

pythonスクリプトを実行しようとしたら

ImportError: No module named '_tkinter', please install the python3-tk package

と怒られてしまった。python3-tkパッケージがないということなのでpip3でsearchをかけたがそれらしきものがない。

$ apt search python3-tk

としたらヒットしたのでaptで入れることにする。

$ sudo apt-get install python3-tk

こうしたら実行ファイルもちゃんと動くようになった。めでたしめでたし。

C++のconst指定子とポインタのややこしい話

C++

C++でよく変更する予定のない変数の型の前にconstを付けるが、あれは唯の目印のようなものではなく、const ホニャララという新しい型を宣言している感覚に近いっぽい。
このconstの仕様はC言語時代からの負の遺産で大分ややこしいものになっているため、ここに少し整理しておくことにする。
double型を例にとって整理しよう。

double x;//一般的なdouble型の宣言
double* x;//double型のポインタの宣言
const double x;//double型で、xの値を変更することはできない
const double* x;//値を変更することのできないdouble型(const double)へのポインタ
double const* x;//実はこれは上と同じものを指す。この辺からややこしい。
double* const x;//xはdouble型のポインタで、ポインタの指す先をかえることはできない。ポインタが指しているdouble型の変数に別の値を代入することはできる。
const double* const x;//変更不能なポインタが指しているのはconst double型なので、こちらに別の値を代入することもできない。
double const* const x;//上と同じ
const double* const* const* x;//const double型へのポインタも変更不能で、そのポインタへのポインタも変更不能だが、このポインタへのポインタにはconst指定子がついていないので変更できる。
deouble const* const* const* x;//上と同じ

おわかり頂けただろうか?
他に、f(const double x)のような関数にdouble型の変数を代入しても問題ないが、f(double x)のような関数にconst double型の変数を代入するとコンパイルエラーになる。
また、この話には直接関係がないが、関数ポインタへのアドレス参照演算子は無視される、intなどの型とintなどのリストは内部では違う型として扱われているので、int型のポインタのポインタにint型のリストのアドレスを代入しようとしてもエラーを吐くなどの話を今日しったのでメモしておく。

(C++)大きさ不明の2次元配列データを2次元vectorに読み込む方法

C++

3/22 17:10

大きさの分からない2次元配列データを2次元vectorに格納する方法がいくら調べても見つからなかったので、分からないなりに調べつつコードを作成してみた。
下記のコードであれば、データが数値のcsvファイルならなんでも読み込めるはず。

//大きさ不明の2次元配列データを2次元vectorに読み込むコード
//読み込み先の2次元vectorはあらかじめ用意しておく必要がある

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;

bool Getdata(string filename,vector<vector<double> >& data){
  ifstream reading_file;
  reading_file.open(filename,ios::in);

  string reading_line_buffer;

  cout << "reading " << filename << "..." << endl;

  getline(reading_file,reading_line_buffer);//1行目を空読み(適用していたデータの都合上) 

  double num;
  char comma;

  while(!reading_file.eof()){
    vector<double> temp_data;
    getline(reading_file,reading_line_buffer);
    istringstream is(reading_line_buffer);
    while(!is.eof()){
      is >> num >> comma;
      temp_data.push_back(num);
    }
    data.push_back(temp_data);
  }

  return true;
}

//動作テスト                                                                      
int main(){
  vector<vector<double> > data;//読み込み先2次元vectorを用意する
  Getdata("post_bz100.tifresult.csv",data);

  for(int j=0 ;j < data.size() ;j++){
    for(int i=0 ;i < data[j].size() ;i++){
      cout << data[j][i] << " ";
    }
    cout << "\n";
  }
  cout << "\n";

  return 0;
}

C++でのファイルの入出力

C++

2/25 17:28

C++でのファイルからの入力、ファイルへの出力の仕様がよく分からなくてもやもやする。検索をしてもどうもC仕様のやり方とC++仕様のやり方があるようで、この二つが混ざって出てくる上に痒いところに手が届かないサイトしかない。あまりにイライラするのでとりあえず今欲しい情報をまとめて調べて、後で忘れた時のために書いておくことにする。
ついでにフラフラとサイトを彷徨っていたら何やら良さそうなC++の本が紹介されていたのでメモ代わりに残しておくことにする。

Accelerated C++ - 効率的なプログラミングのための新しい定跡
Exceptional C++ - 47のクイズ形式によるプログラム問題と解法

まず、stdio.hのヘッダファイルを使った入出力の方法をまとめてみる。これはC言語関数辞典(http://www.c-tipsref.com/reference/stdio.html)に載っていたのでC言語様の入出力方法なのだろう。欲をいえば覚えることは減らしたいので文法は全てC++様のものにしたいのだが、面倒なので当分はこちらをまとめてこちらを使うことにする。
fopenでファイルを開いて、入出力関数でごにょごにょし、fcloseでファイルを閉じるのが一連の流れになる。
openの戻り値は事前に宣言したファイルポインタに入れる。これは、fopenが「開いたファイルの情報を持っているオブジェクト」のポインタを返す関数だからみたいだ。
ちなみにファイル型はstdio.hの中でtypedefによって定義されている型なので、stdio.hをincludeすれば宣言できる様になる。
つまり、test.dataを読み込もうとしたら

#include <stdio.h>
...
    FILE * fp;
    ...
    fp = fopen("test.data", "r");

のようなコードを書けば良い。この時、fopenの二つ目の引数の”r”は読出し専用モードで開くことを指定している。
このようなモード指定は他にもある。
f:id:purple-apple:20170205200133p:plain
(http://www.c-tipsref.com/reference/stdio/fopen.html)

今回僕が知りたいのは開いたファイルの情報を上書きするのではなく、その末尾に追加で情報を加える方法なのだが、”a”で指定できる追加書き込みがどうも欲しい機能を提供してくれそうだ。
write モードではファイルを消してしまう事になるので、ファイル を消さずに書き込みを行うには append モードを用いる。(http://www.wakhok.ac.jp/~kanayama/C/02/node165.html)とあるので、これでできそう。というか全部更新モードでいいじゃないか。まあエラーを吐かせたほうが云々というのはあるのだろうけど。

ちなみにファイルのクローズは

fclose(fp);

のように書くが、プログラム終了時にはオープンしたファイルは必ずクローズされるらしいので途中でモードを変更したい場合以外は特にする必要もないみたい。
ファイルからの情報の読み込みにはfscanfを使う。使う時は下のような感じ。

double one_data;
fscanf(fp,"%lf ",&one_data);
    data[t][i] = one_data;

一つ目の変数で入力に使うオブジェクトのポインタを指定(これをストリーム(プログラム-入出力間のデータの流れ)をしていすると言うらしい)している。
二つ目の引数は書式文字列と言うらしい。

%[代入抑止文字][フィールド幅][長さ修飾子]変換指定子 ※[]内は省略可能

という形式で記述する。代入抑止文字の部分には、もしを書くと指定した文字が読み込まれずに破棄される。例えば、%2cとやると先頭の2文字が破棄されるらしい。
長さ修飾子については以下のような感じで、引数の型を指定している。なんで長さなのかは謎。知っている方いたら是非とも教えていただきたいです。
f:id:purple-apple:20170205200351p:plain
(https://ja.wikipedia.org/wiki/Scanf)
変換指定子については以下
f:id:purple-apple:20170205200406p:plain
(https://ja.wikipedia.org/wiki/Scanf)
読み取った引数を戻す際に変換を加えることができる。
3つ目の引数には適切な方の変数を入れて、以降この変数に入ったデータを扱う。

for(int t = 0; t < TIME; t++){
          for(int i = 0; i< CELL ;i++){
            fscanf(fp,"%lf ",&one_data);
            data[t][i] = one_data;
          }
        }

のように使用すると、fpがさすオブジェクトのデータを勝手に順々にスキャンしていってくれる。また、改行は特に意識されないみたい。
とりあえずこの辺まで調べて満足したので終わり。

3/18 C++仕様の入出力についても簡単にメモしておく。

#include <fstream>
//入力
std::ifstream ifs(“ファイルパス”); //ifsにファイルの内容が読み込まれる
std::getline(ifs,line);//lineにifsの内容を1行ずつ読み込む

//出力
std::ofstream ofs(“ファイルパス”);
off << “書き込みたい文字列等” << std::endl;

軽いプログラムの時はこっちのほうが楽そう。