Save the DolphinS -OpenDolphin データ抽出ツール・プロジェクト-

久しぶりに電子カルテ OpenDolphin-2.7m(実質的には OpenOcean 0.0.1 と一緒)を臨床現場に投入するかもしれないということで、データ抽出ツールも数年ぶりにテスト稼働させる。
開発言語である Java のバージョンも上がっているし、まるっきり動かないかと思っていたら、そうでもなかった。

細かいところではもちろん不具合はあるのだが、データベース(PostgreSQL)に永続化されているカルテ記載内容を OpenDolphin を経由せずに取り出してくれた。
ちょっとほっとした。

なんで、こういうものが必要なのかは一般の人にはわかりにくいと思うが、電子カルテには縛りがあるためだ。具体的に気にかけておくべきは

・カルテ自体に保管義務がある
・電子カルテには3要件(真正性・見読性・保存性)が求められている
・3要件自体はガイドラインで罰則はないが、e-文書法(電子文書法)が適用される場合には罰則の対象になる可能性がある

の三つくらいだろうか。

ここらへんの解説は『OpenDolphin と電子カルテの3要件とメドレー』あたりを読んでみてください。

3要件のうち面倒なのは「真正性」というやつで、

電子カルテのデータを例えばデータベースに保存する場合、「誰が」書いたのか、その後「いつ、誰が」改変(あるいは消去)したのか、わかるような特別の仕組みをつくりこんでおかなければならない

とちょっとややこしい。
たいていの場合、ユーザーにシステム上の記録の「消す」作業に制限をかけることでこの条件をクリアしていると思う。こうしておくと、電子カルテ画面上である表現を削除したとしても、削除する前のバージョンは残っているので、データベース上にはこの一連の経過が残ることになる。
システムレベルで「上書き保存」ではなく「別名で保存」を採用しているといえば伝わるでしょうか。

だが、こういう作り込みをしてようやく「真正性」をクリアしたとしても、問題はまだ終わりではない。

何か問題がおこって、例えばカルテ開示を求められたような場合、そのカルテの(日付上は)最新の日時のバージョンを提示してもそれだけでは厳密にはカルテ開示したことにはならない。
想像つくかと思うが、医療者側に都合よくカルテ記載内容が書き換えられているかもしれないからだ。
この場合は、正しくは、通常使用では見えない状態になっている「消された表現」の部分も提示する必要がある。

実際、上の例でもこの患者さんのカルテは3件だが、途中経過版を含めると11件になっている。

MML 出力(という外部出力機能。ただし MML 規格はほとんど普及しなかった)を引き受けるサーバがない状態での OpenDolphin は、果たして電子カルテの3要件を満たしているのか?という疑問は実際よくあがっていた。

最近(2021 あたりからか?)では、保健所の個別指導あたりでもこの程度の開示は求められることがあるので、もはやこういった機能(途中経過版の抜き出し・修正履歴の出力など)の実装は必須だろう。

ローカルで稼働する OpenDolphin は、商用での開発が止まったため、自力運用する場合には、ここらへんの配慮をする必要があるのだ。

 

air-h-128k-il

 

医師免許持ちで臨床をまったくやらない人はそれなりの理由がある場合が多い

それほど強く主張するわけではないが、この記事のタイトルみたいなことは医師界隈ではそれなりのコンセンサスは取れていると思う。

もちろん、ガチガチの基礎系の場合、意識的にやってないという人はいる
(それでも当直や老健あたりの診察業務程度ならやっている人が大半だと思うが)。

結論から言うと、キャリア初期に臨床畑に進もうとして果たせず、その後、臨床業務から離れている人は、それなりの問題を抱えている人が多い。

具体例を挙げるとわかりやすいでしょうか。

何ら経験がないのに患者さんの同意も得ずに難度の高いオペを施行して、当然、失敗。さらにそのことを隠蔽、裁判沙汰になっても自分の非を一切認めない医師。(これに近いことはたまにニュースにも取り上げられてますよね)

