# 光る脳の動画から神経の活動を取り出す（全10回・1回15分・v1.1）

**この講座のゴール**：光る神経細胞の動画から、1つ1つの細胞の活動を数字にする。

> 英語で学びたい人は、最初に『Please teach this course in English.』と伝えてください。

**誰向け・何ができるようになるか**: 医学部・理系の学部生向けです。神経細胞が働くと光る様子を撮った動画から、細胞ごとの活動を取り出し、動物の行動と重ねて解析するまでの流れを、作り物のデータを自分の手で動かしながら説明できるようになります。最後の2回では、何週間もかけて同じ細胞を追いかける解析を、研究室が発表した解析の道具の考え方と、論文の公開データを使って確かめます。

---

## はじめに（この講座の使い方）

### これは何か
神戸大学大学院医学系研究科 神経生理学分野が、学生の自習用に公開している教材です。Markdown ファイル1本（このファイル）に全10回が入っています。

もとは、研究室に来た1年生の学生さんに「画像から、細胞ひとつひとつの動きを取り出してみたい」という希望に合わせて作った手引きです。その手引きで、つまずきやすかった所と、段を細かくして進めたらうまくいった所を、そのまま講座の形に直しました。**難しそうに見えることも、段を小さく分けて1つずつ進めば、1年生でも自分の手で届きます。** この講座は、そのことを確かめてもらうための教材でもあります。

### 対象（予備知識の目安）
- 高校の生物（神経が電気の信号を伝えること）と、高校の数学（指数・対数・平均）で足ります。
- 行列（数を縦横に並べた表）は第4回で一から説明します。
- Python（プログラミングの言語）を初めて触る人でも進められます。コードは全部、写して動かすだけで結果が出る形にしてあります。
- **コードを読まなくても進められます。** どの課題にも、前に「何を確かめる実験か」、後に「結果の読み方」を文で書いてあります。コードは、自分で確かめたくなった時の道具です。

### この講座の道のり（段差の小さい順）
| 段 | 回 | ここまで来たら言えること |
|---|---|---|
| 1. 光る仕組み | 第1・2回 | 「カルシウムは発火の代わりの目印」 |
| 2. 動画を整える | 第3回 | 「ずれを測って戻す」 |
| 3. 細胞を見つける | 第4・5回 | 「動画から、細胞1つぶんの時間の並びを1本取り出す」 **← ここまでで一区切り** |
| 4. 活動を読む | 第6・7回 | 「どこで・いつ働いたか」 |
| 5. 疑って確かめる | 第8回 | 「その相関・その p は本物か」 |
| 6. 何週間も追う | 第9・10回 | 「日をまたいで同じ細胞を合わせる」（CaliAli の考え方と公開データ） |

第5回まで進めば、「画像 → 細胞ごとの時間の並び」という、この分野でいちばん大事な変換を自分の手で通したことになります。そこで止めても、ひとつの達成です。

### 準備するもの
- 対話型の AI（チャットで質問に答えてくれるもの）。ファイルを読み込ませられるものが便利です。
- メモ（紙でも画面でも）。
- Python を動かせる環境。**無料でブラウザで動かせる環境でかまいません**（numpy という計算の道具が使えるもの）。手元に無い日は、AI に「出力の例」を見せてもらって読み取るだけでも進められます。
- 第10回だけ、論文の公開データ（2.35 MB のファイル1つ）をブラウザでダウンロードします。読み込みに h5py という道具を使います（無料のブラウザの環境の多くに入っています）。

### つまずいた時
- **動かなくてかまいません。** どこで止まったか（何回目の、どの課題の、どの行か）と、出た文字（エラーの文）をメモしておいてください。それを AI に貼れば、たいていは一往復で原因が分かります。
- 動かす環境の準備で詰まるのは、全員が通る道です。能力とは関係ありません。
- 試験や実習で忙しい時期は、止めてかまいません。止めることは遅れではありません。「第6回から再開してください」と打てば、続きから始められます。

### 進め方
1. このファイルを、対話型の AI に読み込ませます（読み込めない場合は、全文を貼り付けます）。
2. 「第1回を始めてください」と打ちます。
3. AI が先生役になって問いを出します。**自分の言葉で答えてください。** 間違えても大丈夫です。間違えた所が、いちばん身につく所です。
4. 1回は約15分で区切ります。次の日に「第2回を始めてください」と打って続けます。途中で止めた時は「第3回の課題から再開してください」のように頼めます。

### 注意
- **AI は間違えることがあります。** 大事な所（数値・定義・論文の中身）は、教科書や原典（下の参考文献）で確かめてください。
- **自分や他人の個人情報、診療の情報、他人のデータを AI に入れないでください。** この講座のデータは全部、講座の中の関数で作った作り物です。
- この講座は、医療上の助言を目的としていません。

### ★フィードバックのお願い（必ずお読みください）
**この講座は、使った人の声で毎回直しています。使った方は、必ずフィードバックをお送りください。**
- 送り先: 研究室ホームページの『連絡先』のページに載っているアドレス
- 件名: 「講座フィードバック：カルシウムイメージングの解析」
- 書いてほしい4点:
  1. 何回目まで進んだか
  2. 分かりにくかった所（回と場所）
  3. 良かった所
  4. 1回にかかった時間
- 1行だけでも助かります。

### 利用の条件
- 個人の学習、授業での利用は自由です。
- 改変して配る時は、研究室へご連絡ください。
- 内容は2026年11月時点のものです（第1.1版）。

---

## AI への指示（先生役のやり方）

この節は、このファイルを読み込んだ AI に向けた指示です。学習者は読み飛ばしてかまいません。

あなたは、この講座の先生役です。次を守って進めてください。

1. **1回は約15分で区切ります。** 学習者が「第N回を始めてください」と言ったら、その回の「この回のねらい」から始め、その回の終わりで止まります。
2. **1度に1つだけ問い、相手の答えを待ちます。** 問いを並べて出さないでください。
3. **答えを先に言わないでください。** 「確認の問い」の答えは、学習者が自分の答えを書いてから示します。各回の「AI 用：答えと考え方」の折りたたみは、そのための資料です。
4. 学習者が分からない様子なら、**一段やさしく言い直します**（身近なたとえ、小さな数での例）。それでも詰まったら、ヒントを1つだけ出します。
5. 「説明」の文は元の文です。そのまま読み上げず、対話で少しずつ崩して伝えてください。各回の説明は、問い→意外な答え→常識と例外、の順に組んであります。
6. 「手を動かす課題」のコードは、学習者に自分で動かしてもらいます。動かせない学習者には「出力の例」を見せ、数字の意味を読み取ってもらいます。コードを長々と1行ずつ解説するより、「この数字は何を意味するか」を問うてください。
7. 各回の終わりに、**要点を3つ**にまとめ、**ミニ確認問題を2問**出します（その回の「確認の問い」と別の、短い問いでかまいません）。
8. **次の回へ勝手に進まないでください。** 「次は第N+1回です。続けるときは『第N+1回を始めてください』と打ってください」と伝えて止まります。
9. 学習者が**医療の相談**や、**自分や他人の個人情報・診療の情報・他人のデータ**を書いたら、その内容は扱わずに、丁寧に断ってください（「この講座ではそれは扱えません。医療のことは医療機関に、データの扱いは指導の先生にご相談ください」）。
10. この文書に書かれていない数値や事実は作らないでください。確かでないことは「確かではないので、教科書や原典で確かめてください」と言ってください。
11. 学習者が『Please teach this course in English.』と言ったら、以後は英語で進めてください。
12. 講座を最後まで終えた学習者、または途中で止める学習者には、最後に「フィードバックのお願い」（件名と4点）を伝えてください。
13. **コードを見せる前に、「これは何を確かめる実験か」を1文で言ってください。** 学習者がコードに抵抗を示したら、コードは出さずに、各課題の「結果の読み方」の数字を使って、同じ問いを進めてください。コードを読まなくても、講座の筋は全部たどれるように書いてあります。
14. 学習者がエラーの文を貼ったら、先に「何回目の、どの課題の、何行目で止まったか」を確かめ、直す所を1つだけ示してください。環境の準備で詰まった学習者には、「全員が通る道で、能力とは関係ない」と伝えてください。
15. 第9・10回で研究室の論文（CaliAli）を扱う時は、この文書と論文・公式の説明書に書いてあることだけを話してください。論文に無い数値や、論文より強い言い方（「いつでも必ず当たる」など）は使わないでください。

---

## 第1回　カルシウムと神経の活動

**問い：神経の働きは電気なのに、なぜカルシウムを撮るのでしょうか？**
↓
**答え：電気の信号は速く小さく、たくさんの細胞から同時に測るのが難しいからです。カルシウムは発火のたびに細胞の中で一気に増え、ゆっくり引くので、カメラで追いかけられます。**

### この回のねらい
1. 細胞の中と外で、カルシウムの濃さが大きく違うことを知る。
2. 発火とカルシウムの関係（すぐ上がり、ゆっくり戻る）を、足し算の式で表せる。
3. カルシウムは発火の「代わりの目印」であって、発火そのものではないことを言える。

### 説明
神経細胞の信号は、活動電位（細胞の膜の電位が一瞬だけ跳ね上がる現象・「発火」とも言う）です。1回の長さは1ミリ秒ほど。電極を刺せば測れますが、一度に測れる細胞の数には限りがあります。

そこで目を付けたのがカルシウムです。細胞の中のカルシウムイオンの濃さは、ふだん約 0.0001 ミリモル（100 ナノモル）。細胞の外は約 1〜2 ミリモルです。外は中の1万倍ほど濃い。発火すると、膜にある「電位で開くカルシウムの通り道（チャネル）」が開き、外から一気に流れ込みます。中の濃さは何倍にも跳ね上がります。

戻るのは遅いのが特徴です。流れ込んだカルシウムは、ポンプでくみ出されたり、細胞の中の袋にしまわれたりして減っていきます。これに数百ミリ秒〜数秒かかります。速い電気の信号が、ゆっくりした「カルシウムの山」に引き伸ばされるわけです。カメラで撮るには、この遅さがかえって都合がよいのです。

この関係は、簡単な式で表せます。時刻 t のカルシウムを c_t、そのコマで起きた発火を s_t（起きたら1、起きなければ0）とすると、

> c_t ＝ g × c_(t−1) ＋ s_t

g は「1コマたっても残っている割合」です。戻る時間の目安を τ（タウ）秒、1秒に撮るコマの数を fs とすると、g ＝ exp(−1 ÷ (τ × fs)) です。前のコマの値に g を掛けて少し減らし、新しい発火のぶんを足す。お風呂の湯にたとえると、栓が少し開いていて湯がゆっくり減り（g）、ときどき蛇口から湯を足す（s）、という形です。

「それならカルシウムを見れば、発火がそのまま分かる」と思うかもしれません。しかし、そう簡単ではありません。理由は大まかに3つです。1つめ、短い間隔の連発は山が重なり、1つの大きな山に見えます。2つめ、発火しなくてもカルシウムが増えることがあります（つながった相手からの信号を受け取る所の通り道や、細胞の中の貯蔵庫から出るカルシウム）。3つめ、1回の発火の光は小さく、雑音に埋もれやすいのです。

**カルシウムは発火の「代わりの目印」です。** この講座の後半は、この目印から元の活動をどこまで取り戻せるか、という話になります。

**別の分野の言葉で言うと**（工学・情報・数学が得意な人向けの対応表。神経科学の言葉に慣れるまでの足場です）

| 神経科学の言葉 | こう思ってよい |
|---|---|
| 神経細胞（ニューロン） | 入力の合計がある線（しきい値）を超えると「1」を出し、超えなければ「0」のままの素子 |
| 活動電位（発火） | 情報の単位。一瞬だけ立つ「1」のできごと |
| つながりの強さ（シナプスの強さ） | 素子と素子のあいだの重み。これが変わることが「学習」にあたる |
| カルシウムの指示薬 | 変換器（センサー）。細胞の中のカルシウムの濃さを、光の明るさに変える |
| カルシウムの山 | 「1」のできごとを、ゆっくり減る形に引き伸ばしたもの（上の式の c） |

たとえは足場で、本物の神経細胞はもっと複雑です。ただ、画像の解析をする間は、この表で十分に進めます。

### 手を動かす課題
**(1) 手計算**
- 細胞の外を 1 ミリモル、中を 100 ナノモルとすると、外は中の何倍ですか（1 ミリモル ＝ 1,000,000 ナノモル）。
- τ ＝ 0.8 秒、fs ＝ 10 コマ/秒のとき、g はいくつですか。1秒（10コマ）たつと、最初の山の何割が残りますか（exp(−0.125) ≈ 0.88、exp(−1.25) ≈ 0.29 を使ってよい）。

**(2) コード**（写して動かす。発火の位置を `|`、カルシウムの量を `#` の長さで描きます）

```python
import numpy as np

fs = 10                         # 1秒に10コマ撮る
T = 6 * fs                      # 6秒分
spikes = np.zeros(T)
spikes[[5, 20, 23, 26, 45]] = 1 # 発火した瞬間（コマの番号）
tau = 0.8                       # 光が戻るまでの時間の目安（秒）
g = np.exp(-1 / (tau * fs))     # 1コマたっても残っている割合
ca = np.zeros(T)
for t in range(1, T):
    ca[t] = g * ca[t - 1] + spikes[t]
print("1コマで残る割合 g =", round(g, 3))
for t in range(T):
    mark = "|" if spikes[t] else " "
    print(f"{t / fs:4.1f}秒 {mark} " + "#" * int(round(ca[t] * 8)))
```

<details><summary>AI 用：出力の例（2026-11-02 に手元で動かした結果・抜粋）</summary>

```
1コマで残る割合 g = 0.882
 0.5秒 | ########
 ...
 2.0秒 | #########
 2.3秒 | ##############
 2.6秒 | ##################
 ...
 4.5秒 | ##########
```
2.0・2.3・2.6 秒の3回の発火は、山が重なって階段状に高くなる。4.5 秒の発火は、前の山がほぼ引いた後なので、1回ぶんの高さに戻る。
</details>

