TRNSYSの計算結果をPlotlyでグラフにしたら見やすかった件

前回Python,Pandasで読み込んだ計算結果をグラフにしてみました。グラフを描くのに使ったパッケージはPlotly。簡単なコーディングで下の動画のような動くチャートが簡単に描けます。

TRNSYSの計算結果をPlotlyでグラフ化

表示範囲を変えたり、チャートの表示、非表示の切り換えなど、値の描画だけじゃなく動かせるグラフが出来上がります。グラフはブラウザ上に表示されますが、1年分の室温、冷房負荷、暖房負荷のデータを使っているのに驚くほど動作が軽い!

グラフの描画処理

コーディング例は以下の通り。

#utf-8
import pandas as pd
import plotly 

# read the csv file and remove an unnecessary row
csv_filename = 'type25a.txt'
csv = pd.read_csv(csv_filename, delim_whitespace=True)
df = csv.drop(0)        # remove the first row
timestep = 1.0          # timestep
step=str(timestep)+'H'
dt = pd.date_range('1995-01-01 0:00',periods=8761,freq=step) # series for datetime column. 
df['DateTime']=dt

#plotly
# plotly.offline.init_notebook_mode(connected=False)
data = [
    # plotly.graph_objs.Bar(x=raw['TIME'], y=raw['TAIR_first_floor'])
    plotly.graph_objs.Scatter(x=df['DateTime'], y=df['TAIR_first_floor'], name='室温'),
    plotly.graph_objs.Scatter(x=df['DateTime'], y=df['QHEAT_first_floor'], name='暖房負荷', yaxis="y2"),
    plotly.graph_objs.Scatter(x=df['DateTime'], y=df['QCOOL_first_floor'], name='冷房負荷', yaxis="y2")
    
]

layout = plotly.graph_objs.Layout(
    title="年間暖冷房負荷",
    legend={"x":0.9, "y":0.9},
    xaxis={"title":"日付時刻"},
    yaxis={"title":"室温[C]"},
    yaxis2={"title":"暖冷房負荷[kJ/h]", 
        "overlaying":"y", 
        "side":"right",
        "exponentformat":"none",    # prevent 'k' notation
        "separatethousands":True},  # add a comma as a thousand separator
)
fig = plotly.graph_objs.Figure(data=data, layout=layout)
#plotly.offline.iplot(fig)
plotly.offline.plot(fig)

ソースコードの前半は単にCSVの読み込み展開処理です。(前回のソースコードとほぼ同じ)

グラフの描画は後半の15行ほど。これだけで見た目も整った動くグラフが出来上がります。シミュレーションでは何度も何度も解析を繰り返してグラフを描く事があります。これが割と面倒な作業なのですが、ちょっとしたスクリプトで描けるとストレス減りそうです。

動作環境

以下の環境で動作を確認しています。

Windows10 Pro(64bit)
Python:Anaconda 5.1(Python 3.6/64bit)
TRNSYS18.00.0017(64bit)

TRNSYSの出力をPythonで取り扱う

TRNSYSの計算結果の出力の仕方はいくつかあります。Type65やType25がよく使われますが、ファイル形式としてはタブ、ペース区切りのテキストで書き出されます。以下はType25の出力例ですが、あまり読みやすいとは言えないですよね。