患者さんとまったくコミュニケーションが取れない医師。(そんな医師いないと思うでしょ? でもいるんですよ、実際。今だと面接でハジかれるとは思いますが)

・・・などなど。

で、こういった医師は、臨床現場の主流からオミットされ、いつの間にか消えているというか、行方知れずになっている場合が多い。

ところで、先日、フェイザーの方々が、こんなコメントの投稿などに関して注意喚起の記事を公開した。

著作権法違反が疑われるコメントの掲載はできかねます

細かいことには触れませんが、ここに至るまでに警告のようなことは発していたのに小林さん完全無視でしたから、しょうがないと言えるでしょう。

私も某MLに入会しようとしたとき、管理人の方から「小林慎治は喧嘩売るような感じできますから、気をつけてくださいね」とアドバイスをもらったことはある。

快く思っていなかった医師は多かったようですね。

 

ANN2b

(追記)これは某掲示板の書き込み。
出どころが出どころなので信頼性に乏しいし(まず、なにより「医者の資格はない」というのは明らかな誤り。愛媛大学第一内科に所属していたれっきとした医師)、この「小林慎治」が件の小林さんと同一かという保証はないんですが、医師-患者の信頼関係ができていないと、こういった感じの悪評立てられますね。(実際は、単なるちょっとした行き違いで患者さんが逆上して、腹いせに勢い任せで書いた、なんてのが多いんですが)

精神科なんて、こんな話は山ほどあるんで、いちいち気にしてたら身が持たないです(苦笑)。

(追記)これはある方tweet 。真偽のほどはわかりませんが、こういうことは医療現場ではよくあります。


それはともかく、旦那さんが受けた治療に大変深い憤りと不信感を持たれていることは伝わってきます。
このような事態を未然に防ぐのも医師の務めだと私は思っております。

Apple Watch の心電図アプリの計測データを外部に取り出す

iPhone の準備が整ったところで Apple Watch も導入。
6 シリーズの Nike モデルにした。


アルミスペースグレイの筐体に黒系のバンドにしたので「ちょっと重くなるかな?」と心配していたが、あまり強い自己主張なくすっきりとまとまっていてこれはこれでアリだと思うようになった。

ついでで書いておくとバンドはかなり容易に変えられるし、文字盤なども画面操作一発で変更できる。だから、購入アイテムの選択肢に迷ったとき、まず決めるべきは、シリーズ(モデル)筐体の材質と大きさと色だ。

 

それでは、本題。

私の興味の中心はやはり心電図アプリなんだが、その意義とか測定方法などは色々な人が様々なやり方で情報発信しているので、ここでは割愛。

Apple Watch で取得したデータは iPhone に送られるのだが、そのデータの取り出し方に関して書く。

手軽にできる方法は次の二通り。

PDF で書き出す

これはよく知られた方法。
ヘルスケア→心電図(ECG)→ PDF に書き出したいデータを選択
で、この画面になる。

「医師に渡すためにPDFを書き出す」をタップして適当なプリンタから打ち出すか、AirDrop などで Mac に PDF ファイルとして送りあとはファイルとして保管すればいい。

気の利いた医療者ならば、医療システム(電子カルテやPACSと呼ばれる画像サーバなど)のどこかに保管してくれる(はず)だ。

電子カルテにこのように貼ってもらえれば、心電図アプリも本望だろう。

 

PACS や画像ビューアなどにも「画像として」取り込むことはできる(後述するように「データとして」取り込む方がメリット大きいんですが)。

ちなみに PHR (Personal Health Record) という概念があり、今後は日本でも自分の医療データは自分で管理するという時代になると言われている。
今のところ、興味深い試みはあるもののなかなか実現できそうな感じがないんですが・・・。

ヘルスケアデータ全体を zip ファイルで取り出す

これはあまり知られていないかもしれないが、iPhone 内に記録されているヘルスケア系のデータを完全な形ですべて取ってこれるので、以下の方法は有用。