**結果の読み方**（コードを動かさなくても分かるように）: このコードは、6秒のあいだに5回発火した細胞のカルシウムを、上の足し算の式で計算して、量を記号の長さで描きます。1コマで残る割合は 0.882 です。0.5秒の1回だけの発火は、1回ぶんの高さの山になって、ゆっくり下がります。2.0・2.3・2.6秒の3回の連発は、前の山が引ききらないうちに次が足されるので、階段のように高くなり、最後は1回ぶんの2倍を超える高さになります。4.5秒の発火は、前の山がほぼ引いた後なので、また1回ぶんの高さに戻ります。

**つまずきやすい所**: 「山が3倍の高さだから、3回発火した」とは読めません。山の高さは、間隔が短いほど高く、指示薬が遅いほど高くなります。第6回で、山から発火を逆算する時にこの話が戻ってきます。

### 確認の問い
1. 2.0秒・2.3秒・2.6秒の3回の発火は、`#` の上でどう見えましたか。0.5秒の1回だけの発火と比べてください。
2. g が 0.99（ほとんど減らない）だったら、連発はどう見えるでしょうか。
3. 「カルシウムが上がった」なら「必ず発火した」と言えますか。

<details><summary>AI 用：答えと考え方</summary>

1. 山が重なり、階段のように高くなって1つの大きな山に見える。間隔が短いほど、何回発火したかを数えにくい。
2. 減るのが遅いので、連発はほぼ1本の高い台地のようにつながり、1回ずつ見分けるのはさらに難しくなる（指示薬が遅いほど同じことが起きる）。
3. 言えない。受け取る側の通り道や細胞の中の貯蔵庫からもカルシウムは増える。カルシウムは発火の代わりの目印にすぎない。
</details>

### まとめ
- 細胞の外のカルシウムは中の約1万倍。発火で流れ込み、ゆっくり引く。
- c_t ＝ g × c_(t−1) ＋ s_t という足し算の式で、カルシウムの山を表せる。
- カルシウムは発火そのものではなく、代わりの目印。

---

## 第2回　蛍光の指示薬と顕微鏡（1光子・2光子・小型顕微鏡）

**問い：細胞を光らせるには、光る薬を外から入れればよいのでしょうか？**
↓
**答え：今の主流は、細胞に「カルシウムで光るたんぱく質」を自分で作らせるやり方です。決まった種類の細胞だけを、何週間も光らせ続けられます。**

### この回のねらい
1. カルシウムの指示薬（カルシウムがつくと明るさが変わる物質）の2種類を知る。
2. 1光子と2光子の顕微鏡の違いを「焦点の外も光るかどうか」で言える。
3. 小型顕微鏡の長所と短所を言える。

### 説明
指示薬は大まかに2種類です。1つめは、外から入れる合成の色素。2つめは、遺伝子で細胞に作らせるたんぱく質です。代表は GCaMP（ジーキャンプ）で、緑に光るたんぱく質（GFP）に、カルシウムがつくと形が変わるたんぱく質（カルモジュリン）などをつないだものです（Nakai ら, 2001）。カルシウムがつくと形が変わり、明るさが増します。改良が重ねられ、速い型・遅い型・明るい型など、いくつもの種類があります（Chen ら, 2013）。速い型は連発を見分けやすく、遅い型は小さな変化を拾いやすい。どちらが良いかは、問いによって変わります。

次は顕微鏡です。

- **1光子の顕微鏡**（ふつうの蛍光顕微鏡）: 青い光を当てて、緑の光を出させます。光の通り道にある物はどれも光るので、焦点より上や下の光が「ぼやけ」として重なります。
- **2光子の顕微鏡**: 波長の長い光を、1兆分の1秒よりも短い、ごく短い光のパルスにして当てます。光る物質が2つの光子を同時に吸ったときだけ光るので、光がいちばん密な焦点の1点だけが光ります（Denk ら, 1990）。焦点の外がほとんど光らず、深い所まで見えます。その代わり、装置は大きく、動物の頭を固定して撮ることが多いのです。
- **小型顕微鏡**: 重さ数グラムの小さな顕微鏡を頭に載せ、自由に動き回る動物で撮ります（Ghosh ら, 2011）。脳の深い所は、細い棒状のレンズを差し込んで見ます。中身は1光子なので、ぼやけが大きく、動物の動きで画像も揺れます。そのかわり、歩く・探る・眠るといった自然な行動の最中に、同じ場所を何日も続けて撮れます。

「深く・くっきり撮れる2光子が、いつでも勝ち」と思うかもしれません。しかし、頭を固定した動物では、自由に歩き回る時の脳の働きは見られません。どの顕微鏡を選ぶかは、何を知りたいかで決まります。

1光子の画像では、血管が暗い筋として見えます。血管は日をまたいでもあまり形を変えないので、後の回（第9回）で、画像を合わせる目印として出てきます。

**1光子の画像では、細胞の光は「ぼやけの上に乗った小さな変化」です。** これが第4回・第5回で背景を引く理由になります。

### 手を動かす課題
**手計算**（電卓を使ってよい）
1光子の顕微鏡で、ある画素の明るさが「細胞の光 100 ＋ ぼやけ 400」だったとします。細胞の光が2倍（200）になると、画素の明るさは何%増えますか。
次に、2光子でぼやけが 20 しかない場合（100 ＋ 20）、細胞の光が2倍になると、画素の明るさは何%増えますか。

### 確認の問い
1. 2光子の顕微鏡で焦点の外がほとんど光らないのは、なぜでしょうか。
2. 小型顕微鏡を選ぶのは、どんな問いを立てた時でしょうか。例を1つ挙げてください。
3. 上の手計算の結果から、1光子のデータでは何をしないと、細胞の変化を小さく見積もってしまうでしょうか。

<details><summary>AI 用：答えと考え方</summary>

- 手計算: 1光子は (200＋400)÷(100＋400) ＝ 1.2 で20%増。2光子は (200＋20)÷(100＋20) ≈ 1.83 で約83%増。同じ「細胞が2倍」でも、ぼやけが大きいと変化は薄まって見える。
1. 2つの光子を同時に吸ったときだけ光る。2つが同時に届くほど光が密なのは焦点の近くだけなので、焦点だけが光る。
2. 例: 迷路を歩き回っている間の、場所と細胞の関係を知りたい。何日もかけて覚えていく間の、同じ細胞の変化を追いたい。眠っている間の活動を見たい。
3. ぼやけ（背景）を引くこと。引かないと、細胞の変化は薄まった値になる。
</details>

### まとめ
- 指示薬は「外から入れる色素」と「細胞に作らせるたんぱく質（GCaMP など）」。速さと明るさの取り合いがある。
- 2光子は焦点だけが光り、くっきり深く。1光子は焦点の外も光り、ぼやける。
- 小型顕微鏡は、自由に動く動物で何日も撮れる代わりに、ぼやけと揺れが大きい。

---

## 第3回　動画の中の動き補正

**問い：動物が動けば画像もずれます。少しくらいなら、たくさんのコマを平均すれば消えるのでしょうか？**
↓
**答え：消えません。平均するとかえってぼやけ、隣の細胞と混ざります。まず、ずれの大きさを測って、元の位置に戻します。**

### この回のねらい
1. ずれがあると何が困るかを言える。
2. 2枚の画像を少しずつずらして重ね、いちばんよく重なる位置から「ずれ」を測る方法（相互相関）を知る。
3. 平行移動だけでは直せないずれ（局所の変形・深さの変化）があることを知る。

### 説明
動画のある画素が、ある細胞を見ているとします。動物が首を振って画像が3画素ずれると、その画素は隣の細胞か、細胞のない所を見ることになります。細胞の明るさの変化と、ずれによる変化が、区別できなくなるのです。

直し方の基本は、基準の画像（最初の数百コマの平均など）を1枚決め、1コマずつ「どれだけずらすと基準とぴったり重なるか」を探すことです。重なりの良さは、2枚の画像の値を画素ごとに掛けて足した数（相互相関）で測ります。ずらし方を全部試すのは大変ですが、フーリエ変換（波の組み合わせに分ける計算）を使うと、全部のずらし方を一度に計算できます。理由はここでは深入りしません。「一度に全部試せる早道がある」とだけ覚えてください。

ずれには種類があります。

- **平行移動（剛体のずれ）**: 画像全体が同じだけ動く。
- **局所の変形（非剛体のずれ）**: 場所ごとにずれ方が違う。画像を小さな区画に分け、区画ごとに合わせてからつなぐ方法があります（Pnevmatikakis と Giovannucci, 2017）。
- **深さのずれ**: 焦点の深さが変わると、別の細胞が見えてしまいます。平面の中で動かしても直せません。

1光子の動画では、細胞は光ったり消えたりするので、目印としては不安定です。形の変わらない模様（血管など）を目印にすると、合わせやすくなります。

「計算で直したのだから、もう大丈夫」と思うかもしれません。しかし、直した後の動画は必ず目で見て確かめます。平均の画像がくっきりしたか、細胞の輪郭がにじんでいないかを見るのです。

### 手を動かす課題
作り物の視野（ぼやけた丸＝細胞12個、斜めの暗い筋＝血管1本）を作り、わざとずらしてから、ずれを測って戻します。

```python
import numpy as np

rng = np.random.default_rng(3)

def make_frame(H=64, W=64):
    """作り物の視野：ぼやけた丸（細胞）12個と、斜めの暗い筋（血管）1本"""
    yy, xx = np.mgrid[0:H, 0:W]
    img = np.full((H, W), 10.0)
    for _ in range(12):
        cy, cx = rng.uniform(8, H - 8), rng.uniform(8, W - 8)
        img += 20 * np.exp(-((yy - cy) ** 2 + (xx - cx) ** 2) / (2 * 2.0 ** 2))
    img -= 6 * np.exp(-((yy - 0.6 * xx - 10) ** 2) / (2 * 1.5 ** 2))
    return img

def find_fix(ref, img):
    """img をどれだけ動かせば ref に重なるか（縦, 横）を、相互相関の山から探す"""
    F = np.fft.fft2(ref - ref.mean())
    G = np.fft.fft2(img - img.mean())
    cc = np.real(np.fft.ifft2(F * np.conj(G)))
    dy, dx = np.unravel_index(np.argmax(cc), cc.shape)
    H, W = ref.shape
    if dy > H // 2:
        dy -= H
    if dx > W // 2:
        dx -= W
    return int(dy), int(dx)

ref = make_frame()
for sy, sx in [(0, 0), (2, -1), (-3, 4), (5, 2), (-1, -5)]:
    moved = np.roll(ref, (sy, sx), axis=(0, 1)) + rng.normal(0, 1.0, ref.shape)
    dy, dx = find_fix(ref, moved)
    fixed = np.roll(moved, (dy, dx), axis=(0, 1))
    before = np.abs(moved - ref).mean()
    after = np.abs(fixed - ref).mean()
    print(f"ずれ {(sy, sx)} → 直す量 {(dy, dx)}   差 {before:.2f} → {after:.2f}")
```

<details><summary>AI 用：出力の例（2026-11-02 に手元で動かした結果）</summary>

```
ずれ (0, 0) → 直す量 (0, 0)   差 0.80 → 0.80
ずれ (2, -1) → 直す量 (-2, 1)   差 1.91 → 0.81
ずれ (-3, 4) → 直す量 (3, -4)   差 2.77 → 0.80
ずれ (5, 2) → 直す量 (-5, -2)   差 2.93 → 0.78
ずれ (-1, -5) → 直す量 (1, 5)   差 2.72 → 0.79
```
「差」は基準との違いの平均。直すと、どのずれでも 0.8 前後（足した雑音の大きさ）まで下がる。
</details>

**結果の読み方**: このコードは、細胞12個と血管1本の作り物の画像を作り、それをわざと縦横に数画素ずらしてから、どれだけ戻せば元に重なるかを計算で探します。試した5通りのずれ（ずれ無し・(2, −1)・(−3, 4)・(5, 2)・(−1, −5) 画素）は、5通りとも、ずれと正反対の量がぴったり見つかりました。基準の画像との違いは、ずらした直後は 1.9〜2.9 ほどでしたが、戻すとどれも 0.8 前後まで下がりました。0.8 は、わざと足した雑音の大きさです。ずれ無しの時も 0.80 のままなので、「雑音より下には下がらない」ことも分かります。

**つまずきやすい所**: 直す量の符号の向き（右へずれたら左へ戻す）で、一度は必ず混乱します。紙に小さな方眼を描いて、点を1つ動かしてみると、すぐに分かります。

### 確認の問い
1. 「直す量」は、いつも「ずれ」の符号を反対にした値でした。なぜでしょうか。
2. 直した後の差が 0 にならず、0.8 前後で止まるのはなぜでしょうか。
3. 動物が動いた拍子に焦点の深さが変わったら、この方法で直せるでしょうか。

<details><summary>AI 用：答えと考え方</summary>

1. 右へ3画素ずれた画像を元に戻すには、左へ3画素動かす。ずれと逆向きに同じだけ動かすのが「直す」こと。
2. 作り物の画像に、わざと雑音（ばらつき）を足したから。雑音は動かしても消えない。差がそこまで下がれば、ずれは取れたと言える。
3. 直せない。別の深さの細胞が見えているので、平面の中で動かしても同じ細胞には戻らない。そういうコマは目で見つけて、解析から外すことがある。
</details>

### まとめ
- ずれたままだと、細胞の明るさの変化とずれによる変化が混ざる。
- 2枚の画像をずらして重ね、いちばんよく重なる位置から「ずれ」を測り、逆向きに戻す。
- 局所の変形・深さのずれもある。直した後は必ず目で確かめる。

---
## 第4回　細胞を見つける（ROI と行列分解の考え方）

