Zhuang, Lemak, Sridhar & Nelson (2025): what DANDI:001177 and the paper's Zenodo deposit support¶
Paper: Zhuang X, Lemak J, Sridhar S, Nelson AB. "Aberrant striatal firing mediates impulsive
decision-making in a mouse model of Parkinson's disease." Brain (2025), doi:10.1093/brain/awaf312.
The claims file (claims/001177/10.1093-brain-awaf312.yaml) was written from the version of record
(Europe PMC full text, PMC12597312) with its supplement, and checked by a second reader.
Data.
- DANDI:001177, version 0.250902.2127, streamed. The paper cites the dandiset without a version ("Raw in vivo electrophysiology datasets have been deposited in DANDI (https://dandiarchive.org/dandiset/001177)"). This is the only published version; the draft was modified later (2026-09-03) with the same 56 assets and total size, so the published version is pinned, as the protocol asks when the paper names none. The dandiset holds the in vivo electrophysiology of Figures 4, 6F-K, S5 and S8.
- Zenodo record 15258978 (doi:10.5281/zenodo.15258978), the paper's deposit of its behaviour,
histology, rotarod and slice data, which the claims file names for every
data: elsewhereclaim. It has one version. Its files are streamed into memory. - The paper's analysis code, UCSF-Nelson-Lab/ICD-Cognitive-Analysis at commit 5528e222, was read for
the event names and the curve fit; it is not run (it needs a GUI), and
icd.pyre-implements the parts used, citing them.
| Claims | Data | Status here |
|---|---|---|
| 14 electrophysiology claims (Figure 4, S5, 6F-I, S8) | DANDI:001177 | blocked: 54 files have no sorted units and the other two have units tables that do not say which units are sorted; no file has unit classes, optical labels, laser pulse times or an injection time |
| 30 behaviour, histology, rotarod and slice claims | Zenodo 15258978 | 28 tested; two blocked (sex not recorded; no PPX open field file) |
| figs2abc-sex-similar | Zenodo | blocked: the deposit does not give each mouse's sex |
| figs1ef-ppx-locomotion | Zenodo | blocked: no PPX open field file in the deposit |
Each claim's outcome is in the attempt record and the summary at the end.
import sys
import warnings
import numpy as np
import pandas as pd
from scipy import stats
import matplotlib.pyplot as plt
import icd
warnings.filterwarnings("ignore", category=RuntimeWarning)
pd.set_option("display.width", 200)
pd.set_option("display.max_columns", 30)
pd.set_option("display.max_rows", 200)
print("DANDI", icd.DANDISET, icd.DANDI_VERSION, "| Zenodo", icd.ZENODO_DOI, "| code", icd.CODE_COMMIT[:8])
DANDI 001177 0.250902.2127 | Zenodo 10.5281/zenodo.15258978 | code 5528e222
Data check¶
DANDI:001177. Every file is opened and its metadata, groups and array shapes are listed (no voltage is read). The claims need, per session, sorted single units, their putative MSN class, their optical identification (laser pulse times) and the PPX injection time.
from concurrent.futures import ThreadPoolExecutor
meta = icd.dandi_metadata()
assets = icd.dandi_assets()
print(meta["name"], "|", meta["version"], "|", len(assets), "assets |", round(assets.size_gb.sum()), "GB")
with ThreadPoolExecutor(8) as ex:
survey = pd.DataFrame(list(ex.map(icd.survey_file, assets.asset_id)))
survey.insert(0, "path", assets.path.str.split("/").str[-1].str.replace("_ecephys.nwb", ""))
print(survey[["path", "subject", "genotype", "sex", "lesion", "start", "segments_min", "n_channels",
"n_spike_event_series", "n_threshold_crossings", "has_units", "n_units"]].to_string())
Abnormal Striatal Activity in a Mouse Model of Impulse Control Disorder in Parkinson’s Disease | 0.250902.2127 | 56 assets | 1994 GB
path subject genotype sex lesion start segments_min n_channels n_spike_event_series n_threshold_crossings has_units n_units 0 sub-C3-2_ses-PPXopenField-C3-2-day1 C3.2 Drd1aCre F saline 2021-11-30T21:35:42.746000-08:00 0.0+30.6; 31.9+300.9; 333.6+69.9 32 32 38396440 False 0 1 sub-C3-2_ses-PPXopenField-C3-2-day2 C3.2 Drd1aCre F saline 2021-12-09T20:19:19.383000-08:00 0.0+33.6; 35.0+296.6; 332.3+72.3 32 25 12315643 False 0 2 sub-C9_ses-PPXopenField-C9-day1 C9 A2aCre M 6-OHDA 2021-11-21T22:23:09.467000-08:00 0.0+30.4; 31.5+10.4; 42.7+42.6; 85.4+0.6; 86.0+257.5; 345.5+68.5 32 22 931492 False 0 3 sub-C9_ses-PPXopenField-C9-day2 C9 A2aCre M 6-OHDA 2021-11-26T22:10:31.094000-08:00 0.0+30.6; 31.9+302.2; 335.1+69.0 32 22 5951798 False 0 4 sub-D0_ses-PPXopenField-D0-day1 D0 A2aCre M 6-OHDA 2022-03-07T19:58:35.940000-08:00 0.0+30.1; 31.7+313.3; 345.8+69.1 32 27 8835331 False 0 5 sub-D0_ses-PPXopenField-D0-day2 D0 A2aCre M 6-OHDA 2022-03-09T19:33:12.425000-08:00 0.0+29.7; 29.7+0.4; 31.3+310.6; 342.7+0.2; 342.9+0.8; 343.7+69.3 32 29 9460690 False 0 6 sub-D0_ses-PPXopenField-D0-day3 D0 A2aCre M 6-OHDA 2022-03-13T21:27:40.381000-07:00 0.0+31.1; 32.5+299.1; 332.1+64.6 32 27 9848278 False 0 7 sub-D0_ses-PPXopenField-D0-day4 D0 A2aCre M 6-OHDA 2022-03-14T19:06:41.126000-07:00 0.0+32.1; 33.9+369.3 32 22 8077508 False 0 8 sub-D0_ses-SalineopenField-DO D0 A2aCre M 6-OHDA 2022-04-21T19:32:05.436000-07:00 0.0+311.5 32 25 9034912 False 0 9 sub-D3-1_ses-PPXopenField-D3-1-day1 D3.1 Drd1aCre M saline 2022-03-03T19:39:41.126000-08:00 0.0+30.5; 31.8+420.4; 453.4+68.6 32 27 10908767 False 0 10 sub-D3-1_ses-PPXopenField-D3-1-day2 D3.1 Drd1aCre M saline 2022-03-06T20:06:10.993000-08:00 0.0+30.7; 32.6+315.2; 348.8+68.3 32 23 12950461 False 0 11 sub-D3-1_ses-PPXopenField-D3-1-day3 D3.1 Drd1aCre M saline 2022-03-10T20:03:13.082000-08:00 0.0+31.2; 33.6+299.2; 333.6+70.0 32 24 13749703 False 0 12 sub-D3-1_ses-PPXopenField-D3-1-day4 D3.1 Drd1aCre M saline 2022-03-16T19:49:54.868000-07:00 0.0+402.5; 403.7+75.5 32 24 10730247 False 0 13 sub-E0_ses-PPXopenField-E0-day1 E0 Drd1a-Cre M 6-OHDA 2022-05-31T19:55:07.507000-07:00 0.0+330.0; 330.5+70.1 32 32 14291722 False 0 14 sub-E0_ses-PPXopenField-E0-day2 E0 Drd1a-Cre M 6-OHDA 2022-06-02T19:21:00.144000-07:00 0.0+401.9 32 32 18910346 False 0 15 sub-E0_ses-PPXopenField-E0-day3 E0 Drd1a-Cre M 6-OHDA 2022-06-07T20:26:53.025000-07:00 0.0+333.3; 334.0+76.7 32 30 21470414 False 0 16 sub-E0_ses-PPXopenField-E0-day4 E0 Drd1a-Cre M 6-OHDA 2022-06-09T18:40:36.259000-07:00 0.0+31.5; 32.5+380.2 32 0 0 True 60 17 sub-E0_ses-Saline-openField-E0 E0 Drd1aCre M 6-OHDA 2022-06-30T20:41:45-07:00 0.0+281.3 32 26 10541180 False 0 18 sub-E5_ses-PPXopenField-E5-day1 E5 Drd1aCre M saline 2022-06-03T19:17:10-07:00 0.0+406.0 32 31 21699159 False 0 19 sub-E5_ses-PPXopenField-E5-day2 E5 Drd1aCre M saline 2022-06-10T02:02:22.314000-07:00 0.0+408.3 32 30 19849820 False 0 20 sub-E5_ses-PPXopenField-E5-day3 E5 Drd1aCre M saline 2022-06-15T19:48:08.711000-07:00 0.0+30.8; 31.6+299.3; 331.4+72.4 32 31 29120247 False 0 21 sub-E5_ses-PPXopenField-E5-day4 E5 Drd1aCre M saline 2022-06-29T21:37:31.385000-07:00 0.0+461.0 32 32 55932665 False 0 22 sub-H0-2_ses-PPXopenField-H0-2-day1 H0.2 Drd1aCre M saline 2023-06-27T18:46:37.936000-07:00 0.0+399.3 32 32 17556746 False 0 23 sub-H0-2_ses-PPXopenField-H0-2-day2 H0.2 Drd1aCre M saline 2023-08-01T18:34:40-07:00 0.0+408.5 32 24 12272821 False 0 24 sub-H0-2_ses-PPXopenField-H0-2-day3 H0.2 Drd1aCre M saline 2025-07-31T02:12:42.291000-07:00 0.0+405.1 32 32 12945176 False 0 25 sub-H0-2_ses-PPXopenField-H0-2-day4 H0.2 Drd1aCre M saline 2025-07-30T00:53:25.412000-07:00 0.0+377.1 32 32 8328807 False 0 26 sub-H1-3_ses-PPXopenField-H1-3-day1 H1.3 A2aCre M 6-OHDA 2023-06-28T18:22:30.410000-07:00 0.0+411.0 32 32 12950779 False 0 27 sub-H1-3_ses-PPXopenField-H1-3-day2 H1.3 A2aCre M 6-OHDA 2023-07-21T20:54:03.499000-07:00 0.0+31.4; 32.5+378.0 32 16 5972698 False 0 28 sub-H1-3_ses-PPXopenField-H1-3-day3 H1.3 A2aCre M 6-OHDA 2023-07-31T20:36:06.730000-07:00 0.0+408.4 32 17 5062788 False 0 29 sub-H1-3_ses-SalineopenField-H1-3 H1.3 A2aCre M 6-OHDA 2023-08-02T20:06:26-07:00 0.0+336.4 32 18 4330415 False 0 30 sub-H4-3_ses-PPXopenField-H4-3-day1 H4.3 Drd1aCre M 6-OHDA 2023-08-21T18:26:34.700000-07:00 0.0+409.5 32 24 9505670 False 0 31 sub-H4-3_ses-PPXopenField-H4-3-day2 H4.3 Drd1aCre M 6-OHDA 2023-09-08T18:22:53.265000-07:00 0.0+337.1 32 32 7207777 False 0 32 sub-H4-3_ses-PPXopenField-H4-3-day3 H4.3 Drd1aCre M 6-OHDA 2025-05-23T01:35:48.365000-07:00 0.0+331.1 32 25 6819351 False 0 33 sub-H4-3_ses-PPXopenField-H4-3-day4 H4.3 Drd1aCre M 6-OHDA 2023-09-18T18:48:41.951000-07:00 0.0+33.4; 34.6+300.8 32 32 5890731 False 0 34 sub-H4-3_ses-SalineopenField-H4-3 H4.3 Drd1aCre M 6-OHDA 2023-10-18T19:55:30-07:00 0.0+301.5 32 32 7985748 False 0 35 sub-J0_ses-PPXopenField-J0-day1 J0 A2aCre M 6-OHDA 2023-11-16T19:48:36.863000-08:00 0.0+30.4; 32.2+301.8; 337.9+74.5 32 32 15330647 False 0 36 sub-J0_ses-PPXopenField-J0-day2 J0 A2aCre M 6-OHDA 2023-11-22T20:22:46.835000-08:00 0.0+30.3; 31.4+371.7 32 32 19894385 False 0 37 sub-J0_ses-PPXopenField-J0-day3 J0 A2aCre M 6-OHDA 2023-11-27T19:51:08.618000-08:00 0.0+31.0; 33.2+376.8 32 32 15241385 False 0 38 sub-J0_ses-PPXopenField-J0-day4 J0 A2aCre M 6-OHDA 2023-12-15T19:21:34.937000-08:00 0.0+29.9; 31.3+410.3 32 31 24849331 False 0 39 sub-JFB_ses-PPXopenField-JFB-day1 JFB Drd1aCre F 6-OHDA 2022-04-05T18:38:16-07:00 0.0+325.0 32 26 8056732 False 0 40 sub-JFC_ses-PPXopenField-JFC-day1 JFC A2aCre M 6-OHDA 2022-04-06T18:53:51-07:00 0.0+332.3 32 25 10879538 False 0 41 sub-JFF_ses-PPXopenField-JFF-day1 JFF Drd1aCre M saline 2022-04-07T20:46:36-07:00 0.0+331.9 32 22 6339273 False 0 42 sub-K1_ses-PPXopenField-K1-day1 K1 Drd1aCre F 6-OHDA 2023-12-01T19:20:06.993000-08:00 0.0+30.6; 31.9+293.5; 335.7+78.7 32 31 20216471 False 0 43 sub-K1_ses-PPXopenField-K1-day2 K1 Drd1aCre F 6-OHDA 2023-12-05T18:33:13.520000-08:00 0.0+30.2; 31.3+371.1 32 29 20503077 False 0 44 sub-K1_ses-PPXopenField-K1-day3 K1 Drd1aCre F 6-OHDA 2023-12-14T19:40:44.984000-08:00 0.0+30.1; 31.3+371.9 32 31 20355367 False 0 45 sub-K1_ses-PPXopenField-K1-day4 K1 Drd1aCre F 6-OHDA 2023-12-20T18:58:15.509000-08:00 0.0+30.2; 31.7+370.4 32 32 22009934 False 0 46 sub-K4_ses-PPXopenField-K4-day1 K4 Drd1aCre M 6-OHDA 2023-11-30T19:35:24.867000-08:00 0.0+30.1; 32.0+376.5 32 32 22790960 False 0 47 sub-K4_ses-PPXopenField-K4-day2-optoSession K4 Drd1aCre M 6-OHDA 2023-12-05T00:18:32.606000-08:00 0.0+71.3 32 32 7038153 False 0 48 sub-K4_ses-PPXopenField-K4-day2 K4 Drd1aCre M 6-OHDA 2023-12-04T18:16:50.393000-08:00 0.0+30.1; 31.3+300.9 32 32 16244697 False 0 49 sub-K4_ses-PPXopenField-K4-day3 K4 Drd1aCre M 6-OHDA 2023-12-13T19:16:24.764000-08:00 0.0+30.0; 31.9+302.8; 336.0+68.5 32 32 29597053 False 0 50 sub-K4_ses-PPXopenField-K4-day4 K4 Drd1aCre M 6-OHDA 2023-12-19T19:17:55.543000-08:00 0.0+30.2; 31.2+377.6 32 32 21848426 False 0 51 sub-N4_ses-PPXopenField-N4-day3 N4 Drd1aCre M 6-OHDA 2021-05-22T20:18:46.327000-07:00 0.0+69.3; 71.8+57.7; 130.1+289.8 32 29 15719661 False 0 52 sub-N4_ses-PPXopenField-N4-day4 N4 Drd1aCre M 6-OHDA 2021-05-25T20:01:23.260000-07:00 0.0+59.6; 60.2+180.7 32 28 13333752 False 0 53 sub-P2_ses-PPXopenField-P2-day1 P2 A2aCre F saline 2020-10-13T22:00:27.030000-07:00 0.0+16.2; 16.2+135.6 32 20 16570679 False 0 54 sub-P2_ses-PPXopenField-P2-day2 P2 A2aCre F saline 2020-10-14T18:46:53-07:00 0.0+159.0 32 27 33381076 False 0 55 sub-P4_ses-PPXopenField-P4-day1 P4 A2aCre M saline 2021-05-26T17:25:53.296000-07:00 0.0+127.8; 128.4+307.1 32 0 0 True 42
subj = survey.drop_duplicates("subject")
print("subjects:", len(subj), "| by lesion:", subj.lesion.value_counts().to_dict(),
"| by genotype:", subj.genotype.str.replace("-", "").value_counts().to_dict())
print("sessions by kind:", survey.path.str.contains("Saline").map({True: "saline", False: "PPX"}).value_counts().to_dict())
print("saline-session mice:", sorted(survey[survey.path.str.contains("Saline")].subject))
print("files with a units table:", survey[survey.has_units].path.tolist())
print("units table columns:", survey[survey.has_units].units_columns.unique().tolist())
for _, r in survey[survey.has_units].iterrows():
c = np.array(r.unit_spike_counts)
print(f" {r.path}: {len(c)} units, spike counts {c.min()} to {c.max()}; even-numbered units median "
f"{np.median(c[::2]):.0f}, odd-numbered median {np.median(c[1::2]):.0f}")
print("files with intervals, stimulus or optogenetics metadata:",
int((survey.intervals != "").sum()), int((survey.stimulus != "").sum()), int(survey.ogen.sum()))
print("processing modules:", survey.processing.unique().tolist())
print("session start years:", survey.start.str[:4].value_counts().sort_index().to_dict())
print("description encoding (first 40 characters):", survey.description_start.iloc[0])
subjects: 18 | by lesion: {'6-OHDA': 11, 'saline': 7} | by genotype: {'Drd1aCre': 11, 'A2aCre': 7}
sessions by kind: {'PPX': 52, 'saline': 4}
saline-session mice: ['D0', 'E0', 'H1.3', 'H4.3']
files with a units table: ['sub-E0_ses-PPXopenField-E0-day4', 'sub-P4_ses-PPXopenField-P4-day1']
units table columns: ['spike_times,unit_name']
sub-E0_ses-PPXopenField-E0-day4: 60 units, spike counts 1 to 2108473; even-numbered units median 9838, odd-numbered median 657980
sub-P4_ses-PPXopenField-P4-day1: 42 units, spike counts 48 to 639831; even-numbered units median 72753, odd-numbered median 83826
files with intervals, stimulus or optogenetics metadata: 0 0 0
processing modules: ['ecephys/LFP']
session start years: {'2020': 2, '2021': 7, '2022': 21, '2023': 23, '2025': 3}
description encoding (first 40 characters): A total of 1.5 microliters of saline w
for _, r in survey[survey.has_units].iterrows():
u = icd.open_nwb(assets.asset_id[assets.path.str.contains(r.path, regex=False)].iloc[0])["units"]
names = [x.decode() if isinstance(x, bytes) else str(x) for x in u["unit_name"][:]]
print(f"{r.path}: units columns {list(u.keys())}; unit_name values {names[:5]} ... {names[-3:]} "
f"(all integers 0 to n-1: {names == [str(i) for i in range(len(names))]})")
sub-E0_ses-PPXopenField-E0-day4: units columns ['id', 'spike_times', 'spike_times_index', 'unit_name']; unit_name values ['0', '1', '2', '3', '4'] ... ['57', '58', '59'] (all integers 0 to n-1: True)
sub-P4_ses-PPXopenField-P4-day1: units columns ['id', 'spike_times', 'spike_times_index', 'unit_name']; unit_name values ['0', '1', '2', '3', '4'] ... ['39', '40', '41'] (all integers 0 to n-1: True)
What the dandiset holds: 18 mice, 7 with striatal saline and 11 with 6-OHDA (as the paper's Ctrl
N = 7 and Park N = 11), 52 PPX open field sessions and 4 saline sessions (4 mice, as Figure S5E),
each a 30 kHz 32-channel recording split into segments (most often about 30 min, then about 300 min,
then about 70 min, the last presumably the laser session), the 1 kHz LFP, and per electrode the
threshold crossings with their 48-sample waveforms ("Events detected with threshold crossing,
manually set for each electrode"). These are the input to the paper's manual sorting in Plexon
Offline Sorter, not its output. Two files carry a units table, with spike times only; in both,
even-numbered units have far more spikes than odd-numbered ones, consistent with an unsorted and a
sorted cluster per channel, but no column says which, nor the channel, the MSN class or the
optical label; their unit_name column holds only the integers 0 to n-1. No file has laser pulse times, an injection time or behaviour. The segment gaps are
consistent with an injection after the first 30 min, but this is not stated in the files.
No session has a trial or event table, so whether the streams share a trial clock cannot be
established for any electrophysiology session; this is moot here, as no claim on them is tested.
Zenodo deposit: the files, then the delay discounting sessions parsed from the raw operant logs.
files = icd.zenodo_files()
print(files.to_string())
groups = icd.readme_groups()
print({f"{e}/{g}": len(v) for (e, g), v in groups.items()})
sess = icd.sessions()
print("skipped files:", sess.attrs["skipped"])
print(sess.drop_duplicates(["experiment", "file"]).groupby(["experiment", "group", "condition"]).agg(
mice=("mouse", "nunique"), sessions=("file", "nunique")).to_string())
print("mice per experiment and group with no drug session:",
sess.groupby(["experiment", "group", "mouse"]).condition.apply(lambda c: "on" not in set(c))
.loc[lambda s: s].index.tolist())
import hashlib
digests = {e: {n.split("/")[-1]: hashlib.md5(z.read(n)).hexdigest() for n in z.namelist()
if n.upper().endswith(".CSV") and not n.startswith("__")} for e, z in icd.cognitive_archives().items()}
for a in digests:
for b in digests:
if a < b:
common = set(digests[a]) & set(digests[b])
print(f"files in both {a} and {b}: {len(common)}, byte-identical {sum(digests[a][f] == digests[b][f] for f in common)}")
listed = {(e, m) for (e, g), ids in groups.items() for m in ids}
present = set(zip(sess.experiment, sess.mouse))
print("README mice with no delay discounting file:", sorted(listed - present))
print("free choice trials per block:", sess.trials.value_counts().sort_index().to_dict())
print("block labels (delay -> label: sessions):",
sess.groupby(["delay", "block_label"]).file.nunique().to_dict())
print("sessions dated from the log (file name malformed):",
sess[sess.date_from == "log"].drop_duplicates("file")[["file", "date"]].values.tolist())
print("range of % delayed/large:", sess.pct_large.min(), sess.pct_large.max(),
"| latency (s):", round(np.nanmin(sess.lat_all), 3), round(np.nanmax(sess.lat_all), 3))
key size_mb checksum 0 Data_ICD_Striatum_TH_Quantification_RawImages_cohort7.zip 10150.037067 md5:ac5c84255e0843330140639bc4170302 1 Data_ICD_Striatum_TH_Quantification_RawImages_cohort2.zip 4273.593546 md5:86d8ad67e6704c57cad806a02bc2da60 2 Data_ICD_FigS1_SNcTH_CellCounting_RawImages 2.zip 9190.857163 md5:f5d3336d6acbcfcd74ea545b5216ad54 3 Data_ICD_A77636OpenField_Raw.zip 75.851286 md5:1e154fb5ae37d95e145f083ec3fe05cf 4 README_ICD_CognitiveAssessment.txt 0.002194 md5:ffd1303a280d6f7132d7432f1573f65c 5 Data_ICD_Fig5_DREADDLocomotion_Raw.zip 81.884337 md5:e48cd0ba4e705c58f6b16809ba123d51 6 README_ICD_TH_Striatum_RawImages.txt 0.001805 md5:3593e5d9cb09e6da3096cbbfe4fcba62 7 README_ICD_LocomotionRaw.txt 0.001460 md5:ffcdfca9c83605ec9c7af6f913932f28 8 README_ICD_SNcTH_CellCounting_RawImages.txt 0.002394 md5:4c2164ad6d10847c9b6389277ade0e89 9 Data_ICD_Fig1_Rotarod_PPX.xlsx 0.010831 md5:f664394131446bc60ffc45c3c79f7f92 10 KeyResourceTable_ICD.xlsx 0.021407 md5:d5d3842aca6810b1f4167ab30720a48c 11 Data_ICD_FigS6_SliceValidation.xlsx 0.010469 md5:beedac9cd80832cd44721fa7cc5aaf1d 12 Data_ICD_Fig3_HistologyQuantification_striatum_raw.xlsx 0.243944 md5:1e44d08f5ec0c66b7ccefe78781de696 13 Data_ICD_Fig1&2&5&6_CognitiveAssay.zip 35.908733 md5:a7f44aa0cddf55a9856a14de6436edf8 14 Data_ICD_FigS1_SNcTH_CellCounting_RawImages.xlsx 0.137562 md5:c8600a97a775263b9d928e0f79a0f8a6 15 Data_ICD_Striatum_TH_Quantification_RawImages_cohort1.zip 2530.627526 md5:a50707dc5299bfe74572707d42f4228f 16 Data_ICD_Striatum_TH_Quantification_RawImages_cohort3.zip 3751.987414 md5:82785a096dee570a6687d0b1e81c91cb 17 Data_ICD_Striatum_TH_Quantification_RawImages_cohort4.zip 3914.302469 md5:9fdefa9e1117a00b9bd6fa734935fca8 18 Data_ICD_Striatum_TH_Quantification_RawImages_cohort5.zip 266.207508 md5:e0ac9e4a1998e6636fb40703f362acd5 19 Data_ICD_Striatum_TH_Quantification_RawImages_cohort6.zip 1330.661444 md5:f3c1bd1e97c764235e2845352b1e5617 20 Data_ICD_Striatum_TH_Quantification_RawImages_cohort8.zip 2053.840511 md5:34c9155c1560bead27137ef3e09a07c7
{'PPX/control': 16, 'PPX/parkinsonian': 31, 'A77636/control': 10, 'A77636/parkinsonian': 16, 'DREADD/mCherry': 15, 'DREADD/hM4Di': 12, 'DREADD/hM3Dq': 12}
skipped files: []
mice sessions
experiment group condition
A77636 control baseline 10 33
on 10 40
parkinsonian baseline 16 50
off 16 64
on 16 64
DREADD hM3Dq baseline 12 40
on 12 48
hM4Di baseline 12 41
on 12 43
mCherry baseline 14 43
on 14 55
PPX control baseline 16 49
on 16 60
parkinsonian baseline 31 98
off 30 105
on 30 117
mice per experiment and group with no drug session: [('PPX', 'parkinsonian', 'E6')]
files in both DREADD and PPX: 233, byte-identical 233
files in both A77636 and PPX: 0, byte-identical 0
files in both A77636 and DREADD: 75, byte-identical 75
README mice with no delay discounting file: [('DREADD', 'R5.5')]
free choice trials per block: {0: 30, 7: 2, 15: 1, 20: 3608, 30: 159}
block labels (delay -> label: sessions): {(0, 'B3_'): 877, (0, 'B3_free_0s'): 41, (3, 'B6_'): 877, (3, 'B6_free_6s'): 41, (6, 'B9_'): 877, (6, 'B9_free_12s'): 41, (9, ''): 30, (9, 'B12_'): 877, (9, 'B12_free_18s'): 11}
sessions dated from the log (file name malformed): [['D4.1_delay_03092.CSV', Timestamp('2022-03-09 00:00:00')], ['E6.2_delay_PPXwashout_0830122.CSV', Timestamp('2029-03-03 00:00:00')]]
range of % delayed/large: 0.0 100.0 | latency (s): 0.45 4.343
import hashlib, re
arch = icd.cognitive_archives()
info = {}
for e, z in arch.items():
for n in z.namelist():
b = n.split("/")[-1]
if n.startswith("__") or not b.upper().endswith(".CSV"):
continue
m = icd.DELAY_FILE.match(b.replace("CSV.CSV", ".CSV"))
info.setdefault(e, {})[b] = (hashlib.md5(z.read(n)).hexdigest(),
icd.condition_of(m.group("cond")) if m else "training (not delay discounting)")
for a in info:
for b in info:
if a < b:
common = [f for f in set(info[a]) & set(info[b]) if info[a][f][0] == info[b][f][0]]
print(f"byte-identical files in {a} and {b}: {len(common)}; condition tags",
pd.Series([info[a][f][1] for f in common]).value_counts().to_dict())
ids = {e: {m for (x, g), v in groups.items() if x == e for m in v} for e in ["PPX", "A77636", "DREADD"]}
for a, b in [("PPX", "A77636"), ("PPX", "DREADD"), ("A77636", "DREADD")]:
print(f"mice in both the {a} and {b} README lists:", sorted(ids[a] & ids[b]))
print("DREADD sessions by condition:", sess[sess.experiment == "DREADD"].drop_duplicates("file").condition.value_counts().to_dict())
byte-identical files in DREADD and PPX: 233; condition tags {'training (not delay discounting)': 215, 'baseline': 18}
byte-identical files in A77636 and PPX: 0; condition tags {}
byte-identical files in A77636 and DREADD: 75; condition tags {'training (not delay discounting)': 61, 'baseline': 14}
mice in both the PPX and A77636 README lists: []
mice in both the PPX and DREADD README lists: ['F5', 'F7', 'H0', 'H0.4', 'H1.4', 'H2', 'H2.1', 'H2.2', 'H3', 'H4.1', 'H5.1', 'H5.2']
mice in both the A77636 and DREADD README lists: ['O4.1', 'R17', 'R2.2', 'R4', 'R5']
DREADD sessions by condition: {'on': 146, 'baseline': 124}
files = icd.zenodo_files()
for k in files.key:
if k.lower().endswith(".txt"):
lines = [l.strip() for l in icd.zenodo_bytes(k).decode("utf-8", "replace").splitlines()]
print(f"{k}: {len(lines)} lines; lines naming sex, male or female: {[l for l in lines if re.search(r'sex|male|female', l, re.I)]}")
krt = [k for k in files.key if "KeyResource" in k]
for k in krt:
for sh, d in icd.read_excel(k).items():
print(f"{k} / {sh}: {d.shape}; first row: {d.iloc[0].dropna().tolist()}")
print(" cells naming sex, male or female:", [str(v) for v in d.to_numpy().ravel() if isinstance(v, str) and re.search(r"\b(sex|male|female)\b", v, re.I)])
README_ICD_CognitiveAssessment.txt: 61 lines; lines naming sex, male or female: []
README_ICD_TH_Striatum_RawImages.txt: 36 lines; lines naming sex, male or female: []
README_ICD_LocomotionRaw.txt: 39 lines; lines naming sex, male or female: []
README_ICD_SNcTH_CellCounting_RawImages.txt: 70 lines; lines naming sex, male or female: []
KeyResourceTable_ICD.xlsx / ICD_KRT: (49, 6); first row: ['RESOURCE TYPE', 'RESOURCE NAME', 'SOURCE', 'IDENTIFIER', 'NEW/REUSE', 'ADDITIONAL INFORMATION'] cells naming sex, male or female: []
The files shared between archives are training logs (nosepoke stages) and baseline delay discounting sessions only; no file tagged PPX, A77636 or CNO, and no washout file, sits in more than one archive, so the drug condition read from each file name belongs to the archive it is in. The DREADD archive has no washout sessions. Twelve PPX parkinsonian mice and five A77636 parkinsonian mice are also DREADD mice, as the shared baselines imply.
Sex (figs2abc-sex-similar). No README line and no cell of the Key Resource Table names sex, male or female, and no other deposit file gives a per-mouse table, so the claim is blocked.
Clock and block check. In every free choice block, the delay between the side nosepoke and the large reward delivery, measured on the logs' own clock, should equal the block's delay. This tests the block-to-delay mapping and that the event times share one clock.
def reward_delays(text):
out, block, poke = {}, None, None
for line in text.splitlines()[1:]:
p = [x.strip().strip('"') for x in line.split(",")]
if len(p) < 3:
continue
m = icd.re.match(r"B(\d+)_", p[1])
if m:
block = icd.FREE_BLOCKS.get("B" + m.group(1))
elif block is not None and p[1] in ("np_B in", "np_D in") and poke is None:
poke = icd._ms(p[2])
elif p[1] == "trial start" or p[1] == "cen tri":
poke = None
elif block is not None and p[1] == "l reward delivery" and poke is not None:
out.setdefault(block, []).append((icd._ms(p[2]) - poke) / 1000)
return out
rows = []
for exp, zf in icd.cognitive_archives().items():
for name in zf.namelist():
base = name.split("/")[-1]
if "_delay" in base and not name.startswith("__"):
for d, v in reward_delays(zf.read(name).decode("latin-1")).items():
rows.append({"experiment": exp, "file": base, "delay": d, "median_s": np.median(v),
"old_labels": base.startswith("P")})
rd = pd.DataFrame(rows)
print(rd.groupby(["experiment", "old_labels", "delay"]).median_s.describe()[["count", "25%", "50%", "75%"]].round(2))
count 25% 50% 75%
experiment old_labels delay
A77636 False 0 249.0 0.01 0.02 0.02
3 244.0 3.01 3.01 3.02
6 219.0 6.01 6.01 6.02
9 206.0 9.01 9.01 9.02
DREADD False 0 270.0 0.01 0.02 0.02
3 268.0 3.01 3.01 3.02
6 260.0 6.01 6.01 6.02
9 243.0 9.01 9.01 9.02
PPX False 0 386.0 0.01 0.02 0.02
3 379.0 3.01 3.02 3.02
6 335.0 6.01 6.02 6.02
9 307.0 9.01 9.02 9.02
True 0 41.0 0.06 0.07 0.08
3 40.0 3.05 3.05 3.05
6 40.0 6.03 6.03 6.04
9 11.0 12.03 12.03 12.04
# One session's events in the 0 s free choice block, with what the parser makes of each
z = icd.cognitive_archives()["PPX"]
name = sorted(n for n in z.namelist() if n.split("/")[-1].startswith("D3_delay") and not n.startswith("__"))[0]
text = z.read(name).decode("latin-1")
lines = text.splitlines()
start = next(i for i, l in enumerate(lines) if "B3_" in l)
print(name.split("/")[-1], "| header:", lines[0][:120])
kept = [l for l in lines[start:] if any(e in l for e in ("B3_", "B6_", "trial start", "cen tri", "np_B in", "np_D in", "reward delivery", " omi"))]
cue = False
for l in kept[:24]:
p = [x.strip().strip('"') for x in l.split(",")]
ev = p[1] if len(p) > 1 else ""
if ev in ("np_B in", "np_D in"):
note = "side nosepoke: ends the latency" if cue else "side nosepoke outside a cue: not used"
cue = False
else:
note = {"trial start": "trial counted", "cen tri": "side cue on: latency clock starts",
"l reward delivery": "delayed/large choice", "s reward delivery": "immediate/small choice",
"center omi": "center omission", "side omi": "side omission"}.get(ev, "block marker" if ev.startswith("B") else "")
cue = True if ev == "cen tri" else (False if ev == "trial start" else cue)
print(f" {l[:70]:70s} {note}")
s = icd.parse_session(text)
print({d: {k: (len(v) if isinstance(v, list) else v) for k, v in b.items()} for d, b in s["blocks"].items()})
print("first latencies in the 0 s block (ms):", s["blocks"][0]["lat_large"][:3], s["blocks"][0]["lat_small"][:3])
D3_delay_030722.CSV | header: Date, Event Name, Event Time
"2022/3/7 17:19:38", B3_, 00:10:30:506 block marker
"2022/3/7 17:19:38", trial start, 00:10:30:519 trial counted
"2022/3/7 17:19:39", cen tri, 00:10:31:303 side cue on: latency clock starts
"2022/3/7 17:19:41", np_D in, 00:10:32:980 side nosepoke: ends the latency
"2022/3/7 17:19:41", l reward delivery, 00:10:32:994 delayed/large choice
"2022/3/7 17:20:6", np_D in, 00:10:57:982 side nosepoke outside a cue: not used
"2022/3/7 17:20:13", np_D in, 00:11:05:247 side nosepoke outside a cue: not used
"2022/3/7 17:20:19", np_D in, 00:11:11:171 side nosepoke outside a cue: not used
"2022/3/7 17:20:30", np_D in, 00:11:22:658 side nosepoke outside a cue: not used
"2022/3/7 17:20:30", np_D in, 00:11:22:691 side nosepoke outside a cue: not used
"2022/3/7 17:20:33", trial start, 00:11:25:521 trial counted
"2022/3/7 17:20:34", cen tri, 00:11:26:368 side cue on: latency clock starts
"2022/3/7 17:20:36", np_D in, 00:11:27:966 side nosepoke: ends the latency
"2022/3/7 17:20:36", l reward delivery, 00:11:27:992 delayed/large choice
"2022/3/7 17:21:5", np_D in, 00:11:57:327 side nosepoke outside a cue: not used
"2022/3/7 17:21:28", trial start, 00:12:20:524 trial counted
"2022/3/7 17:21:32", np_D in, 00:12:23:870 side nosepoke outside a cue: not used
"2022/3/7 17:21:32", np_D in, 00:12:23:983 side nosepoke outside a cue: not used
"2022/3/7 17:21:33", cen tri, 00:12:24:862 side cue on: latency clock starts
"2022/3/7 17:21:34", np_D in, 00:12:26:132 side nosepoke: ends the latency
"2022/3/7 17:21:34", l reward delivery, 00:12:26:146 delayed/large choice
"2022/3/7 17:22:14", np_D in, 00:13:05:793 side nosepoke outside a cue: not used
"2022/3/7 17:22:14", np_D in, 00:13:05:862 side nosepoke outside a cue: not used
"2022/3/7 17:22:14", np_D in, 00:13:05:905 side nosepoke outside a cue: not used
{0: {'large': 18, 'small': 1, 'center_om': 0, 'side_om': 1, 'trials': 20, 'lat_large': 18, 'lat_small': 1}, 3: {'large': 19, 'small': 1, 'center_om': 0, 'side_om': 0, 'trials': 20, 'lat_large': 19, 'lat_small': 1}, 6: {'large': 13, 'small': 5, 'center_om': 0, 'side_om': 2, 'trials': 20, 'lat_large': 13, 'lat_small': 5}, 9: {'large': 19, 'small': 0, 'center_om': 1, 'side_om': 0, 'trials': 20, 'lat_large': 19, 'lat_small': 0}}
first latencies in the 0 s block (ms): [1677, 1598, 1270] [2786]
One block of one session, as parsed: each trial starts with "trial start", the side cue light with "cen tri", and the first side nosepoke after the cue ends the choice latency; side pokes outside a cue are not used. The printed counts and latencies are those of this file (latency 1677 ms is 32.980 s minus 31.303 s).
The measured nosepoke-to-reward delays are about 0, 3, 6 and 9 s in the four free choice blocks of every experiment, so the blocks are the paper's delays and the logs keep one clock. The exception is the 2020 cohort of six control PPX mice (files of mice P1 to P7), whose block labels name delays of 0, 6, 12 and 18 s and whose measured delays agree with those labels; 30 of their sessions have no fourth block. The paper's code counts these blocks as the other mice's; so does this analysis, which is a deviation noted under each affected claim. Sessions of the 2021 cohort (C mice) have 30 free choice trials per block, the Methods 20.
Shared definitions for the delay discounting claims. Per mouse and condition, the per-delay value is the mean over the condition's sessions. Readings, from the claims file:
- baseline (a) every baseline session in the deposit, (b) the last stable run by the Methods' CV rule;
- drug ON (a) the first ON session by date, (b) the mean over the first four ON sessions;
- drug OFF: every washout session (the claims file gives no reading; all are used, as Summary_Cognitive.m averages a mouse's sessions within a condition), with the first OFF session as a variant.
W = icd.wide(sess)
D = icd.DELAYS
def per_mouse(exp, group, cond, reading, value="pct_large"):
w = (icd.wide(sess, value) if value != "pct_large" else W)
w = w[(w.experiment == exp) & (w.group == group) & (w.condition == cond)].sort_values("date")
out = {}
for m, g in w.groupby("mouse"):
if reading == "all":
sel = g
elif reading == "first":
sel = g.head(1)
elif reading == "four":
sel = g.head(4)
elif reading == "fourth":
sel = g.iloc[3:4]
elif reading == "stable":
later = W[(W.experiment == exp) & (W.mouse == m) & (W.condition != "baseline")].date.min()
files_b = W[(W.experiment == exp) & (W.mouse == m) & (W.condition == "baseline")]
files_b = files_b[files_b.date < later] if pd.notna(later) else files_b
sel = g[g.file.isin(icd.stable_window(files_b))]
if len(sel):
out[m] = sel[D].mean()
t = pd.DataFrame(out).T
t.index.name = "mouse"
return t
def long(tab, **kw):
l = tab.reset_index().melt(id_vars="mouse", var_name="delay", value_name="v")
for k, v in kw.items():
l[k] = v
return l
def drug_test(exp, group, rb, rd, value="pct_large"):
base, on = per_mouse(exp, group, "baseline", rb, value), per_mouse(exp, group, "on", rd, value)
L = pd.concat([long(base, t="baseline"), long(on, t="on")])
return icd.split_plot_anova(L, "v", "t", ["baseline", "on"])
def show(res, label):
print(f"{label}: mice {res['n_mice']}, units {res['n_units']}, treatment F{res['treat_df']} = "
f"{res['treat_F']:.3f}, p = {res['treat_p']:.3g}; delay F{res['delay_df']} = {res['delay_F']:.2f}, "
f"p = {res['delay_p']:.3g}; interaction p = {res['inter_p']:.3g}")
print(res["per_delay"].round(4).to_string(index=False))
def params(tab):
r = {m: icd.fit_curve(row.values / 100) for m, row in tab.iterrows()}
return pd.DataFrame(r, index=["A", "K", "AUC"]).T
fig1fg-baseline-similar¶
PPX-naive control and parkinsonian mice showed similar delay discounting.
Criterion: two-way ANOVA on group and delay (Table 1), Bonferroni per delay; reproduced when the group effect and every per-delay comparison have p >= 0.05.
baseline_res = {}
for r in ["all", "stable"]:
b = {g: per_mouse("PPX", g, "baseline", r) for g in ["control", "parkinsonian"]}
L = pd.concat([long(b[g], grp=g) for g in b])
res = icd.between_anova(L, "v", "grp")
baseline_res[r] = res
print(f"reading {r}: mice {res['n_mice']}; group F{res['df']} = {res['factor_F']:.4f}, p = {res['factor_p']:.4f}; "
f"delay F{res['delay_df']} = {res['delay_F']:.2f}, p = {res['delay_p']:.3g}; interaction p = {res['inter_p']:.3f}")
print(res["per_delay"].round(3).to_string(index=False))
nostable = [m for g in ["control", "parkinsonian"] for m in per_mouse("PPX", g, "baseline", "all").index
if m not in per_mouse("PPX", g, "baseline", "stable").index]
print("mice with no stable run under the CV rule:", len(nostable))
reading all: mice {'control': 16, 'parkinsonian': 31}; group F(1, 178) = 0.0071, p = 0.9329; delay F(3, 178) = 38.15, p = 4.33e-19; interaction p = 0.870
delay control parkinsonian n0 n1 p_bonf
0 91.686 85.721 16 31 1.0
3 53.863 57.029 16 31 1.0
6 38.684 39.382 16 31 1.0
9 32.123 32.852 14 31 1.0
reading stable: mice {'control': 3, 'parkinsonian': 9}; group F(1, 40) = 2.6366, p = 0.1123; delay F(3, 40) = 2.14, p = 0.11; interaction p = 0.719
delay control parkinsonian n0 n1 p_bonf
0 95.388 95.664 3 9 1.000
3 92.652 80.750 3 9 1.000
6 85.237 73.259 3 9 1.000
9 82.377 58.767 3 9 0.449
mice with no stable run under the CV rule: 35
rows = []
for g in ["control", "parkinsonian"]:
for m in per_mouse("PPX", g, "baseline", "all").index:
later = W[(W.experiment == "PPX") & (W.mouse == m) & (W.condition != "baseline")].date.min()
b = W[(W.experiment == "PPX") & (W.mouse == m) & (W.condition == "baseline")].sort_values("date")
n_all = len(b)
b = b[b.date < later] if pd.notna(later) else b
vals = b[D].to_numpy(float)
best = {}
for n in (3, 2):
for i in range(len(b) - n + 1):
w = vals[i:i + n]
cv = np.nanstd(w, axis=0, ddof=1) / np.nanmean(w, axis=0) * 100
if (n not in best) or np.sum(cv < 20) > np.sum(best[n] < 20):
best[n] = cv
rows.append({"group": g, "mouse": m, "baselines_all": n_all, "baselines_before_drug": len(b),
"stable": bool(icd.stable_window(b)),
"CV_3_sessions": " ".join(f"{x:.0f}" for x in best[3]) if 3 in best else "",
"CV_2_sessions": " ".join(f"{x:.0f}" for x in best[2]) if 2 in best else ""})
st = pd.DataFrame(rows)
print("Per mouse: baseline sessions before the first drug session, and the per-block CV (%, 0/3/6/9 s) of the"
" 3-session and 2-session windows with the most blocks under 20%:")
print(st.to_string(index=False))
print(st.groupby("group").agg(mice=("mouse", "size"), stable=("stable", "sum"),
median_baselines=("baselines_before_drug", "median")).to_string())
print("baseline sessions per mouse, all deposited: min", st.baselines_all.min(), "max", st.baselines_all.max(),
"| before the first drug session: min", st.baselines_before_drug.min(), "max", st.baselines_before_drug.max())
s_means = {r: {g: per_mouse("PPX", g, "baseline", r).mean().round(1).tolist() for g in ["control", "parkinsonian"]} for r in ["all", "stable"]}
print("mean % delayed/large at 0/3/6/9 s, every baseline:", s_means["all"], "| stable mice only:", s_means["stable"])
Per mouse: baseline sessions before the first drug session, and the per-block CV (%, 0/3/6/9 s) of the 3-session and 2-session windows with the most blocks under 20%:
group mouse baselines_all baselines_before_drug stable CV_3_sessions CV_2_sessions
control C1.1 3 3 False 17 90 nan nan 6 141 nan nan
control D2 3 3 False 11 116 173 88 7 141 141 141
control D2.1 3 3 False 19 34 64 140 15 38 11 141
control D4.2 3 3 True 4 5 4 4 0 4 5 4
control E1 3 3 True 6 7 5 27 0 4 0 4
control F1.1 3 3 False 3 16 35 79 4 23 18 61
control F4 3 3 False 18 34 37 45 18 12 8 47
control H4 2 2 True 0 0 0 10
control J1 3 3 False 12 35 68 53 17 51 70 13
control J3.1 4 4 False 3 29 10 52 4 30 14 76
control P1 4 4 False 19 20 30 52 19 9 27 75
control P2 3 3 False 3 31 50 32 4 1 71 nan
control P4 3 3 False 7 31 66 14 9 44 51 14
control P5 3 3 False 0 92 88 nan 0 141 85 nan
control P6 3 3 False 0 44 58 20 0 11 86 6
control P7 3 3 False 3 50 12 nan 4 68 15 nan
parkinsonian C2 3 3 False 6 15 44 41 3 21 13 8
parkinsonian C3.1 3 3 False 7 96 58 103 9 3 5 141
parkinsonian C9 3 3 False 2 38 102 50 2 10 125 35
parkinsonian D2.2 3 3 True 10 39 57 43 12 0 17 0
parkinsonian D3 3 3 True 3 10 18 10 0 14 0 12
parkinsonian D4 3 3 False 19 16 32 35 23 20 29 4
parkinsonian D4.1 3 3 False 11 67 105 141 16 77 117 105
parkinsonian D6 3 3 False 42 23 23 40 35 7 33 7
parkinsonian E3.3 3 3 False 6 9 69 57 4 12 82 85
parkinsonian E4 4 4 True 0 0 0 6 0 0 0 0
parkinsonian E6 3 3 False 17 60 50 69 19 82 40 0
parkinsonian E6.2 3 3 True 15 2 17 17 9 2 4 22
parkinsonian E7 3 3 False 9 67 55 45 12 47 20 11
parkinsonian E9 3 3 False 19 62 173 87 24 80 141 4
parkinsonian F5 3 3 True 3 7 3 6 4 8 0 8
parkinsonian F7 4 4 False 5 65 143 173 27 4 16 40
parkinsonian H0 2 2 False 5 4 27 85
parkinsonian H0.4 5 5 False 114 90 127 173 5 29 54 33
parkinsonian H1.4 4 2 False 4 42 0 54
parkinsonian H2 2 2 False 7 8 24 13
parkinsonian H2.1 3 1 False
parkinsonian H2.2 2 2 False 12 8 47 141
parkinsonian H3 4 2 True 4 8 9 17
parkinsonian H4.1 4 3 True 0 3 5 10 0 4 4 13
parkinsonian H5.1 2 2 False 73 32 71 82
parkinsonian H5.2 3 3 False 20 19 18 42 0 27 20 3
parkinsonian N0 3 3 False 0 12 66 25 0 17 92 7
parkinsonian N1 3 3 True 6 13 11 4 7 16 4 6
parkinsonian N4 3 3 False 14 50 87 173 18 7 141 nan
parkinsonian N5 4 4 False 16 62 173 173 18 94 141 nan
parkinsonian N5.1 4 4 True 3 14 48 19 0 13 8 26
mice stable median_baselines
group
control 16 3 3.0
parkinsonian 31 9 3.0
baseline sessions per mouse, all deposited: min 2 max 5 | before the first drug session: min 1 max 5
mean % delayed/large at 0/3/6/9 s, every baseline: {'control': [91.7, 53.9, 38.7, 32.1], 'parkinsonian': [85.7, 57.0, 39.4, 32.9]} | stable mice only: {'control': [95.4, 92.7, 85.2, 82.4], 'parkinsonian': [95.7, 80.8, 73.3, 58.8]}
Result: reproduced. Under reading (a), every baseline session (16 control and 31 parkinsonian mice), the group effect is F = 0.007, p = 0.93 (paper F = 0.003, p = 0.96) and no per-delay comparison differs (all Bonferroni p = 1). Reading (b) keeps only the 12 mice whose deposited baseline sessions pass the CV rule (3 of 16 control, 9 of 31 parkinsonian); it also finds no group effect (p = 0.11) and no per-delay difference. Reading (b) is not a sample of the paper's cohort: most mice have only 2 to 4 baselines before the first drug session (median 3), and the mice that pass are those whose curves barely fall (control 95.4% at 0 s to 82.4% at 9 s, against 91.7% to 32.1% for every mouse), so the outcome rests on reading (a). The two control mice of the 2020 cohort without a fourth block are missing at 9 s.
fig1fg-delay-discounting¶
At baseline both control and parkinsonian mice chose the delayed/large reward less often as its delay increased.
Criterion: the ANOVA above; reproduced when the delay effect has p < 0.05 and in each group the mean is lower at 9 s than at 0 s.
for r, res in baseline_res.items():
pdl = res["per_delay"].set_index("delay")
print(f"reading {r}: delay F{res['delay_df']} = {res['delay_F']:.2f}, p = {res['delay_p']:.3g}; "
f"control {pdl.loc[0, 'control']:.1f} -> {pdl.loc[9, 'control']:.1f} %, "
f"parkinsonian {pdl.loc[0, 'parkinsonian']:.1f} -> {pdl.loc[9, 'parkinsonian']:.1f} % (0 s -> 9 s)")
fig, ax = plt.subplots(figsize=(4, 3))
for g in ["control", "parkinsonian"]:
t = per_mouse("PPX", g, "baseline", "all")
ax.errorbar(D, t.mean(), t.sem(), marker="o", label=g)
ax.set(xlabel="delay (s)", ylabel="% delayed/large", ylim=(0, 100), title="Baseline, reading (a)")
ax.legend()
plt.show()
reading all: delay F(3, 178) = 38.15, p = 4.33e-19; control 91.7 -> 32.1 %, parkinsonian 85.7 -> 32.9 % (0 s -> 9 s) reading stable: delay F(3, 40) = 2.14, p = 0.11; control 95.4 -> 82.4 %, parkinsonian 95.7 -> 58.8 % (0 s -> 9 s)
Result: reproduced. Under reading (a) the delay effect is F(3, 178) = 38.15, p = 4e-19 (paper F(3, 180) = 38.53), and the choice of the delayed/large reward falls from 91.7 to 32.1% in control and from 85.7 to 32.9% in parkinsonian mice between 0 and 9 s. Under reading (b) the means also fall (95.4 to 82.4%, 95.7 to 58.8%) but the delay effect is not significant (p = 0.11) in 12 mice, which are the mice that discount least (above), so reading (b) does not bear on the claim.
fig1f-ctrl-ppx-no-change and fig1g-park-ppx-fewer-large¶
PPX did not change delay discounting in healthy control mice. In parkinsonian mice PPX reduced the likelihood of choosing the delayed/large reward at every delay.
Split-plot ANOVA (unit = mouse x delay, see icd.py) of baseline against PPX ON, Bonferroni per
delay on the pooled error (paired t tests as a variant). Readings: baseline (a)/(b) x PPX first/four.
for rb in ["all", "stable"]:
for rd in ["first", "four"]:
show(drug_test("PPX", "control", rb, rd), f"control, baseline {rb}, PPX {rd}")
control, baseline all, PPX first: mice 16, units 58, treatment F(1, 54) = 2.767, p = 0.102; delay F(3, 54) = 12.15, p = 3.47e-06; interaction p = 0.994
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 16 91.6864 86.3289 -5.3576 1.0 0.3437
3 on 16 53.8628 49.9383 -3.9246 1.0 1.0000
6 on 16 38.6839 35.0749 -3.6090 1.0 1.0000
9 on 10 35.9417 32.2458 -3.6959 1.0 1.0000
control, baseline all, PPX four: mice 16, units 58, treatment F(1, 54) = 1.982, p = 0.165; delay F(3, 54) = 12.81, p = 1.96e-06; interaction p = 0.835
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 16 91.6864 86.1761 -5.5104 0.535 0.2138
3 on 16 53.8628 52.5610 -1.3018 1.000 1.0000
6 on 16 38.6839 36.8143 -1.8697 1.000 1.0000
9 on 10 35.9417 34.3093 -1.6324 1.000 1.0000
control, baseline stable, PPX first: mice 3, units 12, treatment F(1, 8) = 0.857, p = 0.382; delay F(3, 8) = 0.48, p = 0.707; interaction p = 0.899
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 3 95.3885 96.4912 1.1028 1.0 1.0000
3 on 3 92.6515 94.7368 2.0853 1.0 1.0000
6 on 3 85.2365 89.4737 4.2371 1.0 0.8774
9 on 3 82.3768 82.4561 0.0793 1.0 1.0000
control, baseline stable, PPX four: mice 3, units 12, treatment F(1, 8) = 1.423, p = 0.267; delay F(3, 8) = 0.26, p = 0.853; interaction p = 0.997
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 3 95.3885 90.6043 -4.7842 1.0 1.0
3 on 3 92.6515 85.9649 -6.6866 1.0 1.0
6 on 3 85.2365 80.0292 -5.2073 1.0 1.0
9 on 3 82.3768 74.9484 -7.4284 1.0 1.0
Result: reproduced. In the 16 control mice the PPX effect is not significant under any reading (p = 0.10 to 0.38; paper F(1, 60) = 0.96, p = 0.33), and no per-delay comparison reaches p < 0.05 on the pooled error. With the first four PPX sessions and every baseline, F(1, 54) = 1.98, p = 0.16. Six control mice of the 2020 cohort had delays of 0, 6, 12 and 18 s; their fourth block is missing in some sessions, so 10 mice enter at 9 s.
for rb in ["all", "stable"]:
for rd in ["first", "four"]:
show(drug_test("PPX", "parkinsonian", rb, rd), f"parkinsonian, baseline {rb}, PPX {rd}")
parkinsonian, baseline all, PPX first: mice 30, units 120, treatment F(1, 116) = 28.559, p = 4.6e-07; delay F(3, 116) = 19.02, p = 4.24e-10; interaction p = 0.102
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 30 85.6118 72.4719 -13.1399 0.0006 0.0473
3 on 30 57.3981 45.1491 -12.2491 0.0016 0.0008
6 on 30 39.9275 31.9118 -8.0157 0.0740 0.0153
9 on 30 32.9257 30.4727 -2.4530 1.0000 1.0000
parkinsonian, baseline all, PPX four: mice 30, units 120, treatment F(1, 116) = 91.457, p = 2.51e-16; delay F(3, 116) = 21.21, p = 5.03e-11; interaction p = 0.0621
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 30 85.6118 73.1243 -12.4875 0.0000 0.0007
3 on 30 57.3981 42.7435 -14.6546 0.0000 0.0000
6 on 30 39.9275 30.2722 -9.6553 0.0002 0.0000
9 on 30 32.9257 26.5300 -6.3957 0.0218 0.0034
parkinsonian, baseline stable, PPX first: mice 9, units 36, treatment F(1, 32) = 11.494, p = 0.00187; delay F(3, 32) = 3.48, p = 0.0272; interaction p = 0.223
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 9 95.6644 92.6023 -3.0621 1.0000 0.7218
3 on 9 80.7501 66.1113 -14.6389 0.0192 0.0225
6 on 9 73.2594 61.3223 -11.9371 0.0759 0.4307
9 on 9 58.7668 55.6537 -3.1131 1.0000 1.0000
parkinsonian, baseline stable, PPX four: mice 9, units 36, treatment F(1, 32) = 35.415, p = 1.25e-06; delay F(3, 32) = 3.41, p = 0.0291; interaction p = 0.0287
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 9 95.6644 90.4360 -5.2284 0.3390 0.4562
3 on 9 80.7501 66.7590 -13.9911 0.0002 0.0006
6 on 9 73.2594 60.5133 -12.7461 0.0005 0.0147
9 on 9 58.7668 55.7528 -3.0140 1.0000 1.0000
Result: reproduced. With every baseline session and the mean of the four PPX sessions, the PPX effect is F(1, 116) = 91.46, p = 2.5e-16 (paper F(1, 120) = 95.48) and the delayed/large choices are lower under PPX at all four delays (Bonferroni p < 0.0001, < 0.0001, 0.0002 and 0.022 at 0, 3, 6 and 9 s; paired variant p <= 0.0034). With the first PPX session only, two of four delays are significant on the pooled error (three with paired tests). 30 of the 31 parkinsonian mice have PPX sessions in the deposit (mouse E6 has only baseline sessions).
fig1ijk-ppx-a-k-auc¶
In parkinsonian mice PPX decreased A, increased K and reduced the area under the discounting curve.
Fit of V = A/(1 + K D) per mouse and condition, Friedman over baseline, PPX ON and PPX OFF, Dunn's comparisons against baseline (Bonferroni over two).
def friedman_block(exp, group, ron, roff, label):
P = {"baseline": params(per_mouse(exp, group, "baseline", "all")),
"on": params(per_mouse(exp, group, "on", ron)),
"off": params(per_mouse(exp, group, "off", roff))}
fails = {k: int(v.A.isna().sum()) for k, v in P.items()}
out = {}
for p in ["A", "K", "AUC"]:
t = pd.DataFrame({k: v[p] for k, v in P.items()})
r = icd.friedman_dunn(t, "baseline")
rm = icd.rm_oneway(t, "baseline")
out[p] = (r, rm, t)
print(f"{label} {p}: n = {r['n']}, Friedman chi2 = {r['chi2']:.2f}, p = {r['p']:.3g}; "
+ "; ".join(f"Dunn baseline vs {c}: median {v['median_ref']:.3f} -> {v['median']:.3f}, p = {v['p_bonf']:.3g}"
for c, v in r["dunn"].items())
+ f" | RM ANOVA p = {rm['p']:.3g}, Bonferroni paired " + ", ".join(f"{k} p = {v:.3g}" for k, v in rm["pairs"].items())
+ ", pooled error " + ", ".join(f"{k} p = {v:.3g}" for k, v in rm["pairs_pooled"].items()))
print(f"{label}: failed fits per condition {fails}")
return out
ppx_params = {}
for ron, roff in [("four", "all"), ("four", "first"), ("first", "all"), ("first", "first")]:
ppx_params[(ron, roff)] = friedman_block("PPX", "parkinsonian", ron, roff, f"PPX ON {ron}, OFF {roff}")
PPX ON four, OFF all A: n = 30, Friedman chi2 = 27.27, p = 1.2e-06; Dunn baseline vs on: median 0.891 -> 0.785, p = 1.86e-06; Dunn baseline vs off: median 0.891 -> 0.879, p = 0.732 | RM ANOVA p = 2.88e-07, Bonferroni paired baseline vs on p = 0.000178, baseline vs off p = 1, on vs off p = 3.19e-05, pooled error baseline vs on p = 2.24e-06, baseline vs off p = 1, on vs off p = 5.06e-06
PPX ON four, OFF all K: n = 30, Friedman chi2 = 6.87, p = 0.0323; Dunn baseline vs on: median 0.258 -> 0.321, p = 0.187; Dunn baseline vs off: median 0.258 -> 0.419, p = 0.0196 | RM ANOVA p = 0.0276, Bonferroni paired baseline vs on p = 0.148, baseline vs off p = 0.0634, on vs off p = 1, pooled error baseline vs on p = 0.191, baseline vs off p = 0.0278, on vs off p = 1
PPX ON four, OFF all AUC: n = 30, Friedman chi2 = 33.07, p = 6.6e-08; Dunn baseline vs on: median 3.948 -> 2.905, p = 2.69e-08; Dunn baseline vs off: median 3.948 -> 3.379, p = 0.0777 | RM ANOVA p = 1.44e-07, Bonferroni paired baseline vs on p = 5.08e-07, baseline vs off p = 0.0388, on vs off p = 0.00108, pooled error baseline vs on p = 6.83e-08, baseline vs off p = 0.00717, on vs off p = 0.00509
PPX ON four, OFF all: failed fits per condition {'baseline': 0, 'on': 0, 'off': 0}
PPX ON four, OFF first A: n = 29, Friedman chi2 = 22.97, p = 1.03e-05; Dunn baseline vs on: median 0.899 -> 0.787, p = 2.94e-05; Dunn baseline vs off: median 0.899 -> 0.960, p = 1 | RM ANOVA p = 5.11e-05, Bonferroni paired baseline vs on p = 0.000377, baseline vs off p = 1, on vs off p = 0.00119, pooled error baseline vs on p = 0.000178, baseline vs off p = 1, on vs off p = 0.000441
PPX ON four, OFF first K: n = 29, Friedman chi2 = 2.69, p = 0.261; Dunn baseline vs on: median 0.252 -> 0.300, p = 0.23; Dunn baseline vs off: median 0.252 -> 0.318, p = 0.475 | RM ANOVA p = 0.176, Bonferroni paired baseline vs on p = 0.0617, baseline vs off p = 0.424, on vs off p = 1, pooled error baseline vs on p = 0.329, baseline vs off p = 0.311, on vs off p = 1
PPX ON four, OFF first AUC: n = 29, Friedman chi2 = 21.59, p = 2.05e-05; Dunn baseline vs on: median 4.065 -> 3.017, p = 8.62e-06; Dunn baseline vs off: median 4.065 -> 3.953, p = 0.176 | RM ANOVA p = 3.6e-06, Bonferroni paired baseline vs on p = 9.65e-07, baseline vs off p = 0.37, on vs off p = 0.00203, pooled error baseline vs on p = 2.63e-06, baseline vs off p = 0.197, on vs off p = 0.00172
PPX ON four, OFF first: failed fits per condition {'baseline': 0, 'on': 0, 'off': 1}
PPX ON first, OFF all A: n = 30, Friedman chi2 = 10.40, p = 0.00552; Dunn baseline vs on: median 0.891 -> 0.808, p = 0.00389; Dunn baseline vs off: median 0.891 -> 0.879, p = 0.877 | RM ANOVA p = 0.000466, Bonferroni paired baseline vs on p = 0.016, baseline vs off p = 1, on vs off p = 0.0107, pooled error baseline vs on p = 0.00146, baseline vs off p = 1, on vs off p = 0.00225
PPX ON first, OFF all K: n = 30, Friedman chi2 = 3.80, p = 0.15; Dunn baseline vs on: median 0.258 -> 0.257, p = 0.491; Dunn baseline vs off: median 0.258 -> 0.419, p = 0.106 | RM ANOVA p = 0.127, Bonferroni paired baseline vs on p = 1, baseline vs off p = 0.0634, on vs off p = 0.459, pooled error baseline vs on p = 1, baseline vs off p = 0.289, on vs off p = 0.197
PPX ON first, OFF all AUC: n = 30, Friedman chi2 = 19.47, p = 5.93e-05; Dunn baseline vs on: median 3.948 -> 3.179, p = 2.27e-05; Dunn baseline vs off: median 3.948 -> 3.379, p = 0.0196 | RM ANOVA p = 0.000544, Bonferroni paired baseline vs on p = 0.000372, baseline vs off p = 0.0388, on vs off p = 0.469, pooled error baseline vs on p = 0.000373, baseline vs off p = 0.0482, on vs off p = 0.323
PPX ON first, OFF all: failed fits per condition {'baseline': 0, 'on': 0, 'off': 0}
PPX ON first, OFF first A: n = 29, Friedman chi2 = 10.14, p = 0.00629; Dunn baseline vs on: median 0.899 -> 0.810, p = 0.0117; Dunn baseline vs off: median 0.899 -> 0.960, p = 1 | RM ANOVA p = 0.00216, Bonferroni paired baseline vs on p = 0.0284, baseline vs off p = 1, on vs off p = 0.0102, pooled error baseline vs on p = 0.00489, baseline vs off p = 1, on vs off p = 0.00921
PPX ON first, OFF first K: n = 29, Friedman chi2 = 1.10, p = 0.576; Dunn baseline vs on: median 0.252 -> 0.290, p = 1; Dunn baseline vs off: median 0.252 -> 0.318, p = 0.587 | RM ANOVA p = 0.301, Bonferroni paired baseline vs on p = 1, baseline vs off p = 0.424, on vs off p = 1, pooled error baseline vs on p = 1, baseline vs off p = 0.4, on vs off p = 0.857
PPX ON first, OFF first AUC: n = 29, Friedman chi2 = 18.48, p = 9.69e-05; Dunn baseline vs on: median 4.065 -> 3.442, p = 5.3e-05; Dunn baseline vs off: median 4.065 -> 3.953, p = 0.378 | RM ANOVA p = 0.00229, Bonferroni paired baseline vs on p = 0.000783, baseline vs off p = 0.37, on vs off p = 0.21, pooled error baseline vs on p = 0.0016, baseline vs off p = 0.345, on vs off p = 0.128
PPX ON first, OFF first: failed fits per condition {'baseline': 0, 'on': 0, 'off': 1}
Result: partially reproduced. With the four PPX sessions, A falls (median 0.891 to 0.785, Dunn p = 1.9e-06) and AUC falls (3.95 to 2.91, p = 2.7e-08), but the rise in K (0.258 to 0.321) is not significant by Dunn's test (p = 0.19), although the Friedman test over the three conditions gives p = 0.032 (the paper reports p = 0.03 for K). The Dunn p for K depends on which OFF sessions enter the ranks, but it is not significant under any of the four ON/OFF pairs (p = 0.19, 0.23, 0.49 and 1). With the first PPX session, A and AUC fall (p = 0.0039 to 0.012 and 2.3e-05 to 5.3e-05). The repeated measures ANOVA of Table 1 also gives K an omnibus p = 0.028 and a baseline against PPX p = 0.15 (paired) or 0.19 (pooled error), so the paper's p = 0.03 matches the omnibus tests of both. 30 mice enter; no fit failed with every OFF session (one with the first).
figs2ijk-ppx-washout¶
After a 48 h PPX washout the A value of parkinsonian mice returned to baseline while the changes in K and AUC persisted.
The same fits; readings (a) Friedman with Dunn's, (b) repeated measures one-way ANOVA with Bonferroni (Table 1). Reproduced when baseline against OFF has p >= 0.05 for A and p < 0.05 for K and AUC, in the direction seen under PPX.
rows = []
for (ron, roff), out in ppx_params.items():
for p in ["A", "K", "AUC"]:
r, rm, t = out[p]
rows.append({"ON": ron, "OFF": roff, "measure": p, "n": r["n"],
"median_baseline": r["dunn"]["off"]["median_ref"], "median_on": r["dunn"]["on"]["median"],
"median_off": r["dunn"]["off"]["median"],
"(a) Dunn base-OFF": r["dunn"]["off"]["p_bonf"],
"(b) paired base-OFF": rm["pairs"]["baseline vs off"],
"(b) pooled base-OFF": rm["pairs_pooled"]["baseline vs off"],
"paired ON-OFF": rm["pairs"]["on vs off"], "pooled ON-OFF": rm["pairs_pooled"]["on vs off"]})
print("Baseline against PPX OFF under each test and each ON/OFF reading (Bonferroni over three pairs for (b)):")
print(pd.DataFrame(rows).round(4).to_string(index=False))
# The paper's p-values for the six comparisons (Figure S2I-K legend and Table 1), against each way of
# making the Bonferroni comparisons, with the ON four and OFF all reading
paper_p = {("A", "baseline vs off"): "> 0.99", ("K", "baseline vs off"): "0.01", ("AUC", "baseline vs off"): "< 0.01",
("A", "on vs off"): "< 0.0001", ("K", "on vs off"): "> 0.99", ("AUC", "on vs off"): "0.0019"}
paper_sig = {"> 0.99": False, "0.01": True, "< 0.01": True, "< 0.0001": True, "0.0019": True}
rows = []
for (p, pair), pp in paper_p.items():
rm = ppx_params[("four", "all")][p][1]
rows.append({"measure": p, "pair": pair, "paper p": pp, "paired p": rm["pairs"][pair],
"pooled p": rm["pairs_pooled"][pair],
"paired agrees on p < 0.05": (rm["pairs"][pair] < 0.05) == paper_sig[pp],
"pooled agrees on p < 0.05": (rm["pairs_pooled"][pair] < 0.05) == paper_sig[pp]})
cmp = pd.DataFrame(rows)
print("Paper's p against the two ways of making the Bonferroni comparisons (ON four, OFF all):")
print(cmp.round(4).to_string(index=False))
print("comparisons whose significance at 0.05 matches the paper: paired", int(cmp["paired agrees on p < 0.05"].sum()),
"of 6, pooled", int(cmp["pooled agrees on p < 0.05"].sum()), "of 6")
Baseline against PPX OFF under each test and each ON/OFF reading (Bonferroni over three pairs for (b)):
ON OFF measure n median_baseline median_on median_off (a) Dunn base-OFF (b) paired base-OFF (b) pooled base-OFF paired ON-OFF pooled ON-OFF
four all A 30 0.8907 0.7850 0.8788 0.7323 1.0000 1.0000 0.0000 0.0000
four all K 30 0.2580 0.3209 0.4191 0.0196 0.0634 0.0278 1.0000 1.0000
four all AUC 30 3.9484 2.9049 3.3795 0.0777 0.0388 0.0072 0.0011 0.0051
four first A 29 0.8988 0.7871 0.9599 1.0000 1.0000 1.0000 0.0012 0.0004
four first K 29 0.2524 0.3003 0.3179 0.4746 0.4236 0.3106 1.0000 1.0000
four first AUC 29 4.0654 3.0170 3.9526 0.1757 0.3702 0.1972 0.0020 0.0017
first all A 30 0.8907 0.8077 0.8788 0.8772 1.0000 1.0000 0.0107 0.0023
first all K 30 0.2580 0.2571 0.4191 0.1056 0.0634 0.2893 0.4593 0.1967
first all AUC 30 3.9484 3.1791 3.3795 0.0196 0.0388 0.0482 0.4687 0.3229
first first A 29 0.8988 0.8097 0.9599 1.0000 1.0000 1.0000 0.0102 0.0092
first first K 29 0.2524 0.2898 0.3179 0.5870 0.4236 0.4000 1.0000 0.8566
first first AUC 29 4.0654 3.4425 3.9526 0.3783 0.3702 0.3455 0.2096 0.1280
Paper's p against the two ways of making the Bonferroni comparisons (ON four, OFF all):
measure pair paper p paired p pooled p paired agrees on p < 0.05 pooled agrees on p < 0.05
A baseline vs off > 0.99 1.0000 1.0000 True True
K baseline vs off 0.01 0.0634 0.0278 False True
AUC baseline vs off < 0.01 0.0388 0.0072 True True
A on vs off < 0.0001 0.0000 0.0000 True True
K on vs off > 0.99 1.0000 1.0000 True True
AUC on vs off 0.0019 0.0011 0.0051 True True
comparisons whose significance at 0.05 matches the paper: paired 5 of 6, pooled 6 of 6
Result: reproduced, resting on an assumption. With the four PPX sessions and every washout session, A after washout does not differ from baseline under any test (p >= 0.73). Reading (b), repeated measures ANOVA with Bonferroni comparisons on the ANOVA's pooled error, gives all three parts: A p = 1, K 0.258 to 0.419 (p = 0.028) and AUC 3.95 to 3.38 (p = 0.0072), on the PPX side of baseline (ON against OFF A p < 0.0001, K p = 1, AUC p = 0.0051; Table 1 < 0.0001, > 0.99, 0.0019). The paper does not say how its Bonferroni comparisons were made, so the pooled error is the assumption. It is taken because it fits the paper's own p-values better (second table above): pooled comparisons match the paper on significance at 0.05 in all six comparisons and paired t tests in five, missing K (paper p = 0.01, paired 0.063, pooled 0.028); for AUC the paper gives p < 0.01, which pooled meets (0.0072) and paired does not (0.039). Paired is closer only for ON against OFF AUC (paper 0.0019, paired 0.0011, pooled 0.0051), significant either way. With paired comparisons the claim is partially reproduced (AUC p = 0.039, K p = 0.063), the outcome of rounds 1 and 2, changed in round 3. Reading (a), Friedman with Dunn's, gives K persisting (p = 0.020) and AUC not (p = 0.078). With the first OFF session, or the first ON session, no test gives both K and AUC (first table above).
figs2de-omissions-low¶
Omission rates were low at baseline and under PPX; per-delay comparisons found no PPX effect on center or side omissions in either group, except center omissions at the 6 s delay in parkinsonian mice.
om = {}
for value in ["pct_center_om", "pct_side_om"]:
for g in ["control", "parkinsonian"]:
res = drug_test("PPX", g, "all", "four", value)
om[(value, g)] = res
show(res, f"{value}, {g}")
base = per_mouse("PPX", g, "baseline", "all", value)
on = per_mouse("PPX", g, "on", "four", value)
print(f" mean rate baseline {np.nanmean(base.values):.2f} %, PPX {np.nanmean(on.values):.2f} %")
pct_center_om, control: mice 16, units 58, treatment F(1, 54) = 0.371, p = 0.545; delay F(3, 54) = 10.65, p = 1.32e-05; interaction p = 0.895
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 16 2.9427 2.5781 -0.3646 1.0 1.0
3 on 16 7.5694 7.9167 0.3472 1.0 1.0
6 on 16 11.9618 14.5052 2.5434 1.0 1.0
9 on 10 13.3194 14.4167 1.0972 1.0 1.0
mean rate baseline 9.27 %, PPX 9.38 %
pct_center_om, parkinsonian: mice 30, units 120, treatment F(1, 116) = 24.820, p = 2.22e-06; delay F(3, 116) = 9.98, p = 6.68e-06; interaction p = 0.0103
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 30 1.3250 2.5556 1.2306 1.0000 0.0749
3 on 30 3.8528 6.6528 2.8000 0.1506 0.2110
6 on 30 4.5074 11.6667 7.1593 0.0000 0.0003
9 on 30 8.2963 10.3750 2.0787 0.4850 0.7852
mean rate baseline 5.01 %, PPX 7.81 %
pct_side_om, control: mice 16, units 58, treatment F(1, 54) = 0.013, p = 0.911; delay F(3, 54) = 1.46, p = 0.236; interaction p = 0.29
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 16 0.6944 2.1354 1.4410 0.8456 0.6619
3 on 16 4.1406 2.4740 -1.6667 0.5973 1.0000
6 on 16 2.3177 2.6823 0.3646 1.0000 1.0000
9 on 10 1.5833 1.7500 0.1667 1.0000 1.0000
mean rate baseline 2.22 %, PPX 2.31 %
pct_side_om, parkinsonian: mice 30, units 120, treatment F(1, 116) = 0.960, p = 0.329; delay F(3, 116) = 4.62, p = 0.00431; interaction p = 0.761
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 30 0.5056 0.4167 -0.0889 1.0000 1.0
3 on 30 2.2750 2.3472 0.0722 1.0000 1.0
6 on 30 2.4963 2.8750 0.3787 1.0000 1.0
9 on 30 1.2370 1.8056 0.5685 0.9351 1.0
mean rate baseline 1.59 %, PPX 1.86 %
Result: reproduced. With the four PPX sessions, center omissions of parkinsonian mice differ only at 6 s (4.5 against 11.7%, Bonferroni p < 0.0001; other delays p = 0.15 to 1), with a PPX main effect (F(1, 116) = 24.82, p = 2.2e-06; paper F(1, 120) = 16.54); no side omission comparison and no control comparison is significant (smallest p = 0.60). Mean omission rates are 5.0 and 7.8% (center) and 1.6 and 1.9% (side) of free choice trials in parkinsonian mice at baseline and on PPX.
figs2gh-ppx-latency¶
In parkinsonian mice on PPX, the latency to choose the immediate/small reward was shorter than at baseline, and the modulation of choice latency by outcome was lost.
for rd in ["four", "first"]:
show(drug_test("PPX", "parkinsonian", "all", rd, "lat_small"), f"latency to small reward, parkinsonian, baseline vs PPX {rd}")
for cond, rd in [("baseline", "all"), ("on", "four"), ("on", "first")]:
lg = per_mouse("PPX", "parkinsonian", cond, rd, "lat_large")
sm = per_mouse("PPX", "parkinsonian", cond, rd, "lat_small")
L = pd.concat([long(lg, size="large"), long(sm, size="small")])
show(icd.split_plot_anova(L, "v", "size", ["large", "small"]), f"reward size effect on latency, {cond} {rd}")
latency to small reward, parkinsonian, baseline vs PPX four: mice 30, units 114, treatment F(1, 110) = 2.866, p = 0.0933; delay F(3, 110) = 0.60, p = 0.618; interaction p = 0.201
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 27 1.2760 1.0872 -0.1888 0.8457 1.0000
3 on 28 1.3821 1.0227 -0.3594 0.0657 0.0257
6 on 29 1.0936 1.0963 0.0027 1.0000 1.0000
9 on 30 1.0482 1.0807 0.0326 1.0000 1.0000
latency to small reward, parkinsonian, baseline vs PPX first: mice 30, units 109, treatment F(1, 105) = 2.063, p = 0.154; delay F(3, 105) = 0.29, p = 0.834; interaction p = 0.0443
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 24 1.2452 0.8706 -0.3746 0.0851 0.3238
3 on 27 1.3410 1.0378 -0.3032 0.1892 0.0851
6 on 28 1.0941 1.1518 0.0577 1.0000 1.0000
9 on 30 1.0482 1.1746 0.1264 1.0000 1.0000
reward size effect on latency, baseline all: mice 31, units 118, treatment F(1, 114) = 5.334, p = 0.0227; delay F(3, 114) = 0.27, p = 0.85; interaction p = 0.00527
delay level n mean_large mean_level diff p_bonf_pooled p_bonf_paired
0 small 28 0.9022 1.2684 0.3662 0.0404 0.3408
3 small 29 0.9412 1.3901 0.4489 0.0058 0.0127
6 small 30 1.1130 1.1095 -0.0035 1.0000 1.0000
9 small 31 1.2319 1.0839 -0.1479 1.0000 0.5329
reward size effect on latency, on four: mice 30, units 116, treatment F(1, 112) = 0.135, p = 0.714; delay F(3, 112) = 1.86, p = 0.141; interaction p = 0.206
delay level n mean_large mean_level diff p_bonf_pooled p_bonf_paired
0 small 28 0.9178 1.0710 0.1532 0.6359 0.7814
3 small 30 0.9671 1.0595 0.0924 1.0000 1.0000
6 small 29 1.1164 1.0995 -0.0170 1.0000 1.0000
9 small 29 1.2393 1.0907 -0.1486 0.6578 0.7013
reward size effect on latency, on first: mice 30, units 103, treatment F(1, 99) = 1.771, p = 0.186; delay F(3, 99) = 5.08, p = 0.00259; interaction p = 0.834
delay level n mean_large mean_level diff p_bonf_pooled p_bonf_paired
0 small 25 0.9411 0.8633 -0.0778 1.0 1.0
3 small 29 1.0376 1.0319 -0.0058 1.0 1.0
6 small 25 1.3611 1.1970 -0.1640 1.0 1.0
9 small 24 1.4335 1.2539 -0.1796 1.0 1.0
Result: partially reproduced. The latency to choose the small reward is shorter on PPX at 0 and 3 s (1.28 to 1.09 s and 1.38 to 1.02 s) but the PPX effect is not significant (F(1, 110) = 2.87, p = 0.093 with four sessions; p = 0.15 with the first; paper F(1, 114) = 4.505, p = 0.02). The reward size effect on latency is present at baseline (F(1, 114) = 5.33, p = 0.023; paper F(1, 114) = 7.016, p = 0.0092) and absent on PPX (p = 0.71 with four sessions, 0.19 with the first; paper p = 0.70), as the criterion requires.
A77636 claims: fig2d-ctrl-a77636-no-change, fig2e-park-a77636-fewer-large, fig2fgh-a77636-k-auc, figs3-a77636-washout-latency¶
for rb in ["all", "stable"]:
for rd in ["first", "four"]:
show(drug_test("A77636", "control", rb, rd), f"A77636 control, baseline {rb}, ON {rd}")
A77636 control, baseline all, ON first: mice 10, units 40, treatment F(1, 36) = 0.064, p = 0.801; delay F(3, 36) = 4.08, p = 0.0136; interaction p = 0.323
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 10 91.3833 82.8224 -8.5609 0.7315 0.8138
3 on 10 77.3137 73.6241 -3.6896 1.0000 1.0000
6 on 10 58.8680 66.3808 7.5128 0.9645 1.0000
9 on 10 48.3630 49.9008 1.5379 1.0000 1.0000
A77636 control, baseline all, ON four: mice 10, units 40, treatment F(1, 36) = 0.269, p = 0.607; delay F(3, 36) = 5.36, p = 0.00371; interaction p = 0.504
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 10 91.3833 87.2192 -4.1641 1.0 1.0000
3 on 10 77.3137 73.5983 -3.7154 1.0 0.5581
6 on 10 58.8680 61.9747 3.1067 1.0 1.0000
9 on 10 48.3630 49.0523 0.6893 1.0 1.0000
A77636 control, baseline stable, ON first: mice 8, units 32, treatment F(1, 28) = 0.075, p = 0.786; delay F(3, 28) = 5.64, p = 0.00376; interaction p = 0.388
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 8 92.5719 89.3092 -3.2627 1.0000 1.0000
3 on 8 85.6044 79.9575 -5.6469 1.0000 1.0000
6 on 8 67.2949 76.7260 9.4311 0.7135 0.3437
9 on 8 54.9769 50.7094 -4.2676 1.0000 1.0000
A77636 control, baseline stable, ON four: mice 8, units 32, treatment F(1, 28) = 1.059, p = 0.312; delay F(3, 28) = 7.94, p = 0.00055; interaction p = 0.845
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 8 92.5719 92.5557 -0.0161 1.0 1.0000
3 on 8 85.6044 79.5551 -6.0493 1.0 0.4347
6 on 8 67.2949 66.5030 -0.7919 1.0 1.0000
9 on 8 54.9769 49.8909 -5.0860 1.0 1.0000
Result: reproduced. In the 10 control mice the A77636 effect is not significant under any reading (p = 0.31 to 0.80; paper F(1, 36) = 1.05, p = 0.31) and no per-delay comparison reaches p < 0.05.
for rb in ["all", "stable"]:
for rd in ["first", "four"]:
show(drug_test("A77636", "parkinsonian", rb, rd), f"A77636 parkinsonian, baseline {rb}, ON {rd}")
A77636 parkinsonian, baseline all, ON first: mice 16, units 64, treatment F(1, 60) = 16.854, p = 0.000124; delay F(3, 60) = 12.89, p = 1.32e-06; interaction p = 0.458
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 16 87.4962 80.7457 -6.7505 1.0000 1.0000
3 on 16 68.0274 59.2342 -8.7933 0.6306 0.1826
6 on 16 50.9381 34.7898 -16.1483 0.0436 0.1528
9 on 16 41.6775 22.9103 -18.7672 0.0135 0.0462
A77636 parkinsonian, baseline all, ON four: mice 16, units 64, treatment F(1, 60) = 45.056, p = 7.73e-09; delay F(3, 60) = 12.82, p = 1.41e-06; interaction p = 0.176
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 16 87.4962 80.7631 -6.7331 0.5575 0.8286
3 on 16 68.0274 52.7620 -15.2655 0.0049 0.0015
6 on 16 50.9381 31.9062 -19.0319 0.0003 0.0024
9 on 16 41.6775 22.3659 -19.3115 0.0003 0.0053
A77636 parkinsonian, baseline stable, ON first: mice 7, units 28, treatment F(1, 24) = 27.286, p = 2.36e-05; delay F(3, 24) = 9.22, p = 0.000308; interaction p = 0.0117
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 7 92.6469 92.6692 0.0223 1.0000 1.0000
3 on 7 91.7938 77.5224 -14.2714 0.3684 0.1203
6 on 7 77.3823 42.9741 -34.4082 0.0012 0.1346
9 on 7 65.4008 29.0770 -36.3238 0.0006 0.0190
A77636 parkinsonian, baseline stable, ON four: mice 7, units 28, treatment F(1, 24) = 41.294, p = 1.21e-06; delay F(3, 24) = 6.37, p = 0.00249; interaction p = 0.0226
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 7 92.6469 89.7650 -2.8818 1.0000 1.0000
3 on 7 91.7938 71.1943 -20.5995 0.0140 0.1056
6 on 7 77.3823 49.8909 -27.4914 0.0009 0.0338
9 on 7 65.4008 34.6387 -30.7620 0.0003 0.0191
Result: reproduced. With every baseline session and the four A77636 sessions, the effect is F(1, 60) = 45.06, p = 7.7e-09 (paper F(1, 60) = 45.68) and the choices are lower at 3, 6 and 9 s (Bonferroni p = 0.0049, 0.0003, 0.0003; paper 0.0047, 0.0003, 0.0002), not at 0 s (p = 0.56; paper 0.57).
a77_params = {}
for ron, roff in [("four", "all"), ("four", "first"), ("first", "all"), ("first", "first")]:
a77_params[(ron, roff)] = friedman_block("A77636", "parkinsonian", ron, roff, f"A77636 ON {ron}, OFF {roff}")
A77636 ON four, OFF all A: n = 16, Friedman chi2 = 2.38, p = 0.305; Dunn baseline vs on: median 0.915 -> 0.913, p = 0.315; Dunn baseline vs off: median 0.915 -> 0.966, p = 1 | RM ANOVA p = 0.205, Bonferroni paired baseline vs on p = 0.536, baseline vs off p = 1, on vs off p = 0.524, pooled error baseline vs on p = 0.237, baseline vs off p = 1, on vs off p = 0.866
A77636 ON four, OFF all K: n = 16, Friedman chi2 = 9.88, p = 0.00717; Dunn baseline vs on: median 0.115 -> 0.291, p = 0.00531; Dunn baseline vs off: median 0.115 -> 0.209, p = 0.0431 | RM ANOVA p = 0.597, Bonferroni paired baseline vs on p = 0.821, baseline vs off p = 1, on vs off p = 1, pooled error baseline vs on p = 1, baseline vs off p = 0.942, on vs off p = 1
A77636 ON four, OFF all AUC: n = 16, Friedman chi2 = 12.88, p = 0.0016; Dunn baseline vs on: median 5.817 -> 3.971, p = 0.000814; Dunn baseline vs off: median 5.817 -> 4.932, p = 0.0431 | RM ANOVA p = 6.86e-07, Bonferroni paired baseline vs on p = 4.67e-05, baseline vs off p = 0.00256, on vs off p = 0.0393, pooled error baseline vs on p = 5.02e-07, baseline vs off p = 0.00034, on vs off p = 0.0803
A77636 ON four, OFF all: failed fits per condition {'baseline': 0, 'on': 0, 'off': 0}
A77636 ON four, OFF first A: n = 16, Friedman chi2 = 4.50, p = 0.105; Dunn baseline vs on: median 0.915 -> 0.913, p = 0.578; Dunn baseline vs off: median 0.915 -> 0.945, p = 0.578 | RM ANOVA p = 0.189, Bonferroni paired baseline vs on p = 0.536, baseline vs off p = 1, on vs off p = 0.522, pooled error baseline vs on p = 0.412, baseline vs off p = 1, on vs off p = 0.294
A77636 ON four, OFF first K: n = 16, Friedman chi2 = 11.62, p = 0.00299; Dunn baseline vs on: median 0.115 -> 0.291, p = 0.00293; Dunn baseline vs off: median 0.115 -> 0.244, p = 0.016 | RM ANOVA p = 0.399, Bonferroni paired baseline vs on p = 0.821, baseline vs off p = 0.947, on vs off p = 1, pooled error baseline vs on p = 1, baseline vs off p = 0.67, on vs off p = 0.796
A77636 ON four, OFF first AUC: n = 16, Friedman chi2 = 12.88, p = 0.0016; Dunn baseline vs on: median 5.817 -> 3.971, p = 0.000814; Dunn baseline vs off: median 5.817 -> 4.860, p = 0.0431 | RM ANOVA p = 7.44e-06, Bonferroni paired baseline vs on p = 4.67e-05, baseline vs off p = 0.00636, on vs off p = 0.25, pooled error baseline vs on p = 6.44e-06, baseline vs off p = 0.000956, on vs off p = 0.255
A77636 ON four, OFF first: failed fits per condition {'baseline': 0, 'on': 0, 'off': 0}
A77636 ON first, OFF all A: n = 16, Friedman chi2 = 0.88, p = 0.646; Dunn baseline vs on: median 0.915 -> 0.947, p = 1; Dunn baseline vs off: median 0.915 -> 0.966, p = 0.754 | RM ANOVA p = 0.426, Bonferroni paired baseline vs on p = 0.985, baseline vs off p = 1, on vs off p = 1, pooled error baseline vs on p = 0.587, baseline vs off p = 1, on vs off p = 1
A77636 ON first, OFF all K: n = 16, Friedman chi2 = 3.88, p = 0.144; Dunn baseline vs on: median 0.115 -> 0.226, p = 0.432; Dunn baseline vs off: median 0.115 -> 0.209, p = 0.104 | RM ANOVA p = 0.369, Bonferroni paired baseline vs on p = 1, baseline vs off p = 1, on vs off p = 0.87, pooled error baseline vs on p = 1, baseline vs off p = 0.983, on vs off p = 0.521
A77636 ON first, OFF all AUC: n = 16, Friedman chi2 = 6.00, p = 0.0498; Dunn baseline vs on: median 5.817 -> 4.688, p = 0.0678; Dunn baseline vs off: median 5.817 -> 4.932, p = 0.0678 | RM ANOVA p = 0.00175, Bonferroni paired baseline vs on p = 0.0121, baseline vs off p = 0.00256, on vs off p = 1, pooled error baseline vs on p = 0.00233, baseline vs off p = 0.0148, on vs off p = 1
A77636 ON first, OFF all: failed fits per condition {'baseline': 0, 'on': 0, 'off': 0}
A77636 ON first, OFF first A: n = 16, Friedman chi2 = 0.38, p = 0.829; Dunn baseline vs on: median 0.915 -> 0.947, p = 1; Dunn baseline vs off: median 0.915 -> 0.945, p = 1 | RM ANOVA p = 0.347, Bonferroni paired baseline vs on p = 0.985, baseline vs off p = 1, on vs off p = 0.759, pooled error baseline vs on p = 0.721, baseline vs off p = 1, on vs off p = 0.557
A77636 ON first, OFF first K: n = 16, Friedman chi2 = 6.12, p = 0.0468; Dunn baseline vs on: median 0.115 -> 0.226, p = 0.432; Dunn baseline vs off: median 0.115 -> 0.244, p = 0.0267 | RM ANOVA p = 0.345, Bonferroni paired baseline vs on p = 1, baseline vs off p = 0.947, on vs off p = 0.914, pooled error baseline vs on p = 1, baseline vs off p = 0.673, on vs off p = 0.585
A77636 ON first, OFF first AUC: n = 16, Friedman chi2 = 6.12, p = 0.0468; Dunn baseline vs on: median 5.817 -> 4.688, p = 0.104; Dunn baseline vs off: median 5.817 -> 4.860, p = 0.0431 | RM ANOVA p = 0.000806, Bonferroni paired baseline vs on p = 0.0121, baseline vs off p = 0.00636, on vs off p = 1, pooled error baseline vs on p = 0.00134, baseline vs off p = 0.00587, on vs off p = 1
A77636 ON first, OFF first: failed fits per condition {'baseline': 0, 'on': 0, 'off': 0}
Result: reproduced. With the four A77636 sessions, A does not change (Friedman p = 0.31, Dunn p = 0.31; paper 0.31), K rises (median 0.115 to 0.291, Dunn p = 0.0053; paper 0.0053) and AUC falls (5.82 to 3.97, Dunn p = 0.0008; paper 0.0008). With the first session only, the K and AUC changes are not significant (Dunn p = 0.43 and 0.10).
for (ron, roff), out in a77_params.items():
for p in ["K", "AUC"]:
r, rm, t = out[p]
on_off = stats.wilcoxon(t.dropna()["on"], t.dropna()["off"]).pvalue
k = t.dropna()
ranks = k.rank(axis=1)
z = (ranks["off"].mean() - ranks["on"].mean()) / np.sqrt(3 * 4 / (6 * len(k)))
print(f"ON {ron}, OFF {roff} {p}: medians baseline {k.baseline.median():.3f}, ON {k.on.median():.3f}, OFF {k.off.median():.3f}; "
f"Dunn ON vs OFF p = {min(1, 2 * stats.norm.sf(abs(z)) * 3):.3g} (three comparisons); "
f"Dunn baseline vs OFF p = {r['dunn']['off']['p_bonf']:.3g}")
for value in ["pct_center_om", "pct_side_om"]:
show(drug_test("A77636", "parkinsonian", "all", "four", value), f"A77636 parkinsonian, {value}")
for cond, rd in [("baseline", "all"), ("on", "four")]:
lg = per_mouse("A77636", "parkinsonian", cond, rd, "lat_large")
sm = per_mouse("A77636", "parkinsonian", cond, rd, "lat_small")
L = pd.concat([long(lg, size="large"), long(sm, size="small")])
show(icd.split_plot_anova(L, "v", "size", ["large", "small"]), f"A77636 reward size effect on latency, {cond}")
ON four, OFF all K: medians baseline 0.115, ON 0.291, OFF 0.209; Dunn ON vs OFF p = 1 (three comparisons); Dunn baseline vs OFF p = 0.0431
ON four, OFF all AUC: medians baseline 5.817, ON 3.971, OFF 4.932; Dunn ON vs OFF p = 0.648 (three comparisons); Dunn baseline vs OFF p = 0.0431
ON four, OFF first K: medians baseline 0.115, ON 0.291, OFF 0.244; Dunn ON vs OFF p = 1 (three comparisons); Dunn baseline vs OFF p = 0.016
ON four, OFF first AUC: medians baseline 5.817, ON 3.971, OFF 4.860; Dunn ON vs OFF p = 0.648 (three comparisons); Dunn baseline vs OFF p = 0.0431
ON first, OFF all K: medians baseline 0.115, ON 0.226, OFF 0.209; Dunn ON vs OFF p = 1 (three comparisons); Dunn baseline vs OFF p = 0.104
ON first, OFF all AUC: medians baseline 5.817, ON 4.688, OFF 4.932; Dunn ON vs OFF p = 1 (three comparisons); Dunn baseline vs OFF p = 0.0678
ON first, OFF first K: medians baseline 0.115, ON 0.226, OFF 0.244; Dunn ON vs OFF p = 0.648 (three comparisons); Dunn baseline vs OFF p = 0.0267
ON first, OFF first AUC: medians baseline 5.817, ON 4.688, OFF 4.860; Dunn ON vs OFF p = 1 (three comparisons); Dunn baseline vs OFF p = 0.0431
A77636 parkinsonian, pct_center_om: mice 16, units 64, treatment F(1, 60) = 0.867, p = 0.355; delay F(3, 60) = 7.65, p = 0.000206; interaction p = 0.846
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 16 3.5208 2.8906 -0.6302 1.0 1.0000
3 on 16 4.8854 8.0469 3.1615 1.0 0.7352
6 on 16 9.0625 10.3125 1.2500 1.0 1.0000
9 on 16 14.4665 16.3281 1.8616 1.0 1.0000
A77636 parkinsonian, pct_side_om: mice 16, units 64, treatment F(1, 60) = 1.384, p = 0.244; delay F(3, 60) = 4.84, p = 0.0044; interaction p = 0.645
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 16 0.7292 0.7812 0.0521 1.0000 1.0000
3 on 16 3.8125 3.8281 0.0156 1.0000 1.0000
6 on 16 3.5260 2.7344 -0.7917 1.0000 1.0000
9 on 16 2.5000 1.4062 -1.0938 0.6483 0.6939
A77636 reward size effect on latency, baseline: mice 16, units 56, treatment F(1, 52) = 14.698, p = 0.000342; delay F(3, 52) = 0.85, p = 0.474; interaction p = 0.639
delay level n mean_large mean_level diff p_bonf_pooled p_bonf_paired
0 small 14 0.9338 1.3126 0.3789 0.5097 0.2801
3 small 13 0.9769 1.6696 0.6927 0.0346 0.1056
6 small 15 1.1642 1.7112 0.5470 0.0984 0.3103
9 small 14 1.2500 1.5171 0.2671 1.0000 0.8810
A77636 reward size effect on latency, on: mice 16, units 60, treatment F(1, 56) = 4.836, p = 0.032; delay F(3, 56) = 1.10, p = 0.356; interaction p = 0.143
delay level n mean_large mean_level diff p_bonf_pooled p_bonf_paired
0 small 15 0.9302 1.2352 0.3050 0.6121 0.0663
3 small 16 1.0808 1.6693 0.5885 0.0221 0.2994
6 small 15 1.2827 1.2483 -0.0344 1.0000 1.0000
9 small 14 1.2275 1.2572 0.0297 1.0000 1.0000
Result: partially reproduced. After washout K (0.209) and AUC (4.93) do not differ from the A77636 values (Dunn p = 1 and 0.65) and stay on the same side of baseline (0.115, 5.82; Dunn baseline against OFF p = 0.043 for both). The same holds for the other three ON/OFF pairs (ON against OFF p >= 0.65). No per-delay omission comparison is significant (smallest Bonferroni p = 0.65). The reward size effect on choice latency is significant at baseline (F(1, 52) = 14.70, p = 0.0003; paper F(1, 52) = 11.70) but, against the criterion, also on A77636 (F(1, 56) = 4.84, p = 0.032; paper p = 0.07).
DREADD claims: fig5g-mcherry-no-change, fig5hi-dreadd-fewer-large, fig5jl-dreadd-params¶
Pre-CNO baseline sessions against the mean of the post-CNO sessions (first four), per group.
for rb in ["all", "stable"]:
show(drug_test("DREADD", "mCherry", rb, "four"), f"mCherry, baseline {rb}, CNO four")
mCherry, baseline all, CNO four: mice 14, units 56, treatment F(1, 52) = 0.935, p = 0.338; delay F(3, 52) = 5.44, p = 0.00248; interaction p = 0.868
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 14 87.7784 86.6608 -1.1176 1.0 1.0
3 on 14 68.0955 68.4471 0.3516 1.0 1.0
6 on 14 54.9645 52.4803 -2.4842 1.0 1.0
9 on 14 51.1692 47.3819 -3.7873 1.0 1.0
mCherry, baseline stable, CNO four: mice 7, units 28, treatment F(1, 24) = 0.955, p = 0.338; delay F(3, 24) = 1.90, p = 0.156; interaction p = 0.972
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 7 97.1436 89.5225 -7.6211 1.0 1.0
3 on 7 88.4874 86.7183 -1.7691 1.0 1.0
6 on 7 81.6833 78.4373 -3.2460 1.0 1.0
9 on 7 79.6998 74.0795 -5.6203 1.0 1.0
Result: reproduced. In the 14 mCherry mice with delay discounting files, CNO has no effect (F(1, 52) = 0.94, p = 0.34; paper F(1, 56) = 0.97, p = 0.33) and no per-delay comparison differs (all Bonferroni p = 1). The README lists 15 mCherry mice; R5.5 has no delay discounting file in the deposit.
for g in ["hM4Di", "hM3Dq"]:
for rb in ["all", "stable"]:
show(drug_test("DREADD", g, rb, "four"), f"{g}, baseline {rb}, CNO four")
hM4Di, baseline all, CNO four: mice 12, units 48, treatment F(1, 44) = 12.772, p = 0.000868; delay F(3, 44) = 7.67, p = 0.000315; interaction p = 0.594
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 12 86.8084 82.5599 -4.2485 1.0000 0.8134
3 on 12 76.8779 65.3194 -11.5586 0.0220 0.1593
6 on 12 58.8832 52.1164 -6.7668 0.3777 0.2672
9 on 12 45.0875 39.3677 -5.7197 0.6223 0.7787
hM4Di, baseline stable, CNO four: mice 3, units 12, treatment F(1, 8) = 0.443, p = 0.524; delay F(3, 8) = 0.71, p = 0.571; interaction p = 0.961
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 3 96.5351 92.7130 -3.8220 1.0 0.2206
3 on 3 91.2037 88.8932 -2.3105 1.0 1.0000
6 on 3 79.7222 78.7846 -0.9376 1.0 1.0000
9 on 3 71.5970 71.5424 -0.0546 1.0 1.0000
hM3Dq, baseline all, CNO four: mice 12, units 48, treatment F(1, 44) = 40.940, p = 8.75e-08; delay F(3, 44) = 19.57, p = 3.29e-08; interaction p = 0.368
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 12 87.9719 79.7991 -8.1728 0.2650 0.3498
3 on 12 76.4747 58.5096 -17.9651 0.0006 0.0346
6 on 12 50.0719 33.1032 -16.9687 0.0013 0.0024
9 on 12 36.6765 24.2541 -12.4224 0.0256 0.0164
hM3Dq, baseline stable, CNO four: mice 4, units 16, treatment F(1, 12) = 21.986, p = 0.000524; delay F(3, 12) = 6.07, p = 0.00937; interaction p = 0.127
delay level n mean_baseline mean_level diff p_bonf_pooled p_bonf_paired
0 on 4 90.5750 88.7610 -1.8140 1.0000 1.0000
3 on 4 87.3468 78.6119 -8.7349 0.2818 0.3768
6 on 4 71.2664 58.0370 -13.2295 0.0437 0.2152
9 on 4 57.8472 40.3645 -17.4827 0.0074 0.2936
Result: partially reproduced. In hM3Dq mice CNO lowers the delayed/large choices (F(1, 44) = 40.94, p = 8.8e-08; paper 42.30) at 3, 6 and 9 s (p = 0.0006, 0.0013, 0.026). In hM4Di mice the main effect holds (F(1, 44) = 12.77, p = 0.0009; paper 22.22) but only the 3 s comparison is significant (p = 0.022; 6 s p = 0.38, 9 s p = 0.62).
for g in ["mCherry", "hM4Di", "hM3Dq"]:
base = params(per_mouse("DREADD", g, "baseline", "all"))
on = params(per_mouse("DREADD", g, "on", "four"))
for p in ["A", "K", "AUC"]:
t = pd.DataFrame({"baseline": base[p], "on": on[p]}).dropna()
w = stats.wilcoxon(t.baseline, t.on).pvalue
# reading (b): Friedman over the two conditions, which reduces to a two-sided sign test
fr = stats.binomtest(int((t.on > t.baseline).sum()), int((t.on != t.baseline).sum())).pvalue
print(f"{g} {p}: n = {len(t)}, median {t.baseline.median():.3f} -> {t.on.median():.3f}, "
f"higher in {int((t.on > t.baseline).sum())}; Wilcoxon p = {w:.3g}; Friedman (sign test) p = {fr:.3g}")
print(f" failed fits: baseline {int(base.A.isna().sum())}, CNO {int(on.A.isna().sum())}")
mCherry A: n = 14, median 0.914 -> 0.964, higher in 7; Wilcoxon p = 0.903; Friedman (sign test) p = 1 mCherry K: n = 14, median 0.074 -> 0.109, higher in 9; Wilcoxon p = 0.358; Friedman (sign test) p = 0.424 mCherry AUC: n = 14, median 6.026 -> 6.392, higher in 6; Wilcoxon p = 0.626; Friedman (sign test) p = 0.791 failed fits: baseline 0, CNO 0 hM4Di A: n = 12, median 0.952 -> 0.934, higher in 5; Wilcoxon p = 0.204; Friedman (sign test) p = 0.774 hM4Di K: n = 12, median 0.123 -> 0.136, higher in 7; Wilcoxon p = 0.204; Friedman (sign test) p = 0.774 hM4Di AUC: n = 12, median 6.075 -> 5.778, higher in 3; Wilcoxon p = 0.0425; Friedman (sign test) p = 0.146 failed fits: baseline 0, CNO 0
hM3Dq A: n = 12, median 0.923 -> 0.880, higher in 2; Wilcoxon p = 0.0122; Friedman (sign test) p = 0.0386 hM3Dq K: n = 12, median 0.133 -> 0.198, higher in 11; Wilcoxon p = 0.00146; Friedman (sign test) p = 0.00635 hM3Dq AUC: n = 12, median 5.103 -> 4.313, higher in 0; Wilcoxon p = 0.000488; Friedman (sign test) p = 0.000488 failed fits: baseline 0, CNO 0
Result: not reproduced. Under reading (a), Wilcoxon (Table 1), hM3Dq mice show the three changes (A 0.923 to 0.880, p = 0.012; K 0.133 to 0.198, p = 0.0015; AUC 5.10 to 4.31, p = 0.0005), hM4Di mice a lower AUC (6.08 to 5.78, p = 0.043) and unchanged A (p = 0.20), and mCherry mice no change (p >= 0.36). The rise in K of hM4Di mice (0.123 to 0.136, 7 of 12 higher) is not significant (p = 0.20), so "K higher in both DREADD groups" fails. The criterion's partial case needs the K and AUC results to hold with only the A pattern failing; here the A pattern holds and K fails, so by its wording the claim is not reproduced, narrowly (eight of nine parts hold). Reading (b), Friedman, which with two conditions reduces to a sign test, gives the same pattern with fewer significant results (hM4Di AUC p = 0.15).
Repeated dosing: fig6b-ctrl-ppx-stable, fig6c-park-ppx-progressive, fig6de-a77636-persistent¶
Split-plot ANOVA over baseline, first and fourth ON session, with Bonferroni comparisons of the condition means pooled over delays (and per delay as a variant).
def sessions_test(exp, group):
base = per_mouse(exp, group, "baseline", "all")
first = per_mouse(exp, group, "on", "first")
fourth = per_mouse(exp, group, "on", "fourth")
L = pd.concat([long(base, t="baseline"), long(first, t="first"), long(fourth, t="fourth")])
res = icd.split_plot_anova(L, "v", "t", ["baseline", "first", "fourth"])
pairs = icd.main_effect_pairs(L, "v", "t", ["baseline", "first", "fourth"])
print(f"{exp} {group}: mice with a fourth session {len(fourth)} of {len(base)}; "
f"session F{res['treat_df']} = {res['treat_F']:.2f}, p = {res['treat_p']:.3g}")
print(pairs.round(4).to_string(index=False))
L2 = pd.concat([long(first, t="first"), long(fourth, t="fourth")])
print(icd.split_plot_anova(L2, "v", "t", ["first", "fourth"])["per_delay"].round(4).to_string(index=False))
return pairs
sessions_test("PPX", "control")
PPX control: mice with a fourth session 12 of 16; session F(2, 80) = 1.17, p = 0.316
pair mean_a mean_b diff n_units p_bonf
baseline vs first 53.7653 48.5945 -5.1708 44 0.4586
baseline vs fourth 53.7653 49.6067 -4.1586 44 0.7476
first vs fourth 48.5945 49.6067 1.0122 44 1.0000
delay level n mean_first mean_level diff p_bonf_pooled p_bonf_paired
0 fourth 12 87.4297 83.2113 -4.2184 1.0 1.0
3 fourth 12 43.8032 48.7935 4.9903 1.0 1.0
6 fourth 12 29.3348 29.6754 0.3406 1.0 1.0
9 fourth 8 26.4183 30.3169 3.8985 1.0 1.0
| pair | mean_a | mean_b | diff | n_units | p_bonf | |
|---|---|---|---|---|---|---|
| 0 | baseline vs first | 53.765345 | 48.594517 | -5.170828 | 44 | 0.458564 |
| 1 | baseline vs fourth | 53.765345 | 49.606740 | -4.158605 | 44 | 0.747618 |
| 2 | first vs fourth | 48.594517 | 49.606740 | 1.012223 | 44 | 1.000000 |
Result: reproduced. In control mice no pair of baseline, first and fourth PPX session differs (Bonferroni p = 0.46, 0.75 and 1; paper first against fourth p > 0.99); 12 of 16 control mice have a fourth PPX session.
sessions_test("PPX", "parkinsonian")
PPX parkinsonian: mice with a fourth session 27 of 31; session F(2, 208) = 26.72, p = 4.7e-11
pair mean_a mean_b diff n_units p_bonf
baseline vs first 50.7100 41.5791 -9.1308 108 0.000
baseline vs fourth 50.7100 36.2072 -14.5027 108 0.000
first vs fourth 41.5791 36.2072 -5.3719 108 0.024
delay level n mean_first mean_level diff p_bonf_pooled p_bonf_paired
0 fourth 27 70.5828 66.1856 -4.3972 1.0000 1.0000
3 fourth 27 41.6604 33.2555 -8.4049 0.2805 0.2015
6 fourth 27 27.1437 27.6875 0.5438 1.0000 1.0000
9 fourth 27 26.9296 17.7004 -9.2293 0.1883 0.0522
| pair | mean_a | mean_b | diff | n_units | p_bonf | |
|---|---|---|---|---|---|---|
| 0 | baseline vs first | 50.709955 | 41.579119 | -9.130835 | 108 | 2.712342e-05 |
| 1 | baseline vs fourth | 50.709955 | 36.207223 | -14.502732 | 108 | 2.720905e-11 |
| 2 | first vs fourth | 41.579119 | 36.207223 | -5.371896 | 108 | 2.399674e-02 |
Result: reproduced. In the 27 parkinsonian mice with four PPX sessions, the delayed/large choices fall from 50.7% at baseline to 41.6% in the first and 36.2% in the fourth session; baseline differs from both (p = 2.7e-05, 2.7e-11) and the fourth from the first (p = 0.024; paper p < 0.0081).
sessions_test("A77636", "parkinsonian")
sessions_test("A77636", "control")
A77636 parkinsonian: mice with a fourth session 16 of 16; session F(2, 120) = 12.02, p = 1.74e-05
pair mean_a mean_b diff n_units p_bonf
baseline vs first 62.0348 49.4200 -12.6148 64 0.0004
baseline vs fourth 62.0348 47.6817 -14.3531 64 0.0000
first vs fourth 49.4200 47.6817 -1.7383 64 1.0000
delay level n mean_first mean_level diff p_bonf_pooled p_bonf_paired
0 fourth 16 80.7457 82.2533 1.5076 1.0000 1.0000
3 fourth 16 59.2342 50.6006 -8.6336 0.9077 0.8983
6 fourth 16 34.7898 29.9487 -4.8411 1.0000 1.0000
9 fourth 16 22.9103 27.9242 5.0140 1.0000 1.0000
A77636 control: mice with a fourth session 10 of 10; session F(2, 72) = 1.59, p = 0.21
pair mean_a mean_b diff n_units p_bonf
baseline vs first 68.982 68.1820 -0.8000 40 1.0000
baseline vs fourth 68.982 63.1137 -5.8683 40 0.3125
first vs fourth 68.182 63.1137 -5.0683 40 0.4785
delay level n mean_first mean_level diff p_bonf_pooled p_bonf_paired
0 fourth 10 82.8224 92.8889 10.0665 1.0000 0.9602
3 fourth 10 73.6241 66.3755 -7.2486 1.0000 1.0000
6 fourth 10 66.3808 48.7173 -17.6635 0.2287 0.7514
9 fourth 10 49.9008 44.4731 -5.4278 1.0000 1.0000
| pair | mean_a | mean_b | diff | n_units | p_bonf | |
|---|---|---|---|---|---|---|
| 0 | baseline vs first | 68.981992 | 68.182020 | -0.799971 | 40 | 1.000000 |
| 1 | baseline vs fourth | 68.981992 | 63.113674 | -5.868317 | 40 | 0.312516 |
| 2 | first vs fourth | 68.182020 | 63.113674 | -5.068346 | 40 | 0.478544 |
Result: reproduced. In parkinsonian mice baseline differs from the first and fourth A77636 session (p = 0.0004 and < 0.0001) and the two sessions do not differ (p = 1; paper 0.59). In controls no comparison is significant (smallest p = 0.31; paper first against fourth 0.49).
fig1b-th-loss¶
6-OHDA caused about 50% loss of TH immunofluorescence in the rostral dorsolateral and dorsomedial striatum, with less depletion in the ventral striatum.
CTF per ROI (Supplementary methods), normalized to the mean of the control mice of the same staining cohort (each cohort "includes both healthy and parkinsonian samples to control for inter-batch staining variability", deposit README); reading (b) normalizes to the mean of all control mice. Kruskal-Wallis over DLS, DMS and VS of the parkinsonian mice with Dunn's comparisons.
sec = icd.striatal_th()
print("sections:", len(sec), "| mice per cohort and group:")
print(sec.groupby(["cohort", "group"]).mouse.nunique().unstack().to_string())
M = sec.groupby(["cohort", "group", "mouse"])[["DLS", "DMS", "VS"]].mean().reset_index()
ctrl_cohort = M[M.group == "control"].groupby("cohort")[["DLS", "DMS", "VS"]].mean()
ctrl_all = M[M.group == "control"][["DLS", "DMS", "VS"]].mean()
def dunn_kw(df, cols):
allv = pd.concat([df[c] for c in cols]).rank()
n = len(df)
ranks = {c: allv.iloc[i * n:(i + 1) * n].mean() for i, c in enumerate(cols)}
N = n * len(cols)
se = np.sqrt(N * (N + 1) / 12 * (2 / n))
pairs = [(a, b) for i, a in enumerate(cols) for b in cols[i + 1:]]
return {f"{a} vs {b}": min(1, 2 * stats.norm.sf(abs(ranks[a] - ranks[b]) / se) * len(pairs)) for a, b in pairs}
th = {}
for reading, ref in [("per cohort", None), ("all controls", ctrl_all)]:
N = M.copy()
for r in ["DLS", "DMS", "VS"]:
N[r] = N[r] / (N.cohort.map(ctrl_cohort[r]) if ref is None else ref[r])
P = N[N.group == "parkinsonian"].groupby("mouse")[["DLS", "DMS", "VS"]].mean()
th[reading] = P
loss = 100 * (1 - P.mean())
print(f"{reading}: {len(P)} parkinsonian mice; loss % mean {loss.round(1).to_dict()}, "
f"median {(100 * (1 - P.median())).round(1).to_dict()}; Kruskal-Wallis p = {stats.kruskal(P.DLS, P.DMS, P.VS).pvalue:.3g}; "
f"Dunn {dict((k, round(v, 4)) for k, v in dunn_kw(P, ['DLS', 'DMS', 'VS']).items())}")
one = [c for c, n in M[M.group == "control"].groupby("cohort").size().items() if n == 1]
print("cohorts with a single control mouse:", one)
P = th["per cohort"]
keep = M[(M.group == "parkinsonian") & ~M.cohort.isin(one)].mouse.unique()
Pk = P.loc[P.index.intersection(keep)]
print(f"per cohort, without those cohorts: {len(Pk)} mice; loss % mean {(100 * (1 - Pk.mean())).round(1).to_dict()}; "
f"Dunn {dict((k, round(v, 4)) for k, v in dunn_kw(Pk, ['DLS', 'DMS', 'VS']).items())}")
print("parkinsonian mice with sections in more than one cohort:",
M[M.group == "parkinsonian"].groupby("mouse").cohort.nunique().loc[lambda s: s > 1].index.tolist())
sections: 362 | mice per cohort and group:
group control parkinsonian
cohort
cohort1 3 4
cohort2 3 5
cohort3 1 2
cohort4 1 3
cohort5 2 2
cohort6 2 11
cohort7 7 16
cohort8 3 2
per cohort: 45 parkinsonian mice; loss % mean {'DLS': 64.3, 'DMS': 56.8, 'VS': 35.3}, median {'DLS': 66.3, 'DMS': 58.4, 'VS': 39.7}; Kruskal-Wallis p = 3.43e-08; Dunn {'DLS vs DMS': np.float64(0.3836), 'DLS vs VS': np.float64(0.0), 'DMS vs VS': np.float64(0.0001)}
all controls: 45 parkinsonian mice; loss % mean {'DLS': 60.5, 'DMS': 52.4, 'VS': 28.3}, median {'DLS': 70.8, 'DMS': 58.4, 'VS': 44.9}; Kruskal-Wallis p = 0.00291; Dunn {'DLS vs DMS': 1, 'DLS vs VS': np.float64(0.0028), 'DMS vs VS': np.float64(0.0524)}
cohorts with a single control mouse: ['cohort3', 'cohort4']
per cohort, without those cohorts: 40 mice; loss % mean {'DLS': 65.7, 'DMS': 58.1, 'VS': 36.7}; Dunn {'DLS vs DMS': np.float64(0.4442), 'DLS vs VS': np.float64(0.0), 'DMS vs VS': np.float64(0.0002)}
parkinsonian mice with sections in more than one cohort: []
Result: partially reproduced. VS is less depleted than DLS and DMS and DLS does not differ from DMS under the per-cohort reading (Dunn p < 0.0001, 0.0001 and 0.38), but the mean losses in DLS (64.3%) and DMS (56.8%) are outside 50 +/- 5%. Normalized to all controls, the DMS loss (52.4%) is inside the tolerance and DLS (60.5%) is not, and VS against DMS gives p = 0.052. 45 parkinsonian mice enter (Table 1 gives N = 44; no mouse appears in two cohorts, so which mouse is extra cannot be told). Cohorts 3 and 4 have one control each; without them (40 mice) the losses are 65.7% and 58.1% and the pattern holds (DMS against VS p = 0.0002).
figs1d-snc-cells¶
Parkinsonian mice had fewer TH-positive dopamine neurons in the substantia nigra pars compacta than controls.
Density = TH+ cells counted over the four sections and both sides, divided by the area counted. The workbook has no group column. Groups come, in this order, from the histology workbook of the same deposit (its "Ctrl" and "Park" blocks), the deposit README's PPX lists, and, for the electrophysiology mice, the DANDI subjects' lesion (saline or 6-OHDA).
snc = icd.read_excel(icd.INSTRUMENTAL)["Fig. S1D"].iloc[1:].copy()
snc.columns = ["ap", "image", "notes", "mouse", "lc", "la", "rc", "ra"]
for c in ["lc", "la", "rc", "ra"]:
snc[c] = pd.to_numeric(snc[c], errors="coerce")
bad = snc[(snc.la < 1000) | (snc.ra < 1000)]
print("rows whose area is under 1000 (columns shifted):", bad[["mouse", "lc", "la", "rc", "ra"]].values.tolist())
snc.loc[bad.index, ["lc", "la", "rc", "ra"]] = np.nan
mouse_n = snc.mouse.str.replace("JF-", "JF").str.strip()
per = snc.assign(mouse=mouse_n).groupby("mouse").apply(
lambda g: pd.Series({"cells": g.lc.sum() + g.rc.sum(), "area": g.la.sum() + g.ra.sum()}))
per["density"] = per.cells / per.area * 1e6
ppx_c, ppx_p = groups[("PPX", "control")], groups[("PPX", "parkinsonian")]
dandi_lesion = {s.replace("-", "."): l for s, l in zip(subj.subject, subj.lesion)}
dandi_lesion.update({s.replace("-", ""): l for s, l in zip(subj.subject, subj.lesion)})
histo_group = icd.striatal_th().drop_duplicates("mouse").set_index("mouse").group.to_dict()
def snc_group(m):
if m in histo_group:
return histo_group[m]
if m in ppx_c:
return "control"
if m in ppx_p:
return "parkinsonian"
return {"saline": "control", "6-OHDA": "parkinsonian"}.get(dandi_lesion.get(m), None)
per["group"] = [snc_group(m) for m in per.index]
print(per.round(2).to_string())
lab = per.dropna(subset=["group"])
c, p = lab[lab.group == "control"].density, lab[lab.group == "parkinsonian"].density
print(f"linked mice: {len(lab)} of {len(per)} (control {len(c)}, parkinsonian {len(p)}); median density "
f"control {c.median():.1f}, parkinsonian {p.median():.1f} cells/mm2 (area units assumed um2); "
f"Mann-Whitney p = {stats.mannwhitneyu(c, p).pvalue:.3g}")
unl = per[per.group.isna()].density
for g in ["control", "parkinsonian"]:
cc = pd.concat([c, unl]) if g == "control" else c
pp = pd.concat([p, unl]) if g == "parkinsonian" else p
print(f" unlinked mice all counted as {g}: Mann-Whitney p = {stats.mannwhitneyu(cc, pp).pvalue:.3g}")
rows whose area is under 1000 (columns shifted): [['D3', 23.0, 36.0, 269962.877, 292884.817], ['N4', 103.0, 78.0, 414173.457, 383819.083]]
cells area density group mouse C0.1 784.0 2136534.66 366.95 NaN C1.1 578.0 1903569.32 303.64 control C2 468.0 2380161.21 196.63 parkinsonian C2.1 456.0 2180963.42 209.08 NaN C3.2 436.0 2413826.00 180.63 control C9 507.0 2298923.08 220.54 parkinsonian D0.1 780.0 2155545.62 361.86 control D2 578.0 2003834.15 288.45 control D2.2 343.0 2400501.61 142.89 parkinsonian D3 169.0 1480404.26 114.16 parkinsonian D4 361.0 1991927.16 181.23 parkinsonian D4.2 776.0 2135082.28 363.45 control D5.2 748.0 2033955.83 367.76 NaN D6 107.0 2426792.88 44.09 parkinsonian D6.1 587.0 1969567.58 298.03 control E0 169.0 2181647.78 77.46 parkinsonian E1.1 768.0 2105673.48 364.73 control E3 219.0 1842369.50 118.87 parkinsonian E3.2 546.0 1985598.07 274.98 parkinsonian E3.3 493.0 2175821.73 226.58 parkinsonian E4 504.0 1950318.15 258.42 parkinsonian E5 581.0 1838374.32 316.04 control E5.2 971.0 2325759.36 417.50 control E6 299.0 2137092.18 139.91 parkinsonian E6.2 367.0 2255949.93 162.68 parkinsonian E7 375.0 1952691.47 192.04 parkinsonian E9 228.0 2073780.24 109.94 parkinsonian JFB 555.0 2096241.23 264.76 parkinsonian JFC 504.0 1939359.28 259.88 parkinsonian N0 525.0 2380311.74 220.56 parkinsonian N4 333.0 1142465.24 291.47 parkinsonian N5 326.0 2155097.46 151.27 parkinsonian linked mice: 29 of 32 (control 9, parkinsonian 20); median density control 316.0, parkinsonian 186.6 cells/mm2 (area units assumed um2); Mann-Whitney p = 0.000259 unlinked mice all counted as control: Mann-Whitney p = 0.000107 unlinked mice all counted as parkinsonian: Mann-Whitney p = 0.00193
Result: reproduced. In the 29 mice whose group is known (9 control, 20 parkinsonian; the paper has 9 and 21), TH+ cell density in the SNc is lower in parkinsonian mice (median 186.6 against 316.0 cells per mm2, Mann-Whitney p = 0.0003). The three mice in no list (C0.1, C2.1, D5.2) do not change this whichever group they are put in (p = 0.0001 and 0.0019). Two rows of the workbook (D3 and N4 at -3.51 mm) have their count and area columns shifted and are left out.
fig1c-rotarod¶
Parkinsonian mice fell sooner from the accelerating rotarod than controls, and PPX improved their performance.
rr = icd.read_excel("Data_ICD_Fig1_Rotarod_PPX.xlsx")["Sheet1"]
cols = {rr.iat[0, j]: pd.to_numeric(rr.iloc[2:, j], errors="coerce").dropna().reset_index(drop=True)
for j in range(rr.shape[1]) if isinstance(rr.iat[0, j], str)}
for k, v in cols.items():
print(f"{k}: n = {len(v)}, median {v.median():.1f} s, range {v.min():.1f} to {v.max():.1f}")
ctrl = cols["Ctrl_baseline"]
p1, ppx = cols["Park_cohort1_baseline"], cols["Park_cohort1_PPX"]
p2, sal = cols["Park_cohort2_baseline"], cols["Park_cohort2_Saline"]
kw = stats.kruskal(ctrl, p1, ppx, p2, sal)
allv = pd.concat([ctrl, p1, ppx, p2, sal], keys=["ctrl", "p1", "ppx", "p2", "sal"]).rank()
N = len(allv)
def dunn(a, b, m=3):
ra, rb = allv[a].mean(), allv[b].mean()
se = np.sqrt(N * (N + 1) / 12 * (1 / len(allv[a]) + 1 / len(allv[b])))
return min(1, 2 * stats.norm.sf(abs(ra - rb) / se) * m)
print(f"Kruskal-Wallis over the five columns p = {kw.pvalue:.3g}; Dunn (3 comparisons): control vs park "
f"baseline p = {dunn('ctrl', 'p1'):.3g}, park baseline vs PPX p = {dunn('p1', 'ppx'):.3g}, "
f"park baseline vs saline p = {dunn('p2', 'sal'):.3g}")
print(f"variant: Mann-Whitney control vs park baseline (cohort 1) p = {stats.mannwhitneyu(ctrl, p1).pvalue:.3g}; "
f"Wilcoxon baseline vs PPX p = {stats.wilcoxon(p1, ppx).pvalue:.3g}; baseline vs saline p = {stats.wilcoxon(p2, sal).pvalue:.3g}")
names = ["ctrl", "p1", "ppx", "p2", "sal"]
all10 = {f"{a} vs {b}": dunn(a, b, 10) for i, a in enumerate(names) for b in names[i + 1:]}
print("Dunn corrected over all 10 pairs:", {k: float(f"{v:.3g}") for k, v in all10.items()})
Ctrl_baseline: n = 40, median 91.3 s, range 55.7 to 123.3
Park_cohort1_baseline: n = 45, median 47.3 s, range 15.0 to 96.0
Park_cohort1_PPX: n = 45, median 66.7 s, range 26.0 to 127.7
Park_cohort2_baseline: n = 27, median 51.0 s, range 17.0 to 93.7
Park_cohort2_Saline: n = 27, median 62.3 s, range 30.3 to 95.7
Kruskal-Wallis over the five columns p = 6.67e-15; Dunn (3 comparisons): control vs park baseline p = 1.14e-15, park baseline vs PPX p = 1.81e-05, park baseline vs saline p = 0.827
variant: Mann-Whitney control vs park baseline (cohort 1) p = 5.03e-13; Wilcoxon baseline vs PPX p = 3.09e-08; baseline vs saline p = 0.0735
Dunn corrected over all 10 pairs: {'ctrl vs p1': 3.81e-15, 'ctrl vs ppx': 0.00174, 'ctrl vs p2': 2.45e-07, 'ctrl vs sal': 0.000115, 'p1 vs ppx': 6.03e-05, 'p1 vs p2': 1.0, 'p1 vs sal': 0.0539, 'ppx vs p2': 0.185, 'ppx vs sal': 1.0, 'p2 vs sal': 1.0}
Result: reproduced. Parkinsonian mice fall sooner than controls (median 47.3 against 91.3 s, Dunn p = 1.1e-15), PPX raises their latency (to 66.7 s, Dunn p = 1.8e-05) and saline does not (Dunn p = 0.83). The variant tests agree (Mann-Whitney p = 5e-13, Wilcoxon p = 3e-08 and 0.074), and so does Dunn's correction over all ten pairs (p = 3.8e-15, 6.0e-05 and 1). The workbook has 40 control, 45 PPX and 27 saline mice; Table 1 gives 31, 45 and 27. The workbook does not say which 31 controls the paper used, so all 40 enter; the control against parkinsonian difference is far from the threshold either way.
figs1-instrumental-learning¶
Parkinsonian mice had slightly slower response latencies and learning in the first instrumental learning phase but reached performance similar to controls in the second.
Mann-Whitney per session, Bonferroni over six sessions, from the workbook's Figure S1H-I and S1K-L sheets. The second "Session1_Park" header of the S1K-L sheet (row 118), between session 1 parkinsonian and session 2 parkinsonian, is read as session 2 control.
sheets = icd.read_excel(icd.INSTRUMENTAL)
for sheet, cols in (("Fig. S1H&I", [13, 14]), ("Fig. S1K&L", [5, 8])):
d = sheets[sheet]
print(sheet, "| header cells of the columns used:")
for c in cols:
print(f" column {c}: rows 0-2 = {d.iloc[0:3, c].tolist()}")
print(" row 0:", d.iloc[0].tolist())
print(" row 1:", d.iloc[1].tolist())
inst = icd.instrumental_tables()
fix = (inst.phase == "random") & (inst.header_row == 118)
inst.loc[fix, ["session", "group"]] = [2, "control"]
rows = []
for (phase, s), g in inst.groupby(["phase", "session"]):
c, p = g[g.group == "control"], g[g.group == "parkinsonian"]
for m in ["success", "latency"]:
rows.append({"phase": phase, "session": s, "measure": m, "n_ctrl": c[m].notna().sum(),
"n_park": p[m].notna().sum(), "median_ctrl": c[m].median(), "median_park": p[m].median(),
"p_bonf": min(1, stats.mannwhitneyu(c[m].dropna(), p[m].dropna()).pvalue * 6)})
print(pd.DataFrame(rows).round(4).to_string(index=False))
Fig. S1H&I | header cells of the columns used: column 13: rows 0-2 = ['% of TOTAL successful trials', 'TOTAL', 88.67924528301887] column 14: rows 0-2 = ['TOTAL Latency to Trigger (s)', nan, 5.774225996376805] row 0: ['Session1_Ctrl', '# of rewarded trials', 'Latency to Trigger (s)', '# omission', '# of total trials', '% of successful trials', np.float64(nan), '# of rewarded trials', 'Latency to Trigger (s)', '# omission', '# of total trials', '% of successful trials', nan, '% of TOTAL successful trials', 'TOTAL Latency to Trigger (s)', np.float64(nan), nan] row 1: [nan, 'BLOCK1', nan, nan, nan, nan, np.float64(nan), 'BLOCK2', nan, nan, nan, nan, nan, 'TOTAL', nan, np.float64(nan), 'Note: the grey cell in the Latency to Trigger column indicates that there were no rewarded trials in that block. '] Fig. S1K&L | header cells of the columns used: column 5: rows 0-2 = ['% of succesful trials', 87.5, 91.04477611940298] column 8: rows 0-2 = ['CenterTriggerLatency (s)', 3.462640625, 5.9025] row 0: ['Session1_Ctrl', '# Total Trials', '# left rewarded trials', '# of right rewarded trials', '# of center triggered trials', '% of succesful trials', '# of center omission trials', '# of side omission trials', 'CenterTriggerLatency (s)'] row 1: [nan, 72, 33, 30, 64, 87.5, 8, 1, 3.462640625]
phase session measure n_ctrl n_park median_ctrl median_park p_bonf blocked 1 success 32 81 20.4118 11.0000 0.0070 blocked 1 latency 32 81 9.4648 9.1175 1.0000 blocked 2 success 32 81 40.3970 15.7663 0.0683 blocked 2 latency 32 81 8.2558 9.5625 0.2078 blocked 3 success 32 81 82.9910 36.3529 0.0055 blocked 3 latency 32 81 6.6634 9.1053 0.0005 blocked 4 success 32 81 92.4700 61.7647 0.0035 blocked 4 latency 32 81 5.5662 8.0311 0.0041 blocked 5 success 26 81 94.7391 79.1176 0.1093 blocked 5 latency 26 81 4.3295 6.9745 0.0030 blocked 6 success 26 74 97.3214 89.6488 0.0953 blocked 6 latency 26 74 3.7300 5.5436 0.0119 random 1 success 32 80 86.9424 65.9294 0.0030 random 1 latency 32 80 3.1398 3.4129 0.3844 random 2 success 30 80 85.3543 75.7205 0.1538 random 2 latency 30 80 2.8797 2.9480 1.0000 random 3 success 32 80 89.3804 84.8269 0.6919 random 3 latency 32 80 2.2198 2.4812 1.0000 random 4 success 31 80 92.0863 90.5158 1.0000 random 4 latency 31 80 1.7914 2.2506 0.4334 random 5 success 32 79 95.3841 93.2836 0.5890 random 5 latency 32 79 1.6344 2.1397 0.1260 random 6 success 26 74 95.9720 93.1944 0.9782 random 6 latency 26 74 1.6581 1.9721 0.7942
Result: partially reproduced. In blocked learning parkinsonian mice have lower success in sessions 1, 3 and 4 (Bonferroni p = 0.007, 0.0055, 0.0035) and longer latencies in sessions 3 to 6 (p = 0.0005 to 0.012). In random learning they are similar in sessions 2 to 6, but session 1 success differs (65.9 against 86.9%, p = 0.003), against the criterion's "no session of random learning differs". Initiation latency differs in no random session. The columns read are those headed "% of TOTAL successful trials" and "TOTAL Latency to Trigger (s)" (blocked) and "% of succesful trials" and "CenterTriggerLatency (s)" (random), printed above.
Correlations with striatal TH: fig3a-a-correlates-dms, fig3b-k-no-correlation, figs4-a77636-no-correlation¶
A and K on the drug (four ON sessions) of each parkinsonian mouse against its normalized TH (per-cohort reading of fig1b-th-loss), Pearson correlation.
def corr_block(exp, label):
out = {}
for ron in ["four", "first"]:
on = params(per_mouse(exp, "parkinsonian", "on", ron))
P0 = th["per cohort"]
if ron == "four":
print(f"{label}: {len(on)} mice with a fit on the drug, {len(P0)} parkinsonian mice with TH; "
f"joined {len(on.index.intersection(P0.index))}")
print(f" drug mice without TH: {sorted(set(on.index) - set(P0.index))}")
print(f" TH mice of the {label} parkinsonian list without a drug session: "
f"{sorted(set(P0.index) & set(groups[(exp, 'parkinsonian')]) - set(on.index))}")
print(f" TH mice in no README list of any experiment: "
f"{sorted(set(P0.index) - {m for v in groups.values() for m in v})}")
for reading, P in th.items():
j = on.join(P, how="inner")
for p in ["A", "K"]:
for r in ["DMS", "DLS", "VS"]:
rr_, pp = stats.pearsonr(j[p], j[r])
out[(ron, reading, p, r)] = (len(j), rr_, pp)
print(f"{label} ON {ron}, TH {reading}: {p} vs {r} TH, n = {len(j)}, r = {rr_:.2f}, p = {pp:.3g}")
return out
corr_ppx = corr_block("PPX", "PPX")
PPX: 30 mice with a fit on the drug, 45 parkinsonian mice with TH; joined 24 drug mice without TH: ['C3.1', 'E3.3', 'E4', 'H4.1', 'N1', 'N5.1'] TH mice of the PPX parkinsonian list without a drug session: ['E6'] TH mice in no README list of any experiment: ['E3', 'E3.2'] PPX ON four, TH per cohort: A vs DMS TH, n = 24, r = 0.32, p = 0.128 PPX ON four, TH per cohort: A vs DLS TH, n = 24, r = 0.23, p = 0.289 PPX ON four, TH per cohort: A vs VS TH, n = 24, r = 0.28, p = 0.183 PPX ON four, TH per cohort: K vs DMS TH, n = 24, r = 0.03, p = 0.887 PPX ON four, TH per cohort: K vs DLS TH, n = 24, r = 0.40, p = 0.0555 PPX ON four, TH per cohort: K vs VS TH, n = 24, r = 0.32, p = 0.132 PPX ON four, TH all controls: A vs DMS TH, n = 24, r = 0.14, p = 0.516 PPX ON four, TH all controls: A vs DLS TH, n = 24, r = -0.04, p = 0.87 PPX ON four, TH all controls: A vs VS TH, n = 24, r = -0.04, p = 0.843 PPX ON four, TH all controls: K vs DMS TH, n = 24, r = 0.08, p = 0.702 PPX ON four, TH all controls: K vs DLS TH, n = 24, r = 0.39, p = 0.0597 PPX ON four, TH all controls: K vs VS TH, n = 24, r = 0.38, p = 0.0678 PPX ON first, TH per cohort: A vs DMS TH, n = 24, r = 0.08, p = 0.707 PPX ON first, TH per cohort: A vs DLS TH, n = 24, r = -0.11, p = 0.598 PPX ON first, TH per cohort: A vs VS TH, n = 24, r = 0.03, p = 0.889 PPX ON first, TH per cohort: K vs DMS TH, n = 24, r = -0.21, p = 0.319 PPX ON first, TH per cohort: K vs DLS TH, n = 24, r = -0.15, p = 0.476 PPX ON first, TH per cohort: K vs VS TH, n = 24, r = -0.01, p = 0.971 PPX ON first, TH all controls: A vs DMS TH, n = 24, r = 0.07, p = 0.752 PPX ON first, TH all controls: A vs DLS TH, n = 24, r = -0.19, p = 0.362 PPX ON first, TH all controls: A vs VS TH, n = 24, r = -0.06, p = 0.765 PPX ON first, TH all controls: K vs DMS TH, n = 24, r = -0.12, p = 0.569 PPX ON first, TH all controls: K vs DLS TH, n = 24, r = -0.10, p = 0.648 PPX ON first, TH all controls: K vs VS TH, n = 24, r = 0.15, p = 0.499
Result: not reproduced. A on PPX (four sessions) correlates with DMS TH at r = 0.32, p = 0.13 in the 24 mice with both measures (paper r = 0.51, p = 0.006, n = 28), outside the tolerance (0.46 to 0.56); DLS and VS are not significant (p = 0.29 and 0.18). With the first PPX session r = 0.08 (p = 0.71), and normalized to all controls r = 0.14 and 0.07. Of the 30 PPX mice, six have no histology (C3.1, E3.3, E4, H4.1, N1, N5.1), and two histology mice (E3, E3.2) are in no README list. E3.3 and E3 or E3.2 may be the same mouse under two names, but nothing in the deposit links them; the 24 matched identifiers are exact.
for (ron, reading, p, r), (n, rr_, pp) in corr_ppx.items():
if p == "K":
print(f"PPX ON {ron}, TH {reading}: K vs {r}, n = {n}, r = {rr_:.2f}, p = {pp:.3g}")
PPX ON four, TH per cohort: K vs DMS, n = 24, r = 0.03, p = 0.887 PPX ON four, TH per cohort: K vs DLS, n = 24, r = 0.40, p = 0.0555 PPX ON four, TH per cohort: K vs VS, n = 24, r = 0.32, p = 0.132 PPX ON four, TH all controls: K vs DMS, n = 24, r = 0.08, p = 0.702 PPX ON four, TH all controls: K vs DLS, n = 24, r = 0.39, p = 0.0597 PPX ON four, TH all controls: K vs VS, n = 24, r = 0.38, p = 0.0678 PPX ON first, TH per cohort: K vs DMS, n = 24, r = -0.21, p = 0.319 PPX ON first, TH per cohort: K vs DLS, n = 24, r = -0.15, p = 0.476 PPX ON first, TH per cohort: K vs VS, n = 24, r = -0.01, p = 0.971 PPX ON first, TH all controls: K vs DMS, n = 24, r = -0.12, p = 0.569 PPX ON first, TH all controls: K vs DLS, n = 24, r = -0.10, p = 0.648 PPX ON first, TH all controls: K vs VS, n = 24, r = 0.15, p = 0.499
Result: reproduced. K on PPX does not correlate with TH in any subregion (DMS r = 0.03, DLS r = 0.40, VS r = 0.32; p = 0.89, 0.056, 0.13; n = 24). With the first PPX session and under both normalizations, every p >= 0.056.
corr_a77 = corr_block("A77636", "A77636")
A77636: 16 mice with a fit on the drug, 45 parkinsonian mice with TH; joined 16 drug mice without TH: [] TH mice of the A77636 parkinsonian list without a drug session: [] TH mice in no README list of any experiment: ['E3', 'E3.2'] A77636 ON four, TH per cohort: A vs DMS TH, n = 16, r = -0.24, p = 0.381 A77636 ON four, TH per cohort: A vs DLS TH, n = 16, r = -0.09, p = 0.735 A77636 ON four, TH per cohort: A vs VS TH, n = 16, r = -0.19, p = 0.49 A77636 ON four, TH per cohort: K vs DMS TH, n = 16, r = -0.23, p = 0.383 A77636 ON four, TH per cohort: K vs DLS TH, n = 16, r = -0.07, p = 0.793 A77636 ON four, TH per cohort: K vs VS TH, n = 16, r = -0.31, p = 0.235 A77636 ON four, TH all controls: A vs DMS TH, n = 16, r = -0.24, p = 0.381 A77636 ON four, TH all controls: A vs DLS TH, n = 16, r = -0.09, p = 0.735 A77636 ON four, TH all controls: A vs VS TH, n = 16, r = -0.19, p = 0.49 A77636 ON four, TH all controls: K vs DMS TH, n = 16, r = -0.23, p = 0.383 A77636 ON four, TH all controls: K vs DLS TH, n = 16, r = -0.07, p = 0.793 A77636 ON four, TH all controls: K vs VS TH, n = 16, r = -0.31, p = 0.235 A77636 ON first, TH per cohort: A vs DMS TH, n = 16, r = -0.24, p = 0.367 A77636 ON first, TH per cohort: A vs DLS TH, n = 16, r = -0.15, p = 0.581 A77636 ON first, TH per cohort: A vs VS TH, n = 16, r = -0.19, p = 0.485 A77636 ON first, TH per cohort: K vs DMS TH, n = 16, r = -0.36, p = 0.172 A77636 ON first, TH per cohort: K vs DLS TH, n = 16, r = -0.27, p = 0.319 A77636 ON first, TH per cohort: K vs VS TH, n = 16, r = -0.46, p = 0.0708 A77636 ON first, TH all controls: A vs DMS TH, n = 16, r = -0.24, p = 0.367 A77636 ON first, TH all controls: A vs DLS TH, n = 16, r = -0.15, p = 0.581 A77636 ON first, TH all controls: A vs VS TH, n = 16, r = -0.19, p = 0.485 A77636 ON first, TH all controls: K vs DMS TH, n = 16, r = -0.36, p = 0.172 A77636 ON first, TH all controls: K vs DLS TH, n = 16, r = -0.27, p = 0.319 A77636 ON first, TH all controls: K vs VS TH, n = 16, r = -0.46, p = 0.0708
Result: reproduced. None of the six correlations of A and K on A77636 with TH is significant (smallest p = 0.24, K against VS, r = -0.31; paper r = -0.31, p = 0.23; n = 16). With the first A77636 session the smallest is p = 0.071 (K against VS). The two normalizations give the same r, as all 16 mice are in one staining cohort and the reference changes only a constant factor.
figs6-dreadd-validation¶
In slices CNO reduced optically evoked IPSCs from hM4Di-expressing iMSNs and increased the firing of hM3Dq-expressing dMSNs.
sl = icd.read_excel("Data_ICD_FigS6_SliceValidation.xlsx")["Sheet1"]
oipsc = sl.iloc[1:7, 1:3].apply(pd.to_numeric, errors="coerce")
oipsc.columns = ["baseline", "cno"]
print(oipsc.to_string())
print(f"oIPSC: n = {len(oipsc)}, median {oipsc.baseline.median():.1f} -> {oipsc.cno.median():.1f}, "
f"Wilcoxon p = {stats.wilcoxon(oipsc.baseline, oipsc.cno).pvalue:.3g}")
def io_block(r0):
blk = sl.iloc[r0:r0 + 6, 1:11].apply(pd.to_numeric, errors="coerce")
blk.index = blk.iloc[:, 0].astype(int)
return blk.iloc[:, 1:]
base_io, cno_io = io_block(10), io_block(21)
print("cells:", base_io.shape[1])
print(f"firing at 300 pA: median {base_io.loc[300].median():.1f} -> {cno_io.loc[300].median():.1f} Hz, "
f"Wilcoxon p = {stats.wilcoxon(base_io.loc[300], cno_io.loc[300]).pvalue:.3g}")
Lio = pd.concat([base_io.loc[[100, 200, 300, 400]].T.reset_index(drop=True).rename_axis("mouse").reset_index()
.melt(id_vars="mouse", var_name="delay", value_name="v").assign(t="baseline"),
cno_io.loc[[100, 200, 300, 400]].T.reset_index(drop=True).rename_axis("mouse").reset_index()
.melt(id_vars="mouse", var_name="delay", value_name="v").assign(t="cno")])
res = icd.split_plot_anova(Lio, "v", "t", ["baseline", "cno"])
print(f"input-output, CNO effect (cell x current units): F{res['treat_df']} = {res['treat_F']:.2f}, p = {res['treat_p']:.3g}")
import statsmodels.formula.api as smf
from statsmodels.stats.anova import anova_lm
fit = smf.ols("v ~ C(t) * C(delay)", data=Lio).fit()
print("ordinary two-way ANOVA (variant):", anova_lm(fit, typ=2).round(4).to_dict()["PR(>F)"], "error df", int(fit.df_resid))
baseline cno
1 463.00 32.562
2 875.00 15.875
3 1078.00 430.000
4 611.04 27.694
5 683.91 124.360
6 464.32 77.438
oIPSC: n = 6, median 647.5 -> 55.0, Wilcoxon p = 0.0312
cells: 9
firing at 300 pA: median 8.0 -> 16.0 Hz, Wilcoxon p = 0.0156
input-output, CNO effect (cell x current units): F(1, 32) = 17.64, p = 0.000199
ordinary two-way ANOVA (variant): {'C(t)': 0.082, 'C(delay)': 0.0, 'C(t):C(delay)': 0.7639, 'Residual': nan} error df 64
Result: reproduced. CNO reduces oIPSC amplitude (median 647.5 to 55.0 pA, Wilcoxon p = 0.031, 6 cells) and raises firing at 300 pA (8 to 16 Hz, p = 0.016, 9 cells), and the CNO effect on the input-output curve is F(1, 32) = 17.64, p = 0.0002, the paper's values, when each cell and current is the repeated unit; an ordinary two-way ANOVA gives p = 0.082.
Open field: fig2bc-a77636-locomotion and fig5cf-cno-locomotion¶
The files hold time (s) and velocity (cm/s) at 15 or 30 frames/s and no injection mark. Most have a short run of untracked frames at 20.0 to 20.7 min, consistent with the mouse being lifted for the injection after a 20 min baseline. Injection is taken at 20 min (an assumption); a -30 to 0 min baseline does not exist in these files, so only the -20 to 0 min reading can be run. For the CNO files, the variants below use only the files with a gap at 19.5 to 21 min, with injection at 20 min or at the gap.
def of_table(zip_name, pre, post):
of = icd.open_field(zip_name)
rows = []
for _, r in of.iterrows():
t, v = r.t_min - 20, r.velocity
gaps = icd.tracking_gaps(r.t_min, v)
rows.append({"mouse": r.mouse, "file": r.file, "end_min": r.t_min[-1],
"gap_near_20": f"{gaps[0][0]:.1f}" if gaps else "",
"pre": np.nanmean(v[(t >= pre[0]) & (t < pre[1])]),
"post": np.nanmean(v[(t >= post[0]) & (t < post[1])]),
"post_covered": r.t_min[-1] - 20 >= post[1]})
return pd.DataFrame(rows)
a77_of = of_table("Data_ICD_A77636OpenField_Raw.zip", (-20, 0), (30, 100))
ctrl_ids = groups[("A77636", "control")]
a77_of["group"] = np.where(a77_of.mouse.isin(ctrl_ids), "control", "not in the control list")
print(a77_of.round(2).to_string(index=False))
for g, t in a77_of.groupby("group"):
print(f"{g}: n = {len(t)}, median {t.pre.median():.2f} -> {t.post.median():.2f} cm/s, "
f"Wilcoxon p = {stats.wilcoxon(t.pre, t.post).pvalue:.3g}, faster in {int((t.post > t.pre).sum())}")
print("mice not in either A77636 list:", sorted(set(a77_of.mouse) - set(ctrl_ids) - set(groups[("A77636", "parkinsonian")])))
listed = a77_of[a77_of.mouse.isin(groups[("A77636", "parkinsonian")])]
print(f"parkinsonian mice on the README list only: n = {len(listed)}, median {listed.pre.median():.2f} -> "
f"{listed.post.median():.2f} cm/s, Wilcoxon p = {stats.wilcoxon(listed.pre, listed.post).pvalue:.3g}, "
f"faster in {int((listed.post > listed.pre).sum())}")
mouse file end_min gap_near_20 pre post post_covered group R1.3 R1.3_openField_A77636_013125.xlsx 179.96 20.2 3.50 4.00 True not in the control list O3.6 O3.6_openField_A77636_111224.xlsx 122.67 20.1 2.96 1.46 True control R0.2 R0.2_openField_A77636_013025.xlsx 143.77 20.3 2.10 2.37 True not in the control list R6 R6_openField_A77636_121624.xlsx 132.54 20.1 3.64 4.10 True not in the control list O0.1 O0.1_openField_A77636_101624.xlsx 140.11 20.0 3.95 4.19 True not in the control list R0 R0_openField_A77636_122024.xlsx 158.60 20.2 1.55 1.74 True not in the control list O2 O2_openField_A77636_101624.xlsx 140.11 20.0 4.07 3.33 True control R3.2 R3.2_openField_A77636_120224.xlsx 141.05 20.0 3.51 4.45 True not in the control list R1.5 R1.5_openField_A77636_020425.xlsx 147.75 20.1 2.69 3.38 True not in the control list R3.1 R3.1_openField_A77636_120224.xlsx 141.05 20.0 3.66 4.52 True not in the control list R5.1 R5.1_openField_A77636_120224.xlsx 141.05 20.0 4.66 4.03 True control R6.1 R6.1_openField_A77636_013125.xlsx 179.96 20.2 3.28 2.86 True not in the control list R7.3 R7.3_openField_A77636_013025.xlsx 143.77 20.3 3.67 4.30 True control O0 O0_openField_A77636_101624.xlsx 140.11 20.0 3.88 3.80 True control R3.3 R3.3_openField_A77636_013125.xlsx 179.96 20.2 3.06 3.06 True not in the control list R4.1 R4.1_openField_A77636_013025.xlsx 143.77 20.3 3.41 4.38 True not in the control list R5.3 R5.3_openField_A77636_020425.xlsx 147.75 20.1 1.68 1.22 True not in the control list R0.1 R0.1_openField_A77636_112724.xlsx 140.76 20.0 1.74 1.79 True control R4.3 R4.3_openField_A77636_110724.xlsx 147.81 20.0 3.11 3.17 True control O3 O3_openField_A77636_101624.xlsx 140.11 20.0 2.59 2.52 True control R4.4 R4.4_openField_A77636_013025.xlsx 143.77 20.3 2.59 2.44 True control O6 O6_openField_A77636_101624.xlsx 140.11 20.0 2.64 4.46 True not in the control list R1.1 R1.1_openField_A77636_111324.xlsx 136.93 15.0 3.22 4.11 True not in the control list O0.6 O0.6_openField_A77636_013025.xlsx 143.77 20.3 3.27 2.64 True control R1 R1_openField_A77636_121024.xlsx 140.21 20.2 3.07 2.46 True not in the control list R4 R4_openField_A77636_122024.xlsx 158.60 20.2 1.47 1.99 True not in the control list control: n = 10, median 3.19 -> 2.90 cm/s, Wilcoxon p = 0.0645, faster in 3 not in the control list: n = 16, median 3.14 -> 3.69 cm/s, Wilcoxon p = 0.0155, faster in 13 mice not in either A77636 list: ['O6', 'R0', 'R1', 'R3.2', 'R5.3', 'R6'] parkinsonian mice on the README list only: n = 10, median 3.25 -> 3.69 cm/s, Wilcoxon p = 0.0137, faster in 9
Result: reproduced, resting on an assumption. With injection at 20 min, the 16 mice not in the control list are faster 30 to 100 min after A77636 (median 3.14 to 3.69 cm/s, 13 of 16, Wilcoxon p = 0.016; paper p = 0.02) and the 10 controls are not (3.19 to 2.90 cm/s, p = 0.065; paper 0.16). Six of the 16 (O6, R0, R1, R3.2, R5.3, R6) are in neither A77636 list; they are taken as parkinsonian because the control list is complete (10 of 10) and 16 mice remain, the paper's N. The 10 mice on the README's parkinsonian list alone are also faster (3.25 to 3.69 cm/s, 9 of 10, p = 0.014). R1.1's file has long tracking losses before 20 min and its first gap near the injection at 15 min.
cno_raw = icd.open_field("Data_ICD_Fig5_DREADDLocomotion_Raw.zip")
cno_of = of_table("Data_ICD_Fig5_DREADDLocomotion_Raw.zip", (-20, 0), (20, 30))
def dgroup(m):
for g in ["mCherry", "hM4Di", "hM3Dq"]:
if m in groups[("DREADD", g)]:
return g
return None
cno_of["group"] = cno_of.mouse.map(dgroup)
print(cno_of.round(2).to_string(index=False))
import hashlib
digest = cno_raw.apply(lambda r: hashlib.md5(np.nan_to_num(r.velocity, nan=-1).tobytes()).hexdigest(), axis=1)
print("files with identical velocity traces:", cno_raw.groupby(digest).file.apply(list).loc[lambda s: s.str.len() > 1].tolist())
# injection evidenced by a tracking gap starting 19.5 to 21 min, and injection taken at the gap
gap = {r.file: (icd.tracking_gaps(r.t_min, r.velocity, near=(19.5, 21)) or [(np.nan, 0)])[0][0] for _, r in cno_raw.iterrows()}
cno_of["gap_19_21"] = cno_of.file.map(gap)
def at_gap(r):
t = r.t_min - gap[r.name]
return pd.Series({"pre_gap": np.nanmean(r.velocity[(t >= -20) & (t < 0)]),
"post_gap": np.nanmean(r.velocity[(t >= 20) & (t < 30)])})
cno_of = cno_of.join(cno_raw.set_index("file").apply(at_gap, axis=1), on="file")
print("first tracking gap starting 19.5 to 21 min, per file (NaN: none):")
print(cno_of[["file", "group", "gap_19_21"]].round(2).to_string(index=False))
print("files per group with and without a gap at 19.5-21 min:",
cno_of.groupby(["group", cno_of.gap_19_21.notna()]).size().to_dict())
print("velocity (cm/s) per minute from 15 to 25 min in files with no gap there:")
for _, r in cno_raw[cno_raw.file.map(gap).isna()].iterrows():
print(f" {r.file} ({dgroup(r.mouse)}): " + " ".join(f"{np.nanmean(r.velocity[(r.t_min >= a) & (r.t_min < a + 1)]):.1f}" for a in range(15, 25)))
def wil(t, a, b):
return (f"n = {len(t)}, median {t[a].median():.2f} -> {t[b].median():.2f} cm/s, "
+ (f"Wilcoxon p = {stats.wilcoxon(t[a], t[b]).pvalue:.3g}, " if len(t) > 1 else "")
+ f"faster in {int((t[b] > t[a]).sum())}")
variants = {"injection at 20 min, every file": (cno_of, "pre", "post"),
"injection at 20 min, without H0.4 (duplicate of H0)": (cno_of[~cno_of.file.str.startswith("H0.4_")], "pre", "post"),
"files with a gap at 19.5-21 min, injection at 20 min": (cno_of[cno_of.gap_19_21.notna()], "pre", "post"),
"files with a gap at 19.5-21 min, injection at the gap": (cno_of[cno_of.gap_19_21.notna()], "pre_gap", "post_gap")}
for name, (tab, a, b) in variants.items():
for g, t in tab.dropna(subset=["group"]).groupby("group"):
print(f"{name} | {g}: {wil(t, a, b)}")
print("files whose mouse is in no DREADD list:", cno_of[cno_of.group.isna()].file.tolist())
mouse file end_min gap_near_20 pre post post_covered group
R6 R6_openField_CNO_122024.xlsx 158.60 20.2 3.78 6.69 True hM3Dq
R5.3 R5.3_openField_CNO_013125.xlsx 179.96 20.2 2.27 4.35 True hM3Dq
R5 R5_openField_CNO_121924.xlsx 140.43 20.3 1.81 6.83 True hM3Dq
R0.4 R0.4_openField_CNO_020425.xlsx 141.21 20.4 2.03 3.52 True hM3Dq
F5.1 F5.1_openField_CNO_121422.xlsx 54.94 20.7 4.30 7.62 True hM4Di
H2.2 H2.2_openField_CNO_061723.xlsx 63.82 3.63 5.62 True hM4Di
O1 O1_openField_CNO_102524.xlsx 140.59 20.0 2.97 4.00 True hM3Dq
H1 H1_openField_CNO_061323.xlsx 67.91 17.7 4.76 3.61 True mCherry
H4.2 H4.2_openField_CNO_061623.xlsx 60.44 3.44 6.63 True hM4Di
R2.2 R2.2_openField_CNO_112724.xlsx 140.76 20.0 3.82 2.83 True mCherry
R7.2 R7.2_openField_CNO_020425.xlsx 147.75 20.1 1.97 1.52 True mCherry
R0 R0_openField_CNO_121924.xlsx 140.43 20.3 2.61 2.23 True NaN
H0.4 H0.4_openField_CNO_061523.xlsx 60.64 2.91 4.16 True hM4Di
F0 F0_openField_CNO_122622.xlsx 50.02 20.0 5.21 6.59 True NaN
R1.4 R1.4_openField_CNO_020425.xlsx 141.21 20.4 2.13 4.52 True hM3Dq
F1 F1_openField_CNO_122622.xlsx 50.02 20.0 6.62 8.98 True hM4Di
J3 J3_openField_CNO_110923.xlsx 60.00 18.5 2.59 1.89 True mCherry
R2.4 R2.4_openField_CNO_020425.xlsx 141.21 20.4 2.46 2.02 True mCherry
H2.1 H2.1_openField_CNO_062123.xlsx 62.40 4.66 8.10 True hM4Di
R4 R4_openField_CNO_111224.xlsx 122.67 20.1 1.66 2.80 True hM3Dq
H4.1 H4.1_openField_CNO_070223.xlsx 50.50 3.68 5.21 True hM4Di
F3 F3_openField_CNO_121422.xlsx 54.94 20.7 4.75 1.41 True NaN
F5 F5_openField_CNO_1222222.xlsx 60.31 20.1 3.97 3.91 True hM4Di
R1.2 R1.2_openField_CNO_112724.xlsx 140.76 20.0 1.72 2.02 True NaN
R5.5 R5.5_openField_CNO_020425.xlsx 141.21 20.4 2.54 1.88 True mCherry
O4.1 O4.1_openField_CNO_111324.xlsx 136.95 20.0 2.20 3.89 True hM3Dq
H1.4 H1.4_openField_CNO_070223.xlsx 53.59 3.23 2.34 True mCherry
J5.1 J5.1_openField_CNO_110923.xlsx 80.59 2.69 2.09 True mCherry
H0 H0_openField_CNO_061523.xlsx 60.61 2.91 4.16 True hM4Di
H5.2 H5.2_openField_CNO_061323.xlsx 51.15 4.02 7.85 True hM4Di
H7 H7_openField_CNO_062123.xlsx 62.40 3.61 2.57 True mCherry
O8.1 O8.1_openField_CNO_091324.xlsx 142.66 20.0 2.32 5.04 True hM3Dq
R1 R1_openField_CNO_111224.xlsx 122.67 20.1 4.47 5.42 True mCherry
R2 R2_openField_CNO_112724.xlsx 140.76 20.0 2.26 5.59 True hM3Dq
H2 H2_openField_CNO_061323.xlsx 67.91 3.53 3.18 True mCherry
J6 J6_openField_CNO_110923.xlsx 80.59 2.48 2.12 True mCherry
R5.2 R5.2_openField_CNO_020425.xlsx 147.75 20.1 1.56 3.29 True hM3Dq
files with identical velocity traces: [['H0.4_openField_CNO_061523.xlsx', 'H0_openField_CNO_061523.xlsx']]
first tracking gap starting 19.5 to 21 min, per file (NaN: none):
file group gap_19_21
R6_openField_CNO_122024.xlsx hM3Dq 20.15
R5.3_openField_CNO_013125.xlsx hM3Dq 20.22
R5_openField_CNO_121924.xlsx hM3Dq 20.26
R0.4_openField_CNO_020425.xlsx hM3Dq 20.39
F5.1_openField_CNO_121422.xlsx hM4Di 20.74
H2.2_openField_CNO_061723.xlsx hM4Di NaN
O1_openField_CNO_102524.xlsx hM3Dq 20.04
H1_openField_CNO_061323.xlsx mCherry 20.96
H4.2_openField_CNO_061623.xlsx hM4Di NaN
R2.2_openField_CNO_112724.xlsx mCherry 19.99
R7.2_openField_CNO_020425.xlsx mCherry 20.13
R0_openField_CNO_121924.xlsx NaN 20.26
H0.4_openField_CNO_061523.xlsx hM4Di NaN
F0_openField_CNO_122622.xlsx NaN 19.99
R1.4_openField_CNO_020425.xlsx hM3Dq 20.39
F1_openField_CNO_122622.xlsx hM4Di 19.99
J3_openField_CNO_110923.xlsx mCherry 19.57
R2.4_openField_CNO_020425.xlsx mCherry 20.39
H2.1_openField_CNO_062123.xlsx hM4Di NaN
R4_openField_CNO_111224.xlsx hM3Dq 20.06
H4.1_openField_CNO_070223.xlsx hM4Di NaN
F3_openField_CNO_121422.xlsx NaN 20.74
F5_openField_CNO_1222222.xlsx hM4Di 20.07
R1.2_openField_CNO_112724.xlsx NaN 19.99
R5.5_openField_CNO_020425.xlsx mCherry 20.39
O4.1_openField_CNO_111324.xlsx hM3Dq 20.04
H1.4_openField_CNO_070223.xlsx mCherry NaN
J5.1_openField_CNO_110923.xlsx mCherry NaN
H0_openField_CNO_061523.xlsx hM4Di NaN
H5.2_openField_CNO_061323.xlsx hM4Di NaN
H7_openField_CNO_062123.xlsx mCherry NaN
O8.1_openField_CNO_091324.xlsx hM3Dq 19.98
R1_openField_CNO_111224.xlsx mCherry 20.06
R2_openField_CNO_112724.xlsx hM3Dq 19.99
H2_openField_CNO_061323.xlsx mCherry NaN
J6_openField_CNO_110923.xlsx mCherry NaN
R5.2_openField_CNO_020425.xlsx hM3Dq 20.13
files per group with and without a gap at 19.5-21 min: {('hM3Dq', True): 11, ('hM4Di', False): 7, ('hM4Di', True): 3, ('mCherry', False): 5, ('mCherry', True): 7}
velocity (cm/s) per minute from 15 to 25 min in files with no gap there:
H2.2_openField_CNO_061723.xlsx (hM4Di): 4.1 4.1 3.7 2.7 1.8 1.4 2.0 1.8 1.5 2.4
H4.2_openField_CNO_061623.xlsx (hM4Di): 2.3 3.4 2.9 4.2 4.2 3.2 3.7 2.7 1.2 1.5
H0.4_openField_CNO_061523.xlsx (hM4Di): 2.9 2.4 2.6 2.4 3.4 3.5 3.1 1.9 2.4 2.0
H2.1_openField_CNO_062123.xlsx (hM4Di): 4.9 3.3 5.4 4.5 5.0 4.5 3.4 2.3 4.7 4.0
H4.1_openField_CNO_070223.xlsx (hM4Di): 4.3 4.9 2.8 4.1 3.7 3.8 3.6 3.4 2.7 2.4
H1.4_openField_CNO_070223.xlsx (mCherry): 2.2 2.5 3.0 3.0 4.9 3.6 1.9 1.2 2.4 1.7
J5.1_openField_CNO_110923.xlsx (mCherry): 3.0 2.2 1.8 3.2 2.2 3.1 1.9 2.0 0.7 1.3
H0_openField_CNO_061523.xlsx (hM4Di): 3.0 2.4 2.7 2.3 3.4 3.4 3.2 1.9 2.4 2.0
H5.2_openField_CNO_061323.xlsx (hM4Di): 4.6 4.9 6.2 4.9 4.0 2.2 1.4 3.4 1.4 2.9
H7_openField_CNO_062123.xlsx (mCherry): 3.3 3.1 4.7 3.9 1.6 2.5 1.0 2.8 3.6 3.2
H2_openField_CNO_061323.xlsx (mCherry): 3.5 3.8 3.4 3.3 3.5 3.1 3.1 2.3 3.7 2.9
J6_openField_CNO_110923.xlsx (mCherry): 1.8 3.0 2.6 1.8 1.7 3.0 1.2 2.9 1.9 1.4
injection at 20 min, every file | hM3Dq: n = 11, median 2.20 -> 4.35 cm/s, Wilcoxon p = 0.000977, faster in 11
injection at 20 min, every file | hM4Di: n = 10, median 3.83 -> 6.13 cm/s, Wilcoxon p = 0.00391, faster in 9
injection at 20 min, every file | mCherry: n = 12, median 2.96 -> 2.23 cm/s, Wilcoxon p = 0.0161, faster in 1
injection at 20 min, without H0.4 (duplicate of H0) | hM3Dq: n = 11, median 2.20 -> 4.35 cm/s, Wilcoxon p = 0.000977, faster in 11
injection at 20 min, without H0.4 (duplicate of H0) | hM4Di: n = 9, median 3.97 -> 6.63 cm/s, Wilcoxon p = 0.00781, faster in 8
injection at 20 min, without H0.4 (duplicate of H0) | mCherry: n = 12, median 2.96 -> 2.23 cm/s, Wilcoxon p = 0.0161, faster in 1
files with a gap at 19.5-21 min, injection at 20 min | hM3Dq: n = 11, median 2.20 -> 4.35 cm/s, Wilcoxon p = 0.000977, faster in 11
files with a gap at 19.5-21 min, injection at 20 min | hM4Di: n = 3, median 4.30 -> 7.62 cm/s, Wilcoxon p = 0.5, faster in 2
files with a gap at 19.5-21 min, injection at 20 min | mCherry: n = 7, median 2.59 -> 2.02 cm/s, Wilcoxon p = 0.156, faster in 1
files with a gap at 19.5-21 min, injection at the gap | hM3Dq: n = 11, median 2.21 -> 4.39 cm/s, Wilcoxon p = 0.000977, faster in 11
files with a gap at 19.5-21 min, injection at the gap | hM4Di: n = 3, median 4.30 -> 8.07 cm/s, Wilcoxon p = 0.5, faster in 2
files with a gap at 19.5-21 min, injection at the gap | mCherry: n = 7, median 2.61 -> 2.06 cm/s, Wilcoxon p = 0.219, faster in 1
files whose mouse is in no DREADD list: ['R0_openField_CNO_121924.xlsx', 'F0_openField_CNO_122622.xlsx', 'F3_openField_CNO_121422.xlsx', 'R1.2_openField_CNO_112724.xlsx']
Result: partially reproduced, resting on an assumption. With injection at 20 min in every file, hM3Dq mice (11 of 11 faster, p = 0.001) and hM4Di mice (9 of 10, p = 0.004) move faster 20 to 30 min after CNO, but mCherry mice move slower (2.96 to 2.23 cm/s, 1 of 12 faster, p = 0.016), where the criterion needs p >= 0.05. H0 and H0.4 have identical velocity traces, one recording deposited twice; without H0.4, hM4Di gives p = 0.008 (8 of 9). Twelve files (7 hM4Di, 5 mCherry; every 2023 H and J file except H1 and J3, whose gaps start at 20.96 and 19.57 min) have no tracking gap starting 19.5 to 21 min (per-file table above); their per-minute velocity from 15 to 25 min, printed above, does not mark an injection either, so their injection time rests on the 20 min baseline stated for CNO alone. In the files with a gap, mCherry mice are still slower in 6 of 7 but not significantly (p = 0.16 with injection at 20 min, 0.22 at the gap), while only 3 hM4Di files remain (p = 0.5, the smallest a signed-rank test on 3 can give is 0.25), so that subset cannot test the claim. The outcome is the one under the 20 min assumption, which the Methods' "-20 to 0 min" baseline supports. Four files (R0, F0, F3, R1.2) are of mice in no DREADD list and are left out.
Summary¶
A failure to reproduce here may be a failure of this attempt, not of the paper: see the reasoning and the differences from the paper's method.
| Claim | Data | Outcome |
|---|---|---|
| fig1b-th-loss | Zenodo | partially reproduced (pattern holds; losses 64 and 57% against 50 +/- 5%) |
| figs1d-snc-cells | Zenodo | reproduced |
| fig1c-rotarod | Zenodo | reproduced |
| figs1ef-ppx-locomotion | Zenodo | blocked: no PPX open field file in the deposit |
| figs1-instrumental-learning | Zenodo | partially reproduced (random learning session 1 differs) |
| fig1fg-baseline-similar | Zenodo | reproduced |
| fig1fg-delay-discounting | Zenodo | reproduced |
| fig1f-ctrl-ppx-no-change | Zenodo | reproduced |
| fig1g-park-ppx-fewer-large | Zenodo | reproduced |
| fig1ijk-ppx-a-k-auc | Zenodo | partially reproduced (K rise not significant by Dunn's test) |
| figs2abc-sex-similar | Zenodo | blocked: no sex per mouse in the deposit |
| figs2de-omissions-low | Zenodo | reproduced |
| figs2gh-ppx-latency | Zenodo | partially reproduced (PPX shortening of small-reward latency not significant) |
| figs2ijk-ppx-washout | Zenodo | reproduced, resting on an assumption (Bonferroni comparisons on the pooled error, which match the paper's p-values better; partially reproduced with paired t tests) |
| fig2bc-a77636-locomotion | Zenodo | reproduced, resting on an assumption (injection at 20 min) |
| fig2d-ctrl-a77636-no-change | Zenodo | reproduced |
| fig2e-park-a77636-fewer-large | Zenodo | reproduced |
| fig2fgh-a77636-k-auc | Zenodo | reproduced |
| figs3-a77636-washout-latency | Zenodo | partially reproduced (reward size effect on latency remains on A77636) |
| fig3a-a-correlates-dms | Zenodo | not reproduced (r = 0.32, p = 0.13) |
| fig3b-k-no-correlation | Zenodo | reproduced |
| figs4-a77636-no-correlation | Zenodo | reproduced |
| figs6-dreadd-validation | Zenodo | reproduced |
| fig5cf-cno-locomotion | Zenodo | partially reproduced, resting on an assumption (mCherry mice slower) |
| fig5g-mcherry-no-change | Zenodo | reproduced |
| fig5hi-dreadd-fewer-large | Zenodo | partially reproduced (hM4Di significant at 3 s only) |
| fig5jl-dreadd-params | Zenodo | not reproduced (hM4Di K rise not significant; eight of nine parts hold) |
| fig6b-ctrl-ppx-stable | Zenodo | reproduced |
| fig6c-park-ppx-progressive | Zenodo | reproduced |
| fig6de-a77636-persistent | Zenodo | reproduced |
| fig4bc, fig4de (2), fig4f, fig4g, fig4 insets, fig4hk, figs5abcd, figs5ef, fig6f, fig6g, figs8, fig6h, fig6i (14 claims) | DANDI:001177 | blocked: data missing |
How the analysis differs from the paper's. The paper's per-mouse spreadsheets of choices were not deposited, so every session is recounted from the raw operant logs with the paper's event names. The baseline sessions are every baseline session deposited (2 to 5 per mouse, 1 to 5 before the first drug session), since the CV rule finds a stable run in only 12 of 47 PPX mice. The "two-way repeated measures ANOVA" is run with each mouse and delay as the unit, the layout the paper's degrees of freedom imply. The open field windows assume injection at 20 min; twelve CNO files show no tracking gap there. Striatal TH is normalized to the control mice of each staining cohort. Friedman and repeated measures tests on A, K and AUC are shown for every pair of ON (first, four) and OFF (first, all) readings, and the repeated measures comparisons both as paired t tests and on the pooled error; the pooled error matches the paper's printed p-values better.
What was found about the data.
- DANDI:001177 holds raw voltage, LFP and per-electrode threshold crossings for 18 mice and 56 sessions, matching the paper's mice (7 control, 11 parkinsonian, 4 with saline sessions), but no sorted units in 54 files, no unit labels in the other two, no laser pulse times and no injection time, so none of the electrophysiology findings can be tested. Three sessions have start times in 2025, out of order with the same mouse's other days, and the subject descriptions are mis-encoded ("1.5 microliters").
- In the Zenodo deposit, 233 operant logs are byte-identical between the PPX and DREADD folders and 75 between the A77636 and DREADD folders (mice used in two experiments); one PPX parkinsonian mouse (E6) has no PPX sessions and one mCherry mouse (R5.5) no delay discounting files; the 2020 control cohort ran delays of 0, 6, 12 and 18 s and the 2021 cohort 30 free choice trials per block, unlike the Methods; the open field files carry no injection time; the CNO open field files of H0 and H0.4 are the same recording; no file gives each mouse's sex; and no PPX open field file is deposited.