ヘルスケアアイコンをタップして概要のページが出てきたら、画面右上のユーザーアイコンをタップする。


すると次の画面に遷移するので、「すべてのヘルスケアデータを書き出す」を選べばよい。


データをどこに送るか iPhone が訊いてくるので、適当に選ぶ。
たぶん、一番簡単なのは AirDrop で Mac に送ること。
送受信が上手くいけば、Mac の「ダウンロード」フォルダ内に「書き出したデータ.zip」が送られているはずなので、これを解凍する。
apple_health_export フォルダがあるので、これを「書類」あたりに配置しておけばいいでしょう。
なお、心電図データは apple_health_export -> electrocardiograms フォルダ内に CSV ファイル形式で記録されています。
この方法のいい点は、(おそらく)生データが取得できるところ。

「データとして」情報が取って来れると2次的な利用もしやすくなる。
実は apple watch は心電図アプリを使って計測を始めると、生体からの電気シグナルを 1 秒間におおよそ 512 回程度サンプリングしており、そのデータを直接加工することができる。
例えば、


などというデータがあった場合、(この場合は)「S波が歪んでいるのでもうちょっと詳しくみてみたい」ということがある。
これは、適当なプログラムを組めば、以下のように実現できる。
(python という言語を使用。コードはここを参考にさせてもらった)

1550 〜 1650 回のサンプリング値のみを表示させているので、波形形状がより詳細に描かれているのがわかると思う。

もっとマニアックな方法

実は、上記二つ以外にもやり方はあるのだが、プログラミングまで踏み込まないと実現できないのでここでは説明は省略。

 

air-h-128k-il

 

OpenDolphin -wikipedia 風解説-

「医療用フリーソフト紹介」に OpenDolphin の項を追加しようかな?と思ってたら、LSC での販売終了のお知らせ

私がこの数奇?な運命を遂げたオープンソースの電子カルテに触ったのは比較的最近のことだ。具体的には、

猪股先生版 OpenDolphin https://github.com/Hiroaki-Inomata/OpenDolphin-2.7m

を最近の Mac 環境に導入したときからだ。
参考:『OpenDolphin-2.7(m) を Mac OSX にインストールする

だから、きっちりとした記載をしようとするとえらく手間がかかる。
「日本初の Open Source の電子カルテ」というのがウリだったようなのだが、この点に関して「おや」と気になったことがあったので、とりあえずはこの点を中心に気になったことを軽い感じでまとめていく。
なお、特別に断らない限り、ここでいう OpenDolphin とは Ver 2.7 系列のことです。

歴史

経産省の助成を受けて・・・云々の話はネットで探せば出てくると思うので、省く。
ただし、地域医療ネットワークで使われていた時代と開業医向けの商用電子カルテで使われていた時代とでは、運用形態や使われている技術が大きく異なるのでこの区別は重要。

商用利用されるようになってから、いわゆる「本家」と称されている dolphin-dev リポジトリの管理会社は

digital globe → Life Science Computing(LSC) → Medley(メドレー)

と変遷している。
ただ、調べていくと、LSC 時代のある時(2018頃?)から、開発方針や対外的な協力関係は大きく変わったようだ。
前半は、俗っぽい言い方をするなら「喧嘩っぱやい」会社。権利意識が強く、実際、訴訟などもおこしていた。
商標に関しては司法的な判断も公開されており、その解説などは以下の記事を参考にあげておきます。

オープンソースと知財権に関するちょっと小難しい話


要するに LSC OpenDolphin 派生版としてA社が DolphinEvolution というプロダクツを販売していたが、「これは OpenDolphin の周知性のタダノリである」として LSC がA社を訴えたもの。
残念ながら、その結果は意図していたようなものでなく、特許庁は LSC の訴えを退け、A 社の商標の保持を完全に認めている。その影響なのか、これ以降、開発体制なども刷新されたようだ。
後半は、うってかわってマイルドな路線に切り替わる。