**問い：細胞の場所に丸を描き、その中の明るさを平均すれば、細胞の活動は取れるのでしょうか？**
↓
**答え：重なった細胞やぼやけが混ざります。動画全体を「細胞の形 × 時間の動き」の足し算に分けると、重なった細胞も分けられます。**

### この回のねらい
1. ROI（関心領域：解析したい場所を囲んだ範囲）の考え方と、その弱点を言える。
2. 動画を「画素 × 時刻」の大きな表（行列）として見られる。
3. 行列分解（大きな表を、小さな表の掛け算に分けること）で、細胞の形と時間の動きを取り出す考え方を知る。

### 説明
動画は「縦 × 横 × 時間」の数の箱です。画素を1列に並べ直すと、行が画素、列が時刻の大きな表になります。数学では、こういう表を行列と呼びます。

いちばん素直な方法は ROI です。画像の上で細胞に丸を描き、丸の中の明るさを時刻ごとに平均します。簡単で分かりやすい方法です。ただし弱点が2つあります。1つめ、細胞どうしが重なっていると、隣の細胞の光が混ざります。2つめ、ぼやけ（背景）もそのまま混ざります。

そこで、合唱の録音を思い浮かべてください。録音には全員の声が混ざっています。でも、ソプラノは左、バスは右、のように立ち位置が決まっていて、それぞれが自分のメロディを歌っています。「立ち位置（形）」と「メロディ（時間の動き）」の組をいくつか見つけて、掛けて足せば録音が再現できる。そういう組を探すのが行列分解です。式で書くと、

> Y（動画：画素 × 時刻） ≈ A（形：画素 × 細胞） × C（時間の動き：細胞 × 時刻） ＋ 背景

明るさはマイナスにならないので、「AもCもマイナスにならない」という条件をつけて分けるやり方を、非負値行列因子分解（NMF）と呼びます（Lee と Seung, 1999）。カルシウムイメージングでは、主成分分析と独立成分分析を組み合わせる方法（Mukamel ら, 2009）や、形や時間の動きに条件をつけた行列分解（CNMF：Pnevmatikakis ら, 2016）、1光子の大きなぼやけを上手に表す改良版（CNMF-E：Zhou ら, 2018）が広く使われています。

「機械が分けてくれるなら、出てきた成分は全部細胞」と思うかもしれません。しかし、成分の中には背景や、細胞でない物（突起の束・雑音）も混ざります。最後は人が目で見て、細胞でない成分を消す段があります。

**ROI は「場所を決めて平均する」、行列分解は「混ざった動画を形と動きの組に分ける」。**

### 手を動かす課題
4つの細胞（うち2つは重なっている）の作り物の動画を作り、ROI と行列分解（NMF）で取り出した波形を、本当の活動と比べます。

```python
import numpy as np

rng = np.random.default_rng(4)
H, W, T = 32, 32, 600
yy, xx = np.mgrid[0:H, 0:W]
centers = [(8, 8), (12, 20), (14, 23), (24, 12)]   # 細胞1と細胞2は重なっている
A = np.stack([np.exp(-((yy - cy) ** 2 + (xx - cx) ** 2) / (2 * 2.5 ** 2)).ravel()
              for cy, cx in centers], axis=1)       # 画素 × 細胞（形）
def trace(rate):
    s = (rng.random(T) < rate).astype(float)
    c = np.zeros(T)
    for t in range(1, T):
        c[t] = 0.9 * c[t - 1] + s[t]
    return c
C = np.stack([trace(r) for r in [0.02, 0.03, 0.02, 0.025]])   # 細胞 × 時刻（時間の動き）
Y = A @ C + 0.5 + rng.normal(0, 0.15, (H * W, T))              # 動画（画素 × 時刻）
Y = np.clip(Y, 0, None)
K = len(centers)

# (1) ROI：細胞1の中心のまわり半径3画素の平均を取る
cy, cx = centers[1]
roi = ((yy - cy) ** 2 + (xx - cx) ** 2 <= 3 ** 2).ravel()
f_roi = Y[roi].mean(axis=0)
print("ROI の波形と、本当の細胞0〜3との相関:",
      [round(float(np.corrcoef(f_roi, C[j])[0, 1]), 2) for j in range(K)])

# (2) 行列分解（NMF）：Y ≈ A_hat @ C_hat を、かけ算の更新を繰り返して探す
Kfit = K + 1                     # 細胞4つ＋背景1つぶん
A_hat = rng.random((H * W, Kfit))
C_hat = rng.random((Kfit, T))
for it in range(500):
    C_hat *= (A_hat.T @ Y) / (A_hat.T @ A_hat @ C_hat + 1e-9)
    A_hat *= (Y @ C_hat.T) / (A_hat @ C_hat @ C_hat.T + 1e-9)
print("説明しきれずに残った割合:", round(float(np.linalg.norm(Y - A_hat @ C_hat) / np.linalg.norm(Y)), 3))
for k in range(Kfit):
    r = [np.corrcoef(C_hat[k], C[j])[0, 1] for j in range(K)]
    py, px = np.unravel_index(np.argmax(A_hat[:, k]), (H, W))
    print(f"成分{k}: 明るい中心 ({py:2d},{px:2d})  いちばん似た細胞 {int(np.argmax(r))}  相関 {max(r):.2f}")
```

<details><summary>AI 用：出力の例（2026-11-02 に手元で動かした結果）</summary>

```
ROI の波形と、本当の細胞0〜3との相関: [0.01, 0.91, 0.42, -0.08]
説明しきれずに残った割合: 0.26
成分0: 明るい中心 (10,20)  いちばん似た細胞 1  相関 0.01
成分1: 明るい中心 (24,12)  いちばん似た細胞 3  相関 0.98
成分2: 明るい中心 ( 8, 8)  いちばん似た細胞 0  相関 0.96
成分3: 明るい中心 (12,20)  いちばん似た細胞 1  相関 0.92
成分4: 明るい中心 (14,23)  いちばん似た細胞 2  相関 0.92
```
ROI の波形は細胞1（0.91）だけでなく、重なった細胞2とも 0.42 似てしまう。NMF の成分1〜4は4つの細胞をそれぞれ取り出し（相関 0.92〜0.98）、成分0 はどの細胞とも似ない＝背景。成分の番号の順は毎回変わり得る（意味は無い）。残った割合 0.26 は主に足した雑音。
</details>

**結果の読み方**: このコードは、細胞4つ（うち細胞1と細胞2は少し重なっている）の作り物の動画を作り、2つのやり方で細胞1の活動を取り出して、本当の活動と比べます。丸を描いて平均する ROI のやり方では、細胞1との相関は 0.91 と高いのに、重なった隣の細胞2とも 0.42 似てしまいました。隣の光が丸の中に入りこんだからです。動画を「形 × 時間の動き」の組に分けるやり方（NMF）では、5つの成分のうち4つが4つの細胞にそれぞれ対応し、本当の活動との相関は 0.92〜0.98 でした。残りの1つはどの細胞とも似ない成分で、全体に一様に乗せた明るさ（背景）を受け持っていました。

**つまずきやすい所**: 行列の掛け算の向き（画素 × 細胞 と 細胞 × 時刻 を掛けると 画素 × 時刻）で迷ったら、表の縦と横の名前だけを書き出して、真ん中の「細胞」が消えることを確かめてください。数を入れなくても、名前だけで掛け算の形が分かります。

### 確認の問い
1. ROI の波形が、細胞1だけでなく細胞2とも似てしまったのはなぜでしょうか。
2. 成分の数を「細胞4つ＋1つ」の5つにしたのはなぜでしょうか。4つにしたら、何が起きそうでしょうか。
3. 本物のデータでは、細胞がいくつあるか分かりません。成分の数はどう決めればよいでしょうか。

<details><summary>AI 用：答えと考え方</summary>

1. 細胞1と細胞2が重なっていて、細胞1の丸の中に細胞2の光も入るから。丸の中の平均は、混ざった光の平均になる。
2. 背景（どこも一様に明るい 0.5）を受け持つ成分が要るから。4つにすると、背景がどこかの細胞の成分に混ざり、その細胞の波形がゆがむ（または2つの細胞が1つにまとめられる）。
3. 正解は1つではない。よく使われるのは、多めに取ってから、形が細胞らしくない成分・時間の動きが雑音のような成分を、目で見て（または決めた基準で）消すやり方。消す基準は解析の前に決めておく。
</details>

### まとめ
- 動画は「画素 × 時刻」の行列。ROI は丸の中を平均するが、重なりと背景が混ざる。
- 行列分解は、動画を「形 × 時間の動き」の組に分け、重なった細胞も分けられる。
- 出てきた成分には背景や細胞でない物も混ざる。最後は人が確かめる。

---

## 第5回　蛍光の変化 ΔF/F（デルタ・エフ・オーバー・エフ）

**問い：明るさの数字そのものを比べれば、どの細胞がよく働いたか分かるのでしょうか？**
↓
**答え：分かりません。細胞ごとに指示薬の量も、深さも、ぼやけも違うからです。そこで「その細胞のふだんの明るさから、何割増えたか」で比べます。**

### この回のねらい
1. ΔF/F ＝ (F − F0) ÷ F0 の意味を言える。
2. ふだんの明るさ F0 の決め方（動く窓の中の下の方の値）を知る。
3. まわりのぼやけ（ニューロピル）を引く理由と、引き方の考え方を知る。

### 説明
試験の点で考えてみます。ふだん60点の人の80点と、ふだん90点の人の80点。同じ80点でも、意味はまったく違います。比べるべきは「自分のふだんから、どれだけ上がったか」です。

蛍光でも同じです。ある時刻の明るさを F、その細胞のふだんの明るさを F0 として、

> ΔF/F ＝ (F − F0) ÷ F0

と計算します。ΔF/F が 0.5 なら「ふだんより5割明るい」です。

F0 の決め方には、2つの落とし穴があります。1つめ、全体の平均を F0 にすると、発火した時間の明るさも混ざり、基準が高めに出ます。2つめ、光は撮っている間にだんだん弱まります（褪色：光る物質が少しずつ壊れて暗くなること）。全体で1つの基準だと、後半ほど低く見えてしまいます。そこで、各時刻の前後数十秒の窓の中で「下から10%くらいの値」を、その時刻の F0 にするやり方がよく使われます。発火していない時の値に近く、ゆっくりした暗くなり方にもついていけるからです。

もう1つ、細胞のまわりのぼやけ（ニューロピル：細胞の外の、神経の突起が密に集まった所から来る光）が、細胞の明るさに混ざります。2光子のデータでは、細胞のまわりの輪の明るさに係数（0.7 前後がよく使われます）を掛けて引くやり方が一般的です。1光子のデータではぼやけが大きいので、第4回の行列分解の中で背景ごと表して分けることが多くなります。

「引けば引くほどきれいになる」と思うかもしれません。しかし、引きすぎると値がマイナスになり、F0 が小さい細胞では ΔF/F が大きく暴れます。係数は、装置とデータで変わります。

### 手を動かす課題
褪色とまわりのぼやけが混ざった作り物の測定値から、3つのやり方で ΔF/F を作り、本当の活動と比べます。「静かな時間のばらつき」は、発火していない時間の値の揺れ（小さいほど良い）です。

```python
import numpy as np

rng = np.random.default_rng(5)
fs, T = 10, 3000                    # 10コマ/秒で5分
t = np.arange(T) / fs
s = (rng.random(T) < 0.01).astype(float)
c = np.zeros(T)
for i in range(1, T):
    c[i] = 0.92 * c[i - 1] + s[i]
bleach = 100 * (1 - 0.15 * t / t[-1])                       # 光がだんだん弱まる（褪色）
neuropil = 30 + 8 * np.sin(2 * np.pi * t / 40) + rng.normal(0, 1, T)   # まわりのぼやけ
F_cell = bleach * (1 + 0.3 * c)                             # 細胞そのものの光
F_roi = F_cell + 0.7 * neuropil + rng.normal(0, 2, T)       # ROI で測った値

def dff(F, win=300, q=10):
    """ΔF/F：前後 win コマの中で下から q% の値を、その時刻の基準 F0 にする"""
    F0 = np.array([np.percentile(F[max(0, i - win // 2): i + win // 2], q) for i in range(len(F))])
    return (F - F0) / F0

quiet = c < 0.05                                            # 発火していない時間
for name, x in [("全体の平均で割っただけ", (F_roi - F_roi.mean()) / F_roi.mean()),
                ("動く基準のΔF/F", dff(F_roi)),
                ("まわりを引いてからΔF/F", dff(F_roi - 0.7 * neuropil))]:
    print(f"{name:14s} 本当の活動との相関 {np.corrcoef(x, c)[0, 1]:.2f}"
          f"   静かな時間のばらつき {x[quiet].std():.3f}")
```

<details><summary>AI 用：出力の例（2026-11-02 に手元で動かした結果）</summary>

```
全体の平均で割っただけ    本当の活動との相関 0.79   静かな時間のばらつき 0.052
動く基準のΔF/F      本当の活動との相関 0.87   静かな時間のばらつき 0.036
まわりを引いてからΔF/F  本当の活動との相関 0.95   静かな時間のばらつき 0.023
```
動く基準にすると褪色の影響が減り、まわりを引くとぼやけの揺れが減る。この作り物では引く係数（0.7）を正解で知っているが、本物のデータでは係数は推定するしかない。
</details>

**結果の読み方**: このコードは、5分間の作り物の測定値（だんだん暗くなる褪色と、まわりのぼやけが混ざったもの）から、3つのやり方で ΔF/F を作り、本当の活動と比べます。全体の平均で割っただけだと、本当の活動との相関は 0.79、発火していない時間の揺れは 0.052 でした。各時刻の前後の「下から10%」を基準にすると 0.87 と 0.036 に、さらにまわりのぼやけを引くと 0.95 と 0.023 になりました。手を1つ加えるごとに、本当の活動に近づき、静かな時間の揺れが小さくなっています。

