Reproducing Moore et al. (2025) from dandiset 001699¶

Paper. Moore N, Duszkiewicz AJ, Asiminas A, Dudchenko PA, Peyrache A, Wood ER (2025). Age-dependent alterations in the head-direction signal in a rat model of Fragile X Syndrome. bioRxiv. doi:10.1101/2025.01.09.632139. This attempt used the full text of version 1 (9 January 2025), the version the dandiset links and whose title the target names. A revised version 2 (7 January 2026, "Altered developmental profile of the cortical head-direction signal in a rat model of Fragile X Syndrome") was also read; its Methods are used only where version 1 is silent (the Bayesian decoder, the speed smoothing), and its numbers are compared in the attempt record.

Data. DANDI:001699, version 0.260917.2322, streamed from the archive. The paper cites no version (its Data Availability says the data will be released at publication). Two versions are published, 0.260917.2313 and 0.260917.2322, nine minutes apart; the data check below shows that their assets are the same files, and the metadata differ only in the title, description and study target. The most recent published version is pinned, as the protocol asks when no version is cited and no earlier one matches the paper better.

Code. The dandiset links the lab's package woodcode (https://github.com/Wood-Dudchenko-lab/woodcode, read at commit 61ee1784ef8bdeed1befa4d2dd2dd71dc8befd60). It holds general functions (waveform trough-to-peak, Skaggs information, Rayleigh vector length, a Poisson decoder, loading NWB files) and not the paper's analysis, which the Methods say was run in Matlab and R. Where the Methods leave a choice open and woodcode settles it (the channel used for trough-to-peak, positive waveforms, circular smoothing) the helper module hdfx.py follows woodcode; its docstring lists where each parameter comes from.

Claim Paper Tested
unit-counts Results: 406, 372, 543, 507 units in 7, 5, 6, 6 rats tested
units-per-recording Results: 8 to 83 and 30 to 114 units per recording tested
figs1c-juvenile-behaviour-similar Fig. S1c tested
figs2c-adult-behaviour-similar Fig. S2c tested
figs1-juvenile-cell-metrics-similar Fig. S1f-i tested
figs2-adult-cell-metrics-similar Fig. S2f-i tested
fig1ef-juvenile-sharper-tuning Fig. 1e-f tested
fig1g-juvenile-halves-correlation Fig. 1g tested
fig1h-juvenile-smaller-offset Fig. 1h tested
fig1j-juvenile-less-drift Fig. 1i-j tested
figs1j-juvenile-epochs-correlation Fig. S1j tested
figs1k-juvenile-epoch-drift-similar Fig. S1k tested
fig2c-juvenile-isomap-wake-correlation Fig. 2c tested
fig2d-juvenile-isomap-wake-sharper Fig. 2d tested
fig2g-juvenile-isomap-rem-correlation Fig. 2e-g tested
fig2h-juvenile-isomap-rem-sharper Fig. 2h tested
fig3ef-adult-tuning-similar Fig. 3e-f tested
fig3g-adult-halves-correlation Fig. 3g tested
fig3h-adult-larger-offset Fig. 3h tested
fig3j-adult-more-drift Fig. 3i-j tested
figs2j-adult-epochs-correlation Fig. S2j tested
figs2k-adult-epoch-drift-larger Fig. S2k tested
fig4c-adult-isomap-wake-correlation Fig. 4c tested
fig4d-adult-isomap-wake-similar Fig. 4d tested
fig4g-adult-isomap-rem-correlation Fig. 4e-g tested
fig4h-adult-isomap-rem-similar Fig. 4h tested
figs1d-probe-in-posub Fig. S1d, S2d (histology) blocked
In [1]:
import os
os.environ.setdefault("OMP_NUM_THREADS", "1")       # many small fits run in parallel processes
os.environ.setdefault("OPENBLAS_NUM_THREADS", "1")
os.environ.setdefault("MKL_NUM_THREADS", "1")

import time
import warnings

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from dandi.dandiapi import DandiAPIClient
from scipy import stats

import hdfx

warnings.filterwarnings("ignore", category=RuntimeWarning)
warnings.filterwarnings("ignore", message=".*converge.*")
warnings.filterwarnings("ignore", message=".*Hessian.*")
warnings.filterwarnings("ignore", message=".*boundary.*")
pd.set_option("display.width", 220)
pd.set_option("display.max_columns", 40)
pd.set_option("display.max_rows", 200)
pd.set_option("display.max_colwidth", 120)
print("dandiset", hdfx.DANDISET_ID, "version", hdfx.DANDISET_VERSION)
dandiset 001699 version 0.260917.2322
In [2]:
started = time.time()
assets = hdfx.list_assets()
results = hdfx.process_all(list(assets.asset_id), workers=4)
meta = pd.DataFrame([r["meta"] for r in results])
print(f"{len(assets)} NWB files streamed and analysed in {time.time() - started:.0f} s")
36 NWB files streamed and analysed in 812 s

Data check¶

Each check of the description against the values is stated under its output.

In [3]:
with DandiAPIClient() as client:
    ds = client.get_dandiset(hdfx.DANDISET_ID, hdfx.DANDISET_VERSION)
    raw = ds.get_raw_metadata()
    summary = raw["assetsSummary"]
    print("name:", raw["name"])
    print("archive summary: subjects", summary["numberOfSubjects"], "| files", summary["numberOfFiles"],
          "| species", [s["name"] for s in summary["species"]],
          "| variables", summary["variableMeasured"])
    print("related resources:", [(r.get("name"), r.get("relation"), r.get("url")) for r in raw["relatedResource"]])
    print("about:", [(a["name"], a["schemaKey"], a["identifier"]) for a in raw.get("about", [])])
    versions, asset_age = {}, []
    for v in ("0.260917.2313", "0.260917.2322"):
        d = client.get_dandiset(hdfx.DANDISET_ID, v)
        versions[v] = set()
        for a in d.get_assets():
            md = a.get_raw_metadata()
            versions[v].add((a.path, a.size, md["digest"]["dandi:dandi-etag"]))
            if v == hdfx.DANDISET_VERSION and a.path.endswith(".nwb"):
                subj = [w for w in md.get("wasAttributedTo", []) if w.get("schemaKey") == "Participant"]
                asset_age.append({"path": a.path, "asset_metadata_age": subj[0].get("age", {}).get("value") if subj else None})
        print(f"version {v}: {len(versions[v])} assets, title {d.get_raw_metadata()['name']!r}")
    print("same assets (path, size, etag) in both published versions:",
          versions["0.260917.2313"] == versions["0.260917.2322"])
asset_age = pd.DataFrame(asset_age).sort_values("path")
print("\nage in the archive's asset metadata (derived by the archive from the date of birth):")
print(asset_age.to_string(index=False))
name: Altered developmental profile of the head-direction signal in a rat model of fragile X syndrome
archive summary: subjects 24 | files 98 | species ['Rattus norvegicus - Norway rat'] | variables ['ProcessingModule', 'Position', 'LFP', 'Units', 'SpatialSeries', 'CompassDirection', 'ElectricalSeries']
related resources: [('woodcode', 'dcite:IsCompiledBy', 'https://github.com/Wood-Dudchenko-lab/woodcode'), ('Age-dependent alterations in the head-direction signal in a rat model of Fragile X Syndrome', 'dcite:IsDescribedBy', 'https://www.biorxiv.org/content/10.1101/2025.01.09.632139v1')]
about: [('Fragile X Syndrome', 'Disorder', 'http://id.nlm.nih.gov/mesh/D005600'), ('Fmr1 protein, rat', 'Anatomy', 'http://id.nlm.nih.gov/mesh/D005600')]
version 0.260917.2313: 98 assets, title 'Age-dependent alterations in the head-direction signal in a rat model of Fragile X Syndrome'
version 0.260917.2322: 98 assets, title 'Altered developmental profile of the head-direction signal in a rat model of fragile X syndrome'
same assets (path, size, etag) in both published versions: True

age in the archive's asset metadata (derived by the archive from the date of birth):
                                                       path asset_metadata_age
        sub-H3001/sub-H3001_ses-200201_behavior+ecephys.nwb               P25D
        sub-H3001/sub-H3001_ses-200202_behavior+ecephys.nwb               P26D
  sub-H3003/sub-H3003_ses-200207_behavior+ecephys+image.nwb        P26DT69565S
  sub-H3003/sub-H3003_ses-200208_behavior+ecephys+image.nwb        P27DT54048S
sub-H3006/sub-H3006_ses-200314-1_behavior+ecephys+image.nwb        P25DT42701S
sub-H3006/sub-H3006_ses-200314-2_behavior+ecephys+image.nwb        P25DT75822S
  sub-H3008/sub-H3008_ses-200805_behavior+ecephys+image.nwb        P23DT62005S
  sub-H3008/sub-H3008_ses-200807_behavior+ecephys+image.nwb        P25DT58683S
  sub-H3009/sub-H3009_ses-200812_behavior+ecephys+image.nwb        P26DT58673S
  sub-H3009/sub-H3009_ses-200813_behavior+ecephys+image.nwb        P27DT58527S
sub-H3015/sub-H3015_ses-210416-1_behavior+ecephys+image.nwb        P25DT48227S
sub-H3015/sub-H3015_ses-210416-2_behavior+ecephys+image.nwb        P25DT70156S
  sub-H3015/sub-H3015_ses-210417_behavior+ecephys+image.nwb        P26DT50767S
  sub-H3016/sub-H3016_ses-210422_behavior+ecephys+image.nwb        P22DT65724S
  sub-H3016/sub-H3016_ses-210423_behavior+ecephys+image.nwb        P23DT51235S
  sub-H3019/sub-H3019_ses-210617_behavior+ecephys+image.nwb        P24DT56019S
sub-H3019/sub-H3019_ses-210618-1_behavior+ecephys+image.nwb        P25DT41760S
  sub-H3022/sub-H3022_ses-210805_behavior+ecephys+image.nwb        P22DT61583S
  sub-H3022/sub-H3022_ses-210806_behavior+ecephys+image.nwb        P23DT41647S
  sub-H3023/sub-H3023_ses-210812_behavior+ecephys+image.nwb      P-366DT71052S
sub-H3023/sub-H3023_ses-210813-1_behavior+ecephys+image.nwb      P-365DT50184S
  sub-H3026/sub-H3026_ses-211003_behavior+ecephys+image.nwb      P-345DT79247S
sub-H3026/sub-H3026_ses-211004-2_behavior+ecephys+image.nwb      P-344DT66679S
  sub-H3029/sub-H3029_ses-230510_behavior+ecephys+image.nwb        P97DT40365S
  sub-H4813/sub-H4813_ses-220728_behavior+ecephys+image.nwb        P65DT65667S
  sub-H4815/sub-H4815_ses-220814_behavior+ecephys+image.nwb        P82DT73146S
  sub-H4817/sub-H4817_ses-220828_behavior+ecephys+image.nwb        P57DT58685S
  sub-H4819/sub-H4819_ses-220929_behavior+ecephys+image.nwb        P78DT79058S
  sub-H4820/sub-H4820_ses-221007_behavior+ecephys+image.nwb        P86DT68066S
        sub-H4822/sub-H4822_ses-221023_behavior+ecephys.nwb               P71D
        sub-H4823/sub-H4823_ses-221108_behavior+ecephys.nwb         P87DT3600S
  sub-H4824/sub-H4824_ses-221117_behavior+ecephys+image.nwb        P96DT68177S
  sub-H4825/sub-H4825_ses-221124_behavior+ecephys+image.nwb        P72DT78275S
  sub-H4826/sub-H4826_ses-221203_behavior+ecephys+image.nwb          P82DT549S
  sub-H4827/sub-H4827_ses-221210_behavior+ecephys+image.nwb        P88DT72211S
  sub-H4830/sub-H4830_ses-230406_behavior+ecephys+image.nwb        P63DT65155S

The two published versions hold the same 98 assets (36 NWB files and 62 videos); they differ in title and description only, so the choice between them does not change the analysis. The archive counts 24 subjects of Rattus norvegicus, as the files do. Its about field lists "Fmr1 protein, rat" as an anatomy term with the MeSH identifier of Fragile X Syndrome (D005600), a metadata error.

In [4]:
cols = ["subject", "session_id", "archive_genotype", "date_of_birth", "session_start", "age_days",
        "age_field", "n_units", "n_spikes", "n_unsorted_units", "n_channels", "unit_columns"]
print(meta[cols].to_string())
print("\nsession descriptions:", meta.session_description.unique())
print("subjects:", meta.subject.nunique(), "| files:", len(meta), "| units in all files:", meta.n_units.sum())
print("files with unsorted spike times:", meta.loc[meta.n_unsorted_units > 0, ["subject", "session_id", "n_unsorted_units"]].values.tolist())
bad_dob = meta[meta.age_days < 0]
print("files whose date of birth is after the recording:", bad_dob[["subject", "session_id", "date_of_birth", "session_start"]].values.tolist())
print("\nhistology images (acquisition/histology_images) per file:")
print(meta[["subject", "session_id", "histology_images"]].to_string())
print("files with at least one histology image:", int((meta.histology_images != "").sum()), "of", len(meta))
   subject session_id archive_genotype date_of_birth session_start  age_days age_field  n_units  n_spikes  n_unsorted_units  n_channels                                                                  unit_columns
0    H3001     200201               WT    2020-01-07    2020-02-01        25      None       23   1539093                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
1    H3001     200202               WT    2020-01-07    2020-02-02        26      None       16   1145133                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
2    H3003     200207               KO    2020-01-12    2020-02-07        26      None       40   2355251                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
3    H3003     200208               KO    2020-01-12    2020-02-08        27      None       29   1515000                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
4    H3006   200314_1               WT    2020-02-18    2020-03-14        25      None       37   2081499                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
5    H3006   200314_2               WT    2020-02-18    2020-03-14        25      None       26   1110241                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
6    H3008     200805               KO    2020-07-13    2020-08-05        23      None       38   2318166                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
7    H3008     200807               KO    2020-07-13    2020-08-07        25      None       16   1369688                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
8    H3009     200812               WT    2020-07-17    2020-08-12        26      None       37   1560012                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
9    H3009     200813               WT    2020-07-17    2020-08-13        27      None       33   1546335                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
10   H3015   210416_1               WT    2021-03-22    2021-04-16        25      None       34   1029146                 0          31  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
11   H3015   210416_2               WT    2021-03-22    2021-04-16        25      None       45   1709157                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
12   H3015     210417               WT    2021-03-22    2021-04-17        26      None       26   1420962                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
13   H3016     210422               KO    2021-03-31    2021-04-22        22      None       27   1396257                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
14   H3016     210423               KO    2021-03-31    2021-04-23        23      None       46    930169                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
15   H3019     210617               KO    2021-05-24    2021-06-17        24      None       17    688938                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
16   H3019   210618_1               KO    2021-05-24    2021-06-18        25      None        8    127027                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
17   H3022     210805               WT    2021-07-14    2021-08-05        22      None       20    556103                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
18   H3022     210806               WT    2021-07-14    2021-08-06        23      None       31   1049748                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
19   H3023     210812               WT    2022-08-13    2021-08-12      -366      None       22   1182429                 1          31  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
20   H3023   210813_1               WT    2022-08-13    2021-08-13      -365      None       24   1546703                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
21   H3026     211003               WT    2022-09-13    2021-10-03      -345      None       83   4394695                 0          64  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
22   H3026   211004_2               WT    2022-09-13    2021-10-04      -344      None       68   3347010                 0          64  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
23   H3029     230510               WT    2023-02-02    2023-05-10        97      None       32   1193655                 0          64  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
24   H4813     220728               WT    2022-05-24    2022-07-28        65      None       70   3988829                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
25   H4815     220814               WT    2022-05-24    2022-08-14        82      None       99   6066930                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
26   H4817     220828               KO    2022-07-02    2022-08-28        57      None      105   6307039                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
27   H4819     220929               KO    2022-07-13    2022-09-29        78      None      114   5969234                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
28   H4820     221007               WT    2022-07-13    2022-10-07        86      None       63   5490852                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
29   H4822     221023               KO    2022-08-13    2022-10-23        71      None       55   3075000                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
30   H4823     221108               WT    2022-08-13    2022-11-08        87      None      113   6514735                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
31   H4824     221117               KO    2022-08-13    2022-11-17        96      None       88   5649599                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
32   H4825     221124               KO    2022-09-13    2022-11-24        72      None       88   5649599                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
33   H4826     221203               WT    2022-09-13    2022-12-03        81      None      102   4697377                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
34   H4827     221210               KO    2022-09-13    2022-12-10        88      None       78   3591109                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean
35   H4830     230406               WT    2023-02-02    2023-04-06        63      None       96   6890094                 0          32  electrode_group,id,sampling_rate,spike_times,spike_times_index,waveform_mean

session descriptions: <StringArray>
['Exploration, sleep and cue rotation ']
Length: 1, dtype: str
subjects: 24 | files: 36 | units in all files: 1849
files with unsorted spike times: [['H3023', '210812', 1]]
files whose date of birth is after the recording: [['H3023', '210812', '2022-08-13', '2021-08-12'], ['H3023', '210813_1', '2022-08-13', '2021-08-13'], ['H3026', '211003', '2022-09-13', '2021-10-03'], ['H3026', '211004_2', '2022-09-13', '2021-10-04']]

histology images (acquisition/histology_images) per file:
   subject session_id                        histology_images
0    H3001     200201                      H3001_D2, H3001_D3
1    H3001     200202                      H3001_D2, H3001_D3
2    H3003     200207                      H3003_D3, H3003_D4
3    H3003     200208                      H3003_D3, H3003_D4
4    H3006   200314_1                      H3006_C5, H3006_C6
5    H3006   200314_2                      H3006_C5, H3006_C6
6    H3008     200805                                H3008_B7
7    H3008     200807                                H3008_B7
8    H3009     200812                      H3009_C4, H3009_c5
9    H3009     200813                      H3009_C4, H3009_c5
10   H3015   210416_1            H3015_C2, H3015_C3, H3015_C4
11   H3015   210416_2            H3015_C2, H3015_C3, H3015_C4
12   H3015     210417            H3015_C2, H3015_C3, H3015_C4
13   H3016     210422                      H3016_C5, H3016_C6
14   H3016     210423                      H3016_C5, H3016_C6
15   H3019     210617          H3019_4.3(DiI), H3019_4.4(DiI)
16   H3019   210618_1          H3019_4.3(DiI), H3019_4.4(DiI)
17   H3022     210805         H3022(DAPI), H3022_B3, H3022_B4
18   H3022     210806         H3022(DAPI), H3022_B3, H3022_B4
19   H3023     210812                   H3023(DAPI), H3023_E2
20   H3023   210813_1                   H3023(DAPI), H3023_E2
21   H3026     211003                                H3026-D1
22   H3026   211004_2                                H3026-D1
23   H3029     230510                      H3029_D6, H3029_E1
24   H4813     220728            H4813_C3, H4813_C4, H4813_C5
25   H4815     220814  H4815_D1, H4815_E1, H4815_E2, H4815_E3
26   H4817     220828                      H4817_C5, H4817_D1
27   H4819     220929  H4819_C3, H4819_C4, H4819_C5, H4819_C6
28   H4820     221007            H4820_C1, H4820_C6, H4820_D1
29   H4822     221023                      H4822_B6, H4822_C2
30   H4823     221108                      H4823_D5, H4823_D6
31   H4824     221117                                H4824_D3
32   H4825     221124                      H4825_B4, H4825_B5
33   H4826     221203                      H4826_C6, H4826_D2
34   H4827     221210                      H4827_C5, H4827_C6
35   H4830     230406                                H4830_D2
files with at least one histology image: 36 of 36

Every file has a units table with only spike_times, waveform_mean, electrode_group and sampling_rate: no cell type, quality metric or depth, so the paper's cell selection is recomputed from the waveforms and spike trains. No NWB file sets the subject's age; the archive's asset metadata give an age derived from the date of birth (printed above). Subjects H3023 and H3026 have dates of birth a year after their recordings, so the archive gives them negative ages (P-366D to P-344D), a metadata error; their age group is taken from their other properties below. The session description of every file mentions a cue rotation, which version 1 of the paper does not describe; most files hold a third tracked session after the second, which is not used. One unit in H3023 (session 210812) has spike times out of order, a format error; the helper sorts them. Every file holds histology images (acquisition/histology_images, printed above), including the four whose asset names lack +image; none marks the probe tract or the postsubiculum, so figs1d-probe-in-posub is blocked.

In [5]:
def counts(df, age_col, geno_col):
    g = df.groupby([age_col, geno_col])
    return pd.DataFrame({"rats": g.subject.nunique(), "recordings": g.size(), "units": g.n_units.sum(),
                         "min_units": g.n_units.min(), "max_units": g.n_units.max()})

once = meta[~meta.subject.isin(hdfx.DUPLICATE_OF)]
arch = meta.copy()
arch["archive_age_group"] = arch.archive_age_group.fillna("no valid age")
print("Archive labels (age group from date of birth), every file:")
print(counts(arch, "archive_age_group", "archive_genotype").to_string())
print("\nMain grouping, each recording once (H4825 left out):")
print(counts(once, "age_group", "genotype").to_string())
print("\nSubjects whose main group differs from the archive's:")
diff = meta[(meta.genotype != meta.archive_genotype) | (meta.age_group != meta.archive_age_group)]
print(diff[["subject", "session_id", "archive_genotype", "genotype", "archive_age_group", "age_group", "age_days", "n_units", "n_channels"]].to_string())
Archive labels (age group from date of birth), every file:
                                    rats  recordings  units  min_units  max_units
archive_age_group archive_genotype                                               
adult             KO                   6           6    528         55        114
                  WT                   7           7    575         32        113
juvenile          KO                   4           8    221          8         46
                  WT                   5          11    328         16         45
no valid age      WT                   2           4    197         22         83

Main grouping, each recording once (H4825 left out):
                    rats  recordings  units  min_units  max_units
age_group genotype                                               
adult     KO           5           5    440         55        114
          WT           6           6    543         63        113
juvenile  KO           5          10    372          8         83
          WT           7          14    406         16         45