電子カルテとしての特徴

よく
・カルテ2号用紙をメタファーとしたリッチな GUI
・使用頻度の多い項目を簡易にドラッグ&ドロップで入力できる「スタンプ」機能
が特徴としてあげられている。
これは見てもらった方が早いでしょうか。

ただし、現在(2021年)では、こういった特徴はブラウザ型の電子カルテなどにも取りいれられている。
開発時期を考えると当時としては医師目線で使いやすいシステムであったとは言えるでしょう。

技術的特徴

技術的な話も少々。
開発言語は Java で、maven で管理されている。client, common, server という三つのプロジェクトからなる。この名称から予想されるようにクライアント・サーバーシステムである。
基本となる設計は、典型的な MCV(Model-Controller-Viewer) の三層アーキテクチャである。
カルテ記載内容などを記録・保存しておく必要があるため、アプリケーションサーバー(WildFly)を介してデータベース(PostgreSQL)と連携して動作する。
保存形式を決めるモデルは、具体的には上記 common プロジェクト内の infomodel パッケージで定義されている。オブジェクトをデータベースに格納させる際には、ORM である hibernate を用いている。

なお、よく「Java で作成されているためマルチプラットフォームであり、クライアントが Windows/Mac/Linux で動作する」と紹介されているが、これはやや誤解を生む表現である。サーバープログラムも pure Java で書かれているため、適切に環境を整えればサーバープログラムを Windows/Mac/Linux に設置(デプロイ)し動作させることは可能である。

ライセンス

ところで、オープンソースにつきものといえばライセンスだが、当初は GPL というかなり制約の厳しいライセンスを主張していた。が、これも体制の刷新を契機に取り扱いを変えてきている。
もちろん GitHub のリポジトリで謳われているライセンスは現在(2021年1月)でも GPL だが、メドレー本社はこれが妥当なものであるかは明言していない。

なお、ライセンスは曖昧ながらも、他社の商用利用(soso の GlassDolphin と MIA の OpenDolphin)は原則許可、技術的特徴が明示されている猪股版(いわゆる OpenDolphin-2.7m)もその配布(や情報公開など)は許可されている。名称の利用に関しても、メドレー版との相違が誤認されないように情報公開されているなど適切に取り扱われていれば、許可されている。

これは以下のような事情があったためのようだ。

GitHub リポジトリでのプルリク・コードレビューがほぼない

この記事

開発者を限定する、というのはあってもいいのだが(ニッチな分野では不特定多数の開発者をアテにはできないことがしばしばある)、そうだとしてもプルリクやマージは普通に行われる。ところが、「イルカ」ではこのプロセスがつい最近まで一切なかった。ちょうど下請けや孫請けにつくらせたコードをそのままボンッとリポジトリに送りこむかのように突如としてバージョンアップ版が出現していた。

とあって、「んな、バカな」と思っていたのだが、調べたら本当だった。
こういう調べものをするとき、GitHub などの Git ホスティングサービスは便利で誰がいつどのような変更を行ったか容易に確かめることができる。
で、調べてみると・・・


確かにわずか3件。
また、この3件のうち GlassDolphin の linuxmania さんが送ったプルリクエスト(PR)は 2.6.3 時代のもので、2.7.0 アップデートにより現在ではほぼその痕跡は残していない。
MasudaNaika(増田茂医師) が送った診療区分に関する bug fix はマージ(merge プルリクエストを取り込むこと)されて、現在でも生きているが、merge されたのは 2018/6/4 のことだ。
猪股版 OpenDolphin-2.7m のソースコードがこの bug を取り除いた形で GitHub 上に公開されたのは 2016/7/12 のことだから、この修正がどれほどの意味を持つのかという気はする。
実際、現在(2021/7)では、https://www.opendolphin.com/ では以下のように増田氏の名前は見当たらない。

