そうなると再び登場

そうなると、出力チェックのために 少し仕掛けが必要です。これも大分前に作成したプログラム部品です

#ifndef __OSTREAM_H_
#define __OSTREAM_H_
// 二進出力を可能とした ostream (Programmedd by Shigeru SAITO, MD on June 5th, 2009)
// modified by S. SAITO, MD on December 14th, 2010
// 使い方: このheader fileをインクルードし、名前空間ostを用いてcoutに出力する
// ost::ostream cout; とcoutを生成し、
// cout << value;
// のように使う、そして標準出力については std::cout << std::endl; のようにする
// 入力の型(BYTE, WORD, int)に応じて自動的に8桁、16桁で出力するがsetw()で出力桁数を変更できる
#include <iostream>
#include <iomanip>
#include <string>
typedef unsigned char BYTE;
typedef unsigned short WORD;

namespace ost {
	enum e_manip {bin, hex, dec, endl};
	class setw {
		int width_;
		setw() {}	// 引数無しコンストラクタ禁止
	public:
		setw(int n);
		int get_width(void) const;
	};

	class ostream {
	private:
		int width, bitWidth;
		e_manip mManip;
		bool mIsSetW;
		void setWidth(int w);
		void out(int n);
	public:
		ostream();
		ostream & operator << (const setw & sw);
		ostream & operator << (const e_manip em);
		ostream & operator << (const BYTE n);
		ostream & operator << (const WORD n);
		ostream & operator << (const int n);
		ostream & operator << (const char* s);
		ostream & operator << (const std::string str);
	};

};	// namespace ost

何と 2009年6月に作ったものなのですね。二進出力を可能とするクラスです。どうしてC++やCに二進出力が標準的に備わっていないのか不思議で仕方ありません。普段使わない八進出力なんて存在するのに・・・です。

遅々として、しかし着実に進展

DICOM XA Viewerの作成プロジェクト何処までいきましたかね?

もちちろん自分は一義的には Interventional Cardiologistであり、医師であり、プログラマではありませんので、なかなか進みません。そして、何よりも心の問題です。これまで、何年も目標として頑張ってきて、心の何処かに何時も、解けない難問として横たわっていたものが、どうやらもうすぐ解けそう、と思った時、「あー、これで目標が無くなるのか?」という恐れも湧いてきたのです。それが、前に進むのを妨げているのです。

とは言っても、本当に解けるのか? それは実現せねばわかりません。という訳でゆっくりとタラタラやっています。まずは、ファイル読み込みをメモリー中のバッファに展開するクラスを作成しました。といっても今までのクラスを一つにまとめただけですが・・・

このクラスでは、ファイルを読み込み、エラーがあれば、エラー送出クラスでエラーを送り、無ければメモリー中のバッファに展開し、ビット入出力のためのインターフェースを提供します。実装して、基礎的なテストを行い、作動することを確認しています。ヘッダ部分のみ掲載しましょう。

class CBitBuffer
{
protected:
	BYTE *bufTop;			// Bufferの開始アドレス
	BYTE *bufEnd;			// Bufferの終了アドレス
	long bufSize;			// Bufferのサイズ
	BYTE *mbpRead;			// 読み出しアドレス
	BYTE mMask;				// bit maskであると同時に現在の読み出しビット位置 (MSB = 7, LSB = 0)
	bool mReadable;			// 1: 読み出し可、 0: 読み出し不可
	void IncBuf(void);		// 読み出しアドレスのインクリメントとアクセス違反のチェック

public:
	CBitBuffer(void);
	CBitBuffer(const int argc, const char* argv);	// ファイルを読み込んでbufferに収納
	virtual ~CBitBuffer(void);
	BYTE *getBufTop(void);		// 内部bufferの先頭アドレス
	long getFileSize(void);		// 内部bufferの大きさ
	BYTE *getBufEnd(void);		// 内部bufferの最終アドレス