**ここまでで一区切り**: 第4回と第5回で、「動画 → 細胞1つぶんの時間の並び（ΔF/F）」という変換を、自分の手で通したことになります。この分野でいちばん大事な一歩で、ここから先は全部、この時間の並びをどう読むかの話です。

### 確認の問い
1. F0 を「平均」ではなく「下から10%の値」にしたのはなぜでしょうか。
2. 窓（win）を短くしすぎると、何が起きそうでしょうか。
3. ある細胞の ΔF/F が 0.5、別の細胞が 0.2 でした。「前の細胞の方が2.5倍たくさん発火した」と言えるでしょうか。

<details><summary>AI 用：答えと考え方</summary>

1. 平均には発火した時間の明るさも入り、基準が上がる。下の方の値は、発火していない時の明るさに近い。
2. 長く続く活動の間に、基準まで一緒に上がってしまい、活動が小さく（または消えて）見える。窓は、活動の長さより十分に長くする。
3. 言えない。指示薬の量や種類、細胞の性質で、1回の発火あたりの ΔF/F は違う。ΔF/F は「その細胞のふだんから何割」であって、発火の回数そのものではない（第6回）。
</details>

### まとめ
- ΔF/F は「その細胞のふだんの明るさから何割増えたか」。細胞どうしを比べるための物差し。
- F0 は、動く窓の中の下の方の値にすると、褪色にも発火にも引っぱられにくい。
- まわりのぼやけは引く。ただし引きすぎ・小さい F0 に注意。

---

## 第6回　活動の推定（スパイク推定の考え方）

**問い：カルシウムの山の数を数えれば、発火の回数になるのでしょうか？**
↓
**答え：なりません。山は重なり、雑音でも小さな山ができます。山から発火を逆算するのは「推定」で、見逃しと空振りの取り合いになります。**

### この回のねらい
1. 第1回の足し算の式を逆に解いて、発火を推定する考え方を知る。
2. 雑音があると、線（しきい値）の高さで「見逃し」と「空振り」が取り合いになることを体験する。
3. 推定した値を、どんな意味で使えばよいかを言える。

### 説明
第1回の式を思い出してください。

> c_t ＝ g × c_(t−1) ＋ s_t

これを s について解くと、

> s_t ＝ c_t − g × c_(t−1)

です。「今の値」から「前から残っているぶん」を引けば、新しく足されたぶん、つまり発火が出てくる。お風呂で言えば、湯の高さの記録と栓から抜ける速さが分かれば、いつ蛇口から湯を足したかを逆算できる、ということです。

雑音が無ければ、これで完全に当たります。ところが測った値には雑音が乗ります。引き算をすると、2つの時刻の雑音が両方入るので、雑音はかえって大きくなります。そこで「ある線より大きい所だけを発火とみなす」ことにします。線を低くすると見逃しは減りますが、雑音を発火と間違える空振りが増えます。線を高くすると、その逆です。

実際の方法では、「発火はマイナスにならない」「発火はまばらに起きる」という条件をつけて、いちばんもっともらしい発火の並びを探します（FOOPSI：Vogelstein ら, 2010／OASIS：Friedrich ら, 2017）。こうした方法を、電極で同時に測った本物の発火と比べた研究もあります（Berens ら, 2018）。1発ずつ正確に数えるのは、今でも難しいのが実情です。

「推定の方法が進めば、いつか完全に当たる」と思うかもしれません。しかし、雑音に埋もれた小さな山は、どんな方法でも区別できない場合があります。推定した値は「発火の量とタイミングの目安」として扱うのが安全です。

**山から発火を逆算するのは推定。線の高さで、見逃しと空振りが取り合いになる。**

### 手を動かす課題
本当の発火を知っている作り物の波形で、雑音の大きさと線の高さを変え、当たり・見逃し・空振りを数えます。

```python
import numpy as np

rng = np.random.default_rng(6)
T, g = 1200, 0.9
s_true = (rng.random(T) < 0.03).astype(float)
c = np.zeros(T)
for t in range(1, T):
    c[t] = g * c[t - 1] + s_true[t]

def count(s_hat, thr):
    found = s_hat > thr
    hit = int(np.sum(found & (s_true > 0)))      # 当たり
    miss = int(np.sum(~found & (s_true > 0)))    # 見逃し
    false = int(np.sum(found & (s_true == 0)))   # 空振り
    return hit, miss, false

print("本当の発火:", int(s_true.sum()), "回")
for noise in [0.05, 0.3]:
    y = c + rng.normal(0, noise, T)
    s_hat = np.r_[0, y[1:] - g * y[:-1]]          # 今の値 − 前から残っているぶん
    for thr in [0.5, 0.8, 1.1]:
        print(f"雑音 {noise}  線 {thr}: 当たり・見逃し・空振り = {count(s_hat, thr)}")
```

<details><summary>AI 用：出力の例（2026-11-02 に手元で動かした結果）</summary>

```
本当の発火: 30 回
雑音 0.05  線 0.5: 当たり・見逃し・空振り = (30, 0, 0)
雑音 0.05  線 0.8: 当たり・見逃し・空振り = (30, 0, 0)
雑音 0.05  線 1.1: 当たり・見逃し・空振り = (3, 27, 0)
雑音 0.3  線 0.5: 当たり・見逃し・空振り = (28, 2, 129)
雑音 0.3  線 0.8: 当たり・見逃し・空振り = (21, 9, 22)
雑音 0.3  線 1.1: 当たり・見逃し・空振り = (12, 18, 8)
```
雑音 0.05 では線 0.5・0.8 で全部当たるが、線 1.1 は発火1回ぶんの高さ（1.0）より上なので27回見逃す。雑音 0.3 では、線を上げるほど空振りが減り（129→22→8）、見逃しが増える（2→9→18）。
</details>

**結果の読み方**: このコードは、本当は30回発火した作り物の細胞のカルシウムに雑音を足し、「今の値 − 前から残っているぶん」で発火を逆算して、線の高さを3通りに変えながら、当たり・見逃し・空振りを数えます。雑音が小さい時（0.05）は、線が 0.5 でも 0.8 でも30回全部が当たり、空振りは0回でした。線を 1.1 にすると、発火1回ぶんの高さ（1.0）より上なので、27回を見逃しました。雑音が大きい時（0.3）は、線を 0.5 → 0.8 → 1.1 と上げるにつれて、空振りは 129 → 22 → 8 回と減り、見逃しは 2 → 9 → 18 回と増えました。両方を同時に0にする線は、ありません。

### 確認の問い
1. 雑音 0.05・線 0.5 では全部当たるのに、雑音 0.3 では崩れたのはなぜでしょうか。また、雑音 0.05 でも線 1.1 では27回見逃したのはなぜでしょうか。
2. 線を高くすると、何が減って、何が増えましたか。研究の目的によって、どちらを重く見るかは変わるでしょうか。
3. g を本当の値（0.9）ではなく 0.5 と間違えて引き算したら、何が起きそうでしょうか。

<details><summary>AI 用：答えと考え方</summary>

1. 引き算 c_t − g × c_(t−1) で、2つの時刻の雑音が両方入り、雑音がかえって大きくなる。雑音 0.3 では、引いた後の揺れが発火1回ぶん（1.0）に近づき、区別がつきにくい。線 1.1 の見逃しは、線が発火1回ぶんの高さ（1.0）より上にあるため。線は雑音の大きさと発火の大きさの両方を見て決める。
2. 線を高くすると空振りが減り、見逃しが増える。例: 「確かに発火した所だけを使いたい」なら空振りを減らす側、「少しでも反応した細胞を拾いたい」なら見逃しを減らす側を重く見る。目的に応じて決め、解析の前に決めておく。
3. 前から残っているぶんを引き足りないので、山の下り坂（減っていく途中）まで新しい発火に見え、空振りが増える。g（戻る速さ）を正しく知ることが大事で、実際の方法ではデータから g も推定する。
</details>

### まとめ
- 発火の推定は、足し算の式を逆に解く「今 − 前から残るぶん」が出発点。
- 雑音があると、線の高さで見逃しと空振りが取り合いになる。
- 推定した値は、発火の量とタイミングの目安として使う。

---

## 第7回　行動と重ねる（場所細胞の例）

**問い：脳の細胞は、自分がどこにいるかを知っているのでしょうか？**
↓
**答え：海馬（記憶に関わる脳の部分）のある細胞は、通路の決まった場所に来た時だけ働きます。1971年に見つかった「場所細胞」で、2014年のノーベル生理学・医学賞につながりました。**

### この回のねらい
1. 場所ごとの活動の地図を、「いた時間で割る」ことで作れる。
2. 空間情報量（その細胞の活動を見れば、居場所がどれだけ絞れるか）の考え方を知る。
3. くじ引き（時間をずらして、位置との対応だけを壊す）で、偶然と比べる方法を使える。

### 説明
場所細胞は、ラットの海馬で電極を使って見つかりました（O'Keefe と Dostrovsky, 1971）。2014年のノーベル生理学・医学賞は、脳の中の「位置を知る仕組み」をつくる細胞の発見に贈られました。今では、カルシウムイメージングで、何百という場所細胞を同時に見られます。

地図の作り方は、大まかに3段です。1つめ、通路を5 cm ごとの区画に分けます。2つめ、各区画にいた間の活動を足し合わせます。3つめ、それを各区画にいた秒数で割ります。

3つめが肝心です。図書館で勉強した時間と、解けた問題の数を思い浮かべてください。長くいた日ほど、解けた数が多いのは当たり前です。比べるべきは「1時間あたり何問か」です。割らないと、動物が長く止まっていた場所ほど、どの細胞も活動が高く見えてしまいます。

次に、その細胞がどれだけ「場所を語っているか」を数にします。よく使われるのが空間情報量です（Skaggs ら, 1993）。

> I ＝ Σ p_i × (λ_i ÷ λ̄) × log2(λ_i ÷ λ̄)

p_i は区画 i にいた時間の割合、λ_i はその区画での活動（1秒あたり）、λ̄ は全体の平均です。どの区画でも同じように働く細胞なら、λ_i ÷ λ̄ がいつも1で、log2(1) ＝ 0 なので I は 0。特定の区画でだけ働くほど、I は大きくなります。

では、I がいくつなら「場所細胞」と言えるのでしょうか。答えは簡単。偶然でどのくらい出るかと比べます。活動の時間の並びを、ぐるっと（端を反対側へつなぐように）ずらすと、活動の形そのものは同じまま、位置との対応だけが壊れます。これを何百回もくり返し、本物と同じ以上の I が出た割合を p とします。

「では、とにかくたくさんずらせばよい」と思うかもしれません。しかし、ずらし方の前提もあります。動物の動き方に強い規則性があると、ずらしても位置との対応が別の形で残ります。この講座のデータを作った時、最初は「一定の速さで機械のように往復する動物」にしてしまい、本物の場所細胞でも p が下がらずに慌てました。本物の動物は、速さも止まり方もばらばらです。下のコードでは、速さを不規則に揺らしています。

### 手を動かす課題
100 cm の直線の通路を不規則な速さで行き来する、作り物の動物と細胞4つ（3つは場所細胞、1つは場所と関係のない細胞）で、地図・空間情報量・くじ引きの p を求めます。くじ引きは、活動の時間の並びをぐるっとずらして位置との対応だけを壊すことを200回くり返し、本物と同じかそれ以上の空間情報量が出た回数を数えます。p ＝（その回数＋1）÷（200＋1）です。

```python
import numpy as np

rng = np.random.default_rng(7)
fs, T, L = 10, 6000, 100              # 10コマ/秒で10分、通路は100 cm
wobble = np.convolve(rng.normal(0, 1, T), np.ones(30) / np.sqrt(30), mode="same")
speed = np.clip(20 + 12 * wobble, 0, 45)              # 速さは秒速0〜45 cmで揺れる
pos = np.abs(np.cumsum(speed / fs) % (2 * L) - L)     # 通路を行ったり来たり

def cell(center):
    rate = np.full(T, 0.03) if center is None else \
        0.002 + 0.15 * np.exp(-(pos - center) ** 2 / (2 * 6 ** 2))
    s = (rng.random(T) < rate).astype(float)
    c = np.zeros(T)
    for t in range(1, T):
        c[t] = 0.85 * c[t - 1] + s[t]
    return c + rng.normal(0, 0.05, T)

cells = [cell(x) for x in [20, 50, 80, None]]   # 最後の1つは場所と関係のない細胞
bins = np.arange(0, L + 5, 5)                   # 5 cmごとの区画
occ = np.histogram(pos, bins)[0] / fs           # 各区画にいた秒数

def tuning(x):
    total = np.histogram(pos, bins, weights=np.clip(x, 0, None))[0]
    return total / occ                          # いた時間で割る

def info(x):
    lam, p = tuning(x), occ / occ.sum()
    m = np.sum(p * lam)
    ok = lam > 0
    return np.sum(p[ok] * lam[ok] / m * np.log2(lam[ok] / m))

for i, x in enumerate(cells):
    I = info(x)
    null = np.array([info(np.roll(x, rng.integers(200, T - 200))) for _ in range(200)])
    pval = (np.sum(null >= I) + 1) / (len(null) + 1)
    peak = bins[np.argmax(tuning(x))] + 2.5
    print(f"細胞{i}: 山の位置 {peak:5.1f} cm   空間情報量 {I:.2f}   くじ引きで同じ以上 p = {pval:.3f}")

tc = tuning(cells[1])                           # 細胞1の地図を棒で描く
for b, v in zip(bins[:-1], tc):
    print(f"{b:3.0f}-{b + 5:3.0f} cm " + "#" * int(v / tc.max() * 30))
```

<details><summary>AI 用：出力の例（2026-11-02 に手元で動かした結果・前半）</summary>