TIME                        TAIR_first_floor            TOP_first_floor             QHEAT_first_floor           QCOOL_first_floor           QELEQUIP_first_floor        QELLIGHT_first_floor        RELHUM_first_floor            HOURS                  NAV                     NAV                     NAV                     NAV                     NAV                     NAV                     NAV                        
+0.0000000000000000E+00     +2.0000000000000000E+01     +2.0000000000000000E+01     +0.0000000000000000E+00     +0.0000000000000000E+00     +0.0000000000000000E+00     +0.0000000000000000E+00     +5.0000000000000000E+01      +1.0000000000000000E+00     +1.9830580301500703E+01     +1.9808233467796263E+01     +0.0000000000000000E+00     +0.0000000000000000E+00     +9.6768000000000015E+01     +0.0000000000000000E+00     +5.0010156123633521E+01      +2.0000000000000000E+00     +1.9734312966979235E+01     +1.9765312092721750E+01     +0.0000000000000000E+00     +0.0000000000000000E+00     +9.6768000000000015E+01     +0.0000000000000000E+00     +4.9484453863858377E+01      +3.0000000000000000E+00     +1.9771681072855184E+01     +1.9775732049503631E+01     +0.0000000000000000E+00     +0.0000000000000000E+00     +9.6768000000000015E+01     +0.0000000000000000E+00     +4.8758186593351304E+01      +4.0000000000000000E+00     +1.9727156805112390E+01     +1.9738355860938952E+01     +0.0000000000000000E+00     +0.0000000000000000E+00     +9.6768000000000015E+01     +0.0000000000000000E+00     +4.8300004863545269E+01      +5.0000000000000000E+00     +1.9696067740399105E+01     +1.9704197754226797E+01     +0.0000000000000000E+00     +0.0000000000000000E+00     +9.6768000000000015E+01     +0.0000000000000000E+00     +4.7823173447143830E+01      +6.0000000000000000E+00     +1.9649950794393828E+01     +1.9658051948204182E+01     +0.0000000000000000E+00     +0.0000000000000000E+00     +9.6768000000000015E+01     +0.0000000000000000E+00     +4.7411311457958369E+01      +7.0000000000000000E+00     +1.9598627168756757E+01     +1.9606091282868359E+01     +0.0000000000000000E+00     +0.0000000000000000E+00     +9.6768000000000015E+01     +0.0000000000000000E+00     +4.7033436866017283E+01    

これを通常はExcelなどへ読み込んで普通の10進表記やチャートに加工して結果を検討します。(ちょっと手間が掛かります)

Pythonで加工する

計算結果をもう少し手軽に加工できないか考えてみました。PythonにはCSVを扱う便利なパッケージが用意されていますので、今回はその中からPandasを使ってDataFrameへ展開してみます。

#utf-8
import pandas as pd

# read the csv file and remove an unnecessary row.
csv_filename = 'type25a.txt'
csv = pd.read_csv(csv_filename, delim_whitespace=True)
df = csv.drop(0)   # remove the first row.
timestep = 1.0
step=str(timestep)+'H'
dt = pd.date_range('1995-01-01 0:00',periods=8761,freq=step) # series for datetime column. 
df['datetime']=dt
print(df)

ほんの数行でCSVのデータからDataFrameへ変換できます。ここでポイントは2箇所有ります。

空白、タブ区切りの指定

まず、最初は区切り文字の指定。Type25の出力は空白、タブで区切られています。何も指定せずに読み込むと、タブなどがデータとして誤って解釈されます(NaNとして扱われる)
以下のようにdelim_whitespaceを使って空白、タブ区切りを指定します。

csv = pd.read_csv(csv_filename, delim_whitespace=True)

不要な行の削除

2つめは2行目の削除です。テキストの1行目はカラムの名前、2行目には単位が書き出されています。この2行目の部分は値としては不要なので、読み込み後に削除しておきます。

下の図の赤枠部分。ここはカラム名でもデータでもないので削除しておきます。

HOURSの行を削除する
HOURSの行を削除する

やり方としては、下のコードのようにDataFrameの最初の行を削除すればOKです。

df = csv.drop(0)

以上でDataFrameへ展開、不要なデータの削除ができました。あとは、DataFrameの機能を使って必要に応じて加工することができます。

上記のサンプルでは日付時刻のカラムを追加しています。やはり通し時間(Hour)よりも日付時刻の方が分かり易いですよね。

Jupyterの実行例

Jupyterの実行画面
Jupyterの実行画面

動作環境

以下の環境で動作を確認しています。

Windows10 Pro(64bit)
Python:Anaconda 5.1(Python 3.6/64bit)
TRNSYS18.00.0017(64bit)

TRNSYSをPythonから実行する