	BYTE GetBYTE(void);		// 1 BYTE読み出し
	WORD GetWORD(void);		// 1 WORD読み出し
	void CopyBYTEs(BYTE *bpDest, int n);		// n BYTEs読みだしてbpDestのアドレス以降にコピーする
	void SkipBYTE(int n);					// n BYTEs読み飛ばし
	int GetBit(void);						// 1 bit読みだして返す
	int GetBits(int numOfBits);				// numOfBits数のビットを読みだして返す
	BYTE *GetNextAddress(void);				// 次の読み出しアドレスを返す
};

C++ std::cout で char * で示されるアドレスを表示するには?

unsigned char * で表される変数、たとえば

unsigned char * p = 'x';

と宣言した場合、変数pが指すのは’x’という文字が格納されているメモリーのアドレスです。そして、そのアドレスをを用いて表示するとします たちえば

#include 

int main(void) {
  unsigned char * p = 'x';
  std::cout << std::hex << p << std::endl;
  return 0;
}

とします。結果は、たとえば、0023456 とか表記して欲しい訳です。もちろん、この数字は勝手に書いたものですが、要するにメモリーアドレスのつもりです。
しかし、このようにしても何も表示されません。
いくらやっても分かりませんでしたが、この質問箱を読んで分かりました。
要するに、<ostream>には operator<<(const char*)という演算子オーバーロードが定義されているらしいのです。 従って、ここは’x’という文字列を出力するべきなのか、あるいはアドレスを出力すべきなのかが不定となり、何も出力されなくなるらしいのです。

このため、アドレスを出力するためには、演算子オーバーロードされていないもの、void*などにキャストせねばならないらしいのです。以下のようにです

#include 

int main(void) {
  unsigned char *p = 'x';
  std::cout << std::hex << reinterpret_cast<void *>(p) << std::endl;
  return 0;
}

のように、void*にキャストする必要があるらしいのです。勉強になりました。

昨日の成果

昨日は 100gram 100円で 500grams購入して帰ったままかりを食べました

ままかり まるのまま

このまるのままの ままかりをひらきました まるで「コハダ」のようですね。それはそうです、「ままかり」も「コハダ」もニシン科に属するらしいのです。しかし、プロの目で見れば、いや、素人さんにも分かりますが、明らかに違います

  1. まず、鱗が違います。コハダの鱗は小さいのですが、「ままかり」では魚体に似合わず大きいのです 従って「ままかり」では絶対に鱗をはずさねばなりません
  2. 次に、鰓の少し手前に「コハダ」であれば、黒い印がありますが、「ままかり」にはありません
  3. 魚体も「コハダ」では、太目ですが、「ままかり」は写真のように流線型です
  4. 鱗を外した後も、「コハダ」には、小さな連続した印が体全体にありますが、「ままかり」では、のっぺりした感じです。

という訳で、僕のようなプロになれば一目瞭然ですね。しかし、その捌き方は同じです。岡山で「ままかり」は、甘酢で〆ますが、今回はこれを江戸前で〆てみました。本当の江戸前というのは、酢と塩しか使わないのです。、

ままかり ひらいたところ

さらにこれを塩と酢で〆た後です おいしそうでしょ?

ままかり しめた後

この「しめる」という行為は何なのか? と言えば、写真でも分かるように、明らかに蛋白変性を行っています。

塩 –> 主として脱水する これにより、細胞内の無駄な水分を排除すると共に、アミノ酸をはじめ旨味成分を濃縮する

酢 -> 酸の作用により蛋白変性を促し、それと共にアミノ酸分解を促進する

ということなのでしょうか? もちろん度が過ぎるとかえってまずくなりまたパサパサとなってしまい、ダメです。これらの作用ももともと魚体に含まれている脂肪分によって妨げられますので、見極めが大切です。それには経験が必要でしょう。

光藤先生と再会

