|
5.6 データのロードと計算
5.6 データのロードと計算 Mathematica にはデータをロードするさまざまな関数が入っています.これらの関数は関数Importから使うことができます.Importはコンマやタブを区切りにしたテキストデータやグラフィックス,科学,サウンド,XMLのようにより特殊なフォーマットまでをサポートします.バイナリデータは関数Experimental`BinaryImportでロードすることができます.使いたいデータ形式がMathematica では直接サポートされていない場合でも,前のセクションで説明したJava APIを使ってデータがロードできるかもしれません. データをロードする技術を開発するためには,データをロードする関数がどのように動作するのかを理解するためにインタラクティブなMathematica を使うのがよいでしょう.こうするとご自分のWebアプリケーションにデータのロードを追加することができます.まずはじめにデータのソースを決める必要があります.以下のセクションではいくつかの可能性を検討します. 5.6.1 ファイルのI/O データファイルがwebMathematica のサーバが動いているコンピュータのファイルシステムから入手できる場合は,そのファイルをImportのようなコマンドで読むことができます.このためにはデータファイルの名前と場所が指定されなければなりません.指定方法はいくつかあります.ひとつはファイルをディレクトリに入れ,このディレクトリまでの完全パス名を設定する方法です.この方法を取ると,ディレクトリの名前を変更した場合に,この名前を使っている全スクリプトを書き換えなければならないので大変不便です.ディレクトリ名を初期設定パラメータで設定するとこの点が改善されます.下記に示すようにMSP.confでパラメータのKernelInitializationを使うと,こうすることができます.
KernelInitialization=MyApplication`DataDirectory="C:\\Work\\Data"
これでMathematica のシンボルMyApplication`DataDirectoryに"C:\Work\Data"を割り当てます.ここでは完全コンテキスト名を使っていますが,シンボルがカーネルのクリーニングメカニズムで消去されてしまわないためにはこうする必要があるのです.この後これをwebMathematica の計算にロードします.ロードの方法は以下の例をご覧ください.
<msp:evaluate> data = Import[ ToFileName[ MyApplication`DataDirectory], "file.dat", "Table"]; </msp:evaluate>
データファイルをMathematica のパス設定$Pathに置く方法も考えられます.これが次に示す例題Data1.jspのアプローチです.データファイルをスクリプトと同じディレクトリに置き,MSPScriptDirectory[]を使う方法もあります(下記をご覧ください).
<msp:evaluate> data = Import[ ToFileName[MSPScriptDirectory[]], "file.dat", "Table"]; </msp:evaluate>
これは前に説明したXMLの例題Phone.jspで使った方法です.MSPScriptDirectory[]を使うのはデータとスクリプトが同じディレクトリに置かれるので特に便利な方法です.こうするとWebのアプリケーション全体をあるサーバから別のサーバへ最小限の設定で移動することができます.この方法の欠点は,JSPの側から見るとデータファイルがサーバへの直接のリクエストでロードされるので,データファイルに特殊な情報がない場合にしか使えない点です.ある種の情報が各リクエストへの返信のみで使われるのに適している場合がこれに当たるでしょう. 5.6.2 HTTPアップロード webMathematica サーバにデータをロードするまた別の方法に,HTTPのリクエストを使ってクライアントマシンから送るというものがあります.webMathematica には関数MSPGetUploadFileを使ってこれをサポートするツールが含まれています.これは以下に示す例題Upload.jspでご覧ください. 5.6.3 データベースの接続 webMathematica での計算に使うデータの重要なソースにデータベースがあります.Javaのデータベース接続ツールボックスJDBCを使って,上記のようにJavaをコールしてデータベースとインタラクトすることができます.WindowsではMathematica Database Access Kitを使うことができます. 5.6.4 Webサービス Mathematica の計算のための最後のデータソースは他のWebサイトです.現在のところ,これはURLの接続を開き,リクエストを送ってその応答を読むことで行います.これも上記のようなJavaへのコールで行えます.データがXML形式で入手できるなら,XMLのセクションで説明したようにXML`Parser`XMLGetを使うこともできます. 5.6.5 データの例 以下はwebMathematica でデータを使う例題集です. データのロード:Load.jsp 前述のようにwebMathematica をインストールするとhttp://localhost:8080/webMathematica/Examples/Data/Load.jspでこのJSPに接続することができます(ご自分のサーバに接続するURLはこれとは多少異なる場合もあります). この例題はMathematica のパッケージのロード方法とサーバに保存されているファイルの読み方を示しています.データはデータの平滑化アルゴリズムで処理され,2つのプロットが作られます.このページのソースはwebMathematica/Examples/Data/Load.jspにあります.以下はformタグを示している部分です.
<form action="Load.jsp" method="post">
<msp:allocateKernel>
<msp:evaluate> Needs[ "Graphics`MultipleListPlot`"]; Needs[ "Statistics`DataSmoothing`"]; </msp:evaluate>
<msp:evaluate> data = Flatten[ N[ Import[ "Data/DataFile1.dat"]]]; term = 4; If[ MSPValueQ[ $$term], term = MSPToExpression[ $$term]]; </msp:evaluate>
<msp:evaluate> dataSmooth = MovingAverage[ data, term]; MSPShow[ MultipleListPlot[ data, dataSmooth, PlotJoined ->{False, True}, SymbolShape -> Point, SymbolStyle -> {{PointSize[0.008], Hue[0]}, {PointSize[0.001]}}, ImageSize -> 600]] </msp:evaluate>
<br /> <br />
Number of smoothing terms: <input type="text" name="term" size="3" value="<msp:evaluate>MSPValue[ $$term, "3"]</msp:evaluate>" />
</msp:allocateKernel>
<br /> <br /> <input type="submit" name="btnSubmit" value="Evaluate"> </form>
この例題ではmsp:evaluateタグが2つのMathematica パッケージをロードするのに使われています.パッケージは常にそれ自身のタグを使ってロードするようにするとよい練習になるでしょう.次のmsp:evaluateタグは,Importコマンドを使ってデータセットData/DataFile1.datをロードします.これはMathematica $Path上のデータファイルを探し,MSPScriptsディレクトリの中のDataディレクトリを見付けます.MSPScriptsディレクトリはデフォルトではwebMathematica/WEB-INFにあります.ご自分のwebMathematica Webアプリケ−ションの内部を見てデータファイルの場所を確かめるとよいでしょう.例題は移動平均を計算し,もとのデータと平滑化したデータをプロットします.項数が変更できるように,これらはすべてform要素の中に置かれます. この例題の弱点のひとつは,それぞれの計算についてデータをデータファイルからロードしなければならない点です.データを何らかの形で保存しておければ便利でしょう.また,クライアントからデータがロードできるようだと便利でしょう.これについては次のセクションで考えましょう. データのアップロード:Upload.jsp 前述のようにwebMathematica をインストールするとhttp://localhost:8080/webMathematica/Examples/Data/Upload.htmlでこの例題に接続することができます(ご自分のサーバに接続するURLはこれとは多少異なる場合もあります). この例題ではユーザが積分する関数を入力することができます.結果はタイプセットのシステムでフォーマットされ,画像として保存されます.このページのソースはwebMathematica/Examples/Data/Upload.htmlとwebMathematica/Examples/Data/Upload.jspにあります.Upload.htmlの内容は以下の通りです.
<html> <head> <title>Upload File</title> </head> <body> <form method=post enctype="multipart/form-data" action="Upload.jsp"> <p> Enter a file to upload: </p> <input type="file" size=40 name="file"> <br /> <br /> <input type="reset" value="Clear"> <input type="submit" value="Submit"> </form>
<i> To generate suitable data, <a href="DataGenerate.jsp">click here</a> </i> </body> </html>
まず,これがHTMLページであることにご注目ください.ここにはJavaやMathematica は挿入されていません.サーブレットコンテナはJPSを配信するのと同じようにHTMLのページを配信します.どのページもwebappの同じディレクトリに一緒に入れることができます.このwebappには画像や動画等が入っているその他のファイルも入れることができます.このファイルにはmultipart/form-dataのenctype属性を使ってデータファイルを送信する設定を行うform要素が1つとタイプfileのinput要素があります.送信ボタンがクリックされると,フォームはファイルと一緒にUpload.jspに送られます.以下はUpload.jspから選んだものです.
<msp:allocateKernel>
<msp:evaluate> Needs[ "Graphics`MultipleListPlot`"]; Needs[ "Statistics`DataSmoothing`"]; </msp:evaluate>
<msp:evaluate> file = "FileName" /. MSPGetUploadFile[]; data = Flatten[ N[ Import[ file, "Table"]]]; term = 4; </msp:evaluate>
<msp:evaluate> If[ StringQ[ file], dataSmooth = MovingAverage[ data, term]; MSPShow[ MultipleListPlot[ data, dataSmooth, PlotJoined ->{False, True}, SymbolShape -> Point, SymbolStyle -> {{PointSize[0.008], Hue[0]}, {PointSize[0.001]}}, ImageSize -> 600]]] </msp:evaluate>
</msp:allocateKernel>
これを見るとMSPの関数MSPGetUploadFileがサーバ上でファイルを保存しているデータファイルの名前をどうやって抽出するかが分かります.このファイル名は前の例で行ったようにデータを読むのに使われ,続けて計算が行われます.この解決策には限界があります.データは1つの計算につき1回しか使えません.また,例えばデータの平滑化をコントロールするためのパラメータを変更する機能は加えられていません.このため,データはセッション変数に保存される必要があります.これについては次の例題で見てみます. この例ではファイル名が実際に文字列かどうかを判定するテストが行われます.これでデータファイルが実際にアップロードされたかどうかが検証されます.ページUpload.jspがUpload.htmlへのリクエストからではなく直接アクセスされるのであればファイルはアップロードされません. MSPGetUploadFileはサーバで使われるファイル名,クライアントで使われるもとのファイル名,コンテントタイプ等の便利な情報を返します.アップロードするファイルが複数の場合,MSPGetUploadFileは例外を投げます.複数のファイルをアップロードしたい場合はMSPGetUploadFileListを使うとよいでしょう. データのセッション保存:Session.jsp 前述のようにwebMathematica をインストールするとhttp://localhost:8080/webMathematica/Examples/Data/Session.htmlでこのJSPに接続することができます(ご自分サーバに接続するURLはこれとは多少異なる場合もあります). この例題でユーザは積分する関数を入力することができます.結果はタイプセットシステムでフォーマットされ画像として保存されます.このページのソースはwebMathematica/Examples/Data/Session.html,webMathematica/Examples/Data/Session.jsp,webMathematica/Examples/Data/SessionProcess.jspにあります.Session.htmlの内容は以下の通りです.
<html> <head> <title>Upload File</title> </head> <body> <form method=post enctype="multipart/form-data" action="Session.jsp"> <p> Enter a file to upload: </p> <input type="file" size=40 name="file"> <br /> <br /> <input type="reset" value="Clear"> <input type="submit" value="Submit"> </form>
<i> To generate suitable data, <a href="DataGenerate.jsp">click here</a> </i> </body> </html>
これはUpload.htmlに大変よく似ています.違いは,こちらの場合はフォームが送信されるとSession.jspを呼ぶ点です.次はSession.jspです.
<%@ page language="java" %> <%@ taglib uri="/webMathematica-taglib" prefix="msp" %>
<msp:allocateKernel>
<msp:evaluate> file = "FileName" /. MSPGetUploadFile[]; data = Flatten[ N[ Import[ file, "Table"]]]; MSPSessionVariable[ UploadedData, Null]; UploadedData = data; </msp:evaluate>
<jsp:forward page="SessionProcess.jsp" />
</msp:allocateKernel>
この短いJSPはアップロードされたデータを読み,MSPSessionVariableを使ってデータをUploadedDataという名前のセッション変数に保存します.これはあるHTTPのリクエストから他のHTTPへのリクエストへ継続的にデータを保存する便利な方法です.データは実際にはサーバに保存されるので,たとえMathematica のカーネルが再起動されてもデータを使うことができます.保存にはHTTPセッションとして知られているものが使われます.また,サーバは実際にデータを保存するためにクッキーその他のメカニズム使うことがあります.Eコマ−スのWebサイトのショッピングカートはこのようなメカニズムになっているのです.webMathematica Webサイトの開発者に関する限り,これは大変単純です.開発者はただ関数MSPSessionVariableを使い,それに変数の名前と変数に持たせたい値を渡せばいいのです.データを読み終わったら,jsp:forwardで実際に計算とプロットをするページData3.jspに転送します.すべて異なるタスクを行うたくさんの別々のページにコードを分割するのはよい設計原理です.開発しているページにたくさんの複雑なコードが入っている場合は,再分割することでシステムが改善されるかもしれません.次はSessionProcess.jspからの抜粋です.
<form action="SessionProcess.jsp" method="post">
<msp:allocateKernel>
<msp:evaluate> Needs[ "Graphics`MultipleListPlot`"]; Needs[ "Statistics`DataSmoothing`"]; </msp:evaluate>
<msp:evaluate> MSPSessionVariable[ UploadedData, Null]; term = 4; If[ MSPValueQ[ $$term], term = MSPToExpression[ $$term]]; </msp:evaluate>
<msp:evaluate> If[ UploadedData =!= Null, dataSmooth = MovingAverage[ UploadedData, term]; MSPShow[ MultipleListPlot[ UploadedData, dataSmooth, PlotJoined ->{False, True}, SymbolShape -> Point, SymbolStyle -> {{PointSize[0.008], Hue[0]}, {PointSize[0.001]}}, ImageSize -> 600]]] </msp:evaluate> <br /><br /> Number of smoothing terms: <input type="text" name="term" size="3" value="<msp:evaluate>MSPValue[ $$term, "3"]</msp:evaluate>" />
</msp:allocateKernel> <br /><br /> <input type="submit" name="btnSubmit" value="Evaluate"> </form>
SessionProcess.jspはLoad.jspに非常によく似ています.主な違いはデータを入手する行です.SessionProcess.jspはデータをファイルから読む代りにセッション変数のUploadedDataを使います.UploadedDataは前のJSPのSession.jspでデータを割り当てられています.SessionProcess.jspが直接アクセスされた場合に考えられるようにUploadedDataが前もって定義されていない場合,UploadedDataはNullという値を持つことになります.ここでは,このためにプロットが生成されないだけですが,エラーページを表示するのに使われることもあります. このセクションにさらに変更を加えると,データを永久にサーバに保存できるようになります.単純なデータファイルの場合,これはMathematica のファイル出力操作で簡単にできます.より高度なアプリケーションの場合はJavaデータベースの接続性を使ってデータや特定の情報を保存します. セッション変数については「より高度なトピック」の「変数」で詳しく説明します.
     
|