Pythonのsubprocessモジュールを使うと、簡単に外部プログラムを実行することができます。

そして、TRNBuild, Simulation Studio, TRNSYSもコマンドラインから起動できます。で、組み合わせるとスクリプトを使って、一連の処理をまとめて実行することができます。

次の例では、一連の処理をPythonから実行しています。

1.TRNBuildでVFM, SHM/ISMを生成
2. Simulation StudioでDckファイルの書き出し
3. TRNSYSで計算を実行

普段はあまりなさそうな使い方ですが、何度も計算を繰り返すようなケースで役に立ちそうです。

例)RunTRNSYS.py

# coding: utf-8
"""
This example shows how to run TRNBuild, Simulation Studio and TRNSYS.
coded by Yuichi Yasuda @ quattro corporate design
"""

import subprocess
#from subprocess import Popen

if(__name__ == '__main__'):
    # TRNBuild
    #--------------------------------------------------------------------------------------------------------------------------------
    # Creating VFM from command line
    subprocess.call(r'"C:TRNSYS18BuildingTRNBuild.exe" "C:TRNSYS18Examples3D_Building6_Step_Add_Daylightbuilding_ModGeo.b18" /N /vfm')
    
    # Creating SHM/ISM from command line
    subprocess.call(r'"C:TRNSYS18BuildingTRNBuild.exe" "C:TRNSYS18Examples3D_Building6_Step_Add_Daylightbuilding_ModGeo.b18" /N /masks')

    # Simulation Studio
    #--------------------------------------------------------------------------------------------------------------------------------      
    # Creating DCK file from command line. 
    # command line options
    #   /d create deck file
    #   /r run simulation
    #   /q quit
    subprocess.call(r'"C:TRNSYS18StudioExeStudio.exe" /d /q "C:TRNSYS18Examples3D_Building6_Step_Add_DaylightBuilding.tpf"')

    # TRNSYS
    #--------------------------------------------------------------------------------------------------------------------------------
    # Running TRNSYS in interactive mode
    #subprocess.call(r'"C:TRNSYS18ExeTrnEXE64.exe" "Building.dck"', cwd=r'C:TRNSYS18Examples3D_Building6_Step_Add_Daylight')

    # Running TRNSYS in batch mode
    # subprocess.call(r'"C:TRNSYS18ExeTrnEXE64.exe" "Building.dck" /n', cwd=r'C:TRNSYS18Examples3D_Building6_Step_Add_Daylight')

    # Running TRNSYS in Hidden mode
    subprocess.call(r'"C:TRNSYS18ExeTrnEXE64.exe" "Building.dck" /h', cwd=r'C:TRNSYS18Examples3D_Building6_Step_Add_Daylight')
  

動作環境

以下の環境で動作を確認しています。
Windows10 Pro(64bit)
Python:Anaconda 5.1(Python 3.6/64bit)
TRNSYS18.00.0017(64bit)

PythonでBuiファイルを操作する

年末年始にPythonをあれこれ試してみました。Type169で使えるようになったというのもあるんですが、他にも使い道がないかと思ったわけです。とはいえ、そもそもPythonの文法もよく分かっていないので、勉強がてらちょっとしたプログラム書いてみました。

テーマはBuiファイル(.b18)の解析ライブラリ。解析ライブラリというと大げさですがBuiファイルを読み込んで、Layerの厚みを変更するぐらいのプログラムを想定して試作してみました。

Buiファイルはテキスト形式で構造がシンプルなのでプログラムからは比較的扱いやすい内容になっています。厚みを変更するのであれば、ひとまずLayer,Constructionのデータが扱えれば事足りそうです。

Pythonと格闘すること数日。なんかそれっぽく動くライブラリ(パッケージ)が出来上がりました。Buiファイルの保存にも対応したので、Layerの厚みを更新して、保存、計算に利用するような使い方ができそうです。(大量に計算を回すときに使えそう)

#coding:utf-8
"""
Buiファイルを読み込んで、EXT_WALLの断熱材の厚みを変更して保存する
load a Bui file, update the thickness of the insulation material in EXT_WALL and save it.
"""
from b18 import BuiFile