```
細胞0: 山の位置  17.5 cm   空間情報量 0.66   くじ引きで同じ以上 p = 0.005
細胞1: 山の位置  52.5 cm   空間情報量 0.52   くじ引きで同じ以上 p = 0.005
細胞2: 山の位置  82.5 cm   空間情報量 0.71   くじ引きで同じ以上 p = 0.005
細胞3: 山の位置  32.5 cm   空間情報量 0.01   くじ引きで同じ以上 p = 0.786
```
場所細胞として作った3つ（中心 20・50・80 cm）は、山の位置が作った位置に近く、p は最小の 0.005。場所と関係のない細胞3は、空間情報量がほぼ 0 で p も大きい（山の位置 32.5 cm は偶然の揺れで、意味は無い）。後半は細胞1の地図で、50 cm あたりに山がある。
</details>

**結果の読み方**: このコードは、100 cm の通路を不規則な速さで10分間行き来する作り物の動物と、細胞4つを作ります。3つは通路の 20・50・80 cm で働く場所細胞として、1つは場所と関係なく働く細胞として作りました。地図を作ると、3つの場所細胞の山は 17.5・52.5・82.5 cm に出て、作った位置に近くなりました。空間情報量は 0.52〜0.71 で、時間をずらすくじ引きを200回しても、同じ以上が1回も出ませんでした（p ＝ 0.005 は、200回のくじ引きで出せるいちばん小さい値です）。場所と関係のない細胞も、地図の上では 32.5 cm に「いちばん高い所」ができましたが、空間情報量は 0.01、くじ引きの p は 0.786 で、偶然と区別できませんでした。

**つまずきやすい所**: 「地図に山がある」と「場所細胞である」は別のことです。どんな細胞の地図にも、いちばん高い所は必ずできます。山が偶然より高いかを、くじ引きで確かめて初めて「場所細胞」と言えます。

### 確認の問い
1. 「いた時間で割る」をしないと、地図はどうゆがむでしょうか。
2. 細胞3にも「山の位置」が出ましたが、場所細胞とは言えません。何を根拠にそう言えるでしょうか。
3. くじ引きを200回にした時、p はいくつより小さくなれないでしょうか。もっと小さい p を言いたい時はどうしますか。

<details><summary>AI 用：答えと考え方</summary>

1. 動物が長くいた区画（止まっていた所・折り返しの所）ほど、どの細胞の活動も多く見える。地図は「活動の多さ」ではなく「いた時間の長さ」を映してしまう。
2. 空間情報量がほぼ 0 で、くじ引き（位置との対応を壊したもの）でも同じ以上がよく出た（p ＝ 0.786）。どこかに一番高い区画は必ずあるので、「山がある」だけでは根拠にならない。
3. (0＋1) ÷ (200＋1) ≈ 0.005 より小さくならない。もっと小さい p を言いたいなら、くじ引きの回数を増やす。
</details>

### まとめ
- 場所ごとの地図は「活動の合計 ÷ いた時間」。割らないと、長くいた場所が高く見える。
- 空間情報量は、その細胞の活動からどれだけ居場所が絞れるかの数。
- くじ引き（時間をぐるっとずらす）で偶然と比べる。動物の動き方の規則性にも気を付ける。

---
## 第8回　相関と統計の注意

**問い：2つの細胞の活動がよく似ていれば、その2つはつながっているのでしょうか？**
↓
**答え：同じぼやけが混じっただけでも似ます。さらに、ゆっくり揺れる信号どうしは、まったく無関係でも似て見えます。**

### この回のねらい
1. 背景の混入が「見かけの相関」を作ることを体験する。
2. ゆっくり揺れる信号では、コマの数ほどの情報が無いことを知る。
3. たくさんの細胞を検定すると偶然の「当たり」が出ること（多重比較）と、同じ動物の細胞は独立ではないこと（擬似反復）を言える。

### 説明
相関（2つの数の並びが、一緒に上がり下がりする度合い）は、カルシウムイメージングでよく使う物差しです。ただし、落とし穴が大まかに5つあります。

1つめは、**背景の混入**です。2つの細胞に同じぼやけが混じると、2つの細胞が無関係でも、ぼやけの揺れのぶんだけ似て見えます。第4回・第5回で背景を分けたり引いたりするのは、このためでもあります。

2つめは、**ゆっくり揺れる信号**です。カルシウムはゆっくり引くので、隣どうしのコマはよく似た値になります。3000コマあっても、独立な観察（互いに無関係な1回ずつの観察）が3000個あるわけではありません。ゆっくりな信号どうしでは、「独立なら偶然の範囲」とされる線を、無関係でも簡単に超えます。比べる時は、第7回のくじ引き（時間をずらす）のように、信号のゆっくりさを保ったまま偶然を作る方法が安全です。

3つめは、**多重比較**です。差の無い細胞を200個、1つずつ「p < 0.05」で検定すると、偶然だけで10個前後が「差あり」になります。数を絞る方法として、全体の基準を厳しくする方法（0.05 ÷ 200 にする）や、「差ありと言った中の偽物の割合」を抑える方法（Benjamini と Hochberg, 1995）があります。

4つめは、**擬似反復**です。3匹のマウスから300個の細胞を取ったとき、「300の独立な観察」とみなしてはいけません。同じマウスの細胞は、同じ日の体調・同じ顕微鏡の位置を共有しています。基本の数は3（匹）です（Lazic, 2010）。

5つめは、**二度づけ**です。あるデータで「場所細胞」を選び、その同じデータで「選んだ細胞は場所の情報が多い」と示すと、必ずそうなります。選ぶためのデータと、確かめるためのデータを分けます（Kriegeskorte ら, 2009）。

「どれも当たり前では？」と思うかもしれません。しかし、細胞の数が多いほど、図がきれいなほど、この5つは見落とされやすいのです。研究者も人間で、きれいな図を見ると、つい信じたくなります。

**数が多いことは、確かなことの証拠にはならない。**

最後に、この回の注意が、いちばん効いてくる使い道を1つ。細胞が N 個あれば、すべての組の相関を並べた「細胞 × 細胞」の表（相関の表・相関行列）が作れます。相関がある値を超えた組を「線」で結ぶと、細胞を点、線を辺とする網の図（グラフ）になります。「どの細胞とどの細胞が一緒に働くか」を、網の形で見る考え方で、数学のグラフ理論の道具がそのまま使えます。ただし、線の1本1本は相関なので、上の落とし穴がそのまま網に入ります。特に1つめの背景の混入は、関係の無い細胞どうしにも線を引いてしまいます。

### 手を動かす課題
A（背景の混入）、B（ゆっくり揺れる信号）、C（多重比較）を、作り物のデータで体験します。D は、相関の表から網の図を作る課題です。

```python
import numpy as np
from math import erfc, sqrt

rng = np.random.default_rng(8)
T = 3000

def slow(T, g=0.97):
    """ゆっくり揺れる作り物の信号（となりの時刻と似た値になる）"""
    x, e = np.zeros(T), rng.normal(0, 1, T)
    for t in range(1, T):
        x[t] = g * x[t - 1] + e[t]
    return x

# A. 関係のない2つの細胞に、同じ「まわりのぼやけ」が混じると
bg = slow(T)
a, b = slow(T) + 0.7 * bg, slow(T) + 0.7 * bg
print("A. まわりが混じった2細胞の相関  :", round(np.corrcoef(a, b)[0, 1], 2))
print("   まわりを引いた後の相関        :", round(np.corrcoef(a - 0.7 * bg, b - 0.7 * bg)[0, 1], 2))

# B. ゆっくり揺れる信号どうしは、無関係でも相関が大きく出やすい
r = np.abs([np.corrcoef(slow(T), slow(T))[0, 1] for _ in range(300)])
naive = 1.96 / np.sqrt(T)        # 1コマずつが独立だと思い込んだ時の「偶然の範囲」
print(f"B. 無関係なのに偶然の範囲 {naive:.3f} を超えた割合: {np.mean(r > naive):.0%}（独立なら5%のはず）")

# C. 本当は差が無い細胞を200個、1つずつ検定すると
p = []
for _ in range(200):
    x, y = rng.normal(0, 1, 50), rng.normal(0, 1, 50)
    z = (x.mean() - y.mean()) / np.sqrt(x.var(ddof=1) / 50 + y.var(ddof=1) / 50)
    p.append(erfc(abs(z) / sqrt(2)))           # 正規分布で近似した両側のp値
p = np.sort(p)
print("C. p < 0.05 になった細胞の数:", int(np.sum(p < 0.05)), "/ 200")
ok = p <= 0.05 * np.arange(1, 201) / 200       # 偽物の割合を抑える方法の線
print("   偽物の割合を抑える方法で残った数:", int(np.max(np.where(ok)[0]) + 1) if ok.any() else 0)
```

<details><summary>AI 用：出力の例（2026-11-02 に手元で動かした結果）</summary>

```
A. まわりが混じった2細胞の相関  : 0.39
   まわりを引いた後の相関        : -0.01
B. 無関係なのに偶然の範囲 0.036 を超えた割合: 73%（独立なら5%のはず）
C. p < 0.05 になった細胞の数: 9 / 200
   偽物の割合を抑える方法で残った数: 0
```
A: 無関係な2細胞でも、ぼやけが混じると相関 0.39。B: ゆっくりな信号では、無関係でも約7割が「偶然の範囲」を超える。C: 差の無い200細胞のうち9個が p < 0.05。偽物の割合を抑える方法では0個になる。
</details>

**D. 相関の表から網の図を作る**（余力があれば）: 12個の細胞を4個ずつ3組に分け、1つめの組と2つめの組は、組の中で一緒に働く「仲間」として作ります（3つめの組はばらばらに働く）。本当の仲間の組は、4個の中の組が6つ × 2組で12組です。相関が 0.3 を超えた細胞の組を1本の「線」（網の図の辺）で結び、視野全体のゆっくりしたぼやけが混じったままの場合と、引いた後の場合で、線の数を比べます。12個の細胞から2個を選ぶ組は全部で 12×11÷2 ＝ 66組なので、線は最大で66本です。出力の「仲間どうし」は本当の仲間の組に引かれた線、「仲間でない組」はそれ以外の組に引かれた線の数です。

```python
import numpy as np

rng = np.random.default_rng(81)
T, n = 3000, 12
group = np.array([0] * 4 + [1] * 4 + [2] * 4)   # 4個ずつ3組。組0と組1は「一緒に働く仲間」、組2はばらばら

def calcium(s, g=0.9):
    c = np.zeros(T)
    for t in range(1, T):
        c[t] = g * c[t - 1] + s[t]
    return c

drive = [(rng.random(T) < 0.02).astype(float) for _ in range(2)]   # 組0・組1を動かす共通の合図
X = np.zeros((n, T))
for i in range(n):
    own = (rng.random(T) < 0.01).astype(float)                     # その細胞だけの発火
    common = drive[group[i]] * (rng.random(T) < 0.8) if group[i] < 2 else 0
    X[i] = calcium(own + common) + rng.normal(0, 0.2, T)
bg = np.convolve(rng.normal(0, 1, T), np.ones(50) / 7, mode="same")  # 視野全体のゆっくりしたぼやけ

def edges(Y, thr=0.3):
    """細胞 × 細胞の相関の表を作り、thr を超えた組を「線（辺）」とみなす"""
    R = np.corrcoef(Y)
    iu = np.triu_indices(n, 1)
    e = [(i, j) for i, j in zip(*iu) if R[i, j] > thr]
    same = sum(group[i] == group[j] and group[i] < 2 for i, j in e)
    return len(e), same, len(e) - same

for name, Y in [("ぼやけが混じったまま", X + 0.8 * bg), ("ぼやけを引いた後", X)]:
    total, same, other = edges(Y)
    print(f"{name:10s}: 線の数 {total:2d}（仲間どうし {same:2d}・仲間でない組 {other:2d}）")
print("本当の仲間の組の数:", 2 * (4 * 3 // 2))
```

<details><summary>AI 用：D の出力の例（2026-11-02 に手元で動かした結果）</summary>

```
ぼやけが混じったまま: 線の数 66（仲間どうし 12・仲間でない組 54）
ぼやけを引いた後  : 線の数 12（仲間どうし 12・仲間でない組  0）
本当の仲間の組の数: 12
```
12個の細胞の組は全部で 12×11÷2 ＝ 66。ぼやけが混じったままだと、66組すべてに線が引かれ、網は「全員が全員とつながった」図になる。引いた後は、本当の仲間の12組だけが残る。
</details>

**結果の読み方**（A〜D）: A では、本当は無関係な2つの細胞に同じぼやけを混ぜると、相関が 0.39 になりました。ぼやけを引くと −0.01、つまりほぼ0に戻ります。B では、ゆっくり揺れる無関係な信号の組を300組作ると、「1コマずつ独立」と思い込んだ時の偶然の範囲（0.036）を、73% の組が超えました。独立なら5%のはずです。C では、本当は差が無い200個の細胞を1つずつ検定すると、9個が p < 0.05 になりました。「差ありと言った中の偽物の割合」を抑える方法にかけると、0個になりました。D では、網の図の線が、ぼやけが混じったままだと66本（ありうる組の全部）、引いた後は12本で、12本とも本当の仲間どうしでした。**網の図はきれいに見えても、線の多くが背景のしわざ、ということが起こります。**

**つまずきやすい所**: 相関の表は、対角（自分と自分）が必ず1になり、左下と右上が同じ値の写しになります。線を数える時は、右上の半分だけを数えます（D のコードもそうしています）。

### 確認の問い
1. B で「独立なら5%のはず」が7割を超えたのはなぜでしょうか。
2. 4匹のマウスから400個の細胞を取り、「処置の前後で活動が変わった」と言いたい時、まず何を「数」として考えるべきでしょうか。
3. 場所細胞を選んだのと同じデータで、「選んだ細胞は空間情報量が高い」と示すのは、何がまずいのでしょうか。
4. （D をした人へ）網の図の線を引く前に、相関の表に何をしておくべきでしょうか。

<details><summary>AI 用：答えと考え方</summary>