Ver 2.2.1 時代のソースコードも
GitHub: https://github.com/nekop/opendolphin
に残されているが、このバージョンに至っては PR の痕跡は一切ない。

オープンソースのプロジェクトとしては運営形態がかなり特殊だったという指摘はもっともに思える。

https://github.com/Hiroaki-Inomata/OpenDolphin-2.7m/network/members より

これは、猪股先生の OpenDolphin-2.7m の開発形態と比較するとわかりやすいかもしれない。
猪股先生のリポジトリにある
https://github.com/Hiroaki-Inomata/OpenDolphin-2.7m/
が Fork 元になって、いくつかのリポジトリに分岐(Fork 先)しているのがわかると思う。

Fork 先で新たな機能を実装したり bug fix などを行って Fork 元(上流ブランチ)にそのコードを取り込んで欲しい場合、行われるのが Pull Request (PR などと略される)というものだ。
私も Fork 後、PRを送ったことがある。
https://github.com/ANN2b-MD/OpenDolphin-2.7m
が Fork したリポジトリ。
Mac ビルド用に軽微な変更が必要があったため、ローカルでコードを修正した後、リモートのリポジトリに上げた。
以下のように PR → merge が行われた。
( https://github.com/Hiroaki-Inomata/OpenDolphin-2.7m/pull/6


このようなプロセスは GitHub 上の操作で比較的容易に実現できる。
この仕組みのおかげで、誰がいつどのような PR を行ったのか、また、それを merge する側はどのように評価(コードレビュー)したのかわかるようになっている。
上の場合は、コードレビューと言っても thanks だけですが(笑)。

通常のオープンソースのプロジェクトは、上記のように「本家」は大抵の場合、慣例的に一つであり、そこから各 Fork 先に枝分かれ状に分岐していく。逆に言えば、どれほど分岐しようとも、Fork 元をたどっていけば必ず一つの「源流」に行き着くことができる。
このように運営することのメリットは、分岐したブランチの開発者は誰でも本家に修正したコードを送ることができる、プロジェクトの最終産物(プロダクト)のバージョンの統一性が保たれる… などがある。
デメリットとしては、PR を送ったとしても必ずしも merge されるとは限らず、提案された機能などが最終プロダクトに取り込まれないといったことが挙げられる。
なお、dolphin-dev は、当初、このポリシーを取らず、ソースコード提供者を特定の開発者に限定していた。この痕跡は dolphin-dev の README の以下ような記載からも窺い知れる。


OpenDolphinにはコミッターが存在しません。フォークされた場合はそれぞれ独立した開発者になっていただき、 GitHub 等でソースの共有をお願いしています。

このような開発形態にしたため、機能の異なるいくつかのバージョンが存在するようになった。
現在でもソースが一般公開されている猪股バージョンのほか、

・入院対応が(部分的に)可能なバージョン
・音声入力機能を具備したバージョン
・クライアントでの処方箋出力機能を持ったバージョン

などがあったようである。

なかには、データベースレベルでの互換性がなくなっているバージョンもあり、メドレーから関係者に対して、この点に関しての注意がなされたという。

 

誰がソースコード提供者なのかわかりにくい

oracle のサンプルコードや公式には開発者とはされていない人のコードが散見される。

Junzo SATO 氏のコード

これは以前から指摘されていたのだが、もうちょっと網羅的に調べてみた。

Panel2.java (client project)
私のリポジトリであれば、
https://github.com/ANN2b-MD/OpenDolphin-2.7m/blob/master/client/src/main/java/open/dolphin/client/Panel2.java

/**
 *
 * @author  Junzo SATO
 */
public class Panel2 extends JPanel implements Printable {
	
    private String patientName;

    private boolean printName;
    
    private int height;
    
    /** Creates a new instance of Panel2 */
    public Panel2() {
    }

しっかり読んでいるわけではないが、クライアントのエディタ画面を実装しているパネルはこの Panel2 のクラスが基本となっていたはずだ。

その他は以下のファイルに同氏の名前が残っていた。

SchemaHolder.java (client project)

public final class SchemaHolder extends AbstractComponentHolder implements ComponentHolder {
    
    private SchemaModel schema;
    
    //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    // Junzo SATO
    // to restrict the size of the component,
    // setBounds and setSize are overridden.
    private final int fixedSize = 192;//160;/////////////////////////////////////////
    private final int fixedWidth = fixedSize;
    private final int fixedHeight = fixedSize;
    //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
    private boolean selected;
    
    private Position start;
    
    private Position end;
    
    private final KartePane kartePane;
    
    public SchemaHolder(KartePane kartePane, SchemaModel schema) {
        
        this.kartePane = kartePane;
        
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        // Junzo SATO
        // for simplicity, the acpect ratio of the fixed rect is set to 1.
        this.setDoubleBuffered(false);
        this.setOpaque(true);
        this.setBackground(Color.white);
        //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        this.schema = schema;
        //this.setImageIcon(schema.getIcon());
        setIcon(adjustImageSize(schema.getIcon(), new Dimension(fixedWidth, fixedHeight)));
        
    }

KarteViewer.java (client project)

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    // Junzo SATO
    public void printPanel2(final PageFormat format) {
        String name = getContext().getPatient().getFullName();
        boolean printName = true;
        if (pPane==null) {
            printName = printName && Project.getBoolean("plain.print.patinet.name");
        }
        panel2.printPanel(format, 1, false, name, getActualHeight()+60, printName);
    }

KarteEditor.java (client project)

   /**
     * Courtesy of Junzo SATO
     */
    private byte[] getJPEGByte(Image image) {

        byte[] ret = null;

        try {
            JPanel myPanel = getUI();
            Dimension d = new Dimension(image.getWidth(myPanel), image.getHeight(myPanel));
            BufferedImage bf = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_RGB);
            Graphics g = bf.getGraphics();
            g.setColor(Color.white);
            g.drawImage(image, 0, 0, d.width, d.height, myPanel);

            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            ImageIO.write(bf, "jpeg", bo);
            ret = bo.toByteArray();

        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
        return ret;
    }

いずれも、クライアントのエディター上でカルテを表示・記載する際、かなり基本的となる部分で、特に Panel2.java では @author Junzo SATO と authoship を放棄していないことから、この方の著作権表記は retain していないとまずいと思われます。
そして、この時点での OpenDolphin の開発担当者は皆川和史ですから、彼らの理屈(ソースコード提供者は、すべてクレジットされなければいけないというような主張)からすれば、それを怠った皆川は GPL 違反をしていることになります。

funabashi 氏のコード

これは比較的最近(2022 春頃)になって見つかった。(猪股先生のツィート参照)

この方のコードは探すとかなり大量に出てくるため、ここでは一例だけ挙げておきます。

IDocument2.java (server project)

// Module
ModuleModel soa = null;
ModuleModel p = null; // 20131206 add funabashi
if (model.getModules()!=null && model.getModules().size()>0) {

この箇所は OpenDolphin のデータ構造を決めているかなり基本的な部分です。

Junzo SATO 氏のコードにしても funabashi 氏のコードにしてもデータ構造のかなり基本的な部分に関与する部分で、基本設計のかなりの部分がこれまで公的には開発者としてアナウンスされていない人の手によるものであることが推測されます。

ORACLE のコード

これはわかりやすかった。
以下の open.dolphin.helper パッケージの SpringUtilities.java は、oracle が公開しているサンプルコード(https://docs.oracle.com/javase/tutorial/uiswing/examples/layout/SpringGridProject/src/layout/SpringUtilities.java)とファイル名も含めてまったく同一だったからだ。

/*
 * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle or the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 

package open.dolphin.helper;

import javax.swing.*;
import javax.swing.SpringLayout;
import java.awt.*;

/**
 * A 1.4 file that provides utility methods for
 * creating form- or grid-style layouts with SpringLayout.
 * These utilities are used by several programs, such as
 * SpringBox and SpringCompactGrid.
 */
public class SpringUtilities {
    /**
     * A debugging utility that prints to stdout the component's
     * minimum, preferred, and maximum sizes.
     */
    public static void printSizes(Component c) {
        System.out.println("minimumSize = " + c.getMinimumSize());
        System.out.println("preferredSize = " + c.getPreferredSize());
        System.out.println("maximumSize = " + c.getMaximumSize());
    }

けっこうあるもんですね。

 

なぜソースコード管理が曖昧になってしまったのか

当然、この疑問は湧く。
これは、歴史的経緯を考えると分かりやすいかもしれない。
OpenDolphin には、地域医療ネットワークのクライアントとして使われていた時期とそこから一種のコンバートをして開業医さん向けのローカルなシステムとして使われていた時期がある(その後、クラウド化されるが、データベースをクラウドに上げただけで構成の本質は大きく変わっていない)。
このとき、永続化システムの切り替えは必須になってくるが、その移行方法に技術的に若干無理があったのかもしれない。
現在のコード上からも確認できるが、ローカル版(オンプレミス版)ではカルテ記載内容をかなり強引にバイナリ化して、データベースに格納している。
ソースコードにあたればわかると思うが、ここらへんのコードは極めて見通しが悪く可読性も低い。
また(これは個人的な推測になるが)この移行で担当者間で技術的な意図がうまく伝わってなかったのではないかと思われる。

今後

まず、これまでの「本家」を引き継いだメドレーだが、今後、開発・販売を再開する予定はないとしている。
→結局、「運営などの権利はもつが積極的には普及させない」ということになったようですね。

一方、商用利用している組織は、今後も新機能を盛り込みながら、開発・サービスの提供を継続していくとのことである。

 

(適宜更新予定)

 

ANN2b

協力:猪股弘明

無症候性感染者が増えると感染爆発がおこるリスクが増大する

SNS でけっこう支持されたようなので、加筆・修正の上こちらにも転載。


感染症の数理モデルに興味持っている人意外に多いなと思ったんで、ちょっと書きます。(なお、私は感染症の専門家でもなんでもないです)

まず、感染症の数理モデルは既にいくつかあります。有名なのは SIR モデルや SEIR モデルでしょうか。https://ja.wikipedia.org/wiki/SIR%E3%83%A2%E3%83%87%E3%83%AB
あたりを参考に。


何やら、小難しそうですねw

でも、このように数学的に定式化することの利点はあって、それは計算機でシミュレーションできるということです。
ブラウザで使えるシミュレータも用意してあります。
よかったら
https://covid19-seir-model.netlify.app/
で遊んでみてください。

具体的な数値をどう入れていいかわからないって方は下図を参考にしてください。
現在の日本のコロナの感染状況を念頭において1億人の集団で、100万人感染者(緑)がいた場合に設定してます。

R=5.0
R=2.5

R をどう取るかが悩ましいのですが、ここではピークがどう変わるかわかりやすくするため R=2.5 と R=5.0 としました。(実際にはちょっと前-2020/12-で 1.1 。年明けの今はもうちょっと増えていると思います)
なお、ここでは簡便のため R=β/γ としてます。
γは定数(1/γ が平均感染期間)なので、β(感染率)を変化させることで R をコントロールしよう、というのが感染症コントロールの基本です。(私は感染症の専門家でもなんでもないので、日本の「専門家」とは説明の仕方が違うと思いますが、たぶん、数式的にはより忠実にモデルにそって説明していると思います)

ここまででも日本の感染症対策の問題点は幾つか出てくると思います。

・感染者を大雑把に100万人としたが、日本は検査絞り込んだおかげでこの推定が精度よくできない

・モデルとしてはβの方が本質的だが、一部の「専門家」がRtを重視しすぎたせいで、モデルに遡った考察ができにくくなっている

(R が固定値ではないのは理論に遡って考えると明らかでしょう。ウイルスが遺伝子レベルで変異をおこして感染力が変化した場合はもちろん感染のフェーズが変わっても後述するようにRは変化するはずです)
などなど。

一部のコロナ「専門家」と私が見解が異なるのは、「無症候性感染者が増えると、単純な接触制限しただけでは春先(第一波の時)ほど効果は出ない」という点です。

例えば、ある人が10人に接触したとして、そのうちの1人のみが感染者だったとする。その1人を検査で確定して隔離してしまえば、残りの9人といくら濃厚に接触しようが感染の拡大は起こりません(第一波の頃)。
ところが、9人のうち2人が実は「隠れ」感染者だった場合(現在これに近い状態になりつつあると私は思います)、今、注目している1人も感染する可能性が高くなります。もちろんこの場合は感染拡大は止まらないでしょう。

それはともかく、感染が急激に拡大しているときに過去データの延長(外挿)で Rt=1.1 として計算するのはちょっとおかしい・無理があるというのはご理解いただけるかなあと思います。

ついでで言っておくと、外国では年齢別・地域別にβなどを細かく設定して微分方程式に踏み込んでシミュレーションしてます。

駄文長文、失礼しました。

 

猪股弘明
医師:精神科(精神保健指定医)
HorliX, OpenDolphin-2.7m 開発者


🌟 参考
そもそも SEIR ってなんぞやって人は
感染症数理モデルの基本 SEIR をなるべく数式に頼らず直感的に理解する
をどうぞ。

🌟 質疑応答(某所ではこんな感じでした)
Q シミュレーションをどう活用したらいいか?

A シミュレーションってやりっ放しってわけにいはいかず、大抵の場合は検証作業が必要です。なのですが、現在、これはできにくい状況になってます。

例えば、今日(2021/1/14)の東京都の陽性者数は 1502人ですが、検査件数は(確定ではないが)3849 件。単純に陽性率計算すると 39%ほど(集計フローの混乱なのかちょっと高いですね)。検査件数が 10000件なら、3900人陽性者になる。

単純な SEIR シミュレーションで出てくる数値は、対象とした集団のなかでの暴露者数や感染者数だから、検証のためには「感染者数」の確定数値か無作為抽出に近い「陽性率」どちらかがわかっている必要があります。

Q 広島の取り組みについて、全否定されてるドクターがコメントされていました。PCR検査を確定診断するものであってスクリーニングするものではないと。

今後の検査ポリシーで何が正しいのかって難しいと思いますが、経路不明が過半数を超えた時点で、濃厚接触者中心の疫学的調査ってそれほど効果ないんですよ。

これダメなのは、分科会の「専門家」が「今は市中感染がメインとなってきたから、今後は◯◯の検査に切り替える」ってはっきり言わないことです。

Q なんとなくですが、市中感染が広がってるという事というのかクラスター潰しからの次の戦略への移行を分科会は認めたくないの?っていう印象を受けてるんですね。

A 認めたくないって言うのもあるだろうし、そもそも分科会のメンバーの能力を疑問視している医師は多いですよ。

例えば、上の SEIR でも大雑把な方針は見えてくるじゃないですか。上では単純に E としたけど、現実的には「潜在的な陽性者」あたりがこれに該当する。これがある程度数値的に評価できていないと次にどうなるって予測ができないし、政策への提言なんてのもできない。
「市中感染がこれくらい広がっているから、規制を強化しましょう」とか「緩和されてきたので、自粛対象を縮小しましょう」とかってのが、今、一番必要とされていることじゃないですか。
広島はそれを「特定地域の全数調査」で確かめようとしているし、厚労省の一部は「市街地での不特定多数への検査」で概数を掴もうとしている。やり方の良し悪しはともかく意図は明確です。
でも、これ、本来は分科会の専門家が率先して言わないといけないことですよね。

臨床現場だとなおさらそうですが、そういう想像力が働かないリーダーって無能扱いされるんですよ。