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: elsewhere claim. 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.py re-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.

In [1]:
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.

In [2]:
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
In [3]:
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
In [4]:
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.

In [5]:
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
In [6]:
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}
In [7]:
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.

In [8]:
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
In [9]:
# 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.
In [10]:
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.

In [11]:
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
In [12]:
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.

In [13]:
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)
No description has been provided for this image

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.

In [14]:
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.

In [15]:
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).

In [16]:
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
In [17]:
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.

In [18]:
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.

In [19]:
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.

In [20]:
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¶

In [21]:
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.

In [22]:
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).

In [23]:
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).

In [24]:
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.

In [25]:
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.

In [26]:
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).

In [27]:
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).

In [28]:
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
In [29]:
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
Out[29]:
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.

In [30]:
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
Out[30]:
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).

In [31]:
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
Out[31]:
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.

In [32]:
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).

In [33]:
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.

In [34]:
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.

In [35]:
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.

In [36]:
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.

In [37]:
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.

In [38]:
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.

In [39]:
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.

In [40]:
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.

In [41]:
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.