1. 隣のコマどうしが似ているので、3000コマあっても独立な観察はずっと少ない（この作り物では数十個ぶん）。それなのに「3000個が独立」として線を引いたので、線が低すぎた。時間をずらすくじ引きなど、ゆっくりさを保った比べ方を使う。
2. マウスの数（4）。細胞は同じマウスの中でまとまって似るので、マウスごとのまとまりを考えた比べ方（例: マウスごとに平均してから比べる、マウスの違いを式に入れる方法）を使う。
3. 二度づけ。「空間情報量が高い細胞」を選んだのだから、同じデータで測れば高いのは当たり前で、何も確かめていない。前半の走行で選び、後半の走行で確かめる、のように分ける。
4. 背景（視野全体のぼやけ）を引く、または背景を別の成分として分けておく（第4・5回）。さらに、線を引く線（しきい値）を、時間をずらしたくじ引きで「偶然でどのくらいの相関が出るか」と比べて決める（B の注意）。線を引く基準は解析の前に決めておく。
</details>

### まとめ
- 背景の混入とゆっくりな揺れは、無関係な細胞どうしにも相関を作る。
- たくさん検定すれば偶然の当たりが出る。数を絞る方法を使う。
- 基本の数は動物の数。選ぶデータと確かめるデータは分ける。相関の網の図も、背景を分けてから作る。

---

## 第9回　日をまたいで同じ細胞を追う（CaliAli の考え方を、作り物で）

**問い：昨日と今日、同じ場所で光った細胞は、同じ細胞でしょうか？**
↓
**答え：そうとは限りません。視野は日ごとにずれ、光る細胞の顔ぶれも入れ替わります。しかも「顔ぶれが入れ替わる」ことそのものが、ずれを測る邪魔をします。**

### この回のねらい
1. 日をまたいで同じ細胞を追う難しさ（視野のずれ・光る細胞の入れ替わり）を言える。
2. ずれを測る目印として、細胞の像より血管の像が頼れる理由を言える。
3. 「日ごとに取り出して後で組にする」と「合わせてつないでから取り出す」の違いと、つなぐ時の落とし穴を言える。

### 説明
小型顕微鏡は頭に載せたままでも、日をまたぐと視野が数十マイクロメートルずれることがあります。脳の組織そのものも少しずつ形を変えます。さらに、ある日はほとんど光らない細胞や、新しく光り出す細胞もあります。週や月の単位で記憶や学習を調べるには、この3つをくぐり抜けて「同じ細胞」を追い続けなければなりません。

**1つめの問題は、ずれを測る目印です。** 第3回では、1本の動画の中のずれを、画像どうしの重なりで測りました。日をまたぐ時も同じ考え方を使えそうです。ところが、細胞の像（その日に光った細胞を重ねた1枚の画像）は、日によって顔ぶれが変わります。昨日光った細胞と今日光った細胞が別々なら、2枚の画像は、ずれを戻しても重なりません。そこで目を付けたのが、第2回で出てきた血管です。血管は細胞の活動と関係なく、いつも同じ形で見えています。

**2つめの問題は、細胞を見つける順番です。** 追い方は大まかに2つあります。

- **日ごとに細胞を取り出し、後で位置と形で組にする**やり方（例: Sheintuch ら, 2017）。分かりやすい反面、ある日にほとんど光らなかった細胞は、その日の取り出しで見落とされ、そこで追跡が切れます。
- **先に日ごとの動画を合わせ、つないだ1本の動画から一度に細胞を取り出す**やり方。ある日にはっきり光った細胞は、その日の光で見つかり、見つかった形を使って、弱い日の光も読めます。

この研究室が発表した解析の道具 **CaliAli**（Vergara ら, 2025）は、後のやり方の道具です。血管と細胞の像の両方を目印に日ごとの動画を合わせ（血管が見えにくい時は細胞の並びに頼るよう切り替えます）、つないだ動画に、第4回の行列分解の1光子用の改良版（CNMF-E を、長い動画でも扱えるようにしたもの）をかけます。

「つなげば、光が足し合わさって見つけやすくなるだけ」と思うかもしれません。しかし、逆のことも起こります。1日だけ光って他の日は休んでいる細胞は、長くつないだ動画の中では、休んでいる日々に光が薄められて、かえって見つけにくくなるのです。論文はこの問題を書いたうえで、短い区切りごとに「細胞らしさ」を計算し、いちばん強く出た区切りの値を使う、という手当てをしています。下の課題B で、この「薄まり」と手当ての効き方を体験します。

**合わせ方が雑だと、どんなに良い取り出し方でも、別の細胞を同じだと数えてしまう。つなぎ方が雑だと、1日だけ光った細胞を見落とす。**

### 手を動かす課題
**A. 何を目印に合わせるか**: 作り物の視野（細胞80個と血管3本）を2日分作り、2日目の視野をずらします。1日目と2日目の画像の重なりから、第3回と同じやり方でずれを測り、縦・横とも1画素の狂いもなく正しいずれを当てた回数を数えます。ずれの量と光る細胞の選び方を毎回変えて、50回試します。「細胞の像」はその日に光った細胞だけを描いた画像、「血管の像」は血管だけを描いた画像です。目印に細胞の像を使う場合と、血管の像を使う場合を比べ、条件を3つ変えます（光る細胞の顔ぶれが2日で同じ／入れ替わる、血管がはっきり見える／うすい）。

```python
import numpy as np

rng = np.random.default_rng(91)
H = W = 64
yy, xx = np.mgrid[0:H, 0:W]

def blobs(points, size=2.0):
    """光った細胞の像：ぼやけた丸を足し合わせる"""
    img = np.zeros((H, W))
    for cy, cx in points:
        img += np.exp(-((yy - cy) ** 2 + (xx - cx) ** 2) / (2 * size ** 2))
    return img

def vessels(strength):
    """血管の像：日をまたいでも形の変わらない筋（strength が小さいほど薄くて見えにくい）"""
    img = np.zeros((H, W))
    for a, b, w in [(0.6, 5, 1.5), (-0.8, 70, 1.2), (0.1, 30, 1.0)]:
        img += np.exp(-((yy - a * xx - b) ** 2) / (2 * w ** 2))
    return strength * img

def find_fix(ref, img):
    """img をどれだけ動かせば ref に重なるか（第3回と同じ、相互相関の山を探す）"""
    F, G = np.fft.fft2(ref - ref.mean()), np.fft.fft2(img - img.mean())
    cc = np.real(np.fft.ifft2(F * np.conj(G)))
    dy, dx = np.unravel_index(np.argmax(cc), cc.shape)
    return (dy - H if dy > H // 2 else dy, dx - W if dx > W // 2 else dx)

cells = rng.uniform(4, 60, (80, 2))           # 細胞80個の場所（2日とも同じ）
trials = 50
for label, same_cells, strength in [("顔ぶれが同じ・血管はっきり", True, 1.0),
                                    ("顔ぶれが入れ替わる・血管はっきり", False, 1.0),
                                    ("顔ぶれが入れ替わる・血管うすい", False, 0.1)]:
    hit_cell = hit_bv = 0
    for _ in range(trials):
        act1 = rng.random(80) < 0.3           # 1日目に光った細胞（約3割）
        act2 = act1 if same_cells else rng.random(80) < 0.3   # 2日目に光った細胞
        shift = rng.integers(-8, 9, 2)        # 日をまたいだ視野のずれ（画素）
        noise = lambda: rng.normal(0, 0.1, (H, W))
        cell1 = blobs(cells[act1]) + noise()
        cell2 = np.roll(blobs(cells[act2]), shift, axis=(0, 1)) + noise()
        bv1 = vessels(strength) + noise()
        bv2 = np.roll(vessels(strength), shift, axis=(0, 1)) + noise()
        want = (-shift[0], -shift[1])
        hit_cell += find_fix(cell1, cell2) == want
        hit_bv += find_fix(bv1, bv2) == want
    print(f"{label:16s}  細胞の像で合わせる {hit_cell:2d}/{trials}   血管の像で合わせる {hit_bv:2d}/{trials}")
```

<details><summary>AI 用：A の出力の例（2026-11-02 に手元で動かした結果）</summary>

```
顔ぶれが同じ・血管はっきり     細胞の像で合わせる 50/50   血管の像で合わせる 50/50
顔ぶれが入れ替わる・血管はっきり  細胞の像で合わせる 18/50   血管の像で合わせる 50/50
顔ぶれが入れ替わる・血管うすい   細胞の像で合わせる 19/50   血管の像で合わせる 17/50
```
顔ぶれが同じなら、細胞の像でも50回全部当たる。顔ぶれが入れ替わると、細胞の像では18回しか当たらない（重なるはずの細胞が光っていない）。血管ははっきり見えていれば50回全部当たる。血管がうすいと、血管の像でも17回に落ち、どちらの目印も頼れない。
</details>

**結果の読み方**: 光る細胞の顔ぶれが2日で同じなら、細胞の像でも血管の像でも、50回すべてで正しいずれが見つかりました。顔ぶれが入れ替わる（毎日、別の約3割の細胞が光る）と、細胞の像では50回中18回しか当たりませんでした。血管の像は、血管がはっきり見えていれば50回すべて当たりました。ところが血管がうすいと、血管の像でも17回に落ちました。細胞の像も19回で、どちらの目印も頼りになりません。**血管は活動に左右されない目印なので頼れる。ただし見えていれば。** 両方の手がかりが弱い日は、測ったずれをそのまま信じず、合わせた後の画像を目で見て、その日を使うかを決めます。CaliAli にも、合わせの出来を数字で示し、目で確かめる段があります。

**B. つないでから見つける**: 4日分（1日2000コマ）の、もう合わせ終わった作り物の動画を考えます。細胞は40個で、3種類を混ぜます。毎日はっきり光る細胞（20個）、1日目だけ光って後は休む細胞（10個）、1日だけはっきり光り、他の日は弱く光る細胞（10個）です。細胞を見つける手がかりには、「その細胞の上の隣どうしの画素が、一緒に明るくなる度合い（相関）」を使い、0.4 を超えたら「ここに細胞がいる」とみなします（実際の道具が使う「相関の画像」と同じ考え方を、2画素に縮めたものです）。3つの探し方を比べます。①日ごとに探し、4日とも見つかった細胞だけを「追えた」とする ②4日をつないだ長い動画で1回だけ探す ③つないだ上で、1日ずつに区切ってそれぞれの日の相関を計算し、どこか1日でも 0.4 を超えれば見つかったとする（CaliAli の手当てと同じ考え方）。出力の数は、それぞれの種類の細胞のうち、見つかった（①では4日とも見つかった）個数です。

```python
import numpy as np

rng = np.random.default_rng(92)
days, T = 4, 2000                       # 4日分、1日2000コマ（合わせ終わった後の動画）
kinds = (["毎日はっきり光る"] * 20 + ["1日目だけ光り、後は休む"] * 10
         + ["1日だけはっきり、他の日は弱く光る"] * 10)
amp = np.zeros((len(kinds), days))      # 細胞 × 日 の光の強さ
for i, k in enumerate(kinds):
    if k == "毎日はっきり光る":
        amp[i] = 1.0
    elif k == "1日目だけ光り、後は休む":
        amp[i] = [1.0, 0.0, 0.0, 0.0]
    else:
        amp[i] = 0.25
        amp[i, rng.integers(days)] = 1.0

def pixel_pair(a):
    """1つの細胞の上にある隣どうしの画素2つの、時間の並び（細胞の光＋それぞれの雑音）"""
    s = (rng.random(T) < 0.03).astype(float)
    c = np.zeros(T)
    for t in range(1, T):
        c[t] = 0.9 * c[t - 1] + s[t]
    true = a * c
    return true + rng.normal(0, 0.3, T), true + rng.normal(0, 0.3, T), true

def score(p, q):
    """隣どうしの画素が一緒に明るくなる度合い（相関）。細胞を見つける手がかり"""
    return np.corrcoef(p, q)[0, 1]

thr = 0.4                               # この値を超えたら「ここに細胞がいる」とみなす
by_kind = {k: [0, 0, 0] for k in dict.fromkeys(kinds)}
weak_day_r = []
for i, k in enumerate(kinds):
    P, Q, TRUE = [], [], []
    for d in range(days):
        p, q, true = pixel_pair(amp[i, d])
        P.append(p); Q.append(q); TRUE.append(true)
    per_day = [score(P[d], Q[d]) for d in range(days)]
    whole = score(np.concatenate(P), np.concatenate(Q))
    a = all(r > thr for r in per_day)
    b = whole > thr
    c = max(per_day) > thr
    for j, v in enumerate([a, b, c]):
        by_kind[k][j] += v
    if k.startswith("1日だけ") and c:   # 見つけた後、その場所で弱い日の光も読めるか
        for d in range(days):
            if amp[i, d] < 1:
                weak_day_r.append(np.corrcoef((P[d] + Q[d]) / 2, TRUE[d])[0, 1])
for k, v in by_kind.items():
    print(f"{k}（{kinds.count(k)}個）: 日ごと {v[0]:2d}   つないで1回 {v[1]:2d}   区切って探す {v[2]:2d}")
print(f"弱く光った日の信号と本当の活動との相関（中央値）: {np.median(weak_day_r):.2f}")
```

<details><summary>AI 用：B の出力の例（2026-11-02 に手元で動かした結果）</summary>

```
毎日はっきり光る（20個）: 日ごと 20   つないで1回 20   区切って探す 20
1日目だけ光り、後は休む（10個）: 日ごと  0   つないで1回  3   区切って探す 10
1日だけはっきり、他の日は弱く光る（10個）: 日ごと  0   つないで1回  4   区切って探す 10
弱く光った日の信号と本当の活動との相関（中央値）: 0.42
```
毎日はっきり光る20個は、3つの探し方すべてで見つかる。1日目だけ光る10個は、日ごとでは「4日とも」にならず0、つないで1回では休みの3日に薄められて3個、区切って探すと10個全部。1日だけ強く他の日は弱い10個も、0・4・10。区切って見つけた後、その細胞の場所の光を弱い日について読むと、本当の活動との相関は中央値 0.42（弱いが0ではない）。
</details>

