「PIONEチュートリアル-PNML」の版間の差分
(→応用1(Eosコマンドへの利用)) |
|||
行533: | 行533: | ||
=== 応用1([[Eos]]コマンドへの利用) === | === 応用1([[Eos]]コマンドへの利用) === | ||
+ | ==== 問題 ==== | ||
[[Eos]]コマンドを使った例を示します。<br> | [[Eos]]コマンドを使った例を示します。<br> | ||
今回は3D画像(.ref3d)から指定した角度(.refangle)の2D投影像を作成するコマンドを作成してみましょう。<br> | 今回は3D画像(.ref3d)から指定した角度(.refangle)の2D投影像を作成するコマンドを作成してみましょう。<br> | ||
− | |||
<br> | <br> | ||
+ | |||
+ | ==== 解答例 ==== | ||
[[PNML]]ファイル<br> | [[PNML]]ファイル<br> | ||
[[画像:PIONE-PNML-Advanced1.png]]<br> | [[画像:PIONE-PNML-Advanced1.png]]<br> | ||
行569: | 行571: | ||
done; | done; | ||
``` | ``` | ||
+ | |||
+ | </pre> | ||
+ | <br> | ||
+ | |||
+ | ==== コンパイル後 ==== | ||
+ | <pre> | ||
+ | Rule Main | ||
+ | input '*.ref3d'.all | ||
+ | input '*.refangle'.all | ||
+ | output '*.ref2d' | ||
+ | Flow | ||
+ | rule Ref3Dto2D | ||
+ | End | ||
+ | |||
+ | Rule Ref3Dto2D | ||
+ | input '*.refangle' | ||
+ | input '*.ref3d' | ||
+ | output '*.ref2d'.all | ||
+ | Action | ||
+ | num=1; | ||
+ | while [ "$line" != "$(tail -1 {$I[1]})" ] ; \ | ||
+ | do \ | ||
+ | line=$(head -$num {$I[1]} | tail -1); \ | ||
+ | EA=$(echo $line | awk '{printf("%s", $1)}'); \ | ||
+ | ROT1=$(echo $line | awk '{printf("%s", $2)}'); \ | ||
+ | ROT2=$(echo $line | awk '{printf("%s", $3)}'); \ | ||
+ | ROT3=$(echo $line | awk '{printf("%s", $4)}'); \ | ||
+ | mrc3Dto2D -i {$I[2]} \ | ||
+ | -o "{$I[2][1]}-{$I[1][1]}-$num.ref2d" \ | ||
+ | -EulerMode $EA \ | ||
+ | -Rot1 $ROT1 $ROT1 1 \ | ||
+ | -Rot2 $ROT2 $ROT2 1 \ | ||
+ | -Rot3 $ROT3 $ROT3 1; \ | ||
+ | if [ -z "$line" ] ; then \ | ||
+ | break; \ | ||
+ | fi; \ | ||
+ | num=`expr $num + 1`; \ | ||
+ | done; | ||
+ | End | ||
+ | |||
+ | </pre> | ||
+ | <br> | ||
+ | |||
+ | ==== 実行例 ==== | ||
+ | このコマンドは[[mrcImage]](3D)ファイル及び下記のフォーマットの角度情報ファイルを入力として使用します。<br> | ||
+ | <pre> | ||
+ | EulerAngleMode Rot1 Rot2 Rot3 | ||
+ | |||
+ | </pre> | ||
+ | [[matrix3DFromEulerAngle]](-i)と同じフォーマットで、それぞれの意味については[[オイラー角]]をご覧下さい。<br> | ||
+ | <br> | ||
+ | |||
+ | 入力ファイルがない場合は次のコードを使用するとサンプル入力データを作成します。なお、このサンプルデータは[[チュートリアル一覧#SampleData]]を使用していますので、予めダウンロードしておく必要があります。<br> | ||
+ | <br> | ||
+ | [[PNML]]ファイル<br> | ||
+ | [[画像:PIONE-PNML-Advanced1-1.png]]<br> | ||
+ | <br> | ||
+ | [[マークダウン]]ファイル<br> | ||
+ | <pre> | ||
+ | # Initial.pione | ||
+ | |||
+ | ## Initial | ||
+ | It brings ref3d files as Input. | ||
+ | |||
+ | ``` | ||
+ | cp {$I[1]} {$O[1]}; | ||
+ | ``` | ||
+ | |||
+ | ## Angle | ||
+ | It creates angle files. | ||
+ | |||
+ | ``` | ||
+ | for (( rot1 = 0; rot1 < 360; rot1 += 30 )) ; \ | ||
+ | do \ | ||
+ | for (( rot2 = 0; rot2 < 360; rot2 += 30 )) ; \ | ||
+ | do \ | ||
+ | rot22=`expr $rot2 + 15`; \ | ||
+ | echo "YOYS $rot1 $rot2 0" >> {$O[1]}; \ | ||
+ | echo "YOYS $rot1 $rot22 0" >> {$O[2]}; \ | ||
+ | done; \ | ||
+ | done; | ||
+ | ``` | ||
+ | </pre> | ||
+ | <br> | ||
+ | |||
+ | 下記のコマンドで入力ファイルを用意します。<br> | ||
+ | <pre> | ||
+ | pione compile Initial.pnml --action Initial.md > Initial.pione | ||
</pre> | </pre> | ||
<br> | <br> |
2014年11月10日 (月) 02:21時点における版
PIONEは、直接、pione定義書を記述する事もできますが、PNMLを用いて、ペトリネットの形式で記述することもできます. WoPeD(推奨)により、ペトリネットを記述し、PNML形式で保存します。それぞれのアクションは、マークダウン形式で記述する事ができます.
目次
WoPeDを使ったpione定義書の作成
ここではWoPeDを使って、PNMLファイルを作成し、pione定義書を作成するチュートリアルを行います。
まず、WoPeDを起動し、新規作成するためにFileのNewを選択します。
新規作成したファイル内のProcess上で右クリックすると、アイテムを選択することができます。
pione定義書を作成する上では上部2つの"○"(Place)と"□"(Transition)を使用します。主に"○"(Place)はファイルなどの入出力データを指し、"□"(Transition)はRuleなどの処理を指します。そして、"○"(Place)と"□"(Transition)の間をドラッグ操作による矢印(Annotation)でつなぐと、入力ファイルからある処理を経て出力ファイルを作成するフローが完成します。
WoPeDでフローを作成したら、次は"□"(Transition)の中身を作成します。こちらは下記のようなマークダウン形式ファイルを作成します。##が意味持っていることに注意して下さい。
## Transition名 ここにコメントを記述することができます。 ``` Transition内のAction ``` ## 次のTransition名 . . .
PNMLファイルとマークダウンファイルを作成した後は下記のコマンドによって、pione定義書へコンパイルすることができます。
$ pione compile (pnmlファイル) --action (アクション定義ファイル) > (pione定義書ファイル名)
基本1(特定のファイルを出力する)
では、PIONEチュートリアル#基本1(特定のファイルを出力する)と同様にHelloプログラムを作ってみましょう。
まず、下記のようなHelloWorld.pnmlを作成します。このとき出力ファイルの">"はMain Ruleにおける出力を指しています。("<"はMain Ruleの入力)
次に下記のようなHelloWorld.mdを作成します。
# HelloWorld.pione ## Hello Here, you can write Comment. ``` echo "Hello PIONE world !" > {$O[1]} ```
このファイルはこちらからダウンロードできます。
最後にコンパイルを行います。
pione compile HelloWorld.pnml --action HelloWorld.md > HelloWorld.pione
コンパイル後のpione定義書
Rule Main output 'message.txt' Flow rule Hello End Rule Hello output 'message.txt' Action echo "Hello PIONE world !" > {$O[1]} End
PIONEチュートリアル#基本1(特定のファイルを出力する)と同様の機能を持つファイルHelloWorld.pioneが作成されました。
実行結果
/Basic1$ pione-client HelloWorld.pione -b HelloWorld ==> &Anonymous:Root([],{}) --> Rule Application: &Anonymous:Root([],{}) --> Distribution: &Anonymous:Root([],{}) >>> &Anonymous:Main([],{}) ==> &Anonymous:Main([],{}) --> Rule Application: &Anonymous:Main([],{}) --> Distribution: &Anonymous:Main([],{}) >>> &Anonymous:Hello([],{}) ==> &Anonymous:Hello([],{}) SH ------------------------------------------------------------ SH echo "Hello PIONE world !" > message.txt SH ------------------------------------------------------------ <== &Anonymous:Hello([],{}) <-- Distribution: &Anonymous:Main([],{}) <-- Rule Application: &Anonymous:Main([],{}) <-- Distribution: &Anonymous:Root([],{}) <== &Anonymous:Main([],{}) <-- Rule Application: &Anonymous:Root([],{}) <== &Anonymous:Root([],{}) /Basic1$ cat HelloWorld/output/message.txt Hello PIONE world !
同様にHelloWorld/output/message.txt へHello PIONE world !が出力されています。
基本2(複数ルールによる処理)
少しルールを増やした例を試してみましょう。
今回は各行に1つずつの数値が記述されている全ての.inファイルに対して、各数に2を掛ける処理(First)、さらに1を足す処理(Second)を施して、.outを出力するルールを作成します。
PNMLファイル
上記の2つ目のplaceでの{S*}はPIONEの記述における{$I[1]}を表しています。
マークダウンファイル
# Serial2.pione ## First Multiply 2 to all input data. ``` awk '{print $1*2}' {$I[1]} > {$O[1]} ``` ## Second Add 1 to all input data. ``` awk '{print $1+1}' {$I[1]} > {$O[1]} ```
このファイルはこちらからダウンロードできます。
コンパイル後のpione定義書
Rule Main input '*.in' output '*.out' Flow rule First rule Second End Rule First input '*.in' output '{$*}.route' Action awk '{print $1*2}' {$I[1]} > {$O[1]} End Rule Second input '*.route' output '{$*}.out' Action awk '{print $1+1}' {$I[1]} > {$O[1]} End
PIONEの実行結果
入力ファイル
test1.in | test2.in | test3.in | test4.in | test5.in |
3 5 |
2 4 |
7 1 |
8 9 6 |
1 2 3 4 5 6 7 8 9 |
出力ファイル
test1.out | test2.out | test3.out | test4.out | test5.out |
7 11 |
5 9 |
15 3 |
17 19 13 |
3 5 7 9 11 13 15 17 19 |
入力ファイルの各データが×2の後に+1の処理が施され、PIONEチュートリアル#基本5(直列:フロールールの設定 )と同様の処理を作成することができました。
基本3(複数種類の入出力がある処理)
複数種類の入出力がある少し複雑な処理を記述してみましょう。
今回は.txtファイルを元に.swapファイルで指定した行数を入れ替えたファイル.swtxtと.sedファイルで指定した文字列の置換を行ったファイル.sdtxtをそれぞれ出力します。
PNMLファイル
マークダウンファイル
# TextSwapSed.pione ## TextSwap ``` cp {$I[1]} intmp; while read line ; \ do \ i1=$(echo $line | awk '{printf("%d", $1)}'); \ i2=$(echo $line | awk '{printf("%d", $2)}'); \ lnum=$(wc -l intmp | awk '{printf("%d", $1)}'); \ c1=$(expr $lnum - $i2); \ c2=$(expr $i2 - $i1); \ top=$( head -$i1 intmp ); \ middle=$( head -$i2 intmp | tail -$c2 ); \ bottom=$( tail -$c1 intmp ); \ t1=$(expr $i1 - 1); \ m1=$(expr $c2 - 1); \ top1=$( echo "$top" | head -$t1 ); \ str1=$( echo "$top" | tail -1 ); \ middle1=$( echo "$middle" | head -$m1 ); \ str2=$( echo "$middle" | tail -1 ); \ echo "$top1" > outtmp; \ echo "$str2" >> outtmp; \ echo "$middle1" >> outtmp; \ echo "$str1" >> outtmp; \ echo "$bottom" >> outtmp; \ cat outtmp | sed '/^$/d' > intmp; \ done < {$I[2]}; mv intmp {$O[1]}; ``` ## TextSed ``` cp {$I[1]} intmp; while read line ; \ do \ str1=$(echo $line | awk '{printf("%s", $1)}'); \ str2=$(echo $line | awk '{printf("%s", $2)}'); \ sed -e "s/$str1/$str2/g" intmp > outtmp; \ cat outtmp | sed '/^$/d' > intmp; \ done < {$I[2]}; mv intmp {$O[1]}; ```
このファイルはこちらからダウンロードできます。
コンパイル済みpione定義書の実行結果
入力ファイル
aaa aab aba abb baa bab bba bbb |
abc acb bac bca cab cba |
1 3 4 5 1 6 |
1 2 1 3 1 4 1 5 1 6 |
a c bc bd dc DC |
abc ddd aaa eee bc XX |
Input1.txt | Input2.txt | line1.swap | line2.swap | ref1.sed | ref2.sed |
出力ファイル
bab aab aaa baa abb aba bba bbb |
bab aaa aab aba abb baa bba bbb |
ccc ccb cbd cbb bDC bdb bbd bbb |
eee aab aba abb baa bab bba bbb |
Input1-line1.swtxt | Input1-line2.swtxt | Input1-ref1.sdtxt | Input1-ref2.sdtxt |
cba acb abc cab bca bac |
cba abc acb bac bca cab |
cbd ccb bDC bDC ccb cbd |
ddd acb bac XXa cab cba |
Input2-line1.swtxt | Input2-line2.swtxt | Input2-ref1.sdtxt | Input2-ref2.sdtxt |
それぞれの.txtファイルに付いて.sed, .swapファイルによる変換が行われるので、計8つのファイルが出力されます。
応用1(Eosコマンドへの利用)
問題
Eosコマンドを使った例を示します。
今回は3D画像(.ref3d)から指定した角度(.refangle)の2D投影像を作成するコマンドを作成してみましょう。
解答例
PNMLファイル
Ref3Dto2Dの出力ファイル名は.refangleの行数も関連しているため'*.ref2d'.allとして全てのファイルを出力の対象にしています。
マークダウンファイル
# Ref3Dto2D.pione ## Ref3Dto2D Projection 3D to 2D depending on an angle. ``` num=1; while [ "$line" != "$(tail -1 {$I[1]})" ] ; \ do \ line=$(head -$num {$I[1]} | tail -1); \ EA=$(echo $line | awk '{printf("%s", $1)}'); \ ROT1=$(echo $line | awk '{printf("%s", $2)}'); \ ROT2=$(echo $line | awk '{printf("%s", $3)}'); \ ROT3=$(echo $line | awk '{printf("%s", $4)}'); \ mrc3Dto2D -i {$I[2]} \ -o "{$I[2][1]}-{$I[1][1]}-$num.ref2d" \ -EulerMode $EA \ -Rot1 $ROT1 $ROT1 1 \ -Rot2 $ROT2 $ROT2 1 \ -Rot3 $ROT3 $ROT3 1; \ if [ -z "$line" ] ; then \ break; \ fi; \ num=`expr $num + 1`; \ done; ```
コンパイル後
Rule Main input '*.ref3d'.all input '*.refangle'.all output '*.ref2d' Flow rule Ref3Dto2D End Rule Ref3Dto2D input '*.refangle' input '*.ref3d' output '*.ref2d'.all Action num=1; while [ "$line" != "$(tail -1 {$I[1]})" ] ; \ do \ line=$(head -$num {$I[1]} | tail -1); \ EA=$(echo $line | awk '{printf("%s", $1)}'); \ ROT1=$(echo $line | awk '{printf("%s", $2)}'); \ ROT2=$(echo $line | awk '{printf("%s", $3)}'); \ ROT3=$(echo $line | awk '{printf("%s", $4)}'); \ mrc3Dto2D -i {$I[2]} \ -o "{$I[2][1]}-{$I[1][1]}-$num.ref2d" \ -EulerMode $EA \ -Rot1 $ROT1 $ROT1 1 \ -Rot2 $ROT2 $ROT2 1 \ -Rot3 $ROT3 $ROT3 1; \ if [ -z "$line" ] ; then \ break; \ fi; \ num=`expr $num + 1`; \ done; End
実行例
このコマンドはmrcImage(3D)ファイル及び下記のフォーマットの角度情報ファイルを入力として使用します。
EulerAngleMode Rot1 Rot2 Rot3
matrix3DFromEulerAngle(-i)と同じフォーマットで、それぞれの意味についてはオイラー角をご覧下さい。
入力ファイルがない場合は次のコードを使用するとサンプル入力データを作成します。なお、このサンプルデータはチュートリアル一覧#SampleDataを使用していますので、予めダウンロードしておく必要があります。
PNMLファイル
マークダウンファイル
# Initial.pione ## Initial It brings ref3d files as Input. ``` cp {$I[1]} {$O[1]}; ``` ## Angle It creates angle files. ``` for (( rot1 = 0; rot1 < 360; rot1 += 30 )) ; \ do \ for (( rot2 = 0; rot2 < 360; rot2 += 30 )) ; \ do \ rot22=`expr $rot2 + 15`; \ echo "YOYS $rot1 $rot2 0" >> {$O[1]}; \ echo "YOYS $rot1 $rot22 0" >> {$O[2]}; \ done; \ done; ```
下記のコマンドで入力ファイルを用意します。
pione compile Initial.pnml --action Initial.md > Initial.pione