if __name__ == '__main__':
    bui = BuiFile('Building.b18')
    # Search 'EXT_WALL'
    wall = next( (con for con in bui.constructions if con.name=='EXT_WALL') ,None)
    if(wall != None):
        wall.thickness[2] = 0.2 #Thickness for 'DAEMA'
        bui.save('copy_Building.b18')

実際に変更前後のBuiファイルを比べてみるとこんな感じ。ちゃんと厚みが変更されている。

処理前のファイル

CONSTRUCTION EXT_WALL
LAYERS   = PUTZ  KST   DAEMA HOLZ
THICKNESS= 0.015 0.175 0.167 0.02
ABS-FRONT= 0.4   : ABS-BACK= 0.5

処理後のファイル

CONSTRUCTION EXT_WALL
LAYERS   = PUTZ KST DAEMA HOLZ
THICKNESS= 0.015 0.175 0.2 0.02
ABS-FRONT= 0.4   : ABS-BACK= 0.5

これにTRNSYSの実行処理を加えたら壁の構成を変えながらパラメトリックスタディができそうです。しかし、たまに新しい言語を覚えるのは楽しいですね。なんというか、新しい道具を手に入れると、やれることが広がる感じが好きです。

動作環境

以下の環境で動作を確認しています。Windows10 Pro(64bit)
Python:Anaconda 5.0.1(Python 3.6/64bit) https://www.anaconda.com/download/
TRNSYS18.00.0016(64bit)

TRNSYSでPythonスクリプトを動かす

Type169(Python)

TRNSYS18からPython(Type169)が使えるようになりました。TRNSYSのプロジェクトで、ちょっとした計算や判定処理をPythonで手軽(?)に記述できます。でも、いきなりType169を利用すると図のようなエラーが発生します。

Type169でエラーが発生する
Type169でエラーが発生する

詳細なメッセージは以下。

*** Fatal Error at time   :         0.000000
     Generated by Unit     : Not applicable or not available
     Generated by Type     :   169
     TRNSYS Message    105 : A TYPE was called in the TRNSYS input file but was either not linked into trndll.dll or was not found in an external dll. A dummy subroutine was called in its place. Please link the TYPE or remove it from the input file
     Reported information  :  Type169 could not be located in either the trndll.dll or in an external dll. Please relink theTRNDll.dll including this Type or make sure that an external DLL in the \UserLib\DebugDLLs and \UserLib\ReleaseDLLs folders contain the Type.

これ、普段はTypeのDLLが無い、もしくは関連するDLLが不足していると表示されるメッセージです。少々分かりにくいですが、Type169ではPyhtonの実行環境が必須です。Type169を使用する前に、予め環境を整えてないとこのエラーになります。

Pythonの環境を整える

ということで、事前にPythonの実行環境の設定が必要です。

一般的にはPythonの公式サイト(https://www.python.org/)から入手しますが、ここではAnacondaのパッケージを使って環境を整えます。(サイズは少々大きくなりますが、こちらの方が取り扱いが簡単です)

AnacondaのダウンロードサイトからPython3.6,64bit版のインストーラーをダウンロードしてインストールします。いくつかオプションが表示されますが、すべてデフォルトでOKです。

https://www.anaconda.com/download/

Anacondaのダウンロード

環境変数の設定

インストールが終了したら、次は環境変数、PathにAnacondaのパスを追加します。デフォルトでインストールしていれば、環境変数Path C:Users<ユーザー名>Anaconda3 を追加すれば準備完了です。

2018/3/9 追記

Anaconda 5.1をインストールしたら、パスが変わっていました。(というか前回勘違いしていた?)環境変数Pathに追加するのは、こちらのパスになります。

C:\Users\<username>\AppData\Local\Continuum\anaconda3

Anacondaのバージョンやインストール方法で変わるのかも知れないので、環境に合わせて調整してください。

2018/5/11 追記

インストールの仕方(Anacondaのバージョン?)によってはインストール先のパスが変わる事があるようです。Type169の依存関係を調べるとPython36.DLLを参照しているのが分かります。Anacondaのインストール先を確認して、このファイルが存在するフォルダをPathに追加する必要があります。

Dependancy WalkerによるType169.dllの解析結果
Dependancy WalkerによるType169.dllの解析結果

例)環境変数の登録