Subjects whose main group differs from the archive's:
   subject session_id archive_genotype genotype archive_age_group age_group  age_days  n_units  n_channels
19   H3023     210812               WT       WT               NaN  juvenile      -366       22          31
20   H3023   210813_1               WT       WT               NaN  juvenile      -365       24          32
21   H3026     211003               WT       KO               NaN  juvenile      -345       83          64
22   H3026   211004_2               WT       KO               NaN  juvenile      -344       68          64
23   H3029     230510               WT       WT             adult  juvenile        97       32          64

With the archive's labels no grouping reproduces the paper's counts (406 units in 7 juvenile WT rats, 372 in 5 juvenile Fmr1-/y, 543 in 6 adult WT, 507 in 6 adult Fmr1-/y). If H3026 is a juvenile Fmr1-/y rat (the archive says WT, and gives it a birth date after its recording) and H3029 a juvenile WT rat (its birth date, the same as H4830's, makes it 97 days old), three of the four groups match the paper exactly in units and rats. H3026's 83 units in one recording is also the top of the paper's range for juveniles. H3026 and H3029 are the only rats recorded with 64-channel probes, which fits their being a later juvenile cohort. This is consistent with the data but not proven by it; the genotype of H3026 cannot be checked from the files. The main grouping uses it, and the claims show the archive's labels as a variant. The archive's genotype labels are recorded as a finding.

In [6]:
key = ["n_units", "n_spikes"]
dup = meta[meta.duplicated(key, keep=False)].sort_values(key)
print("files sharing unit and spike counts:")
print(dup[["subject", "session_id", "archive_genotype", "n_units", "n_spikes", "spike_checksum"]].to_string())
a = results[meta.index[meta.subject == "H4824"][0]]["meta"]
b = results[meta.index[meta.subject == "H4825"][0]]["meta"]
print("first 20 spike times of every unit identical:", np.array_equal(a["first_spikes"], b["first_spikes"]))
print("trough-to-peak of every unit identical:", np.allclose(a["ttp"], b["ttp"], equal_nan=True))
print("per unit, count and sum of spike times before 1248 s identical:", np.allclose(a["early_fingerprint"], b["early_fingerprint"]))
print("spikes at the file's last spike time: H4824", a["spikes_at_last_time"], "| H4825", b["spikes_at_last_time"])
print("H4824 epochs:\n", a["epochs"].round(1).to_string())
print("H4825 epochs:\n", b["epochs"].round(1).to_string())
print("H4825 tracking frames with a repeated timestamp:", b["non_increasing_frames"])
print("H4825 units with contamination above 0.5:", int(np.sum(b["contamination"] > 0.5)), "of", len(b["contamination"]),
      "| H4824:", int(np.sum(a["contamination"] > 0.5)))
files sharing unit and spike counts:
   subject session_id archive_genotype  n_units  n_spikes  spike_checksum
31   H4824     221117               KO       88   5649599    4.729009e+06
32   H4825     221124               KO       88   5649599    4.715128e+06
first 20 spike times of every unit identical: True
trough-to-peak of every unit identical: True
per unit, count and sum of spike times before 1248 s identical: True
spikes at the file's last spike time: H4824 1 | H4825 131373
H4824 epochs:
     start    stop tag
0     0.0  1472.0  01
1  1580.9  7100.4  02
2  7140.8  8419.4  03
3  8588.2  9909.8  04
H4825 epochs:
     start    stop tag
0     0.0  1248.7  01
1  1323.0  6781.6  02
2  6870.4  8142.5  03
3  8271.3  9564.0  04
H4825 tracking frames with a repeated timestamp: 12970
H4825 units with contamination above 0.5: 87 of 88 | H4824: 3

H4825's file holds H4824's recording: the same 88 units with identical waveforms, spike counts and spike times up to 1248 s (the end of H4825's first epoch), after which H4825's spike and tracking times are shifted piece by piece onto H4825's own epoch table and clipped at its end (many spikes then share the last spike time, which makes 87 of 88 units look contaminated). This recording is counted once, as H4824, and H4825 has no data of its own in the dandiset. No other pair of files shares unit and spike counts.

In [7]:
rows = []
for r in results:
    m = r["meta"]
    rows.append({"subject": m["subject"], "session": m["session_id"],
                 "epochs (s)": "; ".join(f"{e.tag}:{e.start:.0f}-{e.stop:.0f}" for e in m["epochs"].itertuples()),
                 "task epochs": m["task_epochs"],
                 "tracking blocks over 10 min (s)": "; ".join(f"{a:.0f}-{b:.0f}" for a, b in m["blocks"] if b - a >= 600),
                 "sessions used (s)": "; ".join(f"{a:.0f}-{b:.0f}" for a, b in m["sessions"]),
                 "repeated frames": m["non_increasing_frames"]})
print(pd.DataFrame(rows).to_string())
   subject   session                                                          epochs (s)                                                                  task epochs            tracking blocks over 10 min (s)   sessions used (s)  repeated frames
0    H3001    200201                              01:24-1687; 02:1726-6451; 03:6494-8021                                         {'sleep': ['2'], 'wake': ['1', '3']}                         24-1687; 6494-8021  24-1224; 6494-7694                1
1    H3001    200202                                            01:18-5683; 02:5737-7864                                              {'sleep': ['2'], 'wake': ['1']}                                  5737-7864           5737-6937                1
2    H3003    200207                              01:52-1279; 02:1308-6890; 03:6926-8110                                         {'sleep': ['2'], 'wake': ['1', '3']}                         52-1279; 6926-8110  52-1252; 6926-8110                1
3    H3003    200208                              01:49-1252; 02:1305-7412; 03:7451-8653                                         {'sleep': ['2'], 'wake': ['1', '3']}                         49-1252; 7451-8653  49-1249; 7451-8651                1
4    H3006  200314_1   01:4-1276; 02:1313-6769; 03:6808-8320; 04:8594-9403; 05:9404-9405  {'error': ['5'], 'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               4-1276; 6808-8320; 8594-9404   4-1204; 6808-8008                2
5    H3006  200314_2   01:4-1213; 02:1249-6686; 03:6854-6969; 04:6989-8110; 05:8325-9539  {'error': ['3'], 'sleep': ['2'], 'wake': ['1', '4'], 'wake_cue_rot': ['5']}               4-1213; 6989-8110; 8325-9539   4-1204; 6989-8110                2
6    H3008    200805                               01:4-1277; 02:1304-6768; 03:6810-8022                                         {'sleep': ['2'], 'wake': ['1', '3']}                          4-1277; 6810-8022   4-1204; 6810-8010                1
7    H3008    200807                 01:2-1240; 02:1265-6887; 03:6941-8186; 04:8531-9626                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               2-1240; 6941-8186; 8531-9626   2-1202; 6941-8141                2
8    H3009    200812                 01:3-1308; 02:1342-6750; 03:6782-8061; 04:8330-9636                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               3-1308; 6782-8061; 8330-9636   3-1203; 6782-7982                2
9    H3009    200813                 01:2-1247; 02:1267-6697; 03:6749-8182; 04:8477-9801                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               2-1247; 6749-8182; 8477-9801   2-1202; 6749-7949                2
10   H3015  210416_1                 01:0-1843; 02:1884-7096; 03:7096-8382; 04:8382-9737                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}                          0-1843; 7096-9737   0-1200; 7096-8296                2
11   H3015  210416_2                 01:0-1336; 02:1378-6853; 03:6919-8174; 04:8470-9795                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               0-1336; 6919-8174; 8470-9795   0-1200; 6919-8119                2
12   H3015    210417               01:66-1367; 02:1408-6848; 03:6894-8415; 04:8647-10084                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}  66-1367; 1408-6848; 6894-8415; 8647-10084  66-1266; 6894-8094                3
13   H3016    210422                 01:0-1264; 02:1306-6819; 03:6862-8097; 04:8401-9891                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               0-1264; 6862-8097; 8401-9891   0-1200; 6862-8062                2
14   H3016    210423                01:43-1278; 02:1311-6738; 03:6866-8400; 04:8648-9947                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}              43-1278; 6866-8400; 8648-9947  43-1243; 6866-8066                2
15   H3019    210617                 01:0-1230; 02:1264-6684; 03:6715-7978; 04:8301-9628                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               0-1230; 6715-7978; 8301-9628   0-1200; 6715-7915                2
16   H3019  210618_1                                             01:3-1236; 02:1268-3278                                              {'sleep': ['2'], 'wake': ['1']}                                     3-1236              3-1203                0
17   H3022    210805                 01:0-1229; 02:1270-6806; 03:6861-8093; 04:8377-9596                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               0-1229; 6861-8093; 8377-9596   0-1200; 6861-8061                2
18   H3022    210806                 01:0-1219; 02:1263-6756; 03:6806-8162; 04:8422-9703                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               0-1219; 6806-8162; 8422-9700   0-1200; 6806-8006                2
19   H3023    210812                               01:0-1220; 02:1220-6629; 03:6629-9104                                         {'sleep': ['2'], 'wake': ['1', '3']}                          0-1220; 6629-9104   0-1200; 6629-7829                3
20   H3023  210813_1                               01:0-1211; 02:1211-7888; 03:7888-9135                                         {'sleep': ['2'], 'wake': ['1', '3']}                          0-1211; 6661-9135   0-1200; 6661-7861                2
21   H3026    211003                               01:0-6720; 02:6720-7972; 03:7972-9252                                         {'sleep': ['2'], 'wake': ['1', '3']}                          0-1286; 6720-9252   0-1200; 6720-7920                2
22   H3026  211004_2                 01:0-1215; 02:1215-6677; 03:6677-7896; 04:7896-9216                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}                          0-1215; 6677-9186   0-1200; 6677-7877                2
23   H3029    230510                 01:0-1234; 02:1318-6858; 03:6883-8142; 04:8294-9535                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               4-1232; 6886-8140; 8298-9534   4-1204; 6886-8086                0
24   H4813    220728                 01:0-1227; 02:1352-6824; 03:6871-8109; 04:8343-9638                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               4-1223; 6879-8106; 8347-9634   4-1204; 6879-8079                0
25   H4815    220814                 01:0-1295; 02:1411-7025; 03:7083-8359; 04:8459-9784                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               4-1293; 7087-8356; 8462-9780   4-1204; 7087-8287                0
26   H4817    220828                 01:0-1258; 02:1372-6860; 03:6913-8152; 04:8287-9636                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               5-1255; 6921-8149; 8292-9634   5-1205; 6921-8121                0
27   H4819    220929                 01:0-1266; 02:1365-6906; 03:6937-8170; 04:8341-9624                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               6-1263; 6943-8167; 8346-9622   6-1206; 6943-8143                0
28   H4820    221007                 01:0-1273; 02:1340-6867; 03:6925-8173; 04:8389-9719                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               8-1271; 6929-8171; 8393-9717   8-1208; 6929-8129                0
29   H4822    221023                 01:0-1231; 02:1330-6797; 03:6867-8117; 04:8288-9506                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               6-1228; 6871-8116; 8292-9505   6-1206; 6871-8071                0
30   H4823    221108                                                           01:0-9466                                                              {'wake': ['1']}    5-1235; 1242-6836; 6844-8133; 8139-9464   5-1205; 6844-8044                0
31   H4824    221117                 01:0-1472; 02:1581-7100; 03:7141-8419; 04:8588-9910                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               6-1471; 7144-8415; 8591-9909   6-1206; 7144-8344                0
32   H4825    221124                 01:0-1249; 02:1323-6782; 03:6870-8143; 04:8271-9564                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               6-1249; 7158-8143; 8565-9564   6-1206; 7158-8143            12970
33   H4826    221203                 01:0-1293; 02:1410-7091; 03:7134-8410; 04:8573-9877                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               5-1291; 7137-8408; 8576-9875   5-1205; 7137-8337                0
34   H4827    221210                 01:0-1253; 02:1367-6849; 03:6881-8104; 04:8210-9551                  {'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['4']}               4-1251; 6884-8102; 8213-9550   4-1204; 6884-8084                0
35   H4830    230406  01:0-1286; 02:1365-7715; 03:7762-9071; 04:9202-9726; 05:9841-11252  {'error': ['4'], 'sleep': ['2'], 'wake': ['1', '3'], 'wake_cue_rot': ['5']}                          4-1282; 7766-9068   4-1204; 7766-8966                0

The paper describes two 20 min exploration sessions separated by 90 min of sleep. The epochs and processing/tasks tables do not always say which interval is which: in H3001 (200202) task epoch 1 is called wake but spans 94 min with no tracking, and tracking starts in epoch 2; in H3026 (211003) epoch 1 spans 112 min, waking and sleep together; H4823 has a single epoch for the whole recording and no sleep task. The exploration sessions are therefore taken from the tracking itself (helper exploration_sessions): the first tracking block of at least 10 min, and the first such block starting at least 60 min later, each cut to its first 20 min, the paper's session length. This gives sessions of 18.7 to 20.0 min (H4825 aside) before and after the sleep in every recording but two, which have one session: in H3019 210618-1 it is the session before the sleep, and in H3001 200202, where the first epoch has no tracking, it is the session after the sleep. Juvenile files have one to three tracking frames whose timestamp does not increase; those frames are dropped.

In [8]:
print(meta[["subject", "session_id", "pos_unit", "px_per_cm", "pos_x_range", "pos_y_range", "hd_range",
            "hd_nan_fraction", "pos_nan_frames", "pos_y_zero_frames", "pos_x_zero_frames", "pos_y_zero_in_sessions",
            "frame_rate", "same_pos_hd_times"]].round(3).to_string())
cm = meta[meta.px_per_cm.isna()]
print(f"\nfiles in centimetres: {len(cm)}; frames with y exactly 0 per file: {cm.pos_y_zero_frames.min()} to {cm.pos_y_zero_frames.max()}; "
      f"with x exactly 0: {cm.pos_x_zero_frames.min()} to {cm.pos_x_zero_frames.max()}")
   subject session_id     pos_unit  px_per_cm                               pos_x_range                              pos_y_range                                      hd_range  hd_nan_fraction  pos_nan_frames  pos_y_zero_frames  pos_x_zero_frames  pos_y_zero_in_sessions  frame_rate  same_pos_hd_times
0    H3001     200201  centimeters        NaN     (8.31266532669732, 82.80915102590006)                 (0.0, 77.67551865990228)      (7.14238399568412e-05, 6.28256812966937)            0.021            2695                  1                  0                       1      40.000               True
1    H3001     200202  centimeters        NaN     (6.22448820083347, 80.97897235802223)                 (0.0, 77.13461211679251)   (0.00010403409831227783, 6.283156330124877)            0.055            4679                  1                  0                       0      40.000               True
2    H3003     200207  centimeters        NaN    (4.254392715228363, 80.18506162164604)                 (0.0, 77.45854471385374)    (0.0004952033532636957, 6.283165013864346)            0.039            3719                  1                  0                       1      40.000               True
3    H3003     200208  centimeters        NaN    (3.4855474861168148, 81.0520895575169)                 (0.0, 78.18793573667719)    (4.530233278088325e-05, 6.283160021301904)            0.080            7680                  1                  0                       1      40.000               True
4    H3006   200314_1  centimeters        NaN  (-39.24912150765691, 34.464865473849684)                 (0.0, 72.86433259519004)    (0.0003887451518203022, 6.283138334831236)            0.106           15161                  1                  0                       1      40.000               True
5    H3006   200314_2  centimeters        NaN   (14.375590221543582, 89.47698621856365)                 (0.0, 76.88510371155738)  (4.6418587547947254e-05, 6.2831828960513825)            0.043            6124                  1                  0                       1      40.000               True
6    H3008     200805  centimeters        NaN     (8.774492671201171, 81.8940214232544)                 (0.0, 72.14764109675988)  (5.2320810830508435e-06, 6.2831823010643895)            0.023            2241                  1                  0                       0      40.000               True
7    H3008     200807  centimeters        NaN    (8.185606118666605, 84.64659002860012)                 (0.0, 77.97003407569944)    (8.043079296626843e-05, 6.283133785275643)            0.028            3981                  1                  0                       1      40.000               True
8    H3009     200812  centimeters        NaN    (8.650898261755813, 82.89370513959358)                  (0.0, 73.0496336776173)                      (0.0, 6.283009891275324)            0.019            2990                  1                  0                       1      40.000               True
9    H3009     200813  centimeters        NaN     (8.883541202377529, 83.0597001193349)                 (0.0, 74.17023739575387)    (8.186436003931874e-05, 6.283173946419092)            0.008            1342                  1                  0                       1      40.000               True
10   H3015   210416_1  centimeters        NaN    (8.030519748784684, 83.44728798685426)                 (0.0, 73.77846052985556)                      (0.0, 6.283093009314327)            0.076           13577                  1                  0                       1      40.000               True
11   H3015   210416_2  centimeters        NaN    (9.036820770328164, 83.44904850475226)                 (0.0, 75.81724615901662)   (0.00024195041908914305, 6.283175299725974)            0.077           11996                  1                  0                       1      40.000               True
12   H3015     210417  centimeters      4.144     (34.9044720783133, 337.4283329684605)      (20.361810984102, 297.127795725646)     (-3.1415833072905026, 3.1415712992061087)            0.400               0                  0                  0                       0      40.000               True
13   H3016     210422  centimeters        NaN   (11.063705547468544, 82.65281152718646)                 (0.0, 74.38128255195475)    (7.540540872064128e-05, 6.283178568998606)            0.059            9450                  1                  0                       1      40.000               True
14   H3016     210423  centimeters        NaN   (11.014603461648827, 77.90976770435609)                 (0.0, 74.17177098557453)  (5.6855739115402315e-05, 6.2831503431057385)            0.083           13533                  1                  0                       1      40.000               True
15   H3019     210617  centimeters        NaN   (15.207432767441558, 88.97083957186678)                  (0.0, 74.2346535256795)   (0.00018347429727438858, 6.283167031810845)            0.045            6902                  1                  0                       0      40.000               True
16   H3019   210618_1  centimeters        NaN   (15.199594124702942, 88.22278856151468)                 (0.0, 73.37171874703465)                      (0.0, 6.282966184644192)            0.087            4275                  1                  0                       1      40.000               True
17   H3022     210805  centimeters        NaN   (16.329257774411456, 91.68869844884782)                  (0.0, 76.5807822460626)    (8.326341562892026e-07, 6.283154557133571)            0.051            7577                  1                  0                       0      40.000               True
18   H3022     210806  centimeters        NaN   (15.608237563948148, 89.80491674533724)                 (0.0, 76.63558213449262)   (2.5376911591434848e-05, 6.283092408873632)            0.057            8852                  1                  0                       1      40.000               True
19   H3023     210812  centimeters        NaN   (15.580864676896242, 90.09896803489272)                 (0.0, 76.28356322433277)                     (0.0, 6.2831810265596975)            0.165           24369                  1                  0                       1      40.000               True
20   H3023   210813_1  centimeters        NaN   (15.013519399429562, 86.36415505380924)                 (0.0, 72.77644916894586)   (2.5739709484939866e-05, 6.283100295276176)            0.138           20359                  1                  0                       1      40.000               True
21   H3026     211003  centimeters        NaN    (14.50247578673125, 89.05060015278693)                 (0.0, 75.10842865591968)                      (0.0, 6.283152070535207)            0.034            5136                  1                  0                       0      40.000               True
22   H3026   211004_2  centimeters        NaN    (14.784907409236112, 88.9363062579343)                 (0.0, 75.62380581247196)    (3.241062445513698e-05, 6.283160213749489)            0.024            3573                  1                  0                       1      40.000               True
23   H3029     230510  centimeters        NaN    (5.122948046622813, 78.29719986784227)                 (0.0, 74.39847056399377)    (3.873059906389642e-05, 6.283173743036758)            0.000              32                  1                  0                       0      40.733               True
24   H4813     220728  centimeters        NaN    (6.046657060012205, 79.91873106190369)                  (0.0, 74.4253538132477)   (9.923120590205059e-05, 6.2830049797350025)            0.004             635                  1                  0                       1      40.706               True
25   H4815     220814  centimeters        NaN    (6.666092483478095, 83.13545425127765)                 (0.0, 76.60529243018408)  (0.00015325334848093064, 6.2828868044871164)            0.013            2086                  1                  0                       0      40.706               True
26   H4817     220828  centimeters        NaN    (1.0059734506068396, 81.6526271159901)                  (0.0, 77.5628218112984)   (2.5906918790674638e-05, 6.283127166518011)            0.007            1163                  1                  0                       0      40.706               True
27   H4819     220929  centimeters        NaN   (3.0620936113660484, 83.48591111438068)                 (0.0, 76.41338159827286)    (0.0001326068079805509, 6.283169816615555)            0.003             478                  1                  0                       1      40.706               True
28   H4820     221007  centimeters        NaN     (7.16658143094117, 82.86227728119539)                  (0.0, 76.0333930137787)     (8.740303703280716e-05, 6.28318106950539)            0.012            1824                  1                  0                       0      40.706               True
29   H4822     221023  centimeters        NaN   (0.8311122963891096, 78.35830625316574)                 (0.0, 77.60691008254867)    (3.860355501039692e-06, 6.283037484504581)            0.008            1147                  1                  0                       1      40.706               True
30   H4823     221108  centimeters      9.533           (23.9896775, 732.8469500000001)  (12.630911999999999, 728.5544500000001)       (-3.141577381556706, 3.141592653589793)            0.108               0                  0                  0                       0      40.706               True
31   H4824     221117  centimeters        NaN   (2.8797536431714095, 77.11583287827546)                  (0.0, 75.6462314601414)  (0.00014613340048708068, 6.2827676285689105)            0.005             793                  1                  0                       1      40.706               True
32   H4825     221124  centimeters        NaN   (2.8797536431714095, 77.11583287827546)                  (0.0, 75.6462314601414)  (0.00014613340048708068, 6.2827676285689105)            0.005             793                  1                  0                       1      40.761               True
33   H4826     221203  centimeters        NaN    (2.836154238347099, 82.22102193616637)                  (0.0, 78.3684660617393)    (0.0002152602611076304, 6.283180722652367)            0.010            1549                  1                  0                       1      40.706               True
34   H4827     221210  centimeters        NaN     (6.39270567950306, 84.57678479771397)                  (0.0, 76.0392467112476)   (3.5914289056471205e-05, 6.283162798192878)            0.003             455                  1                  0                       1      40.706               True
35   H4830     230406  centimeters        NaN    (2.564488544058552, 78.40980905397977)                 (0.0, 82.98412602084385)   (7.4395905240720595e-06, 6.283174304766208)            0.005             667                  1                  0                       0      40.733               True

files in centimetres: 34; frames with y exactly 0 per file: 1 to 1; with x exactly 0: 0 to 0

Position is stated in centimetres, and in 34 files spans about 72 to 83 cm on each axis, consistent with the 73 cm arena seen from above. In each of these files exactly one frame has y equal to 0 and none has x equal to 0, so the y positions were shifted to start at 0; missing tracking is stored as NaN, not as 0. In two files (H3015 210417 and H4823 221108) it spans 300 and 700 units, so it is in pixels although the file says centimetres (a metadata error); their head direction runs from -pi to pi where the other files run from 0 to 2 pi, and they hold tracking through the sleep. For these two files the scale is set so that the x extent of the exploration tracking equals the arena's 73 cm (4.1 and 9.5 pixels per cm). Tracking is at 40 Hz in juveniles and 40.7 Hz in adults, consistent with the Methods' 40 Hz. H3029 is tracked at 40.7 Hz like the adults, so it was recorded on the adult rig.

In [9]:
ttp = np.concatenate([r["meta"]["ttp"] for r in results if r["meta"]["subject"] not in hdfx.DUPLICATE_OF])
cont = np.concatenate([r["meta"]["contamination"] for r in results if r["meta"]["subject"] not in hdfx.DUPLICATE_OF])
edges = np.arange(0, 1.25, 1 / 30)
h, _ = np.histogram(ttp[~np.isnan(ttp)], edges)
print("trough-to-peak (ms), units per bin of one sample (1/30 ms):")
print(" ".join(f"{e:.2f}:{n}" for e, n in zip(edges, h)))
print(f"range {np.nanmin(ttp):.2f} to {np.nanmax(ttp):.2f} ms; positive waveforms (no duration): {int(np.isnan(ttp).sum())} of {len(ttp)}")
for age, thr in hdfx.TTP_THRESHOLD_MS.items():
    sel = np.concatenate([r["meta"]["ttp"] for r in results if r["meta"]["age_group"] == age and r["meta"]["subject"] not in hdfx.DUPLICATE_OF])
    print(f"{age}: {np.sum(sel > thr)} of {len(sel)} units above {thr} ms")
print(f"contamination score: median {np.nanmedian(cont):.3f}, range {np.nanmin(cont):.3f} to {np.nanmax(cont):.3f}; "
      f"above 0.5: {int(np.sum(cont > 0.5))} units; below 0.5: {int(np.sum(cont < 0.5))}")
fig, ax = plt.subplots(1, 2, figsize=(10, 3))
ax[0].hist(ttp[~np.isnan(ttp)], edges, color="0.4")
ax[0].axvline(0.4, ls="--", c="C1", label="adult 0.4 ms")
ax[0].axvline(0.5, ls="--", c="C0", label="juvenile 0.5 ms")
ax[0].set_xlabel("trough-to-peak (ms)")
ax[0].legend()
ax[1].hist(cont, np.linspace(0, 1, 41), color="0.4")
ax[1].set_xlabel("contamination score")
plt.tight_layout()
plt.show()
trough-to-peak (ms), units per bin of one sample (1/30 ms):
0.00:0 0.03:0 0.07:0 0.10:0 0.13:2 0.17:20 0.20:58 0.23:99 0.27:79 0.30:66 0.33:40 0.37:29 0.40:42 0.43:0 0.47:22 0.50:82 0.53:130 0.57:132 0.60:142 0.63:159 0.67:154 0.70:143 0.73:62 0.77:61 0.80:42 0.83:45 0.87:0 0.90:22 0.93:9 0.97:10 1.00:4 1.03:11 1.07:6 1.10:8 1.13:7 1.17:7 1.20:5
range 0.13 to 1.20 ms; positive waveforms (no duration): 63 of 1761
juvenile: 575 of 778 units above 0.5 ms
adult: 688 of 983 units above 0.4 ms
contamination score: median 0.064, range 0.000 to 1.000; above 0.5: 34 units; below 0.5: 1727
No description has been provided for this image

The trough-to-peak durations are bimodal with the trough between 0.40 and 0.47 ms, consistent with the Methods' thresholds (0.5 ms for juveniles, 0.4 ms for adults). The unit totals match the paper's counts of recorded units (see unit-counts), so the files hold all curated units, not only the putative excitatory ones. The Methods say units with a contamination score "below 0.5" were excluded; almost every unit is below 0.5, so this is read as "above 0.5", which removes few units.

In [10]:
# frame_counts on frames that are not contiguous (speed-filtered), on synthetic spikes
rng = np.random.default_rng(1)
t_all = np.arange(0, 600, 0.025)
keep = rng.random(len(t_all)) > 0.3            # frequent one-frame and longer gaps
t_sel = t_all[keep]
sp = np.sort(rng.uniform(0, 600, 20000))
expected = np.histogram(sp, np.r_[t_all - 0.0125, t_all[-1] + 0.0125])[0][keep]
got = hdfx.frame_counts([sp], t_sel, 0.025)[0]
print(f"spikes in the kept frames: expected {expected.sum()}, counted {int(got.sum())}; "
      f"frames with a wrong count: {int(np.sum(got != expected))} of {len(t_sel)}")
assert np.array_equal(got, expected)
spikes in the kept frames: expected 13843, counted 13843; frames with a wrong count: 0 of 16746

frame_counts counts each tracking frame on its own window, so frames kept by a speed filter need not be contiguous; on synthetic spikes it counts every spike of the kept frames. The first round of this attempt cut frames at gaps and lost or misplaced spikes there.

In [11]:
lag = pd.DataFrame([r["meta"].get("lag_info", [np.nan] * len(hdfx.CLOCK_LAGS)) for r in results],
                   columns=[f"{x:g}s" for x in hdfx.CLOCK_LAGS])
lag.insert(0, "session", meta.subject + " " + meta.session_id)
values = lag.iloc[:, 1:].to_numpy(float)
lag["peak_lag_s"] = [hdfx.CLOCK_LAGS[int(np.nanargmax(v))] if np.isfinite(v).any() else np.nan for v in values]
lag["zero_over_60s"] = lag["0s"] / lag[["-60s", "60s"]].max(axis=1)
print("median HD information (bits/spike) of the cells of session 1 with spikes shifted by each lag:")
print(lag.round(3).to_string())
ok = lag.dropna(subset=["0s"])
print(f"\npeak within 0.2 s of zero in {np.sum(ok.peak_lag_s.abs() <= 0.2)} of {len(ok)} recordings;"
      f" zero-lag information at least 1.5 times that at +-60 s in {np.sum(ok.zero_over_60s >= 1.5)}")
print("recordings where the clock is not established (ratio below 1.5):", ok.loc[ok.zero_over_60s < 1.5, "session"].tolist())
median HD information (bits/spike) of the cells of session 1 with spikes shifted by each lag:
           session   -60s    -2s    -1s  -0.5s  -0.2s  -0.1s     0s   0.1s   0.2s   0.5s     1s     2s    60s  peak_lag_s  zero_over_60s
0     H3001 200201  0.125  0.222  0.245  0.369  0.494  0.505  0.489  0.479  0.484  0.418  0.364  0.260  0.105        -0.1          3.900
1     H3001 200202  0.076  0.142  0.198  0.228  0.263  0.282  0.318  0.336  0.337  0.305  0.192  0.114  0.056         0.2          4.199
2     H3003 200207  0.023  0.046  0.050  0.051  0.055  0.056  0.060  0.061  0.058  0.052  0.046  0.046  0.017         0.1          2.602
3     H3003 200208  0.034  0.215  0.379  0.564  0.820  0.916  0.949  0.899  0.799  0.459  0.275  0.200  0.056         0.0         17.082
4   H3006 200314_1  0.093  0.116  0.078  0.111  0.128  0.113  0.122  0.111  0.099  0.092  0.095  0.096  0.057        -0.2          1.307
5   H3006 200314_2  0.031  0.048  0.058  0.059  0.061  0.061  0.059  0.060  0.063  0.054  0.049  0.062  0.049         0.2          1.205
6     H3008 200805  0.082  0.442  0.647  0.779  0.968  1.040  1.069  1.028  0.942  0.722  0.520  0.320  0.086         0.0         12.492
7     H3008 200807  0.045  0.161  0.223  0.330  0.413  0.432  0.440  0.453  0.385  0.246  0.177  0.132  0.037         0.1          9.703
8     H3009 200812  0.105  0.278  0.336  0.474  0.610  0.639  0.682  0.695  0.658  0.503  0.359  0.251  0.093         0.1          6.507
9     H3009 200813  0.074  0.158  0.262  0.341  0.442  0.506  0.540  0.524  0.487  0.356  0.225  0.135  0.074         0.0          7.304
10  H3015 210416_1  0.083  0.134  0.165  0.201  0.223  0.227  0.213  0.273  0.248  0.194  0.157  0.116  0.106         0.1          2.003
11  H3015 210416_2  0.068  0.089  0.094  0.104  0.113  0.122  0.134  0.127  0.129  0.119  0.113  0.093  0.089         0.0          1.498
12    H3015 210417  0.104  0.110  0.169  0.185  0.200  0.215  0.239  0.242  0.228  0.222  0.201  0.142  0.069         0.1          2.301
13    H3016 210422  0.245  0.488  0.424  0.679  0.897  1.020  1.113  1.156  1.065  0.736  0.432  0.332  0.153         0.1          4.540
14    H3016 210423  0.064  0.111  0.135  0.227  0.267  0.295  0.316  0.311  0.303  0.216  0.135  0.114  0.044         0.0          4.954
15    H3019 210617  0.028  0.144  0.286  0.353  0.439  0.429  0.425  0.412  0.399  0.276  0.207  0.099  0.018        -0.2         15.393
16  H3019 210618_1  0.017  0.018  0.020  0.024  0.034  0.039  0.042  0.045  0.042  0.037  0.026  0.031  0.019         0.1          2.140
17    H3022 210805  0.051  0.173  0.347  0.569  0.718  0.742  0.755  0.747  0.714  0.554  0.326  0.179  0.052         0.0         14.521
18    H3022 210806  0.033  0.092  0.166  0.198  0.241  0.249  0.274  0.255  0.239  0.213  0.137  0.084  0.039         0.0          7.097
19    H3023 210812  0.014  0.019  0.021  0.023  0.022  0.022  0.023  0.023  0.021  0.021  0.020  0.021  0.012        -0.5          1.650
20  H3023 210813_1  0.024  0.033  0.043  0.046  0.046  0.047  0.047  0.044  0.042  0.044  0.039  0.026  0.014        -0.1          1.953
21    H3026 211003  0.085  0.243  0.353  0.474  0.559  0.617  0.678  0.639  0.560  0.424  0.310  0.209  0.081         0.0          7.994
22  H3026 211004_2  0.064  0.133  0.178  0.275  0.379  0.407  0.442  0.438  0.448  0.276  0.199  0.136  0.062         0.2          6.863
23    H3029 230510  0.039  0.059  0.063  0.076  0.081  0.080  0.083  0.082  0.079  0.071  0.061  0.051  0.050         0.0          1.656
24    H4813 220728  0.061  0.174  0.217  0.278  0.365  0.386  0.418  0.425  0.408  0.340  0.229  0.146  0.050         0.1          6.824
25    H4815 220814  0.064  0.158  0.191  0.224  0.254  0.273  0.282  0.300  0.296  0.260  0.207  0.151  0.054         0.1          4.415
26    H4817 220828  0.042  0.067  0.090  0.136  0.137  0.135  0.120  0.116  0.108  0.097  0.093  0.078  0.049        -0.2          2.434
27    H4819 220929  0.060  0.151  0.208  0.282  0.335  0.346  0.346  0.328  0.322  0.276  0.218  0.155  0.054         0.0          5.812
28    H4820 221007  0.013  0.057  0.060  0.065  0.087  0.089  0.081  0.072  0.059  0.046  0.043  0.031  0.013        -0.1          6.053
29    H4822 221023  0.024  0.030  0.039  0.062  0.086  0.097  0.089  0.087  0.074  0.045  0.041  0.030  0.027        -0.1          3.290
30    H4823 221108  0.049  0.170  0.257  0.341  0.467  0.443  0.416  0.386  0.338  0.263  0.208  0.145  0.051        -0.2          8.192
31    H4824 221117  0.046  0.064  0.099  0.118  0.143  0.153  0.158  0.145  0.136  0.105  0.095  0.063  0.041         0.0          3.402
32    H4825 221124    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN         NaN            NaN
33    H4826 221203  0.074  0.209  0.305  0.412  0.522  0.560  0.575  0.553  0.508  0.369  0.268  0.179  0.088         0.0          6.549
34    H4827 221210  0.042  0.162  0.261  0.376  0.514  0.580  0.618  0.569  0.492  0.341  0.225  0.125  0.049         0.0         12.705
35    H4830 230406  0.027  0.069  0.107  0.138  0.166  0.175  0.186  0.175  0.163  0.130  0.093  0.060  0.020         0.0          6.941

peak within 0.2 s of zero in 34 of 35 recordings; zero-lag information at least 1.5 times that at +-60 s in 32
recordings where the clock is not established (ratio below 1.5): ['H3006 200314_1', 'H3006 200314_2', 'H3015 210416_2']

Spikes and tracking share a clock: with the spikes shifted against the head direction, HD information peaks within 0.2 s of zero lag in 34 of 35 recordings and falls towards its floor at 60 s. In H3023 210812 the information is nearly flat (0.019 to 0.023 bits/spike between -2 and 2 s) and peaks at -0.5 s. In three recordings (H3006 200314-1 and 200314-2, H3015 210416-2), whose cells are weakly tuned, the information at zero lag is less than 1.5 times that at 60 s. For these four a shared clock is consistent with the data but not shown.

In [12]:
emg = pd.DataFrame([r["meta"]["emg_median"] for r in results])
emg.insert(0, "session", meta.subject + " " + meta.session_id)
sleep_s = pd.DataFrame([r["meta"]["sleep_s"] for r in results]).add_suffix("_s")
emg = pd.concat([emg, sleep_s], axis=1)
emg["rem_in_exploration"] = [r["meta"]["rem_in_exploration"] for r in results]
print(emg.round(2).to_string())
print(f"\npseudo-EMG median lower in REM than in wake in {np.sum(emg.rem < emg.wake)} of {len(emg)} files; "
      f"REM at or below NREM in {np.sum(emg.rem <= emg.nrem + 1e-9)}")
print(f"REM per file: {emg.rem_s.min():.0f} to {emg.rem_s.max():.0f} s")
           session  wake  nrem   rem   wake_s   nrem_s    rem_s  rem_in_exploration
0     H3001 200201  0.60  0.45  0.36  1416.00  5525.66   983.00                   1
1     H3001 200202  0.67  0.32  0.31  1958.83  4083.00  1706.00                   0
2     H3003 200207  0.63  0.42  0.36  3620.57  3211.00  1163.00                   0
3     H3003 200208  0.82  0.51  0.40  3742.27  3580.00  1192.00                   0
4   H3006 200314_1  0.80  0.48  0.40  5436.14  2828.00  1030.00                   0
5   H3006 200314_2  0.88  0.44  0.39  5124.94  3635.03   690.00                   0
6     H3008 200805  0.78  0.48  0.44  4713.79  2615.04   640.00                   0
7     H3008 200807  0.77  0.41  0.38  5598.60  3255.00   630.00                   0
8     H3009 200812  0.89  0.47  0.43  4425.28  3842.76  1035.00                   0
9     H3009 200813  0.72  0.38  0.31  4338.63  4438.45   906.00                   0
10  H3015 210416_1  0.49  0.44  0.46  4924.37  3396.00  1291.00                   2
11  H3015 210416_2  0.53  0.41  0.40  6014.31  2569.29  1004.00                   4
12    H3015 210417  0.75  0.53  0.54  4187.02  4648.51  1066.00                   0
13    H3016 210422  0.57  0.48  0.43  6044.85  3010.00   689.00                   0
14    H3016 210423  0.51  0.46  0.45  5266.58  3712.00   764.00                   1
15    H3019 210617  0.49  0.32  0.33  6602.68  2326.00   644.00                   0
16  H3019 210618_1  0.68  0.50  0.48  1930.56  1051.00   257.00                   0
17    H3022 210805  0.67  0.55  0.33  4493.07  3840.65  1178.00                   0
18    H3022 210806  0.56  0.34  0.34  5377.78  2823.00  1409.00                   0
19    H3023 210812  0.56  0.42  0.42  5530.99  2885.00   593.00                   0
20  H3023 210813_1  0.57  0.46  0.48  4340.09  3379.00  1337.00                   1
21    H3026 211003  0.68  0.28  0.19  5463.06  2873.00   850.00                   0
22  H3026 211004_2  0.75  0.36  0.22  6226.08  2364.00   539.00                   0
23    H3029 230510  0.61  0.47  0.38  5133.01  3285.00  1037.00                   0
24    H4813 220728  0.57  0.33  0.29  3947.79  4625.37   988.00                   0
25    H4815 220814  0.57  0.33  0.20  5835.50  3463.00   406.00                   0
26    H4817 220828  0.65  0.49  0.47  3634.99  4989.00   756.00                   0
27    H4819 220929  0.50  0.38  0.35  5456.03  3289.00   819.00                   0
28    H4820 221007  0.44  0.16  0.10  6043.68  3184.00   408.00                   0
29    H4822 221023  0.45  0.47  0.36  4918.22  3989.00   457.38                   3
30    H4823 221108  0.51  0.36  0.31  6971.00  2308.00   116.00                   0
31    H4824 221117  0.44  0.31  0.30  5934.04  3350.00   518.00                   0
32    H4825 221124  0.34  0.26  0.23  5654.89  3323.00   520.00                   3
33    H4826 221203  0.39  0.23  0.21  5786.24  3677.00   337.00                   0
34    H4827 221210  0.53  0.38  0.38  6250.73  2832.00   391.00                   0
35    H4830 230406  0.47  0.35  0.26  5441.99  5560.00   133.00                   0

pseudo-EMG median lower in REM than in wake in 36 of 36 files; REM at or below NREM in 31
REM per file: 116 to 1706 s

The sleep stages are consistent with the pseudo-EMG: its median is lower in REM than in wake in all 36 files, and at or below its NREM median in 31. A few REM intervals overlap the tracking blocks of the exploration sessions (counted above, up to 4 in H3015 210416-2 and 3 in H4822). The REM analyses use every REM interval, as the claims' criterion says, and show the result with those intervals left out as a variant.

Tables used by the claims¶

cells has one row per cell (a putative excitatory unit with contamination at most 0.5 and at least 100 spikes in session 1) and recording; recs has one row per recording. H4825 is left out. The archive grouping variant uses the archive's genotype, and the archive's age group where the birth date gives one (H3029 is then adult and its cells are selected with the adult threshold).

In [13]:
cell_rows, rec_rows, arch_rows = [], [], []
first_day = meta[~meta.subject.isin(hdfx.DUPLICATE_OF)].sort_values("session_id").groupby("subject").session_id.first()
for r in results:
    m = r["meta"]
    if r["main"] is None:
        continue
    base = {"subject": m["subject"], "session": m["session_id"], "age_group": m["age_group"], "genotype": m["genotype"],
            "first_day": first_day[m["subject"]] == m["session_id"]}
    rec_rows.append({**base, **r["main"]["rec"]})
    c = r["main"]["cells"].copy()
    for k, v in base.items():
        c[k] = v
    cell_rows.append(c)
    a_res = r["other_age"] if r["other_age"] is not None else r["main"]
    ca = a_res["cells"].copy()
    for k, v in base.items():
        ca[k] = v
    ca["genotype"] = m["archive_genotype"]
    ca["age_group"] = m["archive_age_group"] or m["age_group"]
    arch_rows.append(ca)
cells = pd.concat(cell_rows, ignore_index=True)
cells_arch = pd.concat(arch_rows, ignore_index=True)
recs = pd.DataFrame(rec_rows)
cells["animal"] = cells.subject
cells_arch["animal"] = cells_arch.subject
print("cells per group (main):")
print(cells.groupby(["age_group", "genotype"]).agg(rats=("subject", "nunique"), recordings=("session", "nunique"), cells=("unit", "size")).to_string())
print("\ncells per group (archive labels):")
print(cells_arch.groupby(["age_group", "genotype"]).agg(rats=("subject", "nunique"), recordings=("session", "nunique"), cells=("unit", "size")).to_string())
print("\nper recording:")
print(recs[["subject", "session", "age_group", "genotype", "n_units", "n_exc_ttp", "n_exc", "n_cells", "n_sessions", "rem_s", "n_cells_rem", "rem_in_sessions", "rem_in_sessions_s"]].to_string())
print("\nranges of the cell measures (main):")
print(cells.describe().T[["count", "min", "50%", "max"]].round(3).to_string())
cells per group (main):
                    rats  recordings  cells
age_group genotype                         
adult     KO           5           5    282
          WT           6           6    395
juvenile  KO           5          10    237
          WT           7          14    323

cells per group (archive labels):
                    rats  recordings  cells
age_group genotype                         
adult     KO           5           5    282
          WT           7           7    420
juvenile  KO           4           8    145
          WT           7          15    393

per recording:
   subject   session age_group genotype  n_units  n_exc_ttp  n_exc  n_cells  n_sessions        rem_s  n_cells_rem  rem_in_sessions  rem_in_sessions_s
0    H3001    200201  juvenile       WT       23         18     18       18           2   983.000000         18.0              1.0          14.000000
1    H3001    200202  juvenile       WT       16         13     13       13           1  1706.000000         13.0              0.0           0.000000
2    H3003    200207  juvenile       KO       40         33     33       33           2  1163.000000         32.0              0.0           0.000000
3    H3003    200208  juvenile       KO       29         20     19       19           2  1192.000000         19.0              0.0           0.000000
4    H3006  200314_1  juvenile       WT       37         30     29       28           2  1030.000000         28.0              0.0           0.000000
5    H3006  200314_2  juvenile       WT       26         23     23       23           2   690.000000         23.0              0.0           0.000000
6    H3008    200805  juvenile       KO       38         25     24       24           2   640.000000         24.0              0.0           0.000000
7    H3008    200807  juvenile       KO       16         13     13       13           2   630.000000         13.0              0.0           0.000000
8    H3009    200812  juvenile       WT       37         30     30       30           2  1035.000000         30.0              0.0           0.000000
9    H3009    200813  juvenile       WT       33         26     26       26           2   906.000000         26.0              0.0           0.000000
10   H3015  210416_1  juvenile       WT       34         27     27       27           2  1291.000000         27.0              2.0          21.000000
11   H3015  210416_2  juvenile       WT       45         34     33       33           2  1004.000000         33.0              4.0          49.000000
12   H3015    210417  juvenile       WT       26         15     15       15           2  1066.000000         15.0              0.0           0.000000
13   H3016    210422  juvenile       KO       27         11     11       11           2   689.000000         11.0              0.0           0.000000
14   H3016    210423  juvenile       KO       46         36     35       30           2   764.000000         30.0              1.0          13.000000
15   H3019    210617  juvenile       KO       17         12     12       10           2   644.000000         10.0              0.0           0.000000
16   H3019  210618_1  juvenile       KO        8          5      5        5           1          NaN          NaN              NaN                NaN
17   H3022    210805  juvenile       WT       20         18     18       18           2  1178.000000         18.0              0.0           0.000000
18   H3022    210806  juvenile       WT       31         29     29       29           2  1409.000000         29.0              0.0           0.000000
19   H3023    210812  juvenile       WT       22         19     19       19           2   593.000000         19.0              0.0           0.000000
20   H3023  210813_1  juvenile       WT       24         22     22       22           2  1337.000000         22.0              1.0          13.000000
21   H3026    211003  juvenile       KO       83         50     49       49           2   850.000000         49.0              0.0           0.000000
22   H3026  211004_2  juvenile       KO       68         44     43       43           2   539.000000         43.0              0.0           0.000000
23   H3029    230510  juvenile       WT       32         22     22       22           2  1037.000000         22.0              0.0           0.000000
24   H4813    220728     adult       WT       70         54     54       54           2   988.000000         54.0              0.0           0.000000
25   H4815    220814     adult       WT       99         76     76       76           2   406.000000         76.0              0.0           0.000000
26   H4817    220828     adult       KO      105         73     72       72           2   756.000000         72.0              0.0           0.000000
27   H4819    220929     adult       KO      114         74     74       71           2   819.000000         70.0              0.0           0.000000
28   H4820    221007     adult       WT       63         52     51       51           2   408.000000         51.0              0.0           0.000000
29   H4822    221023     adult       KO       55         30     30       30           2   457.380767         29.0              3.0         196.380767
30   H4823    221108     adult       WT      113         81     81       80           2   116.000000         63.0              0.0           0.000000
31   H4824    221117     adult       KO       88         58     57       57           2   518.000000         57.0              0.0           0.000000
32   H4826    221203     adult       WT      102         73     72       72           2   337.000000         72.0              0.0           0.000000
33   H4827    221210     adult       KO       78         54     52       52           2   391.000000         52.0              0.0           0.000000
34   H4830    230406     adult       WT       96         63     62       62           2   133.000000         62.0              0.0           0.000000

ranges of the cell measures (main):
                       count      min       50%        max
unit                  1237.0    0.000    26.000    113.000
ttp                   1237.0    0.433     0.633      1.200
contamination         1237.0    0.000     0.065      0.487
n_spikes_s1           1237.0  100.000  3087.000  47907.000
mean_rate             1237.0    0.083     2.572     39.922
hd_info               1237.0    0.003     0.277      3.552
hd_info_uniform       1237.0    0.003     0.319      2.617
half_width            1237.0   16.000    66.000    360.000
vector_length         1237.0    0.008     0.288      0.966
peak_rate             1237.0    0.251     8.333     58.560
info_half1            1237.0    0.000     0.320      4.166
info_half2            1237.0    0.004     0.369      4.252
offset_halves         1236.0    0.000    22.000    179.000
n_spikes_s2           1219.0    0.000  2870.000  56477.000
info_s2               1205.0    0.003     0.306      3.554
offset_epochs         1205.0    0.000    32.000    180.000
iso_wake_info         1232.0    0.003     0.312      2.639
real200_info          1232.0    0.001     0.236      3.560
n_spikes_rem          1232.0    0.000  2193.500  32665.000
iso_rem_info          1212.0    0.002     0.313      2.660
iso_rem_info_outside  1212.0    0.002     0.303      2.660
In [14]:
def lme_variants(value, age, higher="KO", log_ok=True, uniform_col=None, extra=None):
    '''The LME test and its variants for one cell measure in one age group.'''
    d = cells[cells.age_group == age]
    rows = []
    def add(name, df, col=value, log=False):
        coef, p, n = hdfx.lme_lrt(df, col, log=log)
        rows.append({"test": name, "n": n, "coef_KO_minus_WT": coef, "p": p})
    add("LME (main)", d)
    if log_ok:
        add("LME on log values", d, log=True)
    if not d.first_day.all():
        add("LME, first day of each rat", d[d.first_day])
    add("LME, archive labels", cells_arch[cells_arch.age_group == age])
    if age == "juvenile":
        add("LME, H3026 left out", d[d.subject != "H3026"])
    if uniform_col:
        add("LME, uniform occupancy (v2)", d, col=uniform_col)
    if extra is not None:
        add(*extra)
    ko, wt = d.loc[d.genotype == "KO", value].dropna(), d.loc[d.genotype == "WT", value].dropna()
    mw = stats.mannwhitneyu(ko, wt)
    rows.append({"test": "Mann-Whitney on cells", "n": len(ko) + len(wt), "coef_KO_minus_WT": ko.median() - wt.median(), "p": mw.pvalue})
    am = d.groupby(["animal", "genotype"])[value].mean().reset_index()
    tt = stats.ttest_ind(am.loc[am.genotype == "KO", value], am.loc[am.genotype == "WT", value])
    rows.append({"test": f"t-test on animal means, t({len(am) - 2}) = {tt.statistic:.2f}", "n": len(am),
                 "coef_KO_minus_WT": am.loc[am.genotype == "KO", value].mean() - am.loc[am.genotype == "WT", value].mean(), "p": tt.pvalue})
    out = pd.DataFrame(rows)
    summ = d.groupby("genotype")[value].agg(["count", "median", "mean", "min", "max"])
    per_animal = d.groupby(["genotype", "animal"])[value].agg(["count", "median", "mean"])
    return out, summ, per_animal


def show(value, age, **kw):
    out, summ, per_animal = lme_variants(value, age, **kw)
    print(f"{value}, {age}: cells by genotype")
    print(summ.round(3).to_string())
    print("\nper rat")
    print(per_animal.round(3).to_string())
    print("\ntests")
    print(out.round(4).to_string())
    return out


def corr(age, x, y, df=None):
    d = (cells if df is None else df)
    d = d[d.age_group == age].dropna(subset=[x, y])
    rows = []
    for g in ("WT", "KO"):
        e = d[d.genotype == g]
        r, p = stats.pearsonr(e[x], e[y])
        f = e[e.first_day]
        rows.append({"genotype": g, "cells": len(e), "rats": e.animal.nunique(), "r": r, "p": p,
                     "spearman": stats.spearmanr(e[x], e[y])[0],
                     "r_first_day": stats.pearsonr(f[x], f[y])[0], "cells_first_day": len(f),
                     "x_range": (round(e[x].min(), 3), round(e[x].max(), 3)), "y_range": (round(e[y].min(), 3), round(e[y].max(), 3))})
    return pd.DataFrame(rows)


def scatter(age, x, y, xlabel, ylabel):
    """Per-cell scatter of y against x by genotype, cells of later days marked."""
    d = cells[cells.age_group == age].dropna(subset=[x, y])
    fig, ax = plt.subplots(1, 2, figsize=(9, 4), sharex=True, sharey=True)
    for k, g in enumerate(("WT", "KO")):
        e = d[d.genotype == g]
        for first, mk, lab in ((True, "o", "first day"), (False, "x", "later day")):
            f = e[e.first_day == first]
            ax[k].scatter(f[x], f[y], s=8, marker=mk, alpha=0.6, label=lab)
        hi = max(d[x].max(), d[y].max())
        ax[k].plot([0, hi], [0, hi], c="0.6", lw=0.8)
        ax[k].set_title(f"{age} {g}")
        ax[k].set_xlabel(xlabel)
    ax[0].set_ylabel(ylabel)
    ax[0].legend()
    plt.tight_layout()
    plt.show()
    print(f"plotted ranges: {x} {d[x].min():.3f} to {d[x].max():.3f}; {y} {d[y].min():.3f} to {d[y].max():.3f} (no point outside the axes)")
    e = d.assign(diff=(d[y] - d[x]).abs()).sort_values("diff", ascending=False)
    print("the ten cells farthest from the diagonal:")
    print(e[["subject", "session", "genotype", "unit", "first_day", x, y, "diff"]].head(10).round(3).to_string())

unit-counts¶

406 units were recorded from 7 juvenile WT rats and 372 from 5 juvenile Fmr1-/y rats; 543 units from 6 adult WT rats and 507 from 6 adult Fmr1-/y rats.

In [15]:
expected = {("juvenile", "WT"): (406, 7), ("juvenile", "KO"): (372, 5), ("adult", "WT"): (543, 6), ("adult", "KO"): (507, 6)}
exc_units = pd.Series({(r["meta"]["subject"], r["meta"]["session_id"]): r["main"]["rec"]["n_exc_ttp"] for r in results if r["main"] is not None})
def table(df, age_col, geno_col, reading):
    rows = []
    for (age, geno), (eu, er) in expected.items():
        d = df[(df[age_col] == age) & (df[geno_col] == geno)]
        n = d.n_units.sum() if reading == "a" else sum(exc_units.get((s, ss), 0) for s, ss in zip(d.subject, d.session_id))
        rows.append({"group": f"{age} {geno}", "units": n, "paper_units": eu, "units_ok": abs(n - eu) <= 0.1 * eu,
                     "rats": d.subject.nunique(), "paper_rats": er, "rats_ok": abs(d.subject.nunique() - er) <= 0.1 * er})
    t = pd.DataFrame(rows)
    t["group_ok"] = t.units_ok & t.rats_ok
    return t
for reading in ("a", "b"):
    t = table(once, "age_group", "genotype", reading)
    print(f"main grouping, reading ({reading}) {'all units' if reading == 'a' else 'putative excitatory units'}:")
    print(t.to_string(), "\ngroups matching:", int(t.group_ok.sum()), "of 4\n")
print("variant, archive labels (all units, each file once):")
print(table(arch[~arch.subject.isin(hdfx.DUPLICATE_OF)], "archive_age_group", "archive_genotype", "a").to_string())
print("\nvariant, main grouping counting H4825's file as a recording of its own (all units):")
print(table(meta, "age_group", "genotype", "a").to_string())
main grouping, reading (a) all units:
         group  units  paper_units  units_ok  rats  paper_rats  rats_ok  group_ok
0  juvenile WT    406          406      True     7           7     True      True
1  juvenile KO    372          372      True     5           5     True      True
2     adult WT    543          543      True     6           6     True      True
3     adult KO    440          507     False     5           6    False     False 
groups matching: 3 of 4

main grouping, reading (b) putative excitatory units:
         group  units  paper_units  units_ok  rats  paper_rats  rats_ok  group_ok
0  juvenile WT    326          406     False     7           7     True     False
1  juvenile KO    249          372     False     5           5     True     False
2     adult WT    399          543     False     6           6     True     False
3     adult KO    289          507     False     5           6    False     False 
groups matching: 0 of 4

variant, archive labels (all units, each file once):
         group  units  paper_units  units_ok  rats  paper_rats  rats_ok  group_ok
0  juvenile WT    328          406     False     5           7    False     False
1  juvenile KO    221          372     False     4           5    False     False
2     adult WT    575          543      True     7           6    False     False
3     adult KO    440          507     False     5           6    False     False

variant, main grouping counting H4825's file as a recording of its own (all units):
         group  units  paper_units  units_ok  rats  paper_rats  rats_ok  group_ok
0  juvenile WT    406          406      True     7           7     True      True
1  juvenile KO    372          372      True     5           5     True      True
2     adult WT    543          543      True     6           6     True      True
3     adult KO    528          507      True     6           6     True      True

Result: partially reproduced. Counting every unit of each recording once, the juvenile WT (406 units, 7 rats), juvenile Fmr1-/y (372, 5) and adult WT (543, 6) groups match the paper exactly, with H3026 taken as Fmr1-/y and H3029 as a juvenile. The adult Fmr1-/y group has 440 units in 5 rats against 507 in 6, because H4825's file holds H4824's recording. Counting H4825's file as a recording of its own gives 528 units in 6 rats, within the tolerance, but it counts one recording twice. As putative excitatory units no group matches, and with the archive's labels no group matches.

units-per-recording¶

Juvenile recordings held 8 to 83 putative excitatory units each, adult recordings 30 to 114.

In [16]:
rr = recs.copy()
rows = []
for reading, col in (("a all units", "n_units"), ("b putative excitatory (trough-to-peak)", "n_exc_ttp"), ("c cells of session 1", "n_cells")):
    for age, (lo, hi) in (("juvenile", (8, 83)), ("adult", (30, 114))):
        d = rr[rr.age_group == age][col]
        rows.append({"reading": reading, "age": age, "min": d.min(), "max": d.max(), "paper": f"{lo} to {hi}",
                     "min_ok": abs(d.min() - lo) <= 0.1 * lo, "max_ok": abs(d.max() - hi) <= 0.1 * hi})
print(pd.DataFrame(rows).to_string())
print("\nadult recordings sorted by units:", rr[rr.age_group == "adult"].sort_values("n_units")[["subject", "n_units", "n_exc_ttp", "n_cells"]].values.tolist())
                                  reading       age  min  max      paper  min_ok  max_ok
0                             a all units  juvenile    8   83    8 to 83    True    True
1                             a all units     adult   55  114  30 to 114   False    True
2  b putative excitatory (trough-to-peak)  juvenile    5   50    8 to 83   False   False
3  b putative excitatory (trough-to-peak)     adult   30   81  30 to 114    True   False
4                    c cells of session 1  juvenile    5   49    8 to 83   False   False
5                    c cells of session 1     adult   30   80  30 to 114    True   False

adult recordings sorted by units: [['H4822', 55, 30, 30], ['H4820', 63, 52, 51], ['H4813', 70, 54, 54], ['H4827', 78, 54, 52], ['H4824', 88, 58, 57], ['H4830', 96, 63, 62], ['H4815', 99, 76, 76], ['H4826', 102, 73, 72], ['H4817', 105, 73, 72], ['H4823', 113, 81, 80], ['H4819', 114, 74, 71]]

Result: partially reproduced. Counting all units, the juvenile recordings hold 8 to 83, as the paper says, and the adult ones 55 to 114, so the adult minimum differs. As putative excitatory units by trough-to-peak duration, the ranges are 5 to 50 (juvenile) and 30 to 81 (adult). The paper's juvenile range and adult maximum are counts of all units, and its adult minimum is the count of putative excitatory units in H4822, so the reported ranges mix the two readings.

figs1c-juvenile-behaviour-similar and figs2c-adult-behaviour-similar¶

Juvenile (and adult) Fmr1-/y and WT rats do not differ in the time spent inactive, the time spent in the centre of the arena, or the speed while active.

In [17]:
def behaviour(age):
    d = recs[recs.age_group == age].groupby(["subject", "genotype"])[["inactive", "centre", "active_speed"]].mean().reset_index()
    rows = []
    for col in ("inactive", "centre", "active_speed"):
        ko, wt = d.loc[d.genotype == "KO", col], d.loc[d.genotype == "WT", col]
        t = stats.ttest_ind(ko, wt)
        rows.append({"measure": col, "WT_mean": wt.mean(), "KO_mean": ko.mean(), "WT_range": (round(wt.min(), 3), round(wt.max(), 3)),
                     "KO_range": (round(ko.min(), 3), round(ko.max(), 3)), "df": len(d) - 2, "t": t.statistic, "p": t.pvalue})
    return d, pd.DataFrame(rows)
for age in ("juvenile", "adult"):
    d, t = behaviour(age)
    print(f"{age}: per rat (fractions of tracked time; speed in cm/s)")
    print(d.round(3).to_string())
    print(t.round(4).to_string(), "\n")
print("variants of the thresholds (rat means): inactive and active at 2 cm/s; centre disc of radius one third of the diameter")
for age in ("juvenile", "adult"):
    d = recs[recs.age_group == age].groupby(["subject", "genotype"])[["inactive_2", "centre_third", "active_speed_2"]].mean().reset_index()
    for col in ("inactive_2", "centre_third", "active_speed_2"):
        tt = stats.ttest_ind(d.loc[d.genotype == "KO", col], d.loc[d.genotype == "WT", col])
        print(f"  {age} {col}: WT {d.loc[d.genotype == 'WT', col].mean():.3f}, KO {d.loc[d.genotype == 'KO', col].mean():.3f}, t({len(d) - 2}) = {tt.statistic:.2f}, p = {tt.pvalue:.4f}")
print("variants: first day of each rat only")
for age in ("juvenile", "adult"):
    keep = recs.first_day
    d = recs[keep & (recs.age_group == age)]
    for col in ("inactive", "centre", "active_speed"):
        tt = stats.ttest_ind(d.loc[d.genotype == "KO", col], d.loc[d.genotype == "WT", col])
        print(f"  {age} {col}: t({len(d) - 2}) = {tt.statistic:.2f}, p = {tt.pvalue:.4f}")
juvenile: per rat (fractions of tracked time; speed in cm/s)
   subject genotype  inactive  centre  active_speed
0    H3001       WT     0.358   0.015         4.778
1    H3003       KO     0.099   0.052         7.359
2    H3006       WT     0.431   0.149         4.149
3    H3008       KO     0.057   0.261         5.714
4    H3009       WT     0.181   0.222         5.038
5    H3015       WT     0.122   0.013         4.485
6    H3016       KO     0.248   0.136         4.866
7    H3019       KO     0.037   0.153         5.158
8    H3022       WT     0.056   0.108         5.219
9    H3023       WT     0.066   0.011         4.972
10   H3026       KO     0.092   0.300         5.621
11   H3029       WT     0.024   0.067         5.504
        measure  WT_mean  KO_mean        WT_range        KO_range  df       t       p
0      inactive   0.1769   0.1068  (0.024, 0.431)  (0.037, 0.248)  10 -0.8951  0.3918
1        centre   0.0836   0.1802  (0.011, 0.222)    (0.052, 0.3)  10  1.8562  0.0931
2  active_speed   4.8778   5.7435  (4.149, 5.504)  (4.866, 7.359)  10  2.0957  0.0625 

adult: per rat (fractions of tracked time; speed in cm/s)
   subject genotype  inactive  centre  active_speed
0    H4813       WT     0.118   0.563         6.996
1    H4815       WT     0.089   0.065         6.582
2    H4817       KO     0.144   0.128         6.712
3    H4819       KO     0.121   0.047         6.833
4    H4820       WT     0.108   0.105         8.570
5    H4822       KO     0.110   0.052         8.254
6    H4823       WT     0.245   0.180         6.116
7    H4824       KO     0.223   0.206         7.017
8    H4826       WT     0.276   0.030         7.079
9    H4827       KO     0.145   0.051         9.132
10   H4830       WT     0.021   0.175         8.677
        measure  WT_mean  KO_mean        WT_range        KO_range  df       t       p
0      inactive   0.1430   0.1484  (0.021, 0.276)   (0.11, 0.223)   9  0.1136  0.9120
1        centre   0.1863   0.0967   (0.03, 0.563)  (0.047, 0.206)   9 -0.9750  0.3550
2  active_speed   7.3369   7.5898  (6.116, 8.677)  (6.712, 9.132)   9  0.3953  0.7018 

variants of the thresholds (rat means): inactive and active at 2 cm/s; centre disc of radius one third of the diameter
  juvenile inactive_2: WT 0.465, KO 0.370, t(10) = -1.23, p = 0.2456
  juvenile centre_third: WT 0.140, KO 0.278, t(10) = 1.76, p = 0.1096
  juvenile active_speed_2: WT 6.823, KO 7.560, t(10) = 1.19, p = 0.2601
  adult inactive_2: WT 0.345, KO 0.362, t(9) = 0.26, p = 0.8023
  adult centre_third: WT 0.273, KO 0.233, t(9) = -0.34, p = 0.7419
  adult active_speed_2: WT 9.225, KO 9.678, t(9) = 0.68, p = 0.5127
variants: first day of each rat only
  juvenile inactive: t(10) = -0.82, p = 0.4318
  juvenile centre: t(10) = 1.56, p = 0.1506
  juvenile active_speed: t(10) = 2.45, p = 0.0342
  adult inactive: t(9) = 0.11, p = 0.9120
  adult centre: t(9) = -0.97, p = 0.3550
  adult active_speed: t(9) = 0.40, p = 0.7018

Result: figs1c-juvenile-behaviour-similar reproduced; figs2c-adult-behaviour-similar reproduced. In juveniles no measure differs by t-test on rat means at 0.05: time inactive p = 0.39, time in the centre p = 0.093, speed while active p = 0.063 (Fmr1-/y 5.74 against WT 4.88 cm/s). The active speed differs with the first day of each rat alone (p = 0.034), so the absence of a speed difference is fragile; with thresholds of 2 cm/s and a centre disc of a third of the diameter, p = 0.25, 0.11 and 0.26. In adults none differs (p = 0.91, 0.355 and 0.70).

figs1-juvenile-cell-metrics-similar and figs2-adult-cell-metrics-similar¶

Cluster contamination, mean and peak firing rates, and resultant vector length of PoSub cells do not differ between genotypes (juveniles, Figure S1f-i; adults, Figure S2f-i).

In [18]:
metric_tests = {}
for age in ("juvenile", "adult"):
    for col in ("contamination", "mean_rate", "peak_rate", "vector_length"):
        print("=" * 100)
        metric_tests[(age, col)] = show(col, age, log_ok=col != "contamination")
print("\nmain LME p per measure:")
print(pd.Series({k: v.loc[0, "p"] for k, v in metric_tests.items()}).round(4).to_string())
====================================================================================================
contamination, juvenile: cells by genotype
          count  median   mean  min    max
genotype                                  
KO          237   0.055  0.080  0.0  0.474
WT          323   0.062  0.083  0.0  0.444

per rat
                 count  median   mean
genotype animal                      
KO       H3003      52   0.052  0.063
         H3008      37   0.033  0.042
         H3016      41   0.091  0.104
         H3019      15   0.059  0.098
         H3026      92   0.059  0.090
WT       H3001      31   0.062  0.061
         H3006      51   0.036  0.068
         H3009      56   0.016  0.045
         H3015      75   0.076  0.095
         H3022      47   0.074  0.099
         H3023      41   0.101  0.117
         H3029      22   0.103  0.108

tests
                                    test    n  coef_KO_minus_WT       p
0                             LME (main)  560           -0.0053  0.7092
1             LME, first day of each rat  289           -0.0044  0.8025
2                    LME, archive labels  538           -0.0074  0.6283
3                    LME, H3026 left out  468           -0.0088  0.5813
4                  Mann-Whitney on cells  560           -0.0071  0.4959
5  t-test on animal means, t(10) = -0.33   12           -0.0051  0.7484
====================================================================================================
mean_rate, juvenile: cells by genotype
          count  median   mean    min     max
genotype                                     
KO          237   1.644  3.092  0.083  22.928
WT          323   2.140  3.358  0.111  18.146

per rat
                 count  median   mean
genotype animal                      
KO       H3003      52   2.423  5.574
         H3008      37   2.787  4.005
         H3016      41   1.169  1.306
         H3019      15   2.900  3.149
         H3026      92   1.340  2.109
WT       H3001      31   3.632  4.031
         H3006      51   2.976  3.846
         H3009      56   1.299  1.842
         H3015      75   1.025  1.648
         H3022      47   2.653  3.025
         H3023      41   8.230  8.040
         H3029      22   2.292  2.953

tests
                                    test    n  coef_KO_minus_WT       p
0                             LME (main)  560           -0.3894  0.7154
1                      LME on log values  560           -0.2427  0.4237
2             LME, first day of each rat  289           -0.3630  0.7555
3                    LME, archive labels  538            0.0383  0.9744
4                    LME, H3026 left out  468           -0.0901  0.9388
5                  Mann-Whitney on cells  560           -0.4958  0.0377
6  t-test on animal means, t(10) = -0.35   12           -0.3979  0.7368
====================================================================================================
peak_rate, juvenile: cells by genotype
          count  median   mean    min     max
genotype                                     
KO          237   7.114  9.307  0.265  40.673
WT          323   7.932  9.961  0.493  58.560

per rat
                 count  median    mean
genotype animal                       
KO       H3003      52  10.054  11.050
         H3008      37  13.471  14.282
         H3016      41   5.073   5.994
         H3019      15   8.104   7.646
         H3026      92   5.983   8.068
WT       H3001      31  14.481  16.529
         H3006      51  11.970  15.566
         H3009      56   6.514   7.588
         H3015      75   3.084   4.230
         H3022      47   9.074  10.130
         H3023      41  13.104  13.255
         H3029      22   5.493   6.792

tests
                                    test    n  coef_KO_minus_WT       p
0                             LME (main)  560           -1.1304  0.6163
1                      LME on log values  560           -0.0970  0.7145
2             LME, first day of each rat  289           -1.4180  0.5996
3                    LME, archive labels  538           -0.8947  0.7152
4                    LME, H3026 left out  468           -0.7694  0.7593
5                  Mann-Whitney on cells  560           -0.8184  0.7102
6  t-test on animal means, t(10) = -0.48   12           -1.1764  0.6407
====================================================================================================
vector_length, juvenile: cells by genotype
          count  median   mean    min    max
genotype                                    
KO          237   0.425  0.440  0.008  0.966
WT          323   0.265  0.338  0.013  0.947

per rat
                 count  median   mean
genotype animal                      
KO       H3003      52   0.400  0.394
         H3008      37   0.504  0.549
         H3016      41   0.348  0.412
         H3019      15   0.170  0.289
         H3026      92   0.440  0.460
WT       H3001      31   0.409  0.402
         H3006      51   0.337  0.344
         H3009      56   0.490  0.501
         H3015      75   0.256  0.295
         H3022      47   0.319  0.393
         H3023      41   0.099  0.157
         H3029      22   0.161  0.191

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  560            0.0981  0.1116
1                     LME on log values  560            0.2295  0.2722
2            LME, first day of each rat  289            0.1016  0.2187
3                   LME, archive labels  538            0.0520  0.4205
4                   LME, H3026 left out  468            0.0882  0.1978
5                 Mann-Whitney on cells  560            0.1596  0.0001
6  t-test on animal means, t(10) = 1.45   12            0.0948  0.1779
====================================================================================================
contamination, adult: cells by genotype
          count  median   mean  min    max
genotype                                  
KO          282   0.063  0.089  0.0  0.475
WT          395   0.077  0.102  0.0  0.487

per rat
                 count  median   mean
genotype animal                      
KO       H4817      72   0.072  0.097
         H4819      71   0.061  0.093
         H4822      30   0.037  0.069
         H4824      57   0.080  0.100
         H4827      52   0.044  0.075
WT       H4813      54   0.055  0.086
         H4815      76   0.058  0.084
         H4820      51   0.113  0.132
         H4823      80   0.090  0.108
         H4826      72   0.072  0.099
         H4830      62   0.086  0.110

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  677           -0.0135  0.1110
1                   LME, archive labels  702           -0.0147  0.0771
2                 Mann-Whitney on cells  677           -0.0141  0.0992
3  t-test on animal means, t(9) = -1.68   11           -0.0166  0.1274
====================================================================================================
mean_rate, adult: cells by genotype
          count  median   mean    min     max
genotype                                     
KO          282   2.839  3.555  0.172  20.981
WT          395   3.198  4.113  0.108  39.922

per rat
                 count  median   mean
genotype animal                      
KO       H4817      72   2.629  3.180
         H4819      71   3.065  4.283
         H4822      30   2.410  3.375
         H4824      57   3.065  3.866
         H4827      52   2.363  2.842
WT       H4813      54   3.190  3.609
         H4815      76   3.297  3.742
         H4820      51   6.622  8.058
         H4823      80   2.279  3.003
         H4826      72   2.326  2.995
         H4830      62   3.668  4.493

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  677           -0.7819  0.3408
1                     LME on log values  677           -0.1983  0.2879
2                   LME, archive labels  702           -0.6084  0.4391
3                 Mann-Whitney on cells  677           -0.3592  0.0219
4  t-test on animal means, t(9) = -0.90   11           -0.8074  0.3901
====================================================================================================
peak_rate, adult: cells by genotype
          count  median    mean    min     max
genotype                                      
KO          282   8.073   9.510  0.575  49.447
WT          395   9.338  11.247  0.251  55.449

per rat
                 count  median    mean
genotype animal                       
KO       H4817      72   5.650   7.171
         H4819      71  10.624  12.615
         H4822      30   5.205   5.852
         H4824      57   9.524   9.824
         H4827      52   9.410  10.277
WT       H4813      54   9.774  11.539
         H4815      76   9.455  11.600
         H4820      51  12.271  14.588
         H4823      80   6.868   8.675
         H4826      72   8.864  12.037
         H4830      62   8.803  10.212

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  677           -2.1479  0.1006
1                     LME on log values  677           -0.2110  0.1643
2                   LME, archive labels  702           -1.5943  0.2476
3                 Mann-Whitney on cells  677           -1.2642  0.0026
4  t-test on animal means, t(9) = -1.64   11           -2.2940  0.1353
====================================================================================================
vector_length, adult: cells by genotype
          count  median   mean    min    max
genotype                                    
KO          282   0.244  0.291  0.010  0.936
WT          395   0.293  0.351  0.009  0.946

per rat
                 count  median   mean
genotype animal                      
KO       H4817      72   0.175  0.217
         H4819      71   0.385  0.376
         H4822      30   0.118  0.139
         H4824      57   0.216  0.238
         H4827      52   0.400  0.426
WT       H4813      54   0.294  0.355
         H4815      76   0.332  0.375
         H4820      51   0.137  0.204
         H4823      80   0.307  0.356
         H4826      72   0.413  0.444
         H4830      62   0.281  0.322

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  677           -0.0619  0.2552
1                     LME on log values  677           -0.2112  0.2583
2                   LME, archive labels  702           -0.0414  0.4551
3                 Mann-Whitney on cells  677           -0.0498  0.0032
4  t-test on animal means, t(9) = -1.06   11           -0.0635  0.3151

main LME p per measure:
juvenile  contamination    0.7092
          mean_rate        0.7154
          peak_rate        0.6163
          vector_length    0.1116
adult     contamination    0.1110
          mean_rate        0.3408
          peak_rate        0.1006
          vector_length    0.2552

Result: figs1-juvenile-cell-metrics-similar reproduced; figs2-adult-cell-metrics-similar reproduced. No main LME test finds a genotype effect on contamination, mean rate, peak rate or vector length (juveniles p = 0.11 to 0.72; adults p = 0.10 to 0.34). Mann-Whitney tests on cells, which ignore the rat, find differences in juvenile mean rate (p = 0.038) and vector length (p = 0.0001), and in adult mean rate, peak rate and vector length (p = 0.022, 0.0026 and 0.0032).

fig1ef-juvenile-sharper-tuning¶

PoSub cells of juvenile Fmr1-/y rats are more sharply tuned to head direction than those of WT littermates, with higher HD information and narrower tuning curves.

In [19]:
t_info = show("hd_info", "juvenile", uniform_col="hd_info_uniform")
print("=" * 100)
t_hw = show("half_width", "juvenile")
d = cells[cells.age_group == "juvenile"]
print("\nfraction of cells with half-width below 120 degrees:", d.groupby("genotype").half_width.apply(lambda x: np.mean(x < 120)).round(3).to_dict())
print("cells with half-width 360 (never below half maximum):", d.groupby("genotype").half_width.apply(lambda x: int(np.sum(x >= 360))).to_dict())
fig, ax = plt.subplots(1, 2, figsize=(10, 3))
for i, (col, lab) in enumerate((("hd_info", "HD info (bits/spike)"), ("half_width", "half-width (deg)"))):
    for g, c in (("WT", "0.5"), ("KO", "C3")):
        ax[i].hist(d.loc[d.genotype == g, col], 30, histtype="step", color=c, density=True, label=g)
    ax[i].set_xlabel(lab)
ax[0].legend()
plt.tight_layout()
plt.show()
print("plotted ranges: HD info", d.hd_info.min().round(3), "to", d.hd_info.max().round(3), "; half-width", d.half_width.min(), "to", d.half_width.max())
hd_info, juvenile: cells by genotype
          count  median   mean    min    max
genotype                                    
KO          237   0.596  0.798  0.004  3.552
WT          323   0.189  0.435  0.006  3.176

per rat
                 count  median   mean
genotype animal                      
KO       H3003      52   0.443  0.641
         H3008      37   0.727  1.055
         H3016      41   0.456  0.740
         H3019      15   0.201  0.422
         H3026      92   0.646  0.869
WT       H3001      31   0.381  0.565
         H3006      51   0.119  0.304
         H3009      56   0.653  0.907
         H3015      75   0.161  0.262
         H3022      47   0.356  0.590
         H3023      41   0.026  0.125
         H3029      22   0.083  0.180

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  560            0.3376  0.0303
1                     LME on log values  560            0.6512  0.1185
2            LME, first day of each rat  289            0.4728  0.0354
3                   LME, archive labels  538            0.2074  0.2311
4                   LME, H3026 left out  468            0.3046  0.0722
5           LME, uniform occupancy (v2)  560            0.2705  0.0811
6                 Mann-Whitney on cells  560            0.4074  0.0000
7  t-test on animal means, t(10) = 2.11   12            0.3263  0.0610
====================================================================================================
half_width, juvenile: cells by genotype
          count  median     mean   min    max
genotype                                     
KO          237    50.0   99.451  20.0  360.0
WT          323    62.0  114.272  16.0  360.0

per rat
                 count  median     mean
genotype animal                        
KO       H3003      52   105.0  162.462
         H3008      37    50.0   92.486
         H3016      41    42.0   64.341
         H3019      15    72.0  126.133
         H3026      92    42.0   77.935
WT       H3001      31    66.0  111.613
         H3006      51    38.0   93.647
         H3009      56    51.0   68.607
         H3015      75    58.0   86.107
         H3022      47    60.0   93.702
         H3023      41   360.0  257.317
         H3029      22   133.0  155.455

tests
                                    test    n  coef_KO_minus_WT       p
0                             LME (main)  560          -18.8909  0.5371
1                      LME on log values  560           -0.1377  0.5739
2             LME, first day of each rat  289          -15.1172  0.7028
3                    LME, archive labels  538           -0.9320  0.9779
4                    LME, H3026 left out  468          -11.7979  0.7272
5                  Mann-Whitney on cells  560          -12.0000  0.1306
6  t-test on animal means, t(10) = -0.58   12          -19.1067  0.5741

fraction of cells with half-width below 120 degrees: {'KO': 0.781, 'WT': 0.734}
cells with half-width 360 (never below half maximum): {'KO': 26, 'WT': 46}
No description has been provided for this image
plotted ranges: HD info 0.004 to 3.552 ; half-width 16.0 to 360.0

Result: partially reproduced. HD information is higher in juvenile Fmr1-/y cells than in WT cells (median 0.596 against 0.189 bits/spike; LME p = 0.030), and stays so with the first day of each rat alone (p = 0.035), but not on log values (p = 0.12), with uniform occupancy as in version 2 (p = 0.081), on rat means (t(10) = 2.11, p = 0.061), with H3026 left out (p = 0.072) or with the archive's labels (p = 0.23). The half-width does not differ (median 50 against 62 degrees; LME p = 0.54).

fig1g-juvenile-halves-correlation¶

In juveniles the HD information of a cell is stable between the two halves of an exploration session (WT r = 0.90, Fmr1-/y r = 0.95).

In [20]:
print(corr("juvenile", "info_half1", "info_half2").round(4).to_string())
print("\nvariant, archive labels:")
print(corr("juvenile", "info_half1", "info_half2", cells_arch).round(4).to_string())
print("\nvariant, H3026 left out:")
print(corr("juvenile", "info_half1", "info_half2", cells[cells.subject != "H3026"]).round(4).to_string())
scatter("juvenile", "info_half1", "info_half2", "HD info, first half (bits/spike)", "HD info, second half")
  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    323     7  0.8151  0.0    0.8632       0.7393              162  (0.004, 3.331)  (0.005, 3.422)
1       KO    237     5  0.8354  0.0    0.9088       0.8984              127    (0.0, 4.166)  (0.006, 4.046)

variant, archive labels:
  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    393     7  0.8264  0.0    0.8883       0.8028              189  (0.004, 4.066)  (0.005, 4.046)
1       KO    145     4  0.8685  0.0    0.9178       0.9151               78    (0.0, 4.166)  (0.006, 3.506)

variant, H3026 left out:
  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    323     7  0.8151  0.0    0.8632       0.7393              162  (0.004, 3.331)  (0.005, 3.422)
1       KO    145     4  0.8685  0.0    0.9178       0.9151               78    (0.0, 4.166)  (0.006, 3.506)
No description has been provided for this image
plotted ranges: info_half1 0.000 to 4.166; info_half2 0.005 to 4.046 (no point outside the axes)
the ten cells farthest from the diagonal:
    subject   session genotype  unit  first_day  info_half1  info_half2   diff
86    H3006  200314_1       WT     6       True       3.125       0.133  2.992
337   H3016    210423       KO    37      False       4.093       1.158  2.935
500   H3026  211004_2       KO     8      False       1.052       3.027  1.975
184   H3009    200812       WT    14       True       2.322       0.447  1.875
142   H3008    200805       KO    10       True       4.125       2.273  1.852
528   H3026  211004_2       KO    47      False       1.333       3.029  1.696
509   H3026  211004_2       KO    17      False       2.293       0.739  1.554
506   H3026  211004_2       KO    14      False       2.660       4.046  1.387
486   H3026    211003       KO    69       True       4.066       2.689  1.377
200   H3009    200812       WT    33       True       2.658       1.293  1.365

Result: not reproduced. With the sessions as the claims file defines them (see the section on the session definition below), HD information of the two halves of session 1 correlates with r = 0.761 over 323 WT cells (paper 0.90, lower bound 0.81) and r = 0.839 over 237 Fmr1-/y cells (paper 0.95, lower bound 0.855), so neither value is within tolerance. With H3026 left out the Fmr1-/y r is 0.869, within tolerance, and WT stays at 0.761; with the first day of each rat alone WT r is 0.650. With the 20 min sessions used in this section, WT r is 0.815, 0.005 above its bound, and Fmr1-/y r 0.835; with the first day alone WT r is 0.739. Spearman correlations with the 20 min sessions are higher (0.863 and 0.909). Five of the ten cells farthest from the diagonal are from H3026, the rat counted as Fmr1-/y against the archive's label. The 20 min cut was adopted after the first round of verification and departs from the claims file, so the outcome follows the claims file's definition.

fig1h-juvenile-smaller-offset¶

Within a session, the tuning curves of juvenile Fmr1-/y cells drift less relative to the room than those of WT cells; the angular offset between the two halves is smaller.

In [21]:
d = cells[cells.age_group == "juvenile"]
t_off = show("offset_halves", "juvenile", log_ok=False,
             extra=("LME, cells with half-width below 120 deg", d[d.half_width < 120]))
print("plotted quantity range (deg):", d.offset_halves.min(), "to", d.offset_halves.max())
offset_halves, juvenile: cells by genotype
          count  median    mean  min    max
genotype                                   
KO          236     7.0  21.983  0.0  176.0
WT          323    26.0  48.672  0.0  179.0

per rat
                 count  median    mean
genotype animal                       
KO       H3003      51     7.0  21.686
         H3008      37     5.0  10.865
         H3016      41    12.0  29.488
         H3019      15    11.0  39.667
         H3026      92     6.0  20.391
WT       H3001      31    13.0  30.161
         H3006      51    52.0  68.745
         H3009      56     6.0  19.429
         H3015      75    47.0  65.987
         H3022      47     8.0  22.617
         H3023      41    52.0  72.146
         H3029      22    27.5  55.545

tests
                                       test    n  coef_KO_minus_WT       p
0                                LME (main)  559          -24.1000  0.0353
1                LME, first day of each rat  288          -32.8744  0.0170
2                       LME, archive labels  537          -17.9190  0.1690
3                       LME, H3026 left out  467          -23.1235  0.0684
4  LME, cells with half-width below 120 deg  421          -20.4668  0.0604
5                     Mann-Whitney on cells  559          -19.0000  0.0000
6     t-test on animal means, t(10) = -2.09   12          -23.3850  0.0627
plotted quantity range (deg): 0.0 to 179.0

Result: reproduced. The offset between the two halves' tuning curves is smaller in juvenile Fmr1-/y cells (median 7 against 26 degrees; LME p = 0.035). It holds with the first day alone (p = 0.017), and not for cells with half-width below 120 degrees (p = 0.060), on rat means (t(10) = -2.09, p = 0.063), with H3026 left out (p = 0.068) or with the archive's labels (p = 0.17). With the claims file's session definition p = 0.014.

fig1j-juvenile-less-drift¶

Bayesian decoding shows less drift of the HD signal relative to the room in juvenile Fmr1-/y rats than in WT rats.

In [22]:
MIN_DRIFT_BINS = 300   # 1 min of decoded movement; a choice, shown as a variant


def drift_test(age, col):
    d = recs[(recs.age_group == age)].dropna(subset=[col])
    am = d.groupby(["subject", "genotype"])[col].mean().reset_index()
    ko, wt = am.loc[am.genotype == "KO", col], am.loc[am.genotype == "WT", col]
    t = stats.ttest_ind(ko, wt)
    return am, {"measure": col, "WT_mean": wt.mean(), "KO_mean": ko.mean(), "rats": f"{len(wt)} WT, {len(ko)} KO",
                "t": t.statistic, "df": len(am) - 2, "p": t.pvalue}
def drift_report(age):
    d = recs[recs.age_group == age]
    print("recordings without decoding (fewer than 6 cells):", d.loc[d.drift_mean.isna(), ["subject", "session", "n_cells"]].values.tolist())
    print("second-half bins of 200 ms: all, with valid tracking, with speed above 2 cm/s, and valid with speed above 2 cm/s (decoded and averaged):")
    print(d[["subject", "session", "genotype", "n_cells", "drift_bins_all", "drift_bins_valid", "drift_bins_fast", "drift_bins", "drift_mean", "drift_sd", "drift_mean_v2"]].round(2).to_string())
    rows = []
    for col in ("drift_mean", "drift_sd", "drift_mean_v2", "drift_sd_v2"):
        am, r = drift_test(age, col)
        rows.append(r)
    print("\nper rat (mean over recordings):")
    print(drift_test(age, "drift_mean")[0].round(2).to_string())
    print("\nt-tests on rat means (degrees):")
    print(pd.DataFrame(rows).round(4).to_string())
    first = recs[(recs.age_group == age) & recs.first_day].dropna(subset=["drift_mean"])
    ko, wt = first.loc[first.genotype == "KO", "drift_mean"], first.loc[first.genotype == "WT", "drift_mean"]
    t = stats.ttest_ind(ko, wt)
    print(f"variant, first day only: WT {wt.mean():.2f}, KO {ko.mean():.2f}, t({len(first) - 2}) = {t.statistic:.2f}, p = {t.pvalue:.4f}")
    arch_g = meta.set_index(["subject", "session_id"]).archive_genotype
    dd = d.dropna(subset=["drift_mean"]).copy()
    dd["genotype"] = [arch_g[(s, ss)] for s, ss in zip(dd.subject, dd.session)]
    am = dd.groupby(["subject", "genotype"]).drift_mean.mean().reset_index()
    t = stats.ttest_ind(am.loc[am.genotype == "KO", "drift_mean"], am.loc[am.genotype == "WT", "drift_mean"])
    print(f"variant, archive genotypes: t({len(am) - 2}) = {t.statistic:.2f}, p = {t.pvalue:.4f}")
    for name, sub in ((f"recordings with at least {MIN_DRIFT_BINS} averaged bins", d[d.drift_bins >= MIN_DRIFT_BINS]),
                      ("H3026 left out", d[d.subject != "H3026"])):
        if age == "adult" and name.startswith("H3026"):
            continue
        sub = sub.dropna(subset=["drift_mean"])
        am = sub.groupby(["subject", "genotype"]).drift_mean.mean().reset_index()
        ko, wt = am.loc[am.genotype == "KO", "drift_mean"], am.loc[am.genotype == "WT", "drift_mean"]
        t = stats.ttest_ind(ko, wt)
        print(f"variant, {name}: {len(wt)} WT, {len(ko)} KO rats; WT {wt.mean():.2f}, KO {ko.mean():.2f}, t({len(am) - 2}) = {t.statistic:.2f}, p = {t.pvalue:.4f}")
drift_report("juvenile")
recordings without decoding (fewer than 6 cells): [['H3019', '210618_1', 5]]
second-half bins of 200 ms: all, with valid tracking, with speed above 2 cm/s, and valid with speed above 2 cm/s (decoded and averaged):
   subject   session genotype  n_cells  drift_bins_all  drift_bins_valid  drift_bins_fast  drift_bins  drift_mean  drift_sd  drift_mean_v2
0    H3001    200201       WT       18          3000.0            2914.0            330.0       279.0       11.90     14.63          12.21
1    H3001    200202       WT       13          3000.0            2804.0            857.0       709.0       11.52     15.31          16.07
2    H3003    200207       KO       33          3000.0            2705.0           2150.0      1889.0       15.46     21.96          16.19
3    H3003    200208       KO       19          3000.0            2804.0           2047.0      1868.0        9.13     12.96           9.67
4    H3006  200314_1       WT       28          3000.0            2977.0            514.0       491.0       40.96     57.62          46.13
5    H3006  200314_2       WT       23          3000.0            2811.0           1727.0      1612.0       32.28     50.09          32.62
6    H3008    200805       KO       24          3000.0            2765.0           2711.0      2480.0        8.90     13.09           9.19
7    H3008    200807       KO       13          3000.0            2983.0           1476.0      1459.0       16.48     23.67          18.55
8    H3009    200812       WT       30          3000.0            2837.0           1267.0      1122.0       25.18     45.34          40.02
9    H3009    200813       WT       26          3000.0            2969.0            969.0       943.0       16.17     31.28          23.26
10   H3015  210416_1       WT       27          3000.0            2709.0           1385.0      1149.0       60.27     65.64          65.74
11   H3015  210416_2       WT       33          3000.0            2679.0           1412.0      1135.0       62.99     67.80          62.62
12   H3015    210417       WT       15          3000.0            2969.0           1335.0      1333.0       39.17     53.86          39.39
13   H3016    210422       KO       11          3000.0            2968.0           1338.0      1316.0       37.30     58.55          41.89
14   H3016    210423       KO       30          3000.0            2366.0           1776.0      1310.0       24.27     37.86          30.19
15   H3019    210617       KO       10          3000.0            2839.0           2214.0      2073.0       15.48     23.50          16.64
16   H3019  210618_1       KO        5             NaN               NaN              NaN         NaN         NaN       NaN            NaN
17   H3022    210805       WT       18          3000.0            2760.0           2181.0      2038.0       13.30     16.87          14.66
18   H3022    210806       WT       29          3000.0            2709.0           2174.0      1915.0       13.59     22.08          15.16
19   H3023    210812       WT       19          3000.0            2549.0           2068.0      1778.0       69.50     77.79          65.67
20   H3023  210813_1       WT       22          3000.0            1122.0           2188.0      1009.0       41.76     55.12          43.45
21   H3026    211003       KO       49          3000.0            2892.0           2463.0      2360.0       12.75     19.52          13.56
22   H3026  211004_2       KO       43          3000.0            2816.0           2001.0      1841.0       15.15     26.19          15.80
23   H3029    230510       WT       22          3000.0            3000.0           1557.0      1557.0       52.59     50.88          64.81

per rat (mean over recordings):
   subject genotype  drift_mean
0    H3001       WT       11.71
1    H3003       KO       12.29
2    H3006       WT       36.62
3    H3008       KO       12.69
4    H3009       WT       20.68
5    H3015       WT       54.14
6    H3016       KO       30.79
7    H3019       KO       15.48
8    H3022       WT       13.45
9    H3023       WT       55.63
10   H3026       KO       13.95
11   H3029       WT       52.59

t-tests on rat means (degrees):
         measure  WT_mean  KO_mean        rats       t  df       p
0     drift_mean  34.9728  17.0389  7 WT, 5 KO -1.9149  10  0.0845
1       drift_sd  43.7683  26.0811  7 WT, 5 KO -1.7142  10  0.1173
2  drift_mean_v2  39.3350  18.8341  7 WT, 5 KO -2.0835  10  0.0638
3    drift_sd_v2  48.4885  29.4186  7 WT, 5 KO -1.8337  10  0.0966
variant, first day only: WT 39.10, KO 17.98, t(10) = -1.89, p = 0.0884
variant, archive genotypes: t(10) = -1.39, p = 0.1960
variant, recordings with at least 300 averaged bins: 7 WT, 5 KO rats; WT 34.95, KO 17.04, t(10) = -1.91, p = 0.0854
variant, H3026 left out: 7 WT, 4 KO rats; WT 34.97, KO 17.81, t(9) = -1.63, p = 0.1380

Result: not reproduced. Decoder drift is lower in Fmr1-/y rats (rat means 17.0 against 35.0 degrees) but the t-test on rat means is not significant (t(10) = -1.91, p = 0.085). With version 2's 1.5 cm/s threshold p = 0.064, for the SD of drift p = 0.12, with the first day alone p = 0.088, with the archive's labels p = 0.20, with H3026 left out p = 0.14. H3019 (210618-1) is left out with 5 cells. H3001 (200201) is decoded on 279 bins, where the other recordings have 491 to 2480: only 330 of its 3000 second-half bins have a speed above 2 cm/s, though 2914 have valid tracking. Leaving out recordings under 300 bins gives p = 0.085.

figs1j-juvenile-epochs-correlation and figs1k-juvenile-epoch-drift-similar¶

In juveniles HD information is preserved between the two exploration sessions (WT r = 0.85, Fmr1-/y r = 0.85), and the drift of tuning curves between the sessions does not differ between genotypes.

In [23]:
print(corr("juvenile", "hd_info", "info_s2").round(4).to_string())
scatter("juvenile", "hd_info", "info_s2", "HD info, session 1 (bits/spike)", "HD info, session 2")
print()
t_ep = show("offset_epochs", "juvenile", log_ok=False)
  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    309     7  0.8534  0.0    0.8694       0.8708              162  (0.006, 3.176)  (0.004, 2.464)
1       KO    225     5  0.7533  0.0    0.8102       0.7340              121  (0.004, 3.413)  (0.007, 3.554)
No description has been provided for this image
plotted ranges: hd_info 0.004 to 3.413; info_s2 0.004 to 3.554 (no point outside the axes)
the ten cells farthest from the diagonal:
    subject   session genotype  unit  first_day  hd_info  info_s2   diff
202   H3009    200813       WT     1      False    2.885    0.502  2.382
36    H3003    200207       KO     6       True    0.015    2.237  2.221
506   H3026  211004_2       KO    14      False    2.996    1.136  1.859
505   H3026  211004_2       KO    13      False    1.760    3.554  1.794
43    H3003    200207       KO    13       True    2.038    0.268  1.770
526   H3026  211004_2       KO    45      False    1.709    0.186  1.523
145   H3008    200805       KO    13       True    1.797    3.251  1.454
206   H3009    200813       WT     6      False    3.176    1.782  1.394
53    H3003    200207       KO    26       True    2.222    0.831  1.391
512   H3026  211004_2       KO    22      False    2.484    1.105  1.379

offset_epochs, juvenile: cells by genotype
          count  median    mean  min    max
genotype                                   
KO          225    14.0  54.373  0.0  180.0
WT          309    21.0  46.961  0.0  180.0

per rat
                 count  median    mean
genotype animal                       
KO       H3003      50    23.5  57.880
         H3008      37     6.0  15.135
         H3016      37    12.0  28.081
         H3019      10    29.5  51.600
         H3026      91    28.0  79.396
WT       H3001      18    12.5  19.667
         H3006      51    77.0  83.569
         H3009      56     9.0  23.054
         H3015      74    46.5  60.338
         H3022      47    11.0  20.362
         H3023      41    39.0  50.634
         H3029      22    19.0  50.273

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  534            2.3135  0.8659
1            LME, first day of each rat  283           -5.6405  0.7156
2                   LME, archive labels  512          -11.6712  0.4406
3                   LME, H3026 left out  443           -7.0643  0.6015
4                 Mann-Whitney on cells  534           -7.0000  0.2245
5  t-test on animal means, t(10) = 0.17   12            2.4333  0.8694

Result: figs1j-juvenile-epochs-correlation partially reproduced; figs1k-juvenile-epoch-drift-similar reproduced. HD information correlates between the two sessions with r = 0.853 over 309 WT cells (paper 0.85) and 0.753 over 225 Fmr1-/y cells (paper 0.85, tolerance down to 0.765), so one of the two values is within tolerance. The offset between sessions does not differ between genotypes (median 14 against 21 degrees; LME p = 0.87; first day p = 0.72; archive labels p = 0.44).

fig2c-juvenile-isomap-wake-correlation and fig2d-juvenile-isomap-wake-sharper¶

In juveniles the HD information of tuning curves computed against the Isomap angle of waking population activity matches that of real HD tuning curves (WT r = 0.84, Fmr1-/y r = 0.92), and juvenile Fmr1-/y cells are better tuned than WT cells to this internal HD signal.

In [24]:
def iso_report(age):
    d = recs[recs.age_group == age]
    print("Isomap alignment with real HD (Rayleigh length of the error) per recording; recordings with fewer than 6 cells left out:")
    print(d[["subject", "session", "genotype", "n_cells", "iso_alignment", "iso_flipped"]].round(3).to_string())
    print(f"alignment range {d.iso_alignment.min():.3f} to {d.iso_alignment.max():.3f}")
    c = cells[cells.age_group == age]
    for col in ("iso_wake_info", "real200_info"):
        top = c.sort_values(col, ascending=False).groupby("genotype").head(3)
        print(f"three highest {col} per genotype:")
        print(top[["genotype", "subject", "session", "unit", "n_spikes_s1", "iso_wake_info", "real200_info", "hd_info"]].round(4).to_string())
iso_report("juvenile")
print()
print(corr("juvenile", "real200_info", "iso_wake_info").round(4).to_string())
print()
t_iso = show("iso_wake_info", "juvenile")
Isomap alignment with real HD (Rayleigh length of the error) per recording; recordings with fewer than 6 cells left out:
   subject   session genotype  n_cells  iso_alignment iso_flipped
0    H3001    200201       WT       18          0.435       False
1    H3001    200202       WT       13          0.468        True
2    H3003    200207       KO       33          0.484       False
3    H3003    200208       KO       19          0.755       False
4    H3006  200314_1       WT       28          0.301       False
5    H3006  200314_2       WT       23          0.284        True
6    H3008    200805       KO       24          0.884       False
7    H3008    200807       KO       13          0.621        True
8    H3009    200812       WT       30          0.823        True
9    H3009    200813       WT       26          0.422       False
10   H3015  210416_1       WT       27          0.381        True
11   H3015  210416_2       WT       33          0.438       False
12   H3015    210417       WT       15          0.235        True
13   H3016    210422       KO       11          0.357       False
14   H3016    210423       KO       30          0.477       False
15   H3019    210617       KO       10          0.492        True
16   H3019  210618_1       KO        5            NaN         NaN
17   H3022    210805       WT       18          0.901        True
18   H3022    210806       WT       29          0.465       False
19   H3023    210812       WT       19          0.273        True
20   H3023  210813_1       WT       22          0.402       False
21   H3026    211003       KO       49          0.688        True
22   H3026  211004_2       KO       43          0.459       False
23   H3029    230510       WT       22          0.213       False
alignment range 0.213 to 0.901
three highest iso_wake_info per genotype:
    genotype subject session  unit  n_spikes_s1  iso_wake_info  real200_info  hd_info
147       KO   H3008  200805    15         3344         2.2181        2.0773   2.3404
182       WT   H3009  200812    12          443         2.1900        2.2096   2.2445
175       WT   H3009  200812     4          463         2.0906        1.9209   1.6418
139       KO   H3008  200805     7         1039         2.0871        2.7183   3.1417
486       KO   H3026  211003    69          632         2.0658        2.4720   3.2062
191       WT   H3009  200812    23         1652         1.8906        2.1934   2.4373
three highest real200_info per genotype:
    genotype subject   session  unit  n_spikes_s1  iso_wake_info  real200_info  hd_info
302       KO   H3016    210422     1          131         1.7552        3.5599   3.5519
303       KO   H3016    210422     2          497         1.3920        2.9644   2.9878
499       KO   H3026  211004_2     7          424         1.2401        2.8223   3.4133
206       WT   H3009    200813     6          527         1.1544        2.7007   3.1762
202       WT   H3009    200813     1          352         1.4507        2.4486   2.8845
182       WT   H3009    200812    12          443         2.1900        2.2096   2.2445

  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    323     7  0.8151  0.0    0.8368       0.8213              162  (0.002, 2.701)   (0.003, 2.19)
1       KO    232     5  0.9098  0.0    0.9419       0.9162              127   (0.002, 3.56)  (0.004, 2.218)

iso_wake_info, juvenile: cells by genotype
          count  median   mean    min    max
genotype                                    
KO          232   0.416  0.585  0.004  2.218
WT          323   0.243  0.418  0.003  2.190

per rat
                 count  median   mean
genotype animal                      
KO       H3003      52   0.319  0.442
         H3008      37   0.612  0.845
         H3016      41   0.472  0.634
         H3019      10   0.319  0.435
         H3026      92   0.420  0.555
WT       H3001      31   0.318  0.389
         H3006      51   0.154  0.258
         H3009      56   0.547  0.682
         H3015      75   0.390  0.493
         H3022      47   0.276  0.476
         H3023      41   0.095  0.148
         H3029      22   0.199  0.273

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  555            0.1964  0.0556
1                     LME on log values  555            0.3637  0.1312
2            LME, first day of each rat  289            0.2513  0.1452
3                   LME, archive labels  533            0.1681  0.1377
4                   LME, H3026 left out  463            0.2071  0.0747
5                 Mann-Whitney on cells  555            0.1735  0.0007
6  t-test on animal means, t(10) = 1.89   12            0.1936  0.0885
In [25]:
# Isomap fitted on at most 3000 bins (as in the first round of this attempt), beside the fit on every bin used in
# the analysis, for the recording with the most cells in each age group
seed_of = {(m["subject"], m["session_id"]): k for k, m in enumerate(meta.to_dict("records"))}
fit_rows = []
for age in ("juvenile", "adult"):
    rr_ = recs[recs.age_group == age].sort_values("n_cells").iloc[-1]
    k = seed_of[(rr_.subject, rr_.session)]
    s_ = hdfx.load_session(assets.asset_id[k])
    sub_ = hdfx.analyse(s_, age, seed=k, fit_max=3000)["cells"].set_index("unit")
    full_ = cells[(cells.subject == rr_.subject) & (cells.session == rr_.session)].set_index("unit")
    for col in ("iso_wake_info", "iso_rem_info"):
        b_ = full_[col].dropna()
        a_ = sub_[col].reindex(b_.index)
        fit_rows.append({"recording": f"{rr_.subject} {rr_.session}", "age": age, "measure": col, "cells": len(b_),
                         "median_full": b_.median(), "median_3000_bins": a_.median(),
                         "r_full_vs_3000": stats.pearsonr(a_, b_)[0],
                         "r_with_real200_full": stats.pearsonr(full_.loc[b_.index, "real200_info"], b_)[0] if col == "iso_wake_info" else np.nan,
                         "r_with_real200_3000": stats.pearsonr(full_.loc[b_.index, "real200_info"], a_)[0] if col == "iso_wake_info" else np.nan})
    del s_
print(pd.DataFrame(fit_rows).round(3).to_string())
      recording       age        measure  cells  median_full  median_3000_bins  r_full_vs_3000  r_with_real200_full  r_with_real200_3000
0  H3026 211003  juvenile  iso_wake_info     49        0.435             0.546           0.987                0.978                0.982
1  H3026 211003  juvenile   iso_rem_info     49        0.452             0.477           0.996                  NaN                  NaN
2  H4823 221108     adult  iso_wake_info     80        0.360             0.359           0.998                0.978                0.978
3  H4823 221108     adult   iso_rem_info     63        0.434             0.434           1.000                  NaN                  NaN

Result: fig2c-juvenile-isomap-wake-correlation reproduced; fig2d-juvenile-isomap-wake-sharper not reproduced. The HD information of Isomap tuning curves correlates with that of real-HD curves with r = 0.815 in WT and 0.910 in Fmr1-/y (paper 0.84 and 0.92). Isomap HD information is higher in Fmr1-/y cells (median 0.416 against 0.243 bits/spike) but the LME test is not significant (p = 0.056); no variant that keeps the rat is below 0.05 (log values p = 0.13, first day p = 0.15, archive labels p = 0.14, H3026 left out p = 0.075, rat means p = 0.089), and only the Mann-Whitney test on cells is (p = 0.0007). The direction matches the paper. The Isomap angle aligned with real HD with Rayleigh lengths of 0.21 to 0.90. Isomap is fitted on every bin; fitting it on 3000 bins, as in the first round of this attempt, raises the median Isomap information of H3026 211003 from 0.435 to 0.546 bits/spike (r = 0.987 across its cells), while in H4823 the two fits agree (0.360 and 0.359).

fig2g-juvenile-isomap-rem-correlation and fig2h-juvenile-isomap-rem-sharper¶

In juveniles the HD information of tuning curves computed against the Isomap angle of REM activity matches that of real HD tuning curves (WT r = 0.73, Fmr1-/y r = 0.90), and juvenile Fmr1-/y cells are better tuned than WT cells to the internally generated signal during REM.

In [26]:
d = recs[recs.age_group == "juvenile"]
print(d[["subject", "session", "genotype", "rem_s", "n_cells_rem", "rem_bins", "rem_in_sessions", "rem_in_sessions_s"]].to_string())
print()
print(corr("juvenile", "real200_info", "iso_rem_info").round(4).to_string())
print()
t_rem = show("iso_rem_info", "juvenile",
             extra=("LME, REM inside exploration left out", cells[cells.age_group == "juvenile"], "iso_rem_info_outside"))
print("\nvariant, REM inside exploration left out:")
print(corr("juvenile", "real200_info", "iso_rem_info_outside").round(4).to_string())
   subject   session genotype   rem_s  n_cells_rem  rem_bins  rem_in_sessions  rem_in_sessions_s
0    H3001    200201       WT   983.0         18.0    4915.0              1.0               14.0
1    H3001    200202       WT  1706.0         13.0    8530.0              0.0                0.0
2    H3003    200207       KO  1163.0         32.0    5815.0              0.0                0.0
3    H3003    200208       KO  1192.0         19.0    5960.0              0.0                0.0
4    H3006  200314_1       WT  1030.0         28.0    5150.0              0.0                0.0
5    H3006  200314_2       WT   690.0         23.0    3450.0              0.0                0.0
6    H3008    200805       KO   640.0         24.0    3200.0              0.0                0.0
7    H3008    200807       KO   630.0         13.0    3150.0              0.0                0.0
8    H3009    200812       WT  1035.0         30.0    5175.0              0.0                0.0
9    H3009    200813       WT   906.0         26.0    4530.0              0.0                0.0
10   H3015  210416_1       WT  1291.0         27.0    6455.0              2.0               21.0
11   H3015  210416_2       WT  1004.0         33.0    5020.0              4.0               49.0
12   H3015    210417       WT  1066.0         15.0    5330.0              0.0                0.0
13   H3016    210422       KO   689.0         11.0    3445.0              0.0                0.0
14   H3016    210423       KO   764.0         30.0    3820.0              1.0               13.0
15   H3019    210617       KO   644.0         10.0    3220.0              0.0                0.0
16   H3019  210618_1       KO     NaN          NaN       NaN              NaN                NaN
17   H3022    210805       WT  1178.0         18.0    5890.0              0.0                0.0
18   H3022    210806       WT  1409.0         29.0    7045.0              0.0                0.0
19   H3023    210812       WT   593.0         19.0    2965.0              0.0                0.0
20   H3023  210813_1       WT  1337.0         22.0    6685.0              1.0               13.0
21   H3026    211003       KO   850.0         49.0    4250.0              0.0                0.0
22   H3026  211004_2       KO   539.0         43.0    2695.0              0.0                0.0
23   H3029    230510       WT  1037.0         22.0    5185.0              0.0                0.0

  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    323     7  0.8311  0.0    0.7756       0.8269              162  (0.002, 2.701)  (0.005, 2.388)
1       KO    231     5  0.8332  0.0    0.8871       0.8651              126   (0.002, 3.56)  (0.004, 2.404)

iso_rem_info, juvenile: cells by genotype
          count  median   mean    min    max
genotype                                    
KO          231   0.401  0.597  0.004  2.404
WT          323   0.169  0.394  0.005  2.388

per rat
                 count  median   mean
genotype animal                      
KO       H3003      51   0.359  0.532
         H3008      37   0.425  0.681
         H3016      41   0.305  0.578
         H3019      10   0.240  0.418
         H3026      92   0.447  0.628
WT       H3001      31   0.310  0.435
         H3006      51   0.079  0.303
         H3009      56   0.566  0.765
         H3015      75   0.221  0.366
         H3022      47   0.213  0.406
         H3023      41   0.048  0.134
         H3029      22   0.078  0.163

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  554            0.2066  0.0451
1                     LME on log values  554            0.5431  0.0915
2            LME, first day of each rat  288            0.1997  0.1578
3                   LME, archive labels  532            0.1279  0.2527
4                   LME, H3026 left out  462            0.1914  0.0949
5  LME, REM inside exploration left out  554            0.2068  0.0450
6                 Mann-Whitney on cells  554            0.2318  0.0000
7  t-test on animal means, t(10) = 1.95   12            0.1999  0.0791

variant, REM inside exploration left out:
  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    323     7  0.8307  0.0    0.7742       0.8277              162  (0.002, 2.701)  (0.004, 2.388)
1       KO    231     5  0.8306  0.0    0.8870       0.8651              126   (0.002, 3.56)  (0.004, 2.404)

Result: fig2g-juvenile-isomap-rem-correlation partially reproduced; fig2h-juvenile-isomap-rem-sharper reproduced. The HD information of REM Isomap tuning curves correlates with that of waking real-HD curves with r = 0.833 in Fmr1-/y (paper 0.90, within tolerance) and 0.831 in WT (paper 0.73, above the tolerance of 0.657 to 0.803). REM Isomap HD information is higher in Fmr1-/y cells (median 0.401 against 0.169 bits/spike; LME p = 0.045). The result is at the threshold: on log values p = 0.092, with the first day alone p = 0.16, with the archive's labels p = 0.25, with H3026 left out p = 0.095, on rat means p = 0.079; leaving out the REM intervals inside exploration sessions gives p = 0.045.

fig3ef-adult-tuning-similar¶

In adults HD tuning does not differ between Fmr1-/y and WT rats, in HD information or tuning curve width.

In [27]:
a_info = show("hd_info", "adult", uniform_col="hd_info_uniform")
print("=" * 100)
a_hw = show("half_width", "adult")
hd_info, adult: cells by genotype
          count  median   mean    min    max
genotype                                    
KO          282   0.193  0.375  0.003  2.466
WT          395   0.318  0.453  0.003  3.066

per rat
                 count  median   mean
genotype animal                      
KO       H4817      72   0.120  0.198
         H4819      71   0.346  0.479
         H4822      30   0.089  0.120
         H4824      57   0.158  0.228
         H4827      52   0.618  0.784
WT       H4813      54   0.418  0.500
         H4815      76   0.282  0.455
         H4820      51   0.081  0.158
         H4823      80   0.412  0.496
         H4826      72   0.575  0.701
         H4830      62   0.186  0.310

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  677           -0.0738  0.5534
1                     LME on log values  677           -0.2601  0.4681
2                   LME, archive labels  702           -0.0380  0.7561
3           LME, uniform occupancy (v2)  677           -0.0874  0.4762
4                 Mann-Whitney on cells  677           -0.1254  0.0095
5  t-test on animal means, t(9) = -0.54   11           -0.0750  0.5996
====================================================================================================
half_width, adult: cells by genotype
          count  median     mean   min    max
genotype                                     
KO          282    78.0  123.234  20.0  360.0
WT          395    76.0  131.691  20.0  360.0

per rat
                 count  median     mean
genotype animal                        
KO       H4817      72    84.0  134.028
         H4819      71    96.0  118.930
         H4822      30   100.0  145.200
         H4824      57    86.0  134.737
         H4827      52    51.0   88.885
WT       H4813      54    64.0  111.185
         H4815      76    80.0  132.447
         H4820      51   164.0  213.765
         H4823      80    62.0  121.775
         H4826      72    51.0   79.333
         H4830      62   104.0  154.710

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  677          -10.9023  0.5903
1                     LME on log values  677           -0.1010  0.5267
2                   LME, archive labels  702          -15.2640  0.4403
3                 Mann-Whitney on cells  677            2.0000  0.2574
4  t-test on animal means, t(9) = -0.50   11          -11.1801  0.6303

Result: reproduced. In adults neither HD information (median 0.193 in Fmr1-/y against 0.318 in WT; LME p = 0.55) nor half-width (78 against 76 degrees; p = 0.59) differs between genotypes. The Mann-Whitney test on cells finds lower HD information in Fmr1-/y cells (p = 0.0095).

fig3g-adult-halves-correlation¶

In adults HD information is stable between the two halves of an exploration session (WT r = 0.94, Fmr1-/y r = 0.94).

In [28]:
print(corr("adult", "info_half1", "info_half2").round(4).to_string())
scatter("adult", "info_half1", "info_half2", "HD info, first half (bits/spike)", "HD info, second half")
  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    395     6  0.8038  0.0    0.8623       0.8038              395  (0.005, 3.116)  (0.005, 4.252)
1       KO    282     5  0.7477  0.0    0.8184       0.7477              282  (0.003, 2.926)  (0.004, 3.878)
No description has been provided for this image
plotted ranges: info_half1 0.003 to 3.116; info_half2 0.004 to 4.252 (no point outside the axes)
the ten cells farthest from the diagonal:
     subject session genotype  unit  first_day  info_half1  info_half2   diff
633    H4815  220814       WT    26       True       1.517       4.252  2.735
1069   H4826  221203       WT    30       True       1.323       3.707  2.384
677    H4815  220814       WT    83       True       1.918       4.131  2.213
1033   H4824  221117       KO    64       True       1.069       3.194  2.125
1045   H4824  221117       KO    81       True       0.544       2.447  1.903
1129   H4827  221210       KO     9       True       1.543       3.361  1.819
746    H4817  220828       KO    77       True       0.637       2.425  1.788
1142   H4827  221210       KO    31       True       2.194       3.878  1.684
867    H4820  221007       WT    37       True       0.332       1.838  1.506
1046   H4824  221117       KO    82       True       0.387       1.853  1.466

Result: not reproduced. In adults HD information correlates between the two halves of a session with r = 0.804 over 395 WT cells and 0.748 over 282 Fmr1-/y cells, both below the lower bound of 0.846 around the paper's 0.94. Spearman correlations are 0.862 and 0.818. The cells farthest from the diagonal have higher information in the second half and come from several rats of both genotypes.

fig3h-adult-larger-offset¶

Within a session the tuning curves of adult Fmr1-/y cells drift more relative to the room than those of WT cells.

In [29]:
d = cells[cells.age_group == "adult"]
a_off = show("offset_halves", "adult", log_ok=False,
             extra=("LME, cells with half-width below 120 deg", d[d.half_width < 120]))
offset_halves, adult: cells by genotype
          count  median    mean  min    max
genotype                                   
KO          282    60.0  68.340  1.0  175.0
WT          395    20.0  37.754  0.0  176.0

per rat
                 count  median     mean
genotype animal                        
KO       H4817      72   104.0  101.083
         H4819      71    38.0   44.803
         H4822      30    95.0  101.100
         H4824      57    82.0   78.877
         H4827      52    16.0   24.692
WT       H4813      54    12.0   32.556
         H4815      76    41.0   56.618
         H4820      51    13.0   40.784
         H4823      80    13.5   26.638
         H4826      72    12.0   28.792
         H4830      62    27.0   41.419

tests
                                       test    n  coef_KO_minus_WT       p
0                                LME (main)  677           32.0549  0.0298
1                       LME, archive labels  702           28.5177  0.0433
2  LME, cells with half-width below 120 deg  466           42.7367  0.0169
3                     Mann-Whitney on cells  677           40.0000  0.0000
4       t-test on animal means, t(9) = 2.20   11           32.3100  0.0556

Result: reproduced. The offset between the halves is larger in adult Fmr1-/y cells (median 60 against 20 degrees; LME p = 0.030), with the archive's labels (p = 0.043) and for cells with half-width below 120 degrees (p = 0.017); on rat means it is not significant (t(9) = 2.20, p = 0.056).

fig3j-adult-more-drift¶

Bayesian decoding shows more drift of the HD signal relative to the room in adult Fmr1-/y rats than in WT rats.

In [30]:
drift_report("adult")
recordings without decoding (fewer than 6 cells): []
second-half bins of 200 ms: all, with valid tracking, with speed above 2 cm/s, and valid with speed above 2 cm/s (decoded and averaged):
   subject session genotype  n_cells  drift_bins_all  drift_bins_valid  drift_bins_fast  drift_bins  drift_mean  drift_sd  drift_mean_v2
24   H4813  220728       WT       54          3000.0            2996.0           1888.0      1884.0       17.18     29.44          18.74
25   H4815  220814       WT       76          3000.0            2983.0           1777.0      1760.0       23.01     19.80          23.61
26   H4817  220828       KO       72          3000.0            2945.0           1568.0      1513.0       98.23     52.22         100.90
27   H4819  220929       KO       71          3000.0            2998.0           1322.0      1320.0       32.90     20.92          34.00
28   H4820  221007       WT       51          3000.0            2958.0           1980.0      1939.0       18.76     28.23          19.14
29   H4822  221023       KO       30          3000.0            2919.0           2099.0      2032.0      101.21    110.90         100.96
30   H4823  221108       WT       80          3000.0            3000.0           1019.0      1019.0       11.26     10.14          11.68
31   H4824  221117       KO       57          3000.0            2985.0           1325.0      1310.0       91.40     52.03          80.53
32   H4826  221203       WT       72          3000.0            2980.0            774.0       759.0       13.02     20.90          13.69
33   H4827  221210       KO       52          3000.0            2990.0           1713.0      1703.0       18.34     18.66          22.01
34   H4830  230406       WT       62          3000.0            2995.0           1911.0      1906.0       37.12     27.36          39.30

per rat (mean over recordings):
   subject genotype  drift_mean
0    H4813       WT       17.18
1    H4815       WT       23.01
2    H4817       KO       98.23
3    H4819       KO       32.90
4    H4820       WT       18.76
5    H4822       KO      101.21
6    H4823       WT       11.26
7    H4824       KO       91.40
8    H4826       WT       13.02
9    H4827       KO       18.34
10   H4830       WT       37.12

t-tests on rat means (degrees):
         measure  WT_mean  KO_mean        rats       t  df       p
0     drift_mean  20.0587  68.4162  6 WT, 5 KO  2.9272   9  0.0168
1       drift_sd  22.6472  50.9439  6 WT, 5 KO  1.8395   9  0.0990
2  drift_mean_v2  21.0253  67.6784  6 WT, 5 KO  2.9625   9  0.0159
3    drift_sd_v2  23.7104  55.4434  6 WT, 5 KO  2.1580   9  0.0593
variant, first day only: WT 20.06, KO 68.42, t(9) = 2.93, p = 0.0168
variant, archive genotypes: t(9) = 2.93, p = 0.0168
variant, recordings with at least 300 averaged bins: 6 WT, 5 KO rats; WT 20.06, KO 68.42, t(9) = 2.93, p = 0.0168

Result: reproduced. Decoder drift is higher in adult Fmr1-/y rats (rat means 68.4 against 20.1 degrees; t(9) = 2.93, p = 0.017; with version 2's threshold p = 0.016; for the SD of drift p = 0.099), over 5 Fmr1-/y rats where the paper has 6. Three Fmr1-/y rats drift by 91 to 101 degrees, and two (H4819 at 32.9, H4827 at 18.3) lie within the WT range of 11.3 to 37.1.

figs2j-adult-epochs-correlation and figs2k-adult-epoch-drift-larger¶

In adults HD information is preserved between the two exploration sessions (WT r = 0.90, Fmr1-/y r = 0.76), and Fmr1-/y tuning curves drift more than WT ones between the sessions.

In [31]:
print(corr("adult", "hd_info", "info_s2").round(4).to_string())
scatter("adult", "hd_info", "info_s2", "HD info, session 1 (bits/spike)", "HD info, session 2")
print()
a_ep = show("offset_epochs", "adult", log_ok=False)
  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day         x_range         y_range
0       WT    395     6  0.7866  0.0    0.8879       0.7866              395  (0.003, 3.066)  (0.004, 3.401)
1       KO    276     5  0.5617  0.0    0.7144       0.5617              276  (0.003, 2.466)   (0.003, 3.21)
No description has been provided for this image
plotted ranges: hd_info 0.003 to 3.066; info_s2 0.003 to 3.401 (no point outside the axes)
the ten cells farthest from the diagonal:
     subject session genotype  unit  first_day  hd_info  info_s2   diff
746    H4817  220828       KO    77       True    0.768    3.210  2.443
895    H4822  221023       KO    26       True    0.131    2.422  2.291
717    H4817  220828       KO    35       True    0.740    2.904  2.164
713    H4817  220828       KO    30       True    0.359    2.325  1.966
934    H4823  221108       WT    31       True    0.568    2.462  1.894
725    H4817  220828       KO    43       True    0.173    1.951  1.777
984    H4823  221108       WT   101       True    1.294    2.963  1.669
723    H4817  220828       KO    41       True    0.674    2.299  1.624
677    H4815  220814       WT    83       True    2.537    1.013  1.524
1021   H4824  221117       KO    47       True    0.200    1.669  1.469

offset_epochs, adult: cells by genotype
          count  median    mean  min    max
genotype                                   
KO          276    74.0  79.949  0.0  178.0
WT          395    30.0  42.625  0.0  174.0

per rat
                 count  median     mean
genotype animal                        
KO       H4817      70    79.0   74.143
         H4819      68    50.0   61.397
         H4822      29    17.0   41.276
         H4824      57    91.0   79.316
         H4827      52   151.0  134.288
WT       H4813      54    25.0   38.000
         H4815      76    33.0   36.816
         H4820      51     7.0   16.333
         H4823      80    22.5   38.100
         H4826      72    77.5   78.625
         H4830      62    30.0   39.435

tests
                                  test    n  coef_KO_minus_WT       p
0                           LME (main)  671           37.0213  0.0282
1                  LME, archive labels  696           35.9699  0.0222
2                Mann-Whitney on cells  671           44.0000  0.0000
3  t-test on animal means, t(9) = 2.20   11           36.8657  0.0550

Result: figs2j-adult-epochs-correlation not reproduced; figs2k-adult-epoch-drift-larger reproduced. HD information correlates between the sessions with r = 0.787 over 395 WT cells and 0.562 over 276 Fmr1-/y cells, both below the lower bounds (0.81 and 0.684), though lower in Fmr1-/y as in the paper (0.90 and 0.76). Spearman correlations are 0.888 and 0.714; five of the ten cells farthest from the diagonal are from H4817, whose cells gain information in session 2. The offset between the sessions is larger in Fmr1-/y cells (median 74 against 30 degrees; LME p = 0.028; archive labels p = 0.022; rat means p = 0.055).

fig4c-adult-isomap-wake-correlation and fig4d-adult-isomap-wake-similar¶

In adults the HD information of Isomap tuning curves from waking activity matches that of real HD tuning curves (WT r = 0.95, Fmr1-/y r = 0.90), and does not differ between genotypes.

In [32]:
iso_report("adult")
print()
print(corr("adult", "real200_info", "iso_wake_info").round(4).to_string())
print()
a_iso = show("iso_wake_info", "adult")
Isomap alignment with real HD (Rayleigh length of the error) per recording; recordings with fewer than 6 cells left out:
   subject session genotype  n_cells  iso_alignment iso_flipped
24   H4813  220728       WT       54          0.679        True
25   H4815  220814       WT       76          0.871        True
26   H4817  220828       KO       72          0.386        True
27   H4819  220929       KO       71          0.681        True
28   H4820  221007       WT       51          0.476        True
29   H4822  221023       KO       30          0.152        True
30   H4823  221108       WT       80          0.872       False
31   H4824  221117       KO       57          0.224       False
32   H4826  221203       WT       72          0.884       False
33   H4827  221210       KO       52          0.612        True
34   H4830  230406       WT       62          0.807        True
alignment range 0.152 to 0.884
three highest iso_wake_info per genotype:
     genotype subject session  unit  n_spikes_s1  iso_wake_info  real200_info  hd_info
677        WT   H4815  220814    83         1466         2.6395        2.2890   2.5370
1088       WT   H4826  221203    53          451         2.5312        2.8304   3.0664
633        WT   H4815  220814    26         1203         2.4450        2.0818   2.1810
741        KO   H4817  220828    72          620         2.4165        0.4972   0.6352
749        KO   H4817  220828    80          534         2.3580        0.6689   0.8583
711        KO   H4817  220828    27         1281         2.0932        0.4531   0.5184
three highest real200_info per genotype:
     genotype subject session  unit  n_spikes_s1  iso_wake_info  real200_info  hd_info
1088       WT   H4826  221203    53          451         2.5312        2.8304   3.0664
1142       KO   H4827  221210    31         1099         1.6173        2.2899   2.4662
677        WT   H4815  220814    83         1466         2.6395        2.2890   2.5370
633        WT   H4815  220814    26         1203         2.4450        2.0818   2.1810
1171       KO   H4827  221210    73         1032         1.7040        2.0792   2.3627
1129       KO   H4827  221210     9          393         1.4844        2.0709   2.1712

  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day        x_range         y_range
0       WT    395     6  0.9447  0.0    0.9560       0.9447              395  (0.001, 2.83)  (0.003, 2.639)
1       KO    282     5  0.6139  0.0    0.7614       0.6139              282  (0.003, 2.29)  (0.004, 2.417)

iso_wake_info, adult: cells by genotype
          count  median   mean    min    max
genotype                                    
KO          282   0.279  0.455  0.004  2.417
WT          395   0.336  0.477  0.003  2.639

per rat
                 count  median   mean
genotype animal                      
KO       H4817      72   0.538  0.661
         H4819      71   0.248  0.354
         H4822      30   0.248  0.357
         H4824      57   0.230  0.322
         H4827      52   0.307  0.509
WT       H4813      54   0.323  0.424
         H4815      76   0.398  0.559
         H4820      51   0.162  0.248
         H4823      80   0.360  0.481
         H4826      72   0.472  0.624
         H4830      62   0.275  0.435

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  677           -0.0203  0.7869
1                     LME on log values  677           -0.0305  0.8542
2                   LME, archive labels  702            0.0058  0.9403
3                 Mann-Whitney on cells  677           -0.0564  0.3986
4  t-test on animal means, t(9) = -0.26   11           -0.0210  0.8041

Result: fig4c-adult-isomap-wake-correlation partially reproduced; fig4d-adult-isomap-wake-similar reproduced. Isomap and real-HD information correlate with r = 0.945 in WT (paper 0.95, within tolerance) and 0.614 in Fmr1-/y (paper 0.90, outside). Isomap HD information does not differ between genotypes (median 0.279 in Fmr1-/y against 0.336 in WT; LME p = 0.79; rat means p = 0.80). The Isomap angle aligned poorly with real HD in H4822 (0.152), H4824 (0.224) and H4817 (0.386), the three Fmr1-/y rats with the largest decoder drift; the three Fmr1-/y cells with the highest Isomap information are from H4817 and carry little real-HD information (0.45 to 0.67 bits/spike).

fig4g-adult-isomap-rem-correlation and fig4h-adult-isomap-rem-similar¶

In adults the HD information of Isomap tuning curves from REM activity matches that of real HD tuning curves (WT r = 0.82, Fmr1-/y r = 0.80), and does not differ between genotypes.

In [33]:
d = recs[recs.age_group == "adult"]
print(d[["subject", "session", "genotype", "rem_s", "n_cells_rem", "rem_bins", "rem_in_sessions", "rem_in_sessions_s"]].to_string())
print()
print(corr("adult", "real200_info", "iso_rem_info").round(4).to_string())
print()
a_rem = show("iso_rem_info", "adult",
             extra=("LME, REM inside exploration left out", cells[cells.age_group == "adult"], "iso_rem_info_outside"))
print("\nvariant, REM inside exploration left out:")
print(corr("adult", "real200_info", "iso_rem_info_outside").round(4).to_string())
print(f"\nrun time so far {time.time() - started:.0f} s")
   subject session genotype       rem_s  n_cells_rem  rem_bins  rem_in_sessions  rem_in_sessions_s
24   H4813  220728       WT  988.000000         54.0    4940.0              0.0           0.000000
25   H4815  220814       WT  406.000000         76.0    2030.0              0.0           0.000000
26   H4817  220828       KO  756.000000         72.0    3780.0              0.0           0.000000
27   H4819  220929       KO  819.000000         70.0    4095.0              0.0           0.000000
28   H4820  221007       WT  408.000000         51.0    2040.0              0.0           0.000000
29   H4822  221023       KO  457.380767         29.0    2287.0              3.0         196.380767
30   H4823  221108       WT  116.000000         63.0     580.0              0.0           0.000000
31   H4824  221117       KO  518.000000         57.0    2590.0              0.0           0.000000
32   H4826  221203       WT  337.000000         72.0    1685.0              0.0           0.000000
33   H4827  221210       KO  391.000000         52.0    1955.0              0.0           0.000000
34   H4830  230406       WT  133.000000         62.0     665.0              0.0           0.000000

  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day        x_range         y_range
0       WT    378     6  0.8201  0.0    0.8306       0.8201              378  (0.001, 2.83)   (0.003, 2.66)
1       KO    280     5  0.6505  0.0    0.7043       0.6505              280  (0.003, 2.29)  (0.002, 2.356)

iso_rem_info, adult: cells by genotype
          count  median   mean    min    max
genotype                                    
KO          280   0.413  0.517  0.002  2.356
WT          378   0.332  0.462  0.003  2.660

per rat
                 count  median   mean
genotype animal                      
KO       H4817      72   0.288  0.454
         H4819      70   0.443  0.517
         H4822      29   0.604  0.656
         H4824      57   0.329  0.428
         H4827      52   0.500  0.623
WT       H4813      54   0.302  0.451
         H4815      76   0.353  0.462
         H4820      51   0.154  0.250
         H4823      63   0.434  0.536
         H4826      72   0.484  0.634
         H4830      62   0.241  0.374

tests
                                   test    n  coef_KO_minus_WT       p
0                            LME (main)  658            0.0724  0.2677
1                     LME on log values  658            0.1533  0.4068
2                   LME, archive labels  683            0.1095  0.1416
3  LME, REM inside exploration left out  658            0.0227  0.7278
4                 Mann-Whitney on cells  658            0.0807  0.1611
5   t-test on animal means, t(9) = 1.17   11            0.0845  0.2722

variant, REM inside exploration left out:
  genotype  cells  rats       r    p  spearman  r_first_day  cells_first_day        x_range         y_range
0       WT    378     6  0.8201  0.0    0.8306       0.8201              378  (0.001, 2.83)   (0.003, 2.66)
1       KO    280     5  0.6905  0.0    0.7713       0.6905              280  (0.003, 2.29)  (0.002, 2.356)

run time so far 860 s

Result: fig4g-adult-isomap-rem-correlation partially reproduced; fig4h-adult-isomap-rem-similar reproduced. REM Isomap and waking real-HD information correlate with r = 0.820 over 378 WT cells (paper 0.82) and 0.651 over 280 Fmr1-/y cells (paper 0.80, below the bound of 0.72; 0.691 with the REM inside exploration left out). REM Isomap HD information does not differ between genotypes (median 0.413 in Fmr1-/y against 0.332 in WT; LME p = 0.27; with the REM inside exploration left out p = 0.73).

Session definition of the claims file¶

The analysis above cuts every exploration session to its first 20 min. The claims file defines the sessions as the same tracking blocks but cuts only a block longer than 30 min, to its first 1300 s. This cell repeats the main test of every claim with the claims file's definition, beside the 20 min sessions used above.

In [34]:
def rule_tables(key):
    cr, rr = [], []
    for r in results:
        m = r["meta"]
        if r[key] is None:
            continue
        base = {"subject": m["subject"], "session": m["session_id"], "age_group": m["age_group"], "genotype": m["genotype"],
                "first_day": first_day[m["subject"]] == m["session_id"]}
        rr.append({**base, **r[key]["rec"]})
        c = r[key]["cells"].copy()
        for k, v in base.items():
            c[k] = v
        cr.append(c)
    c = pd.concat(cr, ignore_index=True)
    c["animal"] = c.subject
    return c, pd.DataFrame(rr)


def main_stats(c, rc):
    rows = []
    def lme(claim, age, col):
        d = c[c.age_group == age]
        coef, p, n = hdfx.lme_lrt(d, col)
        rows.append({"claim": claim, "quantity": f"{col}: LME coef KO-WT; p", "value": f"{coef:.3f}; {p:.4f}", "n": n})
    def rr(claim, age, x, y):
        d = c[c.age_group == age].dropna(subset=[x, y])
        for g in ("WT", "KO"):
            e = d[d.genotype == g]
            rows.append({"claim": claim, "quantity": f"r {g}", "value": f"{stats.pearsonr(e[x], e[y])[0]:.4f}", "n": len(e)})
    def rat_t(claim, age, col):
        am = rc[rc.age_group == age].dropna(subset=[col]).groupby(["subject", "genotype"])[col].mean().reset_index()
        ko, wt = am.loc[am.genotype == "KO", col], am.loc[am.genotype == "WT", col]
        t = stats.ttest_ind(ko, wt)
        rows.append({"claim": claim, "quantity": f"{col}: rat means t; p", "value": f"{t.statistic:.2f}; {t.pvalue:.4f}", "n": len(am)})
    for age, beh, met in (("juvenile", "figs1c", "figs1"), ("adult", "figs2c", "figs2")):
        for col in ("inactive", "centre", "active_speed"):
            rat_t(beh, age, col)
        for col in ("contamination", "mean_rate", "peak_rate", "vector_length"):
            lme(met, age, col)
    j = {"tuning": "fig1ef", "halves": "fig1g", "offset": "fig1h", "drift": "fig1j", "epochs_r": "figs1j", "epochs_off": "figs1k",
         "iso_r": "fig2c", "iso": "fig2d", "rem_r": "fig2g", "rem": "fig2h"}
    a = {"tuning": "fig3ef", "halves": "fig3g", "offset": "fig3h", "drift": "fig3j", "epochs_r": "figs2j", "epochs_off": "figs2k",
         "iso_r": "fig4c", "iso": "fig4d", "rem_r": "fig4g", "rem": "fig4h"}
    for age, n in (("juvenile", j), ("adult", a)):
        lme(n["tuning"], age, "hd_info")
        lme(n["tuning"], age, "half_width")
        rr(n["halves"], age, "info_half1", "info_half2")
        lme(n["offset"], age, "offset_halves")
        rat_t(n["drift"], age, "drift_mean")
        rr(n["epochs_r"], age, "hd_info", "info_s2")
        lme(n["epochs_off"], age, "offset_epochs")
        rr(n["iso_r"], age, "real200_info", "iso_wake_info")
        lme(n["iso"], age, "iso_wake_info")
        rr(n["rem_r"], age, "real200_info", "iso_rem_info")
        lme(n["rem"], age, "iso_rem_info")
    return pd.DataFrame(rows)


cells_cf, recs_cf = rule_tables("claims_rule")
lens = recs[["subject", "session", "age_group", "genotype", "session_s"]].merge(
    recs_cf[["subject", "session", "session_s", "n_cells"]], on=["subject", "session"], suffixes=("_20min", "_claims"))
lens["n_cells_20min"] = recs.n_cells.values
print("session lengths (s) under the two definitions, and cells of session 1:")
print(lens.to_string())
print("\nrecordings whose sessions differ:", int((lens.session_s_20min.astype(str) != lens.session_s_claims.astype(str)).sum()), "of", len(lens))
print("cells per group, claims file definition:")
print(cells_cf.groupby(["age_group", "genotype"]).agg(rats=("subject", "nunique"), cells=("unit", "size")).to_string())
cmp = main_stats(cells, recs).merge(main_stats(cells_cf, recs_cf), on=["claim", "quantity"], suffixes=("_20min", "_claims"))
print("\nmain test of each claim under the two session definitions:")
print(cmp.to_string())
cj = cells_cf[cells_cf.age_group == "juvenile"]
print("\nvariants under the claims file definition, juveniles:")
for name, d in (("first day", cj[cj.first_day]), ("H3026 left out", cj[cj.subject != "H3026"])):
    for col in ("hd_info", "offset_halves", "iso_wake_info", "iso_rem_info"):
        coef, p, n = hdfx.lme_lrt(d, col)
        print(f"  {name}, {col}: coef {coef:.3f}, p = {p:.4f} (n = {n})")
    for g in ("WT", "KO"):
        e = d[d.genotype == g].dropna(subset=["info_half1", "info_half2"])
        print(f"  {name}, halves r {g}: {stats.pearsonr(e.info_half1, e.info_half2)[0]:.4f} ({len(e)} cells)")
session lengths (s) under the two definitions, and cells of session 1:
   subject   session age_group genotype   session_s_20min  session_s_claims  n_cells  n_cells_20min
0    H3001    200201  juvenile       WT  [1200.0, 1200.0]  [1662.8, 1527.1]       18             18
1    H3001    200202  juvenile       WT          [1200.0]          [1300.0]       13             13
2    H3003    200207  juvenile       KO  [1200.0, 1183.6]  [1227.2, 1183.6]       33             33
3    H3003    200208  juvenile       KO  [1200.0, 1200.0]  [1203.6, 1201.6]       19             19
4    H3006  200314_1  juvenile       WT  [1200.0, 1200.0]  [1271.9, 1511.7]       28             28
5    H3006  200314_2  juvenile       WT  [1200.0, 1121.3]  [1208.5, 1121.3]       23             23
6    H3008    200805  juvenile       KO  [1200.0, 1200.0]  [1273.4, 1211.9]       24             24
7    H3008    200807  juvenile       KO  [1200.0, 1200.0]  [1238.0, 1245.8]       13             13
8    H3009    200812  juvenile       WT  [1200.0, 1200.0]  [1304.9, 1278.9]       30             30
9    H3009    200813  juvenile       WT  [1200.0, 1200.0]  [1245.3, 1432.6]       26             26
10   H3015  210416_1  juvenile       WT  [1200.0, 1200.0]  [1300.0, 1300.0]       27             27
11   H3015  210416_2  juvenile       WT  [1200.0, 1200.0]  [1335.7, 1254.8]       33             33
12   H3015    210417  juvenile       WT  [1200.0, 1200.0]  [1301.5, 1520.7]       15             15
13   H3016    210422  juvenile       KO  [1200.0, 1200.0]  [1263.8, 1235.2]       11             11
14   H3016    210423  juvenile       KO  [1200.0, 1200.0]  [1234.5, 1533.7]       30             30
15   H3019    210617  juvenile       KO  [1200.0, 1200.0]  [1229.7, 1263.4]       10             10
16   H3019  210618_1  juvenile       KO          [1200.0]          [1232.9]        5              5
17   H3022    210805  juvenile       WT  [1200.0, 1200.0]  [1229.1, 1231.6]       18             18
18   H3022    210806  juvenile       WT  [1200.0, 1200.0]  [1219.3, 1355.1]       29             29
19   H3023    210812  juvenile       WT  [1200.0, 1200.0]  [1219.6, 1300.0]       19             19
20   H3023  210813_1  juvenile       WT  [1200.0, 1200.0]  [1210.6, 1300.0]       22             22
21   H3026    211003  juvenile       KO  [1200.0, 1200.0]  [1285.8, 1300.0]       49             49
22   H3026  211004_2  juvenile       KO  [1200.0, 1200.0]  [1215.0, 1300.0]       43             43
23   H3029    230510  juvenile       WT  [1200.0, 1200.0]  [1228.6, 1254.2]       22             22
24   H4813    220728     adult       WT  [1200.0, 1200.0]  [1218.5, 1227.2]       54             54
25   H4815    220814     adult       WT  [1200.0, 1200.0]  [1289.3, 1269.2]       76             76
26   H4817    220828     adult       KO  [1200.0, 1200.0]  [1249.5, 1228.1]       72             72
27   H4819    220929     adult       KO  [1200.0, 1200.0]  [1257.7, 1224.2]       71             71
28   H4820    221007     adult       WT  [1200.0, 1200.0]  [1263.7, 1242.1]       51             51
29   H4822    221023     adult       KO  [1200.0, 1200.0]  [1222.2, 1245.0]       30             30
30   H4823    221108     adult       WT  [1200.0, 1200.0]  [1230.0, 1288.8]       80             80
31   H4824    221117     adult       KO  [1200.0, 1200.0]  [1464.7, 1271.4]       57             57
32   H4826    221203     adult       WT  [1200.0, 1200.0]  [1285.9, 1271.2]       72             72
33   H4827    221210     adult       KO  [1200.0, 1200.0]  [1247.1, 1218.3]       52             52
34   H4830    230406     adult       WT  [1200.0, 1200.0]  [1278.3, 1302.8]       62             62

recordings whose sessions differ: 35 of 35
cells per group, claims file definition:
                    rats  cells
age_group genotype             
adult     KO           5    282
          WT           6    395
juvenile  KO           5    237
          WT           7    323
main test of each claim under the two session definitions:
     claim                          quantity      value_20min  n_20min     value_claims  n_claims
0   figs1c          inactive: rat means t; p    -0.90; 0.3918       12    -0.95; 0.3666        12
1   figs1c            centre: rat means t; p     1.86; 0.0931       12     1.91; 0.0847        12
2   figs1c      active_speed: rat means t; p     2.10; 0.0625       12     2.22; 0.0504        12
3    figs1  contamination: LME coef KO-WT; p   -0.005; 0.7092      560   -0.005; 0.7092       560
4    figs1      mean_rate: LME coef KO-WT; p   -0.389; 0.7154      560   -0.383; 0.7197       560
5    figs1      peak_rate: LME coef KO-WT; p   -1.130; 0.6163      560   -1.185; 0.6028       560
6    figs1  vector_length: LME coef KO-WT; p    0.098; 0.1116      560    0.099; 0.1062       560
7   figs2c          inactive: rat means t; p     0.11; 0.9120       11    -0.03; 0.9774        11
8   figs2c            centre: rat means t; p    -0.97; 0.3550       11    -0.99; 0.3474        11
9   figs2c      active_speed: rat means t; p     0.40; 0.7018       11     0.44; 0.6729        11
10   figs2  contamination: LME coef KO-WT; p   -0.014; 0.1110      677   -0.014; 0.1110       677
11   figs2      mean_rate: LME coef KO-WT; p   -0.782; 0.3408      677   -0.763; 0.3547       677
12   figs2      peak_rate: LME coef KO-WT; p   -2.148; 0.1006      677   -2.133; 0.1021       677
13   figs2  vector_length: LME coef KO-WT; p   -0.062; 0.2552      677   -0.063; 0.2476       677
14  fig1ef        hd_info: LME coef KO-WT; p    0.338; 0.0303      560    0.335; 0.0312       560
15  fig1ef     half_width: LME coef KO-WT; p  -18.891; 0.5371      560  -16.330; 0.5966       560
16   fig1g                              r WT           0.8151      323           0.7610       323
17   fig1g                              r KO           0.8354      237           0.8385       237
18   fig1h  offset_halves: LME coef KO-WT; p  -24.100; 0.0353      559  -26.844; 0.0138       559
19   fig1j        drift_mean: rat means t; p    -1.91; 0.0845       12    -2.04; 0.0685        12
20  figs1j                              r WT           0.8534      309           0.8551       309
21  figs1j                              r KO           0.7533      225           0.7576       226
22  figs1k  offset_epochs: LME coef KO-WT; p    2.314; 0.8659      534    0.626; 0.9624       535
23   fig2c                              r WT           0.8151      323           0.8256       323
24   fig2c                              r KO           0.9098      232           0.9097       232
25   fig2d  iso_wake_info: LME coef KO-WT; p    0.196; 0.0556      555    0.180; 0.0794       555
26   fig2g                              r WT           0.8311      323           0.8326       323
27   fig2g                              r KO           0.8332      231           0.8313       231
28   fig2h   iso_rem_info: LME coef KO-WT; p    0.207; 0.0451      554    0.207; 0.0451       554
29  fig3ef        hd_info: LME coef KO-WT; p   -0.074; 0.5534      677   -0.070; 0.5750       677
30  fig3ef     half_width: LME coef KO-WT; p  -10.902; 0.5903      677   -8.572; 0.6604       677
31   fig3g                              r WT           0.8038      395           0.8090       395
32   fig3g                              r KO           0.7477      282           0.7423       282
33   fig3h  offset_halves: LME coef KO-WT; p   32.055; 0.0298      677   30.904; 0.0415       677
34   fig3j        drift_mean: rat means t; p     2.93; 0.0168       11     2.75; 0.0226        11
35  figs2j                              r WT           0.7866      395           0.7862       395
36  figs2j                              r KO           0.5617      276           0.5701       276
37  figs2k  offset_epochs: LME coef KO-WT; p   37.021; 0.0282      671   37.641; 0.0292       671
38   fig4c                              r WT           0.9447      395           0.9370       395
39   fig4c                              r KO           0.6139      282           0.6037       282
40   fig4d  iso_wake_info: LME coef KO-WT; p   -0.020; 0.7869      677   -0.019; 0.7984       677
41   fig4g                              r WT           0.8201      378           0.8200       378
42   fig4g                              r KO           0.6505      280           0.6516       280
43   fig4h   iso_rem_info: LME coef KO-WT; p    0.072; 0.2677      658    0.072; 0.2677       658

variants under the claims file definition, juveniles:
  first day, hd_info: coef 0.459, p = 0.0364 (n = 289)
  first day, offset_halves: coef -38.061, p = 0.0064 (n = 288)
  first day, iso_wake_info: coef 0.217, p = 0.2054 (n = 289)
  first day, iso_rem_info: coef 0.200, p = 0.1578 (n = 288)
  first day, halves r WT: 0.6496 (162 cells)
  first day, halves r KO: 0.8971 (127 cells)
  H3026 left out, hd_info: coef 0.301, p = 0.0742 (n = 468)
  H3026 left out, offset_halves: coef -26.619, p = 0.0280 (n = 467)
  H3026 left out, iso_wake_info: coef 0.193, p = 0.0977 (n = 463)
  H3026 left out, iso_rem_info: coef 0.191, p = 0.0949 (n = 462)
  H3026 left out, halves r WT: 0.7610 (323 cells)
  H3026 left out, halves r KO: 0.8693 (145 cells)

Result. With the claims file's definition every recording's sessions differ from the 20 min sessions, by up to 463 s (session 1 of H3001 200201 lasts 1663 s), and session 1 holds the same cells. One main test changes its outcome. For fig1g WT r falls from 0.815 to 0.761 and Fmr1-/y r is 0.839, so neither value is within tolerance and the claim is not reproduced under the rule used for the correlation claims; the third round of verification agreed with this change of outcome. The other tests stay on the same side of their criterion: figs1c active speed p = 0.0504, fig1ef HD information p = 0.031, fig1h p = 0.014, fig1j p = 0.069, fig2d p = 0.079, fig3h p = 0.042, fig3j p = 0.023, and the correlations of figs1j, fig2c, fig2g, fig3g, figs2j, fig4c and fig4g keep the same values within and outside tolerance. REM Isomap information (fig2h, p = 0.045) is the same under both definitions, as it does not use the sessions and the cells are the same; its change from not reproduced in the first round came from fitting Isomap on every bin.

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 Outcome
unit-counts partially reproduced (3 of 4 groups exact; adult Fmr1-/y 440 units in 5 rats)
units-per-recording partially reproduced (juvenile 8 to 83; adult 55 to 114 for all units)
figs1c-juvenile-behaviour-similar reproduced (active speed p = 0.063; first day p = 0.034)
figs2c-adult-behaviour-similar reproduced
figs1-juvenile-cell-metrics-similar reproduced
figs2-adult-cell-metrics-similar reproduced
fig1ef-juvenile-sharper-tuning partially reproduced (HD information p = 0.030, half-width p = 0.54)
fig1g-juvenile-halves-correlation not reproduced (claims file's sessions: WT r 0.761 below 0.81, Fmr1-/y 0.839 below 0.855; with 20 min sessions WT 0.815 is within)
fig1h-juvenile-smaller-offset reproduced (p = 0.035)
fig1j-juvenile-less-drift not reproduced (p = 0.085, same direction)
figs1j-juvenile-epochs-correlation partially reproduced
figs1k-juvenile-epoch-drift-similar reproduced
fig2c-juvenile-isomap-wake-correlation reproduced
fig2d-juvenile-isomap-wake-sharper not reproduced (p = 0.056, same direction)
fig2g-juvenile-isomap-rem-correlation partially reproduced
fig2h-juvenile-isomap-rem-sharper reproduced (p = 0.045)
fig3ef-adult-tuning-similar reproduced
fig3g-adult-halves-correlation not reproduced (r 0.804 and 0.748 against 0.94)
fig3h-adult-larger-offset reproduced (p = 0.030)
fig3j-adult-more-drift reproduced
figs2j-adult-epochs-correlation not reproduced (r 0.787 and 0.562 against 0.90 and 0.76)
figs2k-adult-epoch-drift-larger reproduced
fig4c-adult-isomap-wake-correlation partially reproduced
fig4d-adult-isomap-wake-similar reproduced
fig4g-adult-isomap-rem-correlation partially reproduced
fig4h-adult-isomap-rem-similar reproduced
figs1d-probe-in-posub blocked (histology without annotation)

Several juvenile results sit near the 0.05 threshold and depend on the grouping. HD information (fig1ef, p = 0.030), the offset between halves (fig1h, p = 0.035) and REM Isomap information (fig2h, p = 0.045) lose significance with the archive's labels and with H3026 left out; fig1ef and fig1h hold with the first day of each rat alone, fig2h does not. Waking (fig2d) and REM (fig2h) Isomap information fall on opposite sides of 0.05 (p = 0.056 and 0.045) with LME coefficients of 0.196 and 0.207.

How the analysis differs from the paper's. The genotype of H3026 and the age group of H3029 are taken from the paper's unit counts, not from the archive; the archive's labels and the juvenile results with H3026 left out are shown as variants. H4825's file is a re-timed copy of H4824's recording, so the adult Fmr1-/y group has 5 rats where the paper has 6. Cells re-recorded on consecutive days could not be excluded (the files give no probe depth per day), so they are counted on each day; the first day of each rat is shown as a variant. Exploration sessions are taken from the tracking, as the epoch tables do not mark them reliably, and cut to 20 min, the paper's session length. This departs from the claims file, which cuts only blocks over 30 min, to 1300 s, and the change was made after the first round of verification. Under the claims file's definition fig1g has neither correlation within tolerance (WT r 0.761, Fmr1-/y 0.839), so its outcome is not reproduced, following the claims file; no other outcome changes. The LME is a random-intercept linear model on the raw values; the paper chose between linear, lognormal and gamma models by the data. The decoder follows version 2's Methods, as version 1 gives none. Contamination above 0.5 is excluded, reading the Methods' "below 0.5" as a slip. The offsets include weakly tuned cells; cells with half-width below 120 degrees are shown as a variant.

What was found about the dandiset. The archive's genotype of H3026 and date of birth of H3029 disagree with the paper's counts, which they match when H3026 is a juvenile Fmr1-/y rat and H3029 a juvenile WT rat; the birth dates of H3023 and H3026 are after their recordings, which gives them negative ages in the archive's asset metadata, and no NWB file sets the age. H4825's file holds H4824's recording, re-timed to H4825's epochs and clipped at its end, so one adult Fmr1-/y rat's data are missing. The units table has no cell type, quality or depth. The epoch and task tables mislabel or merge sessions in several files and one file has a single epoch. Two files give positions in pixels while stating centimetres, with head direction on another range; in the others y starts at exactly 0. One unit has unsorted spike times, and juvenile files repeat tracking timestamps. The archive's about field lists the Fmr1 protein under anatomy with the identifier of the disorder.