昨日は大分より日豊本線特急ソニックで小倉に、そして小倉から岡山に新幹線で移動し、岡山国際会議場で開催された CVIT中四国地方会で講演をしました。講演の前後で久しぶりに (うーん、この前の小倉ライブデモンストレーションの時には話す時間が無かったから・・ ということになるとそれこそ5年以上振りでしょうか)話す機会がありました。やっぱり友は良いです。色々な話しをしました。でも、心配されていた健康ですが、思った以上にお元気そうで何よりでした。

講演を終わってから、空港に急いだのですが、途中市内で魚やさんに寄り、ままかりを丸のまま 500g購入しました。100gで100円、大体 5 – 6匹です。ままかりの酢漬けは岡山名物で、僕も好きで岡山に行った時には必ずといって良いほど買って帰りますが、正直 ままかりを丸のまま購入したことは初めてでした。自宅に戻ってから、コハダと同じような捌き方、つまり、頭と尻尾を落とし、背びれも落とし、それから腹を落とし、腹ワタを出してから、腹から背に向けて包丁を入れ、今度は広げながら腹を下にかえし、それから包丁を背骨に沿って入れ、身を一枚に取り出す方法、この包丁捌きは何と呼ぶのでしょうか? その方法で合計30匹くらいの開きをつくりました。それを塩で〆、そしてその後酢で〆、今は冷蔵庫で寝かしてあります。さぞかしおいしいだろう、と楽しみです。

昨日は

昨日は社会保険 下関厚生病院を訪問させて頂きました。その前に、下関で有名な唐戸市場という、実際の市場でもあり、また観光名所でもある市場で昼食を摂り、それから訪問しました。

慢性完全閉塞二例が準備されていました。一例目は何とかできるかな? と思ったのですが、二例目はとても駄目だ、と思いました。実際に症例を開始したのは、14:00頃でした。一例目は予想よりも難しく、ワイヤー通過の後も、なかなかバルーンを通過させれなかったのですが、最終的には長い病変に対して薬剤溶出性ステントを4本用いて綺麗になりました。そして、次の症例は15:00頃から開始しました。何とか順行性にワイヤーを通過したのですが、これまたバルーン通過に難儀しましたが、最終的には薬剤溶出性ステント2本で綺麗になり、ものすごい嬉しい結果で「あー 良かった」と思いました。これもみな、下関厚生病院の方々のご協力のお蔭です。難しい、と思っていたのですが、結果的には16:00には病院をおいとまさせて頂きました。

本日より西日本

今朝は羽田から山口宇部空港に飛びました。これから下関厚生病院を訪問し、PCIを行わせて頂きます。明日は、大分に移動し、CVIT九州地方会での講演、明後日は岡山に移動し、CVIT中四国地方会での講演です。土曜日には鎌倉に戻ります。

疑問解消

昨日来、Binary Editorを用いて、実際のDICOM fileを解析してきました。そもそも今更これを行っているのは、先日出勤時の自転車で、「あれ? DICOM XAは 1 pixel -> 8 bitsと固定していいのかな?」という疑問からでした。

そうして見直してみると、0x0028 0x0001という Bits Allocatedという DICOM Tagがあるのです。しかし、ここで問題でした。Binary Editorで見てみても、このタグに続くバイト列は

0x28 0x00 0x00 0x01 0x55 0x53 0x02 0x00 0x08 0x00 0x28 0x00 0x01 0x01

という風になっているのです。ちなみに色分けすれば
0x28 0x00 0x00 0x01 0x55 0x53 0x02 0x00 0x08 0x00 0x28 0x00 0x01 0x01

となります。赤字はDICOM Tagです。次の0x55 0x53はアスキーで “US”となります。これは超音波の意味ではなく、unsigned shortの意味であり、C/C++で定義されているデータ型です。つまり16 bits WORDなのです。

そして、次の黄色の部分にそれ以降何バイトが値なのか? が記載され、ここでは2 bytesです。従って、その次の紫色が値となり、値 = 8が得られます。

最初のタグの意味は、Bits Allocatedなので、このデータ列の意味するところは、1ピクセルは、8 bitsで表現されますよ、という意味です。これで、このDICOM XA fileは、1 pixel -> 1 byteで画素が表現されていることになります。