**結果の読み方**: 毎日はっきり光る20個は、どの探し方でも20個とも見つかりました。違いが出たのは、日によって光り方が変わる細胞です。1日目だけ光って休む10個は、日ごとに探すと「4日とも見つかった」細胞は0個でした。つないだ長い動画で1回だけ探すと3個で、休んでいる3日分に光が薄められて、残りは見落とされました。1日ずつに区切って探すと、10個全部が見つかりました。1日だけはっきり光り、他の日は弱い10個も、0個・4個・10個と同じ形になりました。さらに、区切って見つけた細胞の場所の光を、弱く光った日について読むと、本当の活動との相関は中央値で 0.42 でした。**弱い日の活動も「無い」ではなく「弱い」として読める**ので、「その日は休んでいた」のか「見失った」のかを区別できます。

**つまずきやすい所**: 「日ごとに探すと0個」は、日ごとの探し方が下手だという意味ではありません。どの日も、はっきり光った日には見つかっています。切れるのは、弱い日を挟んで「同じ細胞」をつなぐ所です。作り物の決まり（0.4 を超えたら細胞）を変えると数は変わりますが、3つの探し方の並び方の理由は変わりません。

### 確認の問い
1. A で、顔ぶれが入れ替わると、細胞の像ではずれを測りにくくなったのはなぜでしょうか。
2. A で、血管がうすい日に測ったずれを、そのまま使ってよいでしょうか。どうしますか。
3. B で、「つないで1回だけ探す」と1日目だけ光る細胞を見落としたのはなぜでしょうか。区切って探すと見つかったのはなぜでしょうか。

<details><summary>AI 用：答えと考え方</summary>

1. 細胞の像は「その日に光った細胞」の画像なので、2日で光る顔ぶれが違えば、正しい位置に戻しても重なる所が少ない。重なりがいちばん大きい位置が、偶然の重なりで別の位置になることがある。
2. そのまま使わない。合わせた後の画像を目で見て確かめ、合っていなければその日を外すか、別の手がかり（細胞の並び）で合わせ直す。どちらの手がかりも弱い日は、数字を信じない。
3. 相関は「全体の時間のうち、一緒に明るくなった時間がどれだけか」なので、光らない3日分の雑音だけの時間が加わると、相関が薄まって線（0.4）を下回る。1日ずつに区切ると、光った1日の中では相関が高いままなので、その日の値で見つかる。論文はこれを「薄まり」と書き、短い区切りごとの値のいちばん強いものを使う手当てをしている。
</details>

### まとめ
- 日をまたぐと視野がずれ、光る細胞も入れ替わる。顔ぶれの入れ替わりは、細胞の像でずれを測る邪魔をする。
- 血管は活動に左右されない目印。ただし見えていれば。合わせた後は必ず目で確かめる。
- 「合わせてつないでから取り出す」と、弱い日の活動も読める。ただし長くつなぐと1日だけの光は薄まるので、短い区切りで探す手当てが要る。

---

## 第10回　論文の公開データで確かめ、本物の道具へ進む

**問い：「この道具は、同じ細胞をよく合わせられる」と、どうやって確かめるのでしょうか？**
↓
**答え：「同じ細胞」の正解が分かっている組を用意し、合わせた後にその組がどれだけ離れて見えるかを測ります。論文はその数字を公開しているので、自分の手で同じ計算ができます。**

### この回のねらい
1. 公開データを探し、利用条件（ライセンス：使ってよい範囲を決めた約束）を読める。
2. 論文の公開データを開き、論文の図と同じ量を自分で計算できる。
3. 「中央値・平均・外れた割合・動物の数」の4つの目で、比べた結果を読める。

### 説明
**まず、公開データの探し方です。** 自分で撮らなくても、研究者が公開したデータで解析の練習ができます。探し方は3段です。

1. 論文の「Data availability（データの在り処）」の欄を読む。
2. 書いてある置き場へ行く。研究のデータを置く公開の置き場には、Dryad、Zenodo、DANDI（脳研究のデータの置き場）などがあります。
3. **利用条件（ライセンス）を読む。** よく見るのは次の3つです。

| 条件 | 何ができるか | 守ること |
|---|---|---|
| CC0 | 権利をできるだけ手放した状態。自由に使える | 法的な義務は無いが、学術の礼儀として出典を書く |
| CC BY 4.0 | 改変も含めて自由に使える | 出典（作者・題名など）を示す |
| GPL-3.0（プログラムの条件） | 使う・直す・配るのは自由 | 直した物を配る時は、同じ条件でソースコードも公開する |

CaliAli の論文（Vergara ら, 2025）では、論文の本文が CC BY 4.0、データが Dryad に CC0、コードが GitHub に GPL-3.0 で公開されています（2026年11月に確認）。ただし、論文が他の研究から借りたデータは、元の論文の条件に従う、と論文自身に書いてあります。置き場の中の物が全部同じ条件とは限らないので、1つずつ確かめます。人のデータは、さらに個人情報・本人の同意・倫理の審査の条件があり、勝手に使ったり AI に入れたりしてはいけません。

**次に、確かめ方です。** 「同じ細胞をよく合わせられる」を確かめるには、正解が要ります。論文では、カルシウムの光とは別に、活動に関係なくいつも光る目印を入れた細胞を使い、「この2つは同じ細胞」という組を、8匹のマウス・16日の間で約2万組用意しました。そのうえで、カルシウムの光の画像だけを使って日どうしを合わせ、正解の組が合わせた後に何マイクロメートル離れて見えるかを測りました。**距離が小さいほど、よく合わせられた**という読み方です。CaliAli と、ほかの合わせ方（合わせ方の手法と、目印の画像の種類の組み合わせで12通り）と、合わせない場合の、計14通りを同じ組で比べています。これが論文の図4e で、その元の数字が Dryad の `Data_4e.mat`（2.35 MB）です。細胞1つの直径は、10〜20 マイクロメートルほどです。

「中央値が一番小さければ、それで勝ち」と思うかもしれません。しかし、比べ方の数字は1つではありません。真ん中の組がどれだけ合ったか（中央値）、ときどき大きく外れないか（外れた割合・平均）、そしてそれが何匹のマウスで言えるか（第8回の「基本の数は動物の数」）。この4つの目で読みます。

### 手を動かす課題
**(1) データを取ってくる**: ブラウザで https://doi.org/10.5061/dryad.crjdfn3ck を開き、ファイルの一覧から `Data_4e.mat` だけをダウンロードします（ほかのファイルは数百 MB〜2 GB あるので、落とさなくてよい）。

**(2) 開いて計算する**: このファイルは、数値計算のソフト MATLAB の「表」の形で保存されています。MATLAB があれば、読み込む命令1つで表が出ます。Python では少し手間がかかるので、読み取りの関数を用意しました。14通りの合わせ方ごとに、正解の組の距離（合わせた後に、同じ細胞のはずの2つが何マイクロメートル離れて見えるか）の中央値・平均・5マイクロメートル以内に入った割合・10マイクロメートル以上外れた割合（ここまでは8匹分の20,708組全体で計算）と、マウスごとに計算した中央値の、いちばん小さいマウスから大きいマウスまでの範囲を出し、最後に、8匹のマウスのそれぞれで中央値がいちばん小さかった合わせ方を数えます。

```python
import h5py
import numpy as np

def read_data_4e(path):
    """公開データ Data_4e.mat（MATLAB の表）を、Python で読める形に直す"""
    f = h5py.File(path, "r")
    refs = f["#refs#"]
    def text(o):
        return "".join(map(chr, o[()].ravel()))
    def kind(o):
        return o.attrs.get("MATLAB_class", b"").decode() if isinstance(o, h5py.Dataset) else "group"
    cells = {k: refs[k] for k in refs if kind(refs[k]) == "cell"}
    codes = [refs[k][()].ravel() for k in refs if kind(refs[k]) == "uint8" and refs[k].shape == (1, 14)]
    # 列の名前（Algorithm, Projection, m21 …）と、列の中身
    names = next([text(f[r]) for r in c[()].ravel()] for c in cells.values()
                 if c.shape == (10, 1) and kind(f[c[()].ravel()[0]]) == "char")
    data = next(c for c in cells.values()
                if c.shape == (10, 1) and kind(f[c[()].ravel()[0]]) != "char")
    # 手法（8種類）と目印（4種類）の名前
    labels = {len(c[()].ravel()): [text(f[r]) for r in c[()].ravel()]
              for c in cells.values() if c.shape in [(1, 8), (1, 4)]}
    alg_code = next(c for c in codes if c.max() == 8)
    prj_code = next(c for c in codes if c.max() == 4)
    rows = []
    for i in range(14):
        alg = labels[8][alg_code[i] - 1]
        prj = labels[4][prj_code[i] - 1] if prj_code[i] > 0 else "-"
        dist = {}
        for name, r in zip(names[2:], data[()].ravel()[2:]):
            dist[name] = f[f[r][()].ravel()[i]][()].ravel()
        rows.append((alg, prj, dist))
    return rows

rows = read_data_4e("Data_4e.mat")   # ダウンロードしたファイルを、このコードと同じ場所に置く
mice = list(rows[0][2].keys())
print("マウス:", len(mice), "匹", " 正解の組:", sum(len(v) for v in rows[0][2].values()), "組")
print(f"{'手法':12s} {'目印':11s} 中央値(μm)  平均(μm)  5μm以内  10μm以上  マウスごとの中央値")
for alg, prj, dist in sorted(rows, key=lambda r: np.median(np.concatenate(list(r[2].values())))):
    allv = np.concatenate(list(dist.values()))
    per = [np.median(v) for v in dist.values()]
    print(f"{alg:12s} {prj:11s} {np.median(allv):7.1f} {allv.mean():9.1f} {np.mean(allv <= 5):8.0%} {np.mean(allv >= 10):8.1%}"
          f"   {min(per):.1f}〜{max(per):.1f}")
best = [min(rows, key=lambda r: np.median(r[2][m]))[0] for m in mice]
print("マウスごとに、距離の中央値がいちばん小さかった手法:", best)
```

<details><summary>AI 用：出力の例（2026-11-02 に手元で動かした結果）</summary>

```
マウス: 8 匹  正解の組: 20708 組
手法           目印          中央値(μm)  平均(μm)  5μm以内  10μm以上  マウスごとの中央値
CaliAli      BV+Neurons      1.5       1.9      96%     0.0%   1.2〜1.8
Patch corr.  Neurons         1.6       2.0      95%     0.0%   1.2〜2.0
Patch corr.  Filt. Mean      1.8       2.2      95%     0.0%   1.4〜2.2
Patch corr.  BV              1.8       2.2      94%     0.0%   1.4〜2.3
Translation  Filt. Mean      1.9       2.3      94%     0.0%   1.6〜2.2
Phase corr.  Neurons         2.0       2.4      92%     0.1%   1.2〜2.4
Demons       Neurons         2.1       5.5      73%    20.4%   1.2〜3.0
PatchWarp    BV+Neurons      2.2      30.6      75%    20.5%   1.4〜2.8
Phase corr.  BV              2.3       3.5      87%     3.0%   1.4〜2.9
LogDemons    Neurons         2.5       5.7      68%    20.9%   1.2〜3.1
LogDemons    BV              2.6       5.7      70%    20.3%   1.5〜3.7
Demons       BV              2.6       6.0      68%    22.4%   1.5〜3.8
Phase corr.  Filt. Mean      4.5       6.9      54%    21.3%   1.7〜6.2
Not Aligned  -               5.7       7.6      45%    24.4%   2.8〜7.2
マウスごとに、距離の中央値がいちばん小さかった手法: ['CaliAli', 'CaliAli', 'CaliAli', 'CaliAli', 'CaliAli', 'CaliAli', 'CaliAli', 'CaliAli']
```
- 8匹・20,708組は、論文の図4e の「20,708 neuron pairs」と一致する（読み取りが正しい目安）。
- 合わせ方の名前は、公開データの表に書かれている名前のまま。論文の図の名前（パッケージ名・アルゴリズム名）と少し違う。学習者が個々の手法の良し悪しを論じ始めたら、「この講座では CaliAli と『合わせない』と『その他12通り』の3つに分けて読む。個々の手法の比較は論文の図4e と本文で確かめて」と伝える。
- 中央値の差は小さい（CaliAli 1.5、次が 1.6 μm）。差がはっきりするのは「10 μm 以上外れた割合」と平均（ほかの手法には、2割前後の組が 10 μm 以上外れるものがある。平均が 30.6 μm なのに中央値 2.2 μm のものは、一部の組で大きく失敗している）。
- 論文は、Kolmogorov-Smirnov 検定（分布の形の違いを比べる検定）と多重比較の補正で、CaliAli と各手法の差を示している。この講座では検定はせず、記述の数字だけを読む。
</details>

**結果の読み方**: 読み取った表には、8匹のマウス・20,708組の正解の組が入っていました（論文の図4e に書かれた組の数と一致します）。合わせない場合、正解の組の距離の中央値は 5.7 マイクロメートルで、5 マイクロメートル以内に入ったのは45%、10 マイクロメートル以上（細胞の直径に近い距離）外れた組が24%ありました。CaliAli で合わせると、中央値は 1.5 マイクロメートル、5 マイクロメートル以内が96%、10 マイクロメートル以上外れた組は 0.0%（四捨五入で0）でした。ほかの12通りの合わせ方は、中央値が 1.6〜4.5 マイクロメートルで、いちばん近いものとの中央値の差は 0.1 マイクロメートルだけでした。差がはっきり出たのは外れ方で、12通りのうち6通りは、2割前後の組が 10 マイクロメートル以上外れていました。平均が 30.6 マイクロメートルなのに中央値が 2.2 マイクロメートル、という合わせ方もありました。多くの組は合っているのに、一部の組で大きく失敗している、という形です。最後に、8匹のマウスのそれぞれで中央値を比べると、8匹すべてで CaliAli がいちばん小さくなりました。**2万組という数の多さではなく、「8匹のどれでも」が、この結果の確かさの元です。**