環境変数の登録
環境変数の登録

Simulation Studioでなにかプロジェクトを用意して、うまく動けば設定環境です。

Simulation Studioで実行
Simulation Studioで実行

Pythonスクリプト

この例で使っているスクリプト(以下)を簡単に説明すると、Type169からはPythonFunction()を呼び出して、さらにmyFunc()を呼び出しています。

エラーが起きたときにログファル(_error.log)に書き出したかったので、2段階の呼び出しになっています。直接myFunc()を呼び出してもそのまま動くはずです。

type169_wtih_try.py

"""type169(Python) sample"""
import TRNSYSpy as trn
import traceback
import os

def myFunc():
    # retrieve values from the Inputs
    inp1 = trn.getInputValue(1)
    inp2 = trn.getInputValue(2)
    inp3 = trn.getInputValue(3)
    # processing
    out1 = inp1+inp2
    out2 = inp3**inp2
    # return the new values to the Outputs
    trn.setOutputValue(1, out1)
    trn.setOutputValue(2, out2)
    return

def PythonFunction():
    """This function is called from TRNSYS/Type169"""
    # delete the previous log file if it exists.
    logfile = "_error.log"
    if os.path.exists(logfile):
        os.remove(logfile)

    try:
        myFunc()

    except:
        # save messages to the log file when something goes wrong.
        print('error')
        with open(logfile, 'w') as f:
            f.write(traceback.format_exc())

上記サンプルのダウンロードはこちらから。

Github/TRNSYS.JP

https://github.com/TRNSYSJP/TRNSYS.JP/tree/master/TRNSYS18/MyProjects/Type169_Calling_Python

動作環境

以下の環境で動作を確認しています。

Windows10 Pro(64bit)
Python:Anaconda 5.0.1(Python 3.6/64bit) https://www.anaconda.com/download/
TRNSYS18.00.0015(64bit)

TRNSYSにIF文が欲しい

条件判定

TRNSYSで計算する際に条件を判断して処理したいケースってないですか?例えば暖冷房期間の判定処理とか。手軽な方法としてEquationを使って判断する方法(TRNSYSのEquationで条件判定)がありますが、少々分かりにくいのが難点。

単純な処理だと、これはこれで十分なんですが、条件が複数になると途端にハードルが上がります。例えば、冷房期間でも気温の低い早朝は窓開け換気の条件を設定したい。ただし、外気の湿度は60%以下の場合に限る。なんて条件を設定されるとEquationでは表現が難しくなります。(工夫すれば多分できると思うけど、可読性は低くなります)

スクリプトで代用できないか?

開発言語やスクリプトのようにIF文が使えると、少々条件が増えても簡潔に記述することができるはずです。例えば、書き方はこんな感じで。。。

#暖房、冷房期間の判定
if  time<=2760 or time>=7056 then
    heating=true
else
    heating = false
    cooling = not heating 
endif

#外気導入の判定:冷房期間でも外気温が25℃未満、湿度が60%以下なら窓開け換気する
if cooling and tamb <25 and rh <=60 then
    ach=10  #外気導入分の換気量を増やす
    aircon=0  #冷房のスイッチをOFF
else
    ach=0.5 
    aircon=1 #冷房のスイッチをON
endif

あとは、achをInfiltrationへairconをCoolingTypeへ渡して処理する。こういった処理をやろうとすると、いくつかやり方があります。

JavaScriptを試す

以前にスクリプト言語の実装を試みたこともあるのですが、パフォーマンス的にいまいち。cstbが有償配布しているW言語コンポーネント(Type79)と比べると恐ろしく処理速度が遅くなります。