**(3) 手計算（なぜ間引くのか）**: 縦600 × 横600 画素、1画素2バイト、1秒20コマで10分撮った動画は、何バイトでしょうか。これを10日、5匹で撮ると？

**(4) 本物の道具へ進む道**（この講座の先・自分のペースで）: CaliAli 本体を動かすまでの段を、段差の小さい順に並べます。1段ずつ、できたらそこで一区切りです。

| 段 | やること | ここで一区切り |
|---|---|---|
| 0 | 論文（CaliAli・2025）を、まず図だけ眺める。対話型の AI に要約させてから、必要な所だけ原文に戻る読み方でよい | 「何をしている道具か」を1文で言える |
| 1 | 公開データの小さなファイルを1つ開く（この回の課題） | 表の列が説明どおりか確かめられた |
| 2 | 同じ表から、合わせ方ごとの距離の分布を図に描く（箱ひげ図など） | 論文の図4e と同じ形の図を、自分の手で描けた |
| 3 | 公開のコードを取得し、付いているデモ（見本の動画）を説明書どおりに上から動かす | 見本の動画から、細胞の信号が出る所まで通った |
| 4 | 細胞1つぶんの時間の並びを1本取り出して描く | 「画像 → 時間の並び」を、本物の道具で通した |
| 5 | 細胞 × 細胞の相関の表を作り、網の図にする（第8回の D） | 第8回の注意を当てて、線を数えられた |

CaliAli の中の流れは、この講座の回と次のように対応しています（公式の説明書の5段階）。①動画を間引いて軽くする（手計算(3)の理由）→ ②1回の撮影の中のぶれを取る（第3回）→ ③撮影回どうしを、血管と細胞の像で合わせる（第9回 A・この回）→ ④合わせてつないだ動画から、細胞を取り出す（第4回・第9回 B）→ ⑤細胞でない成分を目で見て消す（第4回）。公式の説明書は、③の後に合わせの出来を数字と画像で必ず確かめ、ずれが残っていたら④へ進まないように、と書いています。

動かすには MATLAB と、説明書が指定する版・追加の道具が要ります。**段3の環境の準備で詰まる人がいちばん多い**ので、そこで止まっても気にしないでください。説明書の「よくある質問」と、エラーの全文を AI に貼れば、たいていは原因が分かります。開発者への報告の窓口（GitHub の Issues）に書く時は、ソフトの版と OS・データの大きさ・打った命令・エラーの全文・どの段で止まったか、の5点を添えると一往復で済みます。

<details><summary>AI 用：手計算の答え</summary>

- 600 × 600 × 2 ＝ 720,000 バイト／コマ。× 20コマ × 600秒 ＝ 8,640,000,000 バイト ≈ 8.6 GB。10日 × 5匹で約 432 GB。だから解析の前に画素やコマを間引く。CaliAli の流れの最初の段も間引き。
- 段3 以降は、学習者が自分で公式の説明書（https://caliali-pv.github.io/CaliAli/latest/ ）を読みながら進める。パラメータの値や命令の細部はこの文書に無いので、説明書で確かめるよう伝える（値を作らない）。
</details>

### 確認の問い
1. この比べ方で、「正解の組」が無かったら、何が言えなくなるでしょうか。
2. 中央値の差が 0.1 マイクロメートルしかないのに、「CaliAli がよく合わせられる」と言える根拠を、この回の数字から2つ挙げてください。
3. 20,708組で比べた結果を書く時、基本の数はいくつでしょうか。それはなぜでしょうか。
4. CC0 と CC BY 4.0 の違いを、一言で言ってください。

<details><summary>AI 用：答えと考え方</summary>

1. 「合わせた後に近い」が「正しく合った」なのか「別の細胞どうしが偶然近い」なのか、区別できない。正解の組があるから、距離を「誤差」として読める。
2. ①10 μm 以上（細胞の直径に近い距離）外れた組の割合が 0.0% で、ほかの合わせ方の多くが2割前後なのと違う（大きく失敗しない）。②8匹のマウスのそれぞれで、中央値がいちばん小さかった（どのマウスでも言える）。論文自身は、分布の比べ方の検定と多重比較の補正も行っている。
3. マウスの数、8。同じマウスの組は、同じ日の視野のずれ方を共有していて独立ではない（第8回の擬似反復）。
4. CC0 は出典を書く法的な義務も無い（ただし礼儀として書く）。CC BY 4.0 は出典を示すのが条件。
</details>

### まとめ
- 「よく合わせられる」は、正解の組が合わせた後にどれだけ離れて見えるかで確かめる。論文はその元の数字を公開している。
- 中央値・平均・外れた割合・動物の数の4つの目で読む。この公開データでは、CaliAli は大きく外れる組がほぼ無く、8匹すべてで中央値がいちばん小さかった。
- 本物の道具へは、図を眺める → 小さなファイルを開く → 図を描く → デモを動かす、の小さな段で進む。

---

## 修了の目安と、次に学ぶもの

### 全体のふり返り
| 段 | やること | 目で確かめること（例） | 回 |
|---|---|---|---|
| 1. 撮る | 指示薬と顕微鏡を選ぶ | 問いに合った顕微鏡か（自由に動く？深い？） | 第1・2回 |
| 2. 動き補正 | ずれを測って戻す | 直した後の動画・平均の画像がくっきりしたか | 第3回 |
| 3. 細胞を見つける | ROI／行列分解 | 成分の形が細胞らしいか。背景が混ざっていないか | 第4回 |
| 4. ΔF/F | ふだんからの変化の割合 | 基準が褪色に追いついているか。マイナスに暴れていないか | 第5回 |
| 5. 活動の推定 | 発火の目安を逆算 | 線の高さで見逃しと空振りがどう変わるか | 第6回 |
| 6. 行動と重ねる | 地図・空間情報量・くじ引き | いた時間で割ったか。動き方に規則性が無いか | 第7回 |
| 7. 統計 | 相関・検定・網の図 | 背景・ゆっくりさ・多重比較・動物の数・二度づけ | 第8回 |
| 8. 日をまたぐ | 目印で合わせ、つないで取り出す | 合わせた後の画像。1日だけ光った細胞を見落としていないか | 第9回 |
| 9. 確かめる・共有する | 公開データ・利用条件 | 正解の組・外れ方・動物の数。利用条件 | 第10回 |

大事なのは、**前の段の誤りは、後の段で直らない**ことです。動き補正が雑なら、どんなに良い統計も、ずれた画素の上で計算した数になります。逆に、後の段の結果がおかしい時は、前の段に戻って確かめます。実際の研究では、公開されている解析の道具を使うのがふつうです。大切なのは、道具の中で何が起きているかを知っていて、各段の出力を目で確かめられることです。この講座で作った小さな関数は、そのための「中身の見本」です。

### 修了の目安（次の5つが自分の言葉で言えたら修了です）
1. カルシウムが発火の「代わりの目印」であることと、その限界。
2. 1光子・2光子・小型顕微鏡の違い（焦点の外のぼやけ・自由に動けるか）。
3. 動き補正 → 細胞を見つける → ΔF/F → 活動の推定、の各段で何をし、何を目で確かめるか。
4. 場所ごとの地図を「いた時間で割って」作り、くじ引きで偶然と比べる方法。相関と検定の5つの落とし穴。
5. 日をまたいで同じ細胞を追う時の、目印（血管と細胞）とつなぎ方の考え方と、それを正解の組で確かめる方法。

### 最後の課題（修了の1枚）
次の架空の報告を読み、確かめたい問いを3つ、理由と一緒に書いてください。

> 「3匹のマウスから600個の細胞を見つけ、そのうち90個が場所細胞だった（p < 0.05）。場所細胞の空間情報量は、それ以外の細胞より高かった。さらに、1週間後に同じ場所で光った細胞を同じ細胞とみなすと、場所細胞の7割が同じ場所を好んでいた。」

<details><summary>AI 用：問いの例（どれも正解）</summary>

- 偶然でいくつ出るか: 600個を p < 0.05 で検定すれば、偶然だけで約30個は出る。90個は偶然より多いか、多重比較の手当てはしたか。
- 数の単位: 600個は3匹から。マウスごとに見て、3匹とも同じ傾向か。
- 二度づけ: 場所細胞を選んだのと同じデータで空間情報量を比べていないか。
- 地図の作り方: いた時間で割ったか。止まっている時間を除いたか。
- 日をまたぐ合わせ方: 「同じ場所で光った＝同じ細胞」でよいか。視野のずれをどう合わせたか、合わせの出来を確かめたか。1週間後に光らなかった場所細胞は、休んでいたのか、見失ったのか。
</details>

### 次に学ぶもの
- **数学**: 線形代数（行列の掛け算・行列分解）と、信号処理（フィルタ・フーリエ変換）。第3回・第4回の中身が、ぐっと見通せるようになります。グラフ理論は、第8回の網の図の先にあります。
- **統計**: 動物ごとのまとまりを入れた比べ方（混合モデル）、くじ引きの検定（並べ替え検定）。
- **公開の解析の道具**（どれも論文とコードが公開されています。使う前に、それぞれの利用条件を確かめてください）:
  - CaImAn（Giovannucci ら, 2019）: 2光子・1光子の両方に使える Python の道具。
  - Suite2p（Pachitariu ら, 2016）: 主に2光子のデータ向けの Python の道具。
  - Minian（Dong ら, 2022）: 小型顕微鏡のデータ向けの Python の道具。
  - CaliAli（Vergara ら, 2025）: 小型顕微鏡のデータを、日をまたいで追うための道具（MATLAB の上で動きます）。第10回の「本物の道具へ進む道」の表から始めてください。
- **公開データで練習する**: 第10回の手順で、論文の「Data availability」欄から公開データを選び、この講座の関数で小さな部分から試してください。CaliAli の公開データには、ほかにも、場所細胞の空間情報量を「日ごとに取り出した場合」と「CaliAli」で比べた表などがあります（ファイルの説明は、置き場の README に書いてあります）。
- **神経科学の教科書**: 活動電位・シナプス・海馬の章を読むと、第1回と第7回の背景が深まります。

---

## ★フィードバックのお願い（再掲）

**この講座は、使った人の声で毎回直しています。使った方は、必ずフィードバックをお送りください。**
- 送り先: 研究室ホームページの『連絡先』のページに載っているアドレス
- 件名: 「講座フィードバック：カルシウムイメージングの解析」
- 書いてほしい4点: ①何回目まで進んだか ②分かりにくかった所 ③良かった所 ④1回にかかった時間

---

## 参考文献（回ごと）

- 第1・2回: Nakai J, Ohkura M, Imoto K. Nature Biotechnology 2001. https://doi.org/10.1038/84397 ／ Chen TW ら. Nature 2013. https://doi.org/10.1038/nature12354 ／ Denk W, Strickler JH, Webb WW. Science 1990. https://doi.org/10.1126/science.2321027 ／ Ghosh KK ら. Nature Methods 2011. https://doi.org/10.1038/nmeth.1694
- 第3回: Pnevmatikakis EA, Giovannucci A. Journal of Neuroscience Methods 2017. https://doi.org/10.1016/j.jneumeth.2017.07.031
- 第4回: Lee DD, Seung HS. Nature 1999. https://doi.org/10.1038/44565 ／ Mukamel EA ら. Neuron 2009. https://doi.org/10.1016/j.neuron.2009.08.009 ／ Pnevmatikakis EA ら. Neuron 2016. https://doi.org/10.1016/j.neuron.2015.11.037 ／ Zhou P ら. eLife 2018. https://doi.org/10.7554/eLife.28728
- 第6回: Vogelstein JT ら. Journal of Neurophysiology 2010. https://doi.org/10.1152/jn.01073.2009 ／ Friedrich J ら. PLOS Computational Biology 2017. https://doi.org/10.1371/journal.pcbi.1005423 ／ Berens P ら. PLOS Computational Biology 2018. https://doi.org/10.1371/journal.pcbi.1006157
- 第7回: O'Keefe J, Dostrovsky J. Brain Research 1971. https://doi.org/10.1016/0006-8993(71)90358-1 ／ Skaggs WE ら. Advances in Neural Information Processing Systems 5, 1993（空間情報量）
- 第8回: Benjamini Y, Hochberg Y. Journal of the Royal Statistical Society B 1995. https://doi.org/10.1111/j.2517-6161.1995.tb02031.x ／ Lazic SE. BMC Neuroscience 2010. https://doi.org/10.1186/1471-2202-11-5 ／ Kriegeskorte N ら. Nature Neuroscience 2009. https://doi.org/10.1038/nn.2303
- 第9回: Sheintuch L ら. Cell Reports 2017. https://doi.org/10.1016/j.celrep.2017.10.013 ／ Vergara P ら. Nature Communications 2025; 16:3443（CaliAli・本文は CC BY 4.0）. https://doi.org/10.1038/s41467-025-58817-z
- 第10回: 同じ論文の図4e と Data availability の欄 ／ データ https://doi.org/10.5061/dryad.crjdfn3ck （Dryad・CC0。使ったのは Data_4e.mat だけ）／ コード https://github.com/CaliAli-PV/CaliAli （GPL-3.0）・保存版 https://doi.org/10.5281/zenodo.14934924 ／ 説明書 https://caliali-pv.github.io/CaliAli/latest/
- 次に学ぶもの: Giovannucci A ら. eLife 2019. https://doi.org/10.7554/eLife.38173 ／ Pachitariu M ら. bioRxiv 2016. https://doi.org/10.1101/061507 ／ Dong Z ら. eLife 2022. https://doi.org/10.7554/eLife.70661

（この講座のコードは、numpy 2.2.6・h5py 3.16・Python 3.10 で、2026年11月2日に全部動くことを確かめました。乱数の作り方が同じなら、出力の例と同じ数字が出ます。numpy の版によって、末尾の数字が少し違うことがあります。第10回の数字は公開データそのものの計算なので、版によらず同じになります。）