TRNSYSでJavaScriptを使ってみる

TRNSYS Type79 とスピード対決

素直にType79を購入すればいいのですが、共同研究とか納品とか考えると、それもちょっとなーという感じです。(とはいえ使ってみた感じ、そこそこ便利は便利そうです)

世の中には同じような事を考える人がいるらしく、Javaで実装している例もあります。

TRNSYSとJavaを連成?(1)

こもれなんかJavaの環境設定が面倒で簡単じゃないんですよね。

単純に配布できて、誰でも利用できる仕組みって作れないんだろうか?パフォーマンスが良くて、配布も関連ファイル同梱するだけでOKとか、Lua言語とか検討してみるか?とか考えていると。。。

Type169(Direct Call)登場

TRNSYS18からPythonが標準でサポートされるようになりました。Pythonなら技術計算では広く使われているのでパフォーマンスも定評があります。Pythonは別途インストールが必要になりますが、使いやすいディストリビューションも利用できます。

スクリプトは次のような感じで記述できます。

import TRNSYSpy as trn 
def PythonFunction():
     # retrieve values from the Inputs
     time = trn.getInputValue(1) 
     tamb = trn.getInputValue(2)    
     rh=trn.getInputValue(3)
     #冷房、暖房期間の判定
     if  time<=2760 or time>=7056 :
         heating=True
         cooling=False
     else:
         heating = False
         cooling=True
         
     #冷房期間の外気導入判定
     if (cooling==True) :
         if  (tamb <25) and (rh <=60) :
             ach=10
             aircon=0 
         else:
             ach=0.5 
             aircon=1
     else:
         aircon=0
     
     # return the new values to the Outputs
     trn.setOutputValue(1,ach)
     trn.setOutputValue(2,aircon)
     return
Type169(Direct Call)
Type169(Direct Call)

Equationで書くのに比べると、だいぶ解りやすいですね。(まあPythonが前提ではありますが)
Pythonには数値計算のライブラリも用意されているので、使いようによってはMatlabのような使い方もありそうです。

動作環境

Windows10 Pro(64bit)
Python:Anaconda 4.3.1(Python 3.6/64bit)
TRNSYS18.00.0014(64bit)

TRNLizardをセットアップする(2)

前回はRhino/Grasshopperのインストールまで終わったので、いよいよTRNLizardのインストールです。

TRNLizardを準備する

Transsolar社のサイトのTRNLizardのページのダウンロードのリンクを辿って、food4RhinoのサイトからTRNLizardをダウンロードしてインストールします。

Transsolar社のTRNLizardのページ
Transsolar社のTRNLizardのページ

food4Rhino

ここからTRNLizardをダウンロードします。(はじめてダウンロードする場合、ユーザー登録が要ります。)

food4RhinoのTRNLizardのページ
food4RhinoのTRNLizardのページ

TRNLizardのインストール

ダウンロードしたファイル(Zip形式)を解凍すると、大量のGrasshopper User Object ファイルが展開される。

TRNLizardのGrasshopper User Object ファイル
TRNLizardのGrasshopper User Object ファイル

で、これをどうするのかと思ったら、専用のフォルダにコピーすればOKらしい。
Grasshopperのメニューから File > Special Folders > User Object Folder を選んで専用フォルダを開く。

User Object Folder を開く
User Object Folder を開く

開いたフォルダに展開したファイルをすべてコピーする。

TRNLizardのファイルをすべてコピーする
TRNLizardのファイルをすべてコピーする

するとこの時点で、GrasshopperにTRNLizardのタブが追加され、TRNLizardのアイコンが表示されます。

TRNLizardのタブにアイコンが表示される
TRNLizardのタブにアイコンが表示される

早速アイコンをドラッグして配置してみると。。。

エラーだとおぉ!

Pythonのエラーメッセージ
Pythonのエラーメッセージ

メッセージを見ると、 Python Interpreter がインストールされていないのが原因のようです。(Pythonインタプリタってオプションなのか?)調べてみると、food4Rhinoで公開されている GhPython がそれらしいので、これもインストールします。

food4Rhinoから GhPythonをダウンロードする
food4Rhinoから GhPythonをダウンロードする

GhPythonをインストール

上記のサイトからghpython2(ghaファイル)をダウンロードして、これも専用フォルダへコピーすればOK。(TRNLizardとはフォルダが違うので注意!)Grasshopperのメニューから File > Special Folders > Components Folder を選んで専用フォルダを開く。

Components Folder を選んで専用フォルダを開く
Components Folder を選んで専用フォルダを開く
GhPythonのファイルをすべてコピーする
GhPythonのファイルをすべてコピーする

ここで注意点。ネットワークからダウンロードしたファイルはアクセスがブロックされているので解除しておきます。エクスプローラーの画面でghpyhton2を選択して、右クリックでプロパティを選択して、「ブロックの解除」をチェックします。

ファイルのブロックを解除する
ファイルのブロックを解除する

TRNLizardを起動

Rhino,Grasshopperを再起動して、TRNLizardのアイコンを配置すると。。。おおっ!なんかそれっぽい画面が展開された!

TRNLizardの起動画面
TRNLizardの起動画面

どうにかTRNLizardのセットアップが完了したので、次は実際に動かしてみます。つづく。

動作環境

Windows10 Pro(64bit)
Rhinoceros5(64bit) 5 SR14 64-bit
(5.14.522.8390, 05/22/2017)
Grasshopper 0.90076, GhPython 0.6.0.3
TRNLizard(trnlizardpackage201704.zip)
TRNSYS18.00.0014(64bit)

TRNSYSの計算結果をPythonでグラフ化する

TRNSYS18のリリースに備えてPythonを勉強しています。以前に一度やりかけたことがあるのですが、だいぶ忘れているのでおさらいです。

TRNSYSの計算結果をサクッとグラフ化する

やり方としてはTRNSYSの計算結果(ファイル)を読み込んで、グラフを描くモジュールを使ってグラフ化します。

計算結果はExamlesのBegin.tpfの出力ファイル(”C:\Trnsys17\Examples\Begin\Begin.out”)をそのまま使用します。

ちなみに中身はこんな感じのテキストファイルになっています。TIME,QColl(集熱パネルの集熱量)、QAux(補助ヒーターの負荷)の3カラムの構成です。

Begin.outのデータ
Begin.outのデータ

ライブラリの準備

はじめに処理に使用するライブラリ(パッケージ)をインポートしておきます。詳細は省略しますが、それぞれファイルを読んでグラフ化するのに使用します。
なお、以下のPythonのコーディングはPython3.6/Jupyter Notebookを使って検証しています。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

ファイルを読み込む

そしてファイルを読み込む処理は、たったの一行。

df= pd.read_csv('C:\Trnsys17\Examples\Begin\Begin.out')

これで、ファイルの読み込んでDataframeという形式に展開してくれます。表示してみましょう。

df.head() で最初の数行分を表示してくれます。

読み込んだファイルの内容を表示

読み込んだファイルの内容を表示

読み込まれたデータが表形式で表示されています。 でもこの状態だと実は、まだだめなんですね。元データは3カラムで構成されていましたが、区切りがうまく認識されれず一行まとめて一つの値になっています。(値というか、単なるテキスト) ここで表をよく見ると、タブ区切り(\t)記号が含まれています。(赤枠の部分)

タブ区切りが含まれている
タブ区切りが含まれている

そこでファイルの読み込みの箇所で、タブ区切り記号を指定して処理を行います。

df= pd.read_csv('C:Trnsys17\Examples\Begin\Begin.out',delimiter='t')

こんどは無事にカラムごとに分けて読み込まれました。最後にUnnamedなんとかという名前のカラムがありますが、これは空のデータが入っているためなので、あまり気にしなくてOKです。

カラム分けされたデータ
カラム分けされたデータ

グラフを描く

そしてQColl,QAuxをグラフにプロットするのは、ほんの2行ほど。カラム名を指定して次のようにします。

df.loc[:,['Qcoll','Qaux']].plot()

plt.show() と、ここで大量のエラーメッセージが。。。

大量のエラーメッセージが表示される
大量のエラーメッセージが表示される

いろいろごちゃごちゃ書いてありますが、重要な点は最後の1行に書いてあります。

KeyError: "None of [['Qcoll', 'Qaux']] are in the [columns]"
(指定された'Qcoll', 'Qaux'はカラムに存在しません)

これちょっと分かり難いのですが、TRNSYSから書き出されたファイルではカラム名に空白が含まれています。Pythonで読み込む際に、空白も含めてカラム名として認識されてしまうため、’Qcoll’で指定しても、実際にはないのでエラーとして処理されてしまっています。正確に’Qcoll             ’のように空白を含めてカラムを指定する必要があります。でも、これ少々面倒なので、逆にカラム名を再設定する方が簡単です。これも一行で済みます。

df.columns=['TIME','Qcoll','Qaux','UNNAMED']

この行を追加したら、再度グラフを描いてみます。
下図のような画面が表示されたら成功です。

TRNSYSの結果をグラフで表示
TRNSYSの結果をグラフで表示

しかし、Begin.tpfの出力は積算値なので、右肩上がりのグラフになってしまっていまいちですね。。。(なにか比較対象がないとというか、面白い表示じゃないすよね?)

ちょっと工夫すると描く範囲を指定したり、複数のデータをまとめてグラフ化することもできます。一度Pythonのスクリプトを書いてしまえば、再利用もできます。なんども繰り返し計算を行うようなケースでは気軽にグラフ表示できる方法です。

以下、実際に動かしたスクリプトです。実質3,4行でグラフが描けるので非常に楽です。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df= pd.read_csv('C:Trnsys17\Examples\Begin\Begin.out',delimiter='t')
df.columns=['TIME','Qcoll','Qaux','UNNAMED']
df.loc[:,['Qcoll','Qaux']].plot()
plt.show()

TRNLizardってなんだ?

TRNSYS18と一緒にリリースされるTRNLizard(Rhino/Grasshopperプラグイン)ですが、調べてみると海外の学会などですでに発表されているようです。ちょっとググったらいくつか出てきました。

IBPSA(2014)

TRNSYSLizard – Open Source tool für RHINOCEROS – IBPSA

ドイツ語で書いてあるらしく、よく分かりません。ところどころTRNSYSという単語の他、Radianceも出てくるので、やはり形状と日射(昼光利用とか?)のツールのようです。(いまからドイツ語勉強するのはつらいな)  

DIVADay(2015)

positive proof of Global Warming 

↑この資料、トップページにに下着の写真が表示されます。表示すると少々怪しいページに見えます(会社だったので少々慌てた)が、中身はまじめなプレゼン資料です。

p.48~ TRNLizardの説明があります。DIVAってRadianceのツールですよね?

発表の時期(2014,2015)を考えると、TRNSYS18版は十分開発が進んでいそうです。リリースが楽しみです。

しかしRhino(サイ)、Grasshopper(バッタ、イナゴ)、Lizard(トカゲ)と動物の名前がつづいて不思議な感じですね。

Pythonを使ってTRNSYSでパラメトリックシミュレーション

このところ、Pythonづいております。以前書いたように、汎用のパッケージを使ってTRNSYSの計算結果を簡単に扱うことができます。他にも使えそうなツールや、もしかしてすでにTRNSYSがらみのツールがあったりするんじゃないかと、ググってみたらありました。

PyBPS A parametric simulation manager for building performance simulation projects

pybps 0.1.2
pybps 0.1.2

シミュレーション実行の他、パラメトリック処理やプリ、ポストプロセスへも対応しているようです。Pythonのパッケージを組み合わせると、いろいろ処理ができそうです。

並列実行も対応しているようなので、大量に計算が必要なプロジェクトには良いかもしれません。 しかし、これPython2.7で書いているのか。。。(3.xだったら